diff --git a/.run/Demo10.run.xml b/.run/Demo10.run.xml new file mode 100644 index 0000000..19c1c9c --- /dev/null +++ b/.run/Demo10.run.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/.run/Demo9.run.xml b/.run/Demo9.run.xml new file mode 100644 index 0000000..97cff0d --- /dev/null +++ b/.run/Demo9.run.xml @@ -0,0 +1,17 @@ + + + + \ No newline at end of file diff --git a/playground/Demo10/Main.snow b/playground/Demo10/Main.snow new file mode 100644 index 0000000..de91d63 --- /dev/null +++ b/playground/Demo10/Main.snow @@ -0,0 +1,10 @@ +function: main + return_type: int + body: + declare res: boolean = 8L > 7L + if res then + return 131 + end if + return 65537 + end body +end function \ No newline at end of file diff --git a/playground/Demo9/Main.snow b/playground/Demo9/Main.snow new file mode 100644 index 0000000..46749dd --- /dev/null +++ b/playground/Demo9/Main.snow @@ -0,0 +1,31 @@ +module: Math + function: main + parameter: + return_type: int + body: + Math.factorial(6) + return 0 + end body + end function + + function: factorial + parameter: + declare n:int + return_type: int + body: + declare num1:int = 1 + loop: + initializer: + declare counter:int = 1 + condition: + counter <= n + update: + counter = counter + 1 + body: + num1 = num1 * counter + end body + end loop + return num1 + end body + end function +end module 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 0f10d64..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; @@ -10,18 +10,26 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister; import java.util.Map; /** - * 条件比较跳转指令生成器 + * 条件比较跳转指令生成器 *

- * 该类实现了 {@link InstructionGenerator} 接口,用于将 IR 中的条件比较跳转指令 - * 转换为虚拟机可执行的指令序列。主要流程是先将比较操作数加载到虚拟机栈中,生成比较操作码, - * 并发出跳转到目标标签的指令。 + * 该类实现了 {@link InstructionGenerator} 接口, + * 负责将 IR 中的 {@link IRCompareJumpInstruction}(条件比较并跳转指令) + * 转换为目标虚拟机(VM)可执行的指令序列。 + *

+ * + * 主要功能 + * */ public class CmpJumpGenerator implements InstructionGenerator { /** - * 返回该生成器所支持的指令类型。 + * 返回本生成器支持的 IR 指令类型。 * - * @return {@link IRCompareJumpInstruction} 的类对象 + * @return IRCompareJumpInstruction 的类对象 */ @Override public Class supportedClass() { @@ -29,7 +37,19 @@ public class CmpJumpGenerator implements InstructionGenerator类型宽度优先级:D > F > L > I > S > B + *
    + *
  • D(double):6
  • + *
  • F(float):5
  • + *
  • L(long):4
  • + *
  • I(int):3
  • + *
  • S(short):2
  • + *
  • B(byte):1
  • + *
  • 未识别类型:0
  • + *
+ * + * @param p 类型标记字符 + * @return 优先级数值(越大类型越宽) */ private static int rank(char p) { return switch (p) { @@ -39,27 +59,40 @@ public class CmpJumpGenerator implements InstructionGenerator 3; case 'S' -> 2; case 'B' -> 1; - default -> 0; + default -> 0; }; } /** - * 返回优先级更高的类型字符 + * 返回更“宽”的公共类型(即优先级高的类型)。 + * + * @param a 类型标记字符 1 + * @param b 类型标记字符 2 + * @return 宽度更高的类型标记字符 */ private static char promote(char a, char b) { return rank(a) >= rank(b) ? a : b; } /** - * 单字符转字符串 + * 单字符类型标记转字符串。 + * + * @param p 类型标记字符 + * @return 类型字符串 */ private static String str(char p) { return String.valueOf(p); } /** - * 获取从类型 {@code from} 到 {@code to} 的转换指令名。 - * 相同类型或无显式转换需求返回 {@code null}。 + * 获取 {@code from → to} 的类型转换指令名(如不需转换则返回 {@code null})。 + *

+ * 仅覆盖目前常见的整数与浮点类型提升与转换,后续有新类型可补充。 + *

+ * + * @param from 源类型标记字符 + * @param to 目标类型标记字符 + * @return 转换指令名,如“L2I”;无转换返回 {@code null} */ private static String convert(char from, char to) { if (from == to) return null; @@ -78,46 +111,64 @@ public class CmpJumpGenerator implements InstructionGenerator "D2F"; case "SI" -> "S2I"; case "BI" -> "B2I"; - default -> null; + default -> null; }; } /** - * 生成条件比较跳转相关的虚拟机指令。 + * 生成 IR 条件比较跳转指令的 VM 指令序列。 + *
    + *
  1. 确定左右操作数的槽位及静态类型
  2. + *
  3. 加载并按需类型提升转换
  4. + *
  5. 根据公共类型调整比较指令前缀
  6. + *
  7. 发出最终比较和跳转指令
  8. + *
* - * @param ins 需要生成的条件比较跳转中间指令(IR) - * @param out 虚拟机程序构建器,用于输出生成的指令 - * @param slotMap 虚拟寄存器到实际槽(slot)编号的映射表 - * @param currentFn 当前处理的函数名(可用于调试或作用域标识) + * @param ins IR 条件比较跳转指令 + * @param out VMProgramBuilder:用于发出 VM 指令 + * @param slotMap 虚拟寄存器到 VM 槽位的映射表 + * @param currentFn 当前处理的函数名(调试用,当前未使用) */ @Override - public void generate(IRCompareJumpInstruction ins, - VMProgramBuilder out, - Map slotMap, - String currentFn) { - // 获取左操作数所在的寄存器槽编号 - int leftSlot = slotMap.get(ins.left()); - // 获取右操作数所在的寄存器槽编号 - int rightSlot = slotMap.get(ins.right()); + public void generate(IRCompareJumpInstruction ins, + VMProgramBuilder out, + Map slotMap, + String currentFn) { - char lType = out.getSlotType(leftSlot); // 未登记默认 'I' - char rType = out.getSlotType(rightSlot); + // 1. 获取左右操作数的槽位与静态类型 + int leftSlot = slotMap.get(ins.left()); + int rightSlot = slotMap.get(ins.right()); + char lType = out.getSlotType(leftSlot); // 若未登记则默认 'I' + char rType = out.getSlotType(rightSlot); + char tType = promote(lType, rType); // 公共类型提升 - char tType = promote(lType, rType); // 类型提升结果 - - // 加载左操作数到虚拟机栈 + // 2. 加载左右操作数并按需类型转换 + // 左操作数 out.emit(OpHelper.opcode(str(lType) + "_LOAD") + " " + leftSlot); String cvt = convert(lType, tType); - if (cvt != null) out.emit(OpHelper.opcode(cvt)); + if (cvt != null) { + out.emit(OpHelper.opcode(cvt)); + } - // 加载右操作数到虚拟机栈 + // 右操作数 out.emit(OpHelper.opcode(str(rType) + "_LOAD") + " " + rightSlot); cvt = convert(rType, tType); - if (cvt != null) out.emit(OpHelper.opcode(cvt)); + if (cvt != null) { + out.emit(OpHelper.opcode(cvt)); + } - // 获取与当前比较操作对应的虚拟机操作码 + // 3. 选择正确的比较指令前缀 String cmpOp = IROpCodeMapper.toVMOp(ins.op()); - // 生成分支跳转指令,如果比较成立则跳转到目标标签 + /* + * 指令前缀(如 int 类型要用 IC_*, long 类型要用 LC_*) + */ + if (tType == 'I' && cmpOp.startsWith("LC_")) { + cmpOp = "IC_" + cmpOp.substring(3); + } else if (tType == 'L' && cmpOp.startsWith("IC_")) { + cmpOp = "LC_" + cmpOp.substring(3); + } + + // 4. 发出比较与跳转指令 out.emitBranch(OpHelper.opcode(cmpOp), ins.label()); } } 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 91% 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 abeb48f..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; @@ -83,12 +83,12 @@ public final class IROpCodeMapper { // 比较运算映射 // 整形32位比较运算映射 - 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"); // 大于 - opcodeMap.put(IROpCode.CMP_LE, "IC_LE"); // 小于等于 - opcodeMap.put(IROpCode.CMP_GE, "IC_GE"); // 大于等于 + opcodeMap.put(IROpCode.CMP_IEQ, "IC_E"); // 相等 + opcodeMap.put(IROpCode.CMP_INE, "IC_NE"); // 不等 + opcodeMap.put(IROpCode.CMP_ILT, "IC_L"); // 小于 + opcodeMap.put(IROpCode.CMP_IGT, "IC_G"); // 大于 + opcodeMap.put(IROpCode.CMP_ILE, "IC_LE"); // 小于等于 + opcodeMap.put(IROpCode.CMP_IGE, "IC_GE"); // 大于等于 // 整形64位比较运算映射 opcodeMap.put(IROpCode.CMP_LEQ, "LC_E"); // 相等 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; 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 1b5afaf..f53d8cc 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 @@ -4,6 +4,7 @@ import org.jcnc.snow.compiler.ir.core.IROpCode; import org.jcnc.snow.compiler.ir.instruction.CallInstruction; import org.jcnc.snow.compiler.ir.instruction.LoadConstInstruction; import org.jcnc.snow.compiler.ir.instruction.UnaryOperationInstruction; +import org.jcnc.snow.compiler.ir.utils.ComparisonUtils; import org.jcnc.snow.compiler.ir.value.IRConstant; import org.jcnc.snow.compiler.ir.value.IRVirtualRegister; import org.jcnc.snow.compiler.ir.utils.ExpressionUtils; @@ -90,7 +91,7 @@ public record ExpressionBuilder(IRContext ctx) { // !x → (x == 0) if (op.equals("!")) { IRVirtualRegister zero = InstructionFactory.loadConst(ctx, 0); - return InstructionFactory.binOp(ctx, IROpCode.CMP_EQ, val, zero); + return InstructionFactory.binOp(ctx, IROpCode.CMP_IEQ, val, zero); } throw new IllegalStateException("未知一元运算符: " + op); @@ -137,13 +138,18 @@ public record ExpressionBuilder(IRContext ctx) { */ private IRVirtualRegister buildBinary(BinaryExpressionNode bin) { String op = bin.operator(); - IRVirtualRegister left = build(bin.left()); + IRVirtualRegister left = build(bin.left()); IRVirtualRegister right = build(bin.right()); - // 处理比较操作符 - if (ExpressionUtils.isComparisonOperator(op)) { - return InstructionFactory.binOp(ctx, ExpressionUtils.cmpOp(op), left, right); + + // 1. 比较运算 + if (ComparisonUtils.isComparisonOperator(op)) { + return InstructionFactory.binOp( + ctx, + ComparisonUtils.cmpOp(op, bin.left(), bin.right()), + left, right); } - // 处理算术运算符 + + // 2. 其他算术 / 逻辑运算 IROpCode code = ExpressionUtils.resolveOpCode(op, bin.left(), bin.right()); if (code == null) throw new IllegalStateException("不支持的运算符: " + op); return InstructionFactory.binOp(ctx, code, left, right); @@ -161,8 +167,12 @@ public record ExpressionBuilder(IRContext ctx) { IRVirtualRegister a = build(bin.left()); IRVirtualRegister b = build(bin.right()); String op = bin.operator(); - if (ExpressionUtils.isComparisonOperator(op)) { - InstructionFactory.binOpInto(ctx, ExpressionUtils.cmpOp(op), a, b, dest); + + if (ComparisonUtils.isComparisonOperator(op)) { + InstructionFactory.binOpInto( + ctx, + ComparisonUtils.cmpOp(op, bin.left(), bin.right()), + a, b, dest); } else { IROpCode code = ExpressionUtils.resolveOpCode(op, bin.left(), bin.right()); if (code == null) throw new IllegalStateException("不支持的运算符: " + op); 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 7459107..2290278 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 @@ -1,7 +1,7 @@ package org.jcnc.snow.compiler.ir.builder; import org.jcnc.snow.compiler.ir.core.IROpCode; -import org.jcnc.snow.compiler.ir.utils.ExpressionUtils; +import org.jcnc.snow.compiler.ir.utils.ComparisonUtils; import org.jcnc.snow.compiler.ir.utils.IROpCodeUtils; import org.jcnc.snow.compiler.ir.value.IRVirtualRegister; import org.jcnc.snow.compiler.parser.ast.*; @@ -18,23 +18,41 @@ import java.util.Locale; */ public class StatementBuilder { - /** 当前 IR 上下文,包含作用域、指令序列等信息。 */ + /** + * 当前 IR 上下文,包含作用域、指令序列等信息。 + */ private final IRContext ctx; - /** 表达式 IR 构建器,用于将表达式节点转为 IR 指令。 */ + /** + * 表达式 IR 构建器,用于将表达式节点转为 IR 指令。 + */ private final ExpressionBuilder expr; /** * 构造方法。 + * * @param ctx IR 编译上下文环境 */ public StatementBuilder(IRContext ctx) { - this.ctx = ctx; + this.ctx = ctx; this.expr = new ExpressionBuilder(ctx); } + private static char typeSuffixFromType(String type) { + if (type == null) return '\0'; + return switch (type.toLowerCase(Locale.ROOT)) { + case "byte" -> 'b'; + case "short" -> 's'; + case "long" -> 'l'; + case "float" -> 'f'; + case "double" -> 'd'; + default -> '\0'; // 其余默认按 32-bit 整型处理 + }; + } + /** * 将一个 AST 语句节点转为 IR 指令序列。 * 根据节点类型分发到对应的处理方法。 + * * @param stmt 待转换的语句节点 */ public void build(StatementNode stmt) { @@ -107,6 +125,7 @@ public class StatementBuilder { /** * 获取变量名对应的寄存器,不存在则声明一个新的。 + * * @param name 变量名 * @return 变量对应的虚拟寄存器 */ @@ -121,6 +140,7 @@ public class StatementBuilder { /** * 批量构建一组语句节点,顺序处理每个语句。 + * * @param stmts 语句节点集合 */ private void buildStatements(Iterable stmts) { @@ -130,12 +150,13 @@ public class StatementBuilder { /** * 构建循环语句(for/while)。 * 处理流程:初始语句 → 条件判断 → 循环体 → 更新语句 → 跳回条件。 + * * @param loop 循环节点 */ private void buildLoop(LoopNode loop) { if (loop.initializer() != null) build(loop.initializer()); String lblStart = ctx.newLabel(); - String lblEnd = ctx.newLabel(); + String lblEnd = ctx.newLabel(); // 循环开始标签 InstructionFactory.label(ctx, lblStart); @@ -155,11 +176,12 @@ public class StatementBuilder { /** * 构建分支语句(if/else)。 * 处理流程:条件判断 → then 分支 → else 分支(可选)。 + * * @param ifNode if 语句节点 */ private void buildIf(IfNode ifNode) { String lblElse = ctx.newLabel(); - String lblEnd = ctx.newLabel(); + String lblEnd = ctx.newLabel(); // 条件不成立则跳转到 else emitConditionalJump(ifNode.condition(), lblElse); @@ -178,35 +200,30 @@ public class StatementBuilder { /** * 条件跳转指令的生成。 * 如果是二元比较表达式,直接使用对应比较操作码;否则等价于与 0 比较。 - * @param cond 条件表达式 + * + * @param cond 条件表达式 * @param falseLabel 条件不成立时跳转到的标签 */ private void emitConditionalJump(ExpressionNode cond, String falseLabel) { - if (cond instanceof BinaryExpressionNode(ExpressionNode left, String operator, ExpressionNode right) - && ExpressionUtils.isComparisonOperator(operator)) { - // 如果是比较操作(如 ==, >, <),直接生成对应的条件跳转 + if (cond instanceof BinaryExpressionNode( + ExpressionNode left, + String operator, + ExpressionNode right + ) + && ComparisonUtils.isComparisonOperator(operator)) { + IRVirtualRegister a = expr.build(left); IRVirtualRegister b = expr.build(right); - // 获取反向比较操作码 - IROpCode falseOp = IROpCodeUtils.invert(ExpressionUtils.cmpOp(operator)); + + // 使用适配后位宽正确的比较指令 + IROpCode cmp = ComparisonUtils.cmpOp(operator, left, right); + IROpCode falseOp = IROpCodeUtils.invert(cmp); + InstructionFactory.cmpJump(ctx, falseOp, a, b, falseLabel); } else { - // 否则将 cond 与 0 比较,相等则跳转 IRVirtualRegister condReg = expr.build(cond); - IRVirtualRegister zero = InstructionFactory.loadConst(ctx, 0); - InstructionFactory.cmpJump(ctx, IROpCode.CMP_EQ, condReg, zero, falseLabel); + IRVirtualRegister zero = InstructionFactory.loadConst(ctx, 0); + InstructionFactory.cmpJump(ctx, IROpCode.CMP_IEQ, condReg, zero, falseLabel); } } - - private static char typeSuffixFromType(String type) { - if (type == null) return '\0'; - return switch (type.toLowerCase(Locale.ROOT)) { - case "byte" -> 'b'; - case "short" -> 's'; - case "long" -> 'l'; - case "float" -> 'f'; - case "double" -> 'd'; - default -> '\0'; // 其余默认按 32-bit 整型处理 - }; - } } diff --git a/src/main/java/org/jcnc/snow/compiler/ir/core/IROpCode.java b/src/main/java/org/jcnc/snow/compiler/ir/core/IROpCode.java index 4696db8..c45a454 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/core/IROpCode.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/core/IROpCode.java @@ -67,12 +67,12 @@ public enum IROpCode { NEG_D64, // 64位浮点取负 /* ───── 逻辑与比较运算指令(32位整数:int) ───── */ - CMP_EQ, // 32位相等比较:a == b - CMP_NE, // 32位不等比较:a != b - CMP_LT, // 32位小于比较:a < b - CMP_GT, // 32位大于比较:a > b - CMP_LE, // 32位小于等于:a <= b - CMP_GE, // 32位大于等于:a >= b + CMP_IEQ, // 32位相等比较:a == b + CMP_INE, // 32位不等比较:a != b + CMP_ILT, // 32位小于比较:a < b + CMP_IGT, // 32位大于比较:a > b + CMP_ILE, // 32位小于等于:a <= b + CMP_IGE, // 32位大于等于:a >= b /* ───── 逻辑与比较运算指令(64位整数:long) ───── */ CMP_LEQ, // 64位相等比较:a == b diff --git a/src/main/java/org/jcnc/snow/compiler/ir/core/IROpCodeMappings.java b/src/main/java/org/jcnc/snow/compiler/ir/core/IROpCodeMappings.java index 78f38f0..32593d9 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/core/IROpCodeMappings.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/core/IROpCodeMappings.java @@ -9,12 +9,12 @@ public final class IROpCodeMappings { private IROpCodeMappings() {} // 禁止实例化 // 8位整型运算符映射 - public static final Map OP_I8 = Map.of( + public static final Map OP_B8 = Map.of( "+", IROpCode.ADD_B8, "-", IROpCode.SUB_B8, "*", IROpCode.MUL_B8, "/", IROpCode.DIV_B8 ); // 16位整型 - public static final Map OP_I16 = Map.of( + public static final Map OP_S16 = Map.of( "+", IROpCode.ADD_S16, "-", IROpCode.SUB_S16, "*", IROpCode.MUL_S16, "/", IROpCode.DIV_S16 ); @@ -38,8 +38,20 @@ public final class IROpCodeMappings { "+", IROpCode.ADD_D64, "-", IROpCode.SUB_D64, "*", IROpCode.MUL_D64, "/", IROpCode.DIV_D64 ); - // 比较操作符映射 - public static final Map CMP = Map.of( + + /* ────── 比较运算符映射 ────── */ + /** 32-bit(int)比较 */ + public static final Map CMP_I32 = Map.of( + "==", IROpCode.CMP_IEQ, + "!=", IROpCode.CMP_INE, + "<", IROpCode.CMP_ILT, + ">", IROpCode.CMP_IGT, + "<=", IROpCode.CMP_ILE, + ">=", IROpCode.CMP_IGE + ); + + /** 64-bit(long)比较 */ + public static final Map CMP_L64 = Map.of( "==", IROpCode.CMP_LEQ, "!=", IROpCode.CMP_LNE, "<", IROpCode.CMP_LLT, @@ -47,4 +59,6 @@ public final class IROpCodeMappings { "<=", IROpCode.CMP_LLE, ">=", IROpCode.CMP_LGE ); + + } diff --git a/src/main/java/org/jcnc/snow/compiler/ir/utils/ComparisonUtils.java b/src/main/java/org/jcnc/snow/compiler/ir/utils/ComparisonUtils.java new file mode 100644 index 0000000..59042e9 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/utils/ComparisonUtils.java @@ -0,0 +1,49 @@ +package org.jcnc.snow.compiler.ir.utils; + +import org.jcnc.snow.compiler.ir.core.IROpCode; +import org.jcnc.snow.compiler.ir.core.IROpCodeMappings; +import org.jcnc.snow.compiler.parser.ast.NumberLiteralNode; +import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode; + +import java.util.Map; + +/** + * 比较运算辅助工具: + * 根据左右操作数类型(目前通过字面量后缀 L/l 判定)选择 + * 正确的 IR 比较指令,保证 int/long 均能正常运行。 + */ +public final class ComparisonUtils { + private ComparisonUtils() { + } + + /** + * 判断给定操作符是否为比较运算符 + */ + public static boolean isComparisonOperator(String op) { + // 两张表 key 完全一致,只需检查一张 + return IROpCodeMappings.CMP_I32.containsKey(op); + } + + /** + * 返回符合操作数位宽的比较 IROpCode。 + * + * @param op 比较符号(==, !=, <, >, <=, >=) + * @param left 左操作数 AST + * @param right 右操作数 AST + */ + public static IROpCode cmpOp(String op, ExpressionNode left, ExpressionNode right) { + boolean useLong = isLongLiteral(left) || isLongLiteral(right); + Map table = useLong ? IROpCodeMappings.CMP_L64 + : IROpCodeMappings.CMP_I32; + return table.get(op); + } + + /* ------------ 内部工具 ------------ */ + + private static boolean isLongLiteral(ExpressionNode node) { + if (node instanceof NumberLiteralNode(String value)) { + return value.endsWith("L") || value.endsWith("l"); + } + return false; // 变量暂不处理(后续可扩展符号表查询) + } +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/utils/ExpressionUtils.java b/src/main/java/org/jcnc/snow/compiler/ir/utils/ExpressionUtils.java index 8d48011..7c93c9a 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/utils/ExpressionUtils.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/utils/ExpressionUtils.java @@ -12,99 +12,83 @@ import java.util.Map; /** * 表达式分析与运算符辅助工具类。 - *

- * 主要功能包括: + * + *

主要功能:

*
    *
  • 字面量常量的解析与类型推断
  • - *
  • 自动匹配操作码
  • - *
  • 表达式类型合并与判定
  • + *
  • 自动匹配算术/比较操作码
  • + *
  • 表达式类型合并与提升
  • *
*/ -public class ExpressionUtils { +public final class ExpressionUtils { - /** 用于存储默认的类型后缀(如函数返回类型),线程隔离。 */ + private ExpressionUtils() {} + + /* ────────────────── 线程级默认类型后缀 ────────────────── */ + + /** 默认类型后缀(如当前函数返回类型),线程隔离。 */ private static final ThreadLocal DEFAULT_SUFFIX = ThreadLocal.withInitial(() -> '\0'); - /** - * 在进入函数 IR 构建前设置默认的类型后缀(比如函数返回类型)。 - * @param suffix 默认后缀字符,如 'i', 'l', 'f', 'd' 等 - */ - public static void setDefaultSuffix(char suffix) { - DEFAULT_SUFFIX.set(suffix); - } + public static void setDefaultSuffix(char suffix) { DEFAULT_SUFFIX.set(suffix); } - /** - * 在函数 IR 构建结束后清除默认后缀,避免影响后续分析。 - */ - public static void clearDefaultSuffix() { - DEFAULT_SUFFIX.set('\0'); - } + public static void clearDefaultSuffix() { DEFAULT_SUFFIX.set('\0'); } + + /* ───────────────────── 字面量 & 常量 ───────────────────── */ /** * 解析整数字面量字符串,自动去除类型后缀(b/s/l/f/d/B/S/L/F/D),并转换为 int。 - * - * @param literal 字面量字符串,如 "123", "123l", "42B" - * @return 解析得到的 int 整数 */ public static int parseIntSafely(String literal) { - // 去掉类型后缀,只保留数字部分 String digits = literal.replaceAll("[bslfdBSDLF]$", ""); return Integer.parseInt(digits); } /** - * 根据数字字面量字符串自动判断类型,生成对应类型的 IRConstant。 - * 支持 b/s/l/f/d 类型后缀与浮点格式,自动分配合适类型。 - * - * @param ctx IR 编译上下文环境 - * @param value 字面量字符串(如 "1", "2l", "3.14f", "5D") - * @return 生成的 IRConstant 对象,包含正确类型 + * 根据数字字面量字符串自动判断类型,生成对应类型的 {@link IRConstant}。 + * 支持 b/s/l/f/d 后缀与浮点格式。 */ public static IRConstant buildNumberConstant(IRContext ctx, String value) { - char suffix = value.isEmpty() ? '\0' : Character.toLowerCase(value.charAt(value.length() - 1)); + char suffix = value.isEmpty() ? '\0' + : Character.toLowerCase(value.charAt(value.length() - 1)); + String digits = switch (suffix) { case 'b','s','l','f','d' -> value.substring(0, value.length() - 1); default -> { + /* 如果字面量本身没有后缀,则回退到变量目标类型(如声明语句左值) */ if (ctx.getVarType() != null) { - final var receiverType = ctx.getVarType(); - switch (receiverType) { - case "byte" -> suffix = 'b'; - case "short" -> suffix = 's'; - case "int" -> suffix = 'i'; - case "long" -> suffix = 'l'; - case "float" -> suffix = 'f'; - case "double" -> suffix = 'd'; - } + String t = ctx.getVarType(); + suffix = switch (t) { + case "byte" -> 'b'; + case "short" -> 's'; + case "int" -> 'i'; + case "long" -> 'l'; + case "float" -> 'f'; + case "double" -> 'd'; + default -> '\0'; + }; } - yield value; } }; - // 根据类型后缀或数值格式创建常量 + + /* 创建常量 */ return switch (suffix) { case 'b' -> new IRConstant(Byte.parseByte(digits)); case 's' -> new IRConstant(Short.parseShort(digits)); case 'l' -> new IRConstant(Long.parseLong(digits)); case 'f' -> new IRConstant(Float.parseFloat(digits)); case 'd' -> new IRConstant(Double.parseDouble(digits)); - default -> looksLikeFloat(digits) + default -> looksLikeFloat(digits) ? new IRConstant(Double.parseDouble(digits)) : new IRConstant(Integer.parseInt(digits)); }; } + /* ────────────────────── 一元运算 ────────────────────── */ + /** - * 根据表达式节点推断一元取负(-)运算应使用的操作码。 - * - *

优先级与 {@link #resolveOpCode} 使用的类型提升规则保持一致:

- *
    - *
  • 字面量或标识符带显式后缀时,直接以后缀决定位宽;
  • - *
  • 未显式指定时,默认使用 32 位整型 {@link IROpCode#NEG_I32}。
  • - *
- * - * @param operand 一元取负运算的操作数 - * @return 匹配的 {@link IROpCode} + * 推断一元取负(-)运算应使用的 {@link IROpCode}。 */ public static IROpCode negOp(ExpressionNode operand) { char t = typeChar(operand); @@ -114,113 +98,82 @@ public class ExpressionUtils { case 'l' -> IROpCode.NEG_L64; case 'f' -> IROpCode.NEG_F32; case 'd' -> IROpCode.NEG_D64; - default -> IROpCode.NEG_I32; + default -> IROpCode.NEG_I32; // '\0' 或 'i' }; } - /* =================== 类型推断与操作符匹配 =================== */ + /* ────────────────── 比较运算(已适配 long) ────────────────── */ - /** - * 递归推断单个表达式节点的类型后缀(b/s/l/f/d)。 - * 对于二元表达式,将左右两侧的类型自动提升合并,遵循优先级顺序:d > f > l > s > b > '\0'。 - * - * @param node 表达式节点 - * @return 类型后缀字符,b/s/l/f/d 或 '\0' - */ - private static char typeChar(ExpressionNode node) { - // 字面量节点,直接判断最后一位 - if (node instanceof NumberLiteralNode(String value)) { - char last = Character.toLowerCase(value.charAt(value.length() - 1)); - return switch (last) { - case 'b', 's', 'l', 'f', 'd' -> last; - default -> looksLikeFloat(value) ? 'd' : '\0'; - }; - } - // 二元表达式,递归判断左右子节点 - if (node instanceof BinaryExpressionNode bin) { - char l = typeChar(bin.left()); - char r = typeChar(bin.right()); - return maxTypeChar(l, r); - } - // 其他情况(如变量节点),暂不处理,默认返回 '\0' - return '\0'; + /** 判断给定字符串是否是比较运算符(==, !=, <, >, <=, >=)。 */ + public static boolean isComparisonOperator(String op) { + return ComparisonUtils.isComparisonOperator(op); } /** - * 推断两个表达式节点合并后的类型后缀。 - * 返回优先级更高的类型后缀字符。 - * - * @param left 左表达式节点 - * @param right 右表达式节点 - * @return 合并后类型的后缀字符 + * 兼容旧调用:仅凭操作符返回 int32 比较指令。 */ + public static IROpCode cmpOp(String op) { + return IROpCodeMappings.CMP_I32.get(op); // 旧逻辑:一律 i32 + } + + /** + * 推荐调用:根据左右表达式类型自动选择 int / long 比较指令。 + */ + public static IROpCode cmpOp(String op, ExpressionNode left, ExpressionNode right) { + return ComparisonUtils.cmpOp(op, left, right); + } + + /* ──────────────── 类型推断 & 算术操作码匹配 ──────────────── */ + + /** 递归推断单个表达式节点的类型后缀(b/s/i/l/f/d)。 */ + private static char typeChar(ExpressionNode node) { + if (node instanceof NumberLiteralNode(String value)) { + char last = Character.toLowerCase(value.charAt(value.length() - 1)); + return switch (last) { + case 'b','s','i','l','f','d' -> last; + default -> looksLikeFloat(value) ? 'd' : '\0'; + }; + } + if (node instanceof BinaryExpressionNode bin) { + return maxTypeChar(typeChar(bin.left()), typeChar(bin.right())); + } + return '\0'; // 变量等暂不处理 + } + + /** 合并两侧表达式的类型后缀。 */ public static char resolveSuffix(ExpressionNode left, ExpressionNode right) { return maxTypeChar(typeChar(left), typeChar(right)); } - /** - * 在两个类型后缀中选取精度更高的一个。 - * 优先级依次为:d > f > l > s > b > '\0' - * - * @param l 左类型后缀 - * @param r 右类型后缀 - * @return 更高优先级的类型后缀字符 - */ + /** 类型优先级:d > f > l > i > s > b > '\0' */ private static char maxTypeChar(char l, char r) { if (l == 'd' || r == 'd') return 'd'; if (l == 'f' || r == 'f') return 'f'; if (l == 'l' || r == 'l') return 'l'; + if (l == 'i' || r == 'i') return 'i'; if (l == 's' || r == 's') return 's'; if (l == 'b' || r == 'b') return 'b'; return '\0'; } /** - * 判断给定字符串是否为比较运算符(如 >, <, == 等)。 - * - * @param op 操作符字符串 - * @return 如果是比较操作符返回 true,否则返回 false - */ - public static boolean isComparisonOperator(String op) { - return IROpCodeMappings.CMP.containsKey(op); - } - - /** - * 获取比较操作符对应的中间表示操作码(IROpCode)。 - * - * @param op 比较操作符字符串 - * @return 对应的 IROpCode,如果不存在则返回 null - */ - public static IROpCode cmpOp(String op) { - return IROpCodeMappings.CMP.get(op); - } - - /** - * 根据操作符和两侧表达式自动选择正确的 IROpCode。 - * 首先根据参与表达式类型推断后缀,若无法推断则回退到函数默认类型, - * 还无法推断则默认使用 i32(32位整型)。 - * - * @param op 操作符字符串,如 "+" - * @param left 左侧表达式节点 - * @param right 右侧表达式节点 - * @return 匹配的 IROpCode,如果不存在则返回 null + * 根据操作符和两侧表达式选择正确的算术 {@link IROpCode}。 */ public static IROpCode resolveOpCode(String op, ExpressionNode left, ExpressionNode right) { - /* 1) 尝试从参与者常量字面量推断 */ + /* 1. 尝试根据字面量推断 */ char suffix = resolveSuffix(left, right); - /* 2) 若无法推断,退回到函数返回类型(DEFAULT_SUFFIX) */ - if (suffix == '\0') { - suffix = DEFAULT_SUFFIX.get(); - } + /* 2. 若失败则使用函数级默认类型 */ + if (suffix == '\0') suffix = DEFAULT_SUFFIX.get(); - /* 3) 再次失败则默认为 i32 */ + /* 3. 仍失败则默认为 int32 */ Map table = switch (suffix) { - case 'b' -> IROpCodeMappings.OP_I8; - case 's' -> IROpCodeMappings.OP_I16; + case 'b' -> IROpCodeMappings.OP_B8; + case 's' -> IROpCodeMappings.OP_S16; + case 'i' -> IROpCodeMappings.OP_I32; case 'l' -> IROpCodeMappings.OP_L64; case 'f' -> IROpCodeMappings.OP_F32; case 'd' -> IROpCodeMappings.OP_D64; @@ -230,13 +183,12 @@ public class ExpressionUtils { return table.get(op); } - /** - * 判断字符串是否为浮点数形式(即包含小数点或科学计数法 e/E)。 - * - * @param digits 数字字符串 - * @return 如果看起来像浮点数则返回 true,否则返回 false - */ + /* ────────────────────────── 工具 ───────────────────────── */ + + /** 是否像浮点字面量(包含 '.' 或 e/E)。 */ private static boolean looksLikeFloat(String digits) { - return digits.indexOf('.') >= 0 || digits.indexOf('e') >= 0 || digits.indexOf('E') >= 0; + return digits.indexOf('.') >= 0 + || digits.indexOf('e') >= 0 + || digits.indexOf('E') >= 0; } } diff --git a/src/main/java/org/jcnc/snow/compiler/ir/utils/IROpCodeUtils.java b/src/main/java/org/jcnc/snow/compiler/ir/utils/IROpCodeUtils.java index fb2eba0..6e782a7 100644 --- a/src/main/java/org/jcnc/snow/compiler/ir/utils/IROpCodeUtils.java +++ b/src/main/java/org/jcnc/snow/compiler/ir/utils/IROpCodeUtils.java @@ -8,13 +8,21 @@ import java.util.Map; * IR 操作码辅助工具。 */ public class IROpCodeUtils { - private static final Map INVERT = Map.of( - IROpCode.CMP_LEQ, IROpCode.CMP_LNE, - IROpCode.CMP_LNE, IROpCode.CMP_LEQ, - IROpCode.CMP_LLT, IROpCode.CMP_LGE, - IROpCode.CMP_LGE, IROpCode.CMP_LLT, - IROpCode.CMP_LGT, IROpCode.CMP_LLE, - IROpCode.CMP_LLE, IROpCode.CMP_LGT + private static final Map INVERT = Map.ofEntries( + // 32-bit + Map.entry(IROpCode.CMP_IEQ, IROpCode.CMP_INE), + Map.entry(IROpCode.CMP_INE, IROpCode.CMP_IEQ), + Map.entry(IROpCode.CMP_ILT, IROpCode.CMP_IGE), + Map.entry(IROpCode.CMP_IGE, IROpCode.CMP_ILT), + Map.entry(IROpCode.CMP_IGT, IROpCode.CMP_ILE), + Map.entry(IROpCode.CMP_ILE, IROpCode.CMP_IGT), + // 64-bit + Map.entry(IROpCode.CMP_LEQ, IROpCode.CMP_LNE), + Map.entry(IROpCode.CMP_LNE, IROpCode.CMP_LEQ), + Map.entry(IROpCode.CMP_LLT, IROpCode.CMP_LGE), + Map.entry(IROpCode.CMP_LGE, IROpCode.CMP_LLT), + Map.entry(IROpCode.CMP_LGT, IROpCode.CMP_LLE), + Map.entry(IROpCode.CMP_LLE, IROpCode.CMP_LGT) ); /** diff --git a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BinaryExpressionAnalyzer.java b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BinaryExpressionAnalyzer.java index 2bc22de..c14b83b 100644 --- a/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BinaryExpressionAnalyzer.java +++ b/src/main/java/org/jcnc/snow/compiler/semantic/analyzers/expression/BinaryExpressionAnalyzer.java @@ -11,79 +11,75 @@ import org.jcnc.snow.compiler.semantic.type.BuiltinType; import org.jcnc.snow.compiler.semantic.type.Type; /** - * {@code BinaryExpressionAnalyzer} 是一个用于分析二元表达式的语义分析器。 + * {@code BinaryExpressionAnalyzer} 负责对二元表达式做语义分析并返回其类型。 *

- * 支持的特性包括: - *

    - *
  • 字符串拼接(当运算符为加号 "+" 且任一操作数为字符串类型时)
  • - *
  • 数值类型的自动宽化转换(如 int 与 float 运算将转换为 float)
  • - *
  • 基本的数值运算符(如 +, -, *, /, %)
  • - *
  • 关系运算符和比较运算符(如 <, <=, >, >=, ==, !=)
  • - *
- * 对于不支持的运算符或不兼容的类型组合,将记录语义错误,并默认返回 {@code BuiltinType.INT} 以保持分析过程的连续性。 + * 支持特性: + * 1. 字符串拼接「+」 + * 2. 数值运算与自动宽化 + * 3. 比较 / 关系运算 + * 4. 布尔值比较(== / !=) *

- * 实现类遵循 {@code ExpressionAnalyzer} 接口规范。 + * 如遇不支持的运算符或不兼容的类型组合,将记录语义错误, + * 并以 {@code int} 作为回退类型,保持后续分析不中断。 */ public class BinaryExpressionAnalyzer implements ExpressionAnalyzer { - /** - * 分析给定的二元表达式节点,返回其表达式类型。 - * - * @param ctx 当前语义分析上下文,用于访问日志记录、错误收集、注册表等服务。 - * @param mi 当前模块信息,包含模块级别的符号与类型定义。 - * @param fn 当前正在分析的函数节点。 - * @param locals 当前函数作用域内的符号表,用于变量查找。 - * @param bin 要分析的二元表达式节点。 - * @return 分析后推断出的表达式类型。 - */ @Override public Type analyze(Context ctx, ModuleInfo mi, FunctionNode fn, SymbolTable locals, BinaryExpressionNode bin) { + ctx.log("检查二元表达式: " + bin.operator()); - // 获取左侧表达式类型 - Type left = ctx.getRegistry().getExpressionAnalyzer(bin.left()) + /* ----------- 先递归分析左右子表达式类型 ----------- */ + Type left = ctx.getRegistry() + .getExpressionAnalyzer(bin.left()) .analyze(ctx, mi, fn, locals, bin.left()); - // 获取右侧表达式类型 - Type right = ctx.getRegistry().getExpressionAnalyzer(bin.right()) + Type right = ctx.getRegistry() + .getExpressionAnalyzer(bin.right()) .analyze(ctx, mi, fn, locals, bin.right()); String op = bin.operator(); - // 情况 1:字符串拼接(+ 操作符且任一操作数为字符串类型) + /* ----------- 情况 1:字符串拼接 ----------- */ if (op.equals("+") && (left == BuiltinType.STRING || right == BuiltinType.STRING)) { return BuiltinType.STRING; } - // 情况 2:数值类型运算或比较 + /* ----------- 情况 1.5:布尔值比较 ----------- */ + if (("==".equals(op) || "!=".equals(op)) && + left == BuiltinType.BOOLEAN && + right == BuiltinType.BOOLEAN) { + return BuiltinType.BOOLEAN; + } + + /* ----------- 情况 2:数值运算 / 比较 ----------- */ if ("+-*/%".contains(op) || ("<<=>>===!=").contains(op)) { if (left.isNumeric() && right.isNumeric()) { - // 自动宽化到更宽的数值类型(如 int + float => float) + // 自动数值宽化(如 int + float → float) Type wide = Type.widen(left, right); - if (wide == null) wide = BuiltinType.INT; // 容错降级为 int + if (wide == null) wide = BuiltinType.INT; // 容错降级 - // 若为比较运算符,统一返回 boolean 类型作为布尔值表示 + // 比较运算统一返回 boolean if ("< <= > >= == !=".contains(op)) { return BuiltinType.BOOLEAN; } - return wide; } } - // 情况 3:不支持的类型组合,记录语义错误 + /* ----------- 情况 3:不支持的类型组合 ----------- */ ctx.getErrors().add(new SemanticError( bin, String.format("运算符 '%s' 不支持类型: %s 和 %s", op, left, right) )); ctx.log("错误: 运算符 '" + op + "' 不支持类型: " + left + ", " + right); - // 错误情况下默认返回 int 类型,以保证语义分析不中断 + // 回退类型 return BuiltinType.INT; } } 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; diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCECommand.java new file mode 100644 index 0000000..f7ccc5b --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.byte8; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The BCECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if they are equal, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two byte8 from the virtual machine stack.
  • + *
  • If the two byte8 are equal, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class BCECommand implements Command { + /** + * Default constructor for creating an instance of BCECommand. + * This constructor is empty as no specific initialization is required. + */ + public BCECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // If the operands are equal, jump to the target command + if (a == b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCGCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCGCommand.java new file mode 100644 index 0000000..92fb765 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCGCommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.byte8; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The BCGCommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is greater than the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two byte8 from the virtual machine stack.
  • + *
  • If the first byte8 is greater than the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class BCGCommand implements Command { + /** + * Default constructor for creating an instance of BCGCommand. + * This constructor is empty as no specific initialization is required. + */ + public BCGCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // If the first operand is greater than the second, jump to the target command + if (a > b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCGECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCGECommand.java new file mode 100644 index 0000000..16f468e --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCGECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.byte8; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The BCGECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is greater than or equal to the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two byte8 from the virtual machine stack.
  • + *
  • If the first byte8 is greater than or equal to the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class BCGECommand implements Command { + /** + * Default constructor for creating an instance of BCGECommand. + * This constructor is empty as no specific initialization is required. + */ + public BCGECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // If the first operand is greater than or equal to the second, jump to the target command + if (a >= b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCLCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCLCommand.java new file mode 100644 index 0000000..1753865 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCLCommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.byte8; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The BCLCommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is less than the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two byte8 from the virtual machine stack.
  • + *
  • If the first byte8 is less than the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class BCLCommand implements Command { + /** + * Default constructor for creating an instance of BCLCommand. + * This constructor is empty as no specific initialization is required. + */ + public BCLCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // If the first operand is less than the second, jump to the target command + if (a < b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCLECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCLECommand.java new file mode 100644 index 0000000..bb90118 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCLECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.byte8; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The BCLECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is less than or equal to the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two byte8 from the virtual machine stack.
  • + *
  • If the first byte8 is less than or equal to the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class BCLECommand implements Command { + /** + * Default constructor for creating an instance of BCLECommand. + * This constructor is empty as no specific initialization is required. + */ + public BCLECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // If the first operand is less than or equal to the second, jump to the target command + if (a <= b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCNECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCNECommand.java new file mode 100644 index 0000000..a474570 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/byte8/BCNECommand.java @@ -0,0 +1,77 @@ +package org.jcnc.snow.vm.commands.control.byte8; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The BCNECommand class implements the {@link Command} interface and represents a conditional jump command + * in the virtual machine that triggers if two values are not equal. + * + *

Specific behavior:

+ *
    + *
  • Pops two byte8 from the virtual machine stack.
  • + *
  • If the two byte8 are not equal, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class BCNECommand implements Command { + /** + * Default constructor for creating an instance of BCNECommand. + * This constructor is empty as no specific initialization is required. + */ + public BCNECommand() { + + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // If the operands are not equal, jump to the target command + if (a != b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCECommand.java new file mode 100644 index 0000000..0153626 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.double64; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The DCECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if they are equal, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two double64 from the virtual machine stack.
  • + *
  • If the two double64 are equal, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class DCECommand implements Command { + /** + * Default constructor for creating an instance of DCECommand. + * This constructor is empty as no specific initialization is required. + */ + public DCECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // If the operands are equal, jump to the target command + if (a == b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCGCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCGCommand.java new file mode 100644 index 0000000..fd48bff --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCGCommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.double64; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The DCGCommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is greater than the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two double64 from the virtual machine stack.
  • + *
  • If the first double64 is greater than the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class DCGCommand implements Command { + /** + * Default constructor for creating an instance of DCGCommand. + * This constructor is empty as no specific initialization is required. + */ + public DCGCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // If the first operand is greater than the second, jump to the target command + if (a > b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCGECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCGECommand.java new file mode 100644 index 0000000..03dad61 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCGECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.double64; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The DCGECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is greater than or equal to the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two double64 from the virtual machine stack.
  • + *
  • If the first double64 is greater than or equal to the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class DCGECommand implements Command { + /** + * Default constructor for creating an instance of DCGECommand. + * This constructor is empty as no specific initialization is required. + */ + public DCGECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // If the first operand is greater than or equal to the second, jump to the target command + if (a >= b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCLCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCLCommand.java new file mode 100644 index 0000000..344df6c --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCLCommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.double64; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The DCLCommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is less than the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two double64 from the virtual machine stack.
  • + *
  • If the first double64 is less than the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class DCLCommand implements Command { + /** + * Default constructor for creating an instance of DCLCommand. + * This constructor is empty as no specific initialization is required. + */ + public DCLCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // If the first operand is less than the second, jump to the target command + if (a < b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCLECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCLECommand.java new file mode 100644 index 0000000..3d87f1a --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCLECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.double64; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The DCLECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is less than or equal to the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two double64 from the virtual machine stack.
  • + *
  • If the first double64 is less than or equal to the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class DCLECommand implements Command { + /** + * Default constructor for creating an instance of DCLECommand. + * This constructor is empty as no specific initialization is required. + */ + public DCLECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // If the first operand is less than or equal to the second, jump to the target command + if (a <= b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCNECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCNECommand.java new file mode 100644 index 0000000..1da0475 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/double64/DCNECommand.java @@ -0,0 +1,77 @@ +package org.jcnc.snow.vm.commands.control.double64; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The DCNECommand class implements the {@link Command} interface and represents a conditional jump command + * in the virtual machine that triggers if two values are not equal. + * + *

Specific behavior:

+ *
    + *
  • Pops two double64 from the virtual machine stack.
  • + *
  • If the two double64 are not equal, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class DCNECommand implements Command { + /** + * Default constructor for creating an instance of DCNECommand. + * This constructor is empty as no specific initialization is required. + */ + public DCNECommand() { + + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // If the operands are not equal, jump to the target command + if (a != b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCECommand.java new file mode 100644 index 0000000..6c8620d --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.float32; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The FCECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if they are equal, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two float32 from the virtual machine stack.
  • + *
  • If the two float32 are equal, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class FCECommand implements Command { + /** + * Default constructor for creating an instance of FCECommand. + * This constructor is empty as no specific initialization is required. + */ + public FCECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // If the operands are equal, jump to the target command + if (a == b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCGCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCGCommand.java new file mode 100644 index 0000000..2b9b71f --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCGCommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.float32; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The FCGCommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is greater than the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two float32 from the virtual machine stack.
  • + *
  • If the first float32 is greater than the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class FCGCommand implements Command { + /** + * Default constructor for creating an instance of FCGCommand. + * This constructor is empty as no specific initialization is required. + */ + public FCGCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // If the first operand is greater than the second, jump to the target command + if (a > b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCGECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCGECommand.java new file mode 100644 index 0000000..45d5fc1 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCGECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.float32; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The FCGECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is greater than or equal to the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two float32 from the virtual machine stack.
  • + *
  • If the first float32 is greater than or equal to the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class FCGECommand implements Command { + /** + * Default constructor for creating an instance of FCGECommand. + * This constructor is empty as no specific initialization is required. + */ + public FCGECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // If the first operand is greater than or equal to the second, jump to the target command + if (a >= b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCLCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCLCommand.java new file mode 100644 index 0000000..26cc4bb --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCLCommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.float32; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The FCLCommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is less than the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two float32 from the virtual machine stack.
  • + *
  • If the first float32 is less than the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class FCLCommand implements Command { + /** + * Default constructor for creating an instance of FCLCommand. + * This constructor is empty as no specific initialization is required. + */ + public FCLCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // If the first operand is less than the second, jump to the target command + if (a < b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCLECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCLECommand.java new file mode 100644 index 0000000..becc5d5 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCLECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.float32; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The FCLECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is less than or equal to the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two float32 from the virtual machine stack.
  • + *
  • If the first float32 is less than or equal to the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class FCLECommand implements Command { + /** + * Default constructor for creating an instance of FCLECommand. + * This constructor is empty as no specific initialization is required. + */ + public FCLECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // If the first operand is less than or equal to the second, jump to the target command + if (a <= b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCNECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCNECommand.java new file mode 100644 index 0000000..d75ac57 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/float32/FCNECommand.java @@ -0,0 +1,77 @@ +package org.jcnc.snow.vm.commands.control.float32; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The FCNECommand class implements the {@link Command} interface and represents a conditional jump command + * in the virtual machine that triggers if two values are not equal. + * + *

Specific behavior:

+ *
    + *
  • Pops two float32 from the virtual machine stack.
  • + *
  • If the two float32 are not equal, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class FCNECommand implements Command { + /** + * Default constructor for creating an instance of FCNECommand. + * This constructor is empty as no specific initialization is required. + */ + public FCNECommand() { + + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // If the operands are not equal, jump to the target command + if (a != b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICECommand.java index 6e923af..fc1636e 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICECommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICECommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the two integers are equal, jumps to the target command.
  • + *
  • Pops two int32 from the virtual machine stack.
  • + *
  • If the two int32 are equal, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICGCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICGCommand.java index a339313..574151e 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICGCommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICGCommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the first integer is greater than the second, jumps to the target command.
  • + *
  • Pops two int32 from the virtual machine stack.
  • + *
  • If the first int32 is greater than the second, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICGECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICGECommand.java index 3cfe02d..8f28127 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICGECommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICGECommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the first integer is greater than or equal to the second, jumps to the target command.
  • + *
  • Pops two int32 from the virtual machine stack.
  • + *
  • If the first int32 is greater than or equal to the second, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICLCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICLCommand.java index ec3d413..e1909e9 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICLCommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICLCommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the first integer is less than the second, jumps to the target command.
  • + *
  • Pops two int32 from the virtual machine stack.
  • + *
  • If the first int32 is less than the second, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICLECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICLECommand.java index 4e6c007..0410d1f 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICLECommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICLECommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the first integer is less than or equal to the second, jumps to the target command.
  • + *
  • Pops two int32 from the virtual machine stack.
  • + *
  • If the first int32 is less than or equal to the second, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICNECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICNECommand.java index 08a46a9..b921efc 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICNECommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/int32/ICNECommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the two integers are not equal, jumps to the target command.
  • + *
  • Pops two int32 from the virtual machine stack.
  • + *
  • If the two int32 are not equal, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCECommand.java index 33ecbfc..9eb73e3 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCECommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCECommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the two integers are equal, jumps to the target command.
  • + *
  • Pops two long64 from the virtual machine stack.
  • + *
  • If the two long64 are equal, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCGCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCGCommand.java index c9abdee..83b99e4 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCGCommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCGCommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the first integer is greater than the second, jumps to the target command.
  • + *
  • Pops two long64 from the virtual machine stack.
  • + *
  • If the first long64 is greater than the second, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCGECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCGECommand.java index 89f50d3..3ce9e90 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCGECommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCGECommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the first integer is greater than or equal to the second, jumps to the target command.
  • + *
  • Pops two long64 from the virtual machine stack.
  • + *
  • If the first long64 is greater than or equal to the second, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCLCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCLCommand.java index 1467371..b52eb64 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCLCommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCLCommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the first integer is less than the second, jumps to the target command.
  • + *
  • Pops two long64 from the virtual machine stack.
  • + *
  • If the first long64 is less than the second, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCLECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCLECommand.java index 634b183..e585fd7 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCLECommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCLECommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the first integer is less than or equal to the second, jumps to the target command.
  • + *
  • Pops two long64 from the virtual machine stack.
  • + *
  • If the first long64 is less than or equal to the second, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCNECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCNECommand.java index 7aba528..4031630 100644 --- a/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCNECommand.java +++ b/src/main/java/org/jcnc/snow/vm/commands/control/long64/LCNECommand.java @@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils; * *

Specific behavior:

*
    - *
  • Pops two integers from the virtual machine stack.
  • - *
  • If the two integers are not equal, jumps to the target command.
  • + *
  • Pops two long64 from the virtual machine stack.
  • + *
  • If the two long64 are not equal, jumps to the target command.
  • *
  • Otherwise, the program continues with the next command.
  • *
*/ diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCECommand.java new file mode 100644 index 0000000..d1715a9 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.short16; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The SCECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if they are equal, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two short16 from the virtual machine stack.
  • + *
  • If the two short16 are equal, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class SCECommand implements Command { + /** + * Default constructor for creating an instance of SCECommand. + * This constructor is empty as no specific initialization is required. + */ + public SCECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + short b = (short) operandStack.pop(); + short a = (short) operandStack.pop(); + + // If the operands are equal, jump to the target command + if (a == b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCGCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCGCommand.java new file mode 100644 index 0000000..42cc70a --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCGCommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.short16; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The SCGCommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is greater than the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two short16 from the virtual machine stack.
  • + *
  • If the first short16 is greater than the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class SCGCommand implements Command { + /** + * Default constructor for creating an instance of SCGCommand. + * This constructor is empty as no specific initialization is required. + */ + public SCGCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + short b = (short) operandStack.pop(); + short a = (short) operandStack.pop(); + + // If the first operand is greater than the second, jump to the target command + if (a > b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCGECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCGECommand.java new file mode 100644 index 0000000..78e8add --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCGECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.short16; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The SCGECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is greater than or equal to the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two short16 from the virtual machine stack.
  • + *
  • If the first short16 is greater than or equal to the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class SCGECommand implements Command { + /** + * Default constructor for creating an instance of SCGECommand. + * This constructor is empty as no specific initialization is required. + */ + public SCGECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + short b = (short) operandStack.pop(); + short a = (short) operandStack.pop(); + + // If the first operand is greater than or equal to the second, jump to the target command + if (a >= b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCLCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCLCommand.java new file mode 100644 index 0000000..96c7a24 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCLCommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.short16; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The SCLCommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is less than the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two short16 from the virtual machine stack.
  • + *
  • If the first short16 is less than the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class SCLCommand implements Command { + /** + * Default constructor for creating an instance of SCLCommand. + * This constructor is empty as no specific initialization is required. + */ + public SCLCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + short b = (short) operandStack.pop(); + short a = (short) operandStack.pop(); + + // If the first operand is less than the second, jump to the target command + if (a < b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCLECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCLECommand.java new file mode 100644 index 0000000..33de323 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCLECommand.java @@ -0,0 +1,76 @@ +package org.jcnc.snow.vm.commands.control.short16; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The SCLECommand class implements the {@link Command} interface and represents a conditional jump command in the virtual machine. + * This class compares two values from the stack, and if the first value is less than or equal to the second, it jumps to the specified target command. + * + *

Specific behavior:

+ *
    + *
  • Pops two short16 from the virtual machine stack.
  • + *
  • If the first short16 is less than or equal to the second, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class SCLECommand implements Command { + /** + * Default constructor for creating an instance of SCLECommand. + * This constructor is empty as no specific initialization is required. + */ + public SCLECommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + short b = (short) operandStack.pop(); + short a = (short) operandStack.pop(); + + // If the first operand is less than or equal to the second, jump to the target command + if (a <= b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCNECommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCNECommand.java new file mode 100644 index 0000000..9bb3f51 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/short16/SCNECommand.java @@ -0,0 +1,77 @@ +package org.jcnc.snow.vm.commands.control.short16; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The SCNECommand class implements the {@link Command} interface and represents a conditional jump command + * in the virtual machine that triggers if two values are not equal. + * + *

Specific behavior:

+ *
    + *
  • Pops two short16 from the virtual machine stack.
  • + *
  • If the two short16 are not equal, jumps to the target command.
  • + *
  • Otherwise, the program continues with the next command.
  • + *
+ */ +public class SCNECommand implements Command { + /** + * Default constructor for creating an instance of SCNECommand. + * This constructor is empty as no specific initialization is required. + */ + public SCNECommand() { + + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's + * specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction + * to be executed.

+ * + *

The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow + * of execution by updating the program counter.

+ * + *

The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching, + * function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame, + * while a `POP` instruction will remove an item from the operand stack.

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the target command address + int target = Integer.parseInt(parts[1]); + + // Pop the two operands from the stack + short b = (short) operandStack.pop(); + short a = (short) operandStack.pop(); + + // If the operands are not equal, jump to the target command + if (a != b) { + LoggingUtils.logInfo("Jumping to command", String.valueOf(target)); + return target; + } + + return currentPC + 1; + } +} 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 1b2f458..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 { - // 1 Arithmetic Operations (1–80) - // 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,8 +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; - // 1.2 long64 (11-20) + public static final int I_NEG = 6; + // endregion + + // 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.

@@ -173,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.

@@ -189,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.

@@ -205,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.

@@ -222,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.

@@ -239,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.

@@ -257,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.

@@ -273,9 +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 - // 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.

@@ -290,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.

@@ -306,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.

@@ -322,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.

@@ -339,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.

@@ -356,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.

@@ -375,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.

@@ -390,9 +379,10 @@ 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 - // 1.4 byte8 (31-40) + // region 1.4 byte8 (31-40) /** * B_ADD Opcode: Represents the byte8 addition operation in the virtual machine. *

This opcode is implemented by the {@link BAddCommand} class, which defines its specific execution logic.

@@ -408,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.

@@ -424,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.

@@ -440,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.

@@ -457,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.

@@ -474,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.

@@ -492,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.

@@ -508,8 +491,9 @@ 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 - // 1.5 double64 (41-50) + // region 1.5 double64 (41-50) /** * D_ADD Opcode: Represents the double64 precision floating-point addition operation in the virtual machine. *

This opcode is implemented by the {@link DAddCommand} class, which defines its specific execution logic.

@@ -525,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.

@@ -541,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.

@@ -557,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.

@@ -574,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.

@@ -591,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.

@@ -609,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.

@@ -624,8 +602,9 @@ 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 - // 1.6 float32 (51-60) + // region 1.6 float32 (51-60) /** * F_ADD Opcode: Represents the float32 addition operation in the virtual machine. *

This opcode is implemented by the {@link FAddCommand} class, which defines its specific execution logic.

@@ -720,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.

@@ -735,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.

@@ -750,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.

@@ -765,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.

@@ -780,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.

@@ -795,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.

@@ -810,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.

@@ -825,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.

@@ -975,11 +950,10 @@ 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 - - - // 2. Bitwise Operations (81–90) - // 2.1 int32 (81-85) + // region 2. Bitwise Operations (81–90) + // region 2.1 int32 (81-85) /** * I_AND Opcode: Represents the int32 bitwise AND operation in the virtual machine. *

This opcode is implemented by the {@link IAndCommand} class, which defines its specific execution logic.

@@ -1039,7 +1013,8 @@ public class VMOpCode { */ public static final int I_XOR = 83; - // 2.2 Long64 (86-90) + // endregion + // region 2.2 Long64 (86-90) /** * L_AND Opcode: Represents the long64 bitwise AND operation in the virtual machine. *

This opcode is implemented by the {@link LAndCommand} class, which defines its specific execution logic.

@@ -1100,8 +1075,10 @@ public class VMOpCode { public static final int L_XOR = 88; - // 3. Control Flow Operations (91–110) - // 3.1 JUMP (91-91) + // endregion + // endregion + // region 3. Control Flow Operations (91–110) + // region 3.1 JUMP (91-91) /** * JUMP Opcode: Represents an unconditional jump to a target instruction address. *

This opcode is implemented by the {@link JumpCommand} class, which defines its specific execution logic.

@@ -1121,7 +1098,9 @@ public class VMOpCode { * */ public static final int JUMP = 91; - // 3.2 int32 (92-97) + + // endregion + // region 3.2 int32 (92-97) /** * IC_E Opcode: Represents a conditional jump based on int32 equality. *

This opcode is implemented by the {@link ICECommand} class, which defines its specific execution logic.

@@ -1248,7 +1227,9 @@ public class VMOpCode { * */ public static final int IC_LE = 97; - // 3.3 long64 (98-103) + + // endregion + // region 3.3 long64 (98-103) /** * LC_E Opcode: Represents a conditional jump based on long64 equality. *

This opcode is implemented by the {@link ICECommand} class, which defines its specific execution logic.

@@ -1376,8 +1357,10 @@ public class VMOpCode { */ public static final int LC_LE = 103; - // 4. Stack Operations (111–150) - // 4.1 PUSH (111-120) + // endregion + // endregion + // region 4. Stack Operations (111–150) + // region 4.1 PUSH (111-120) /** * I_PUSH Opcode: Represents a stack operation that pushes an int32 value onto the operand stack. *

This opcode is implemented by the {@link IPushCommand} class, which defines its specific execution logic.

@@ -1492,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.

@@ -1510,8 +1495,9 @@ public class VMOpCode { *
  • Ensuring stack balance during function calls or control flow transitions.
  • * */ - // 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.

    @@ -1530,8 +1516,11 @@ public class VMOpCode { *
  • Managing stack balance when performing operations that require repeated access to the same data.
  • * */ - // 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.

    @@ -1551,10 +1540,11 @@ public class VMOpCode { *
  • Ensuring proper operand placement for later instructions that depend on the order of stack elements.
  • * */ - // 4.4 SWAP (131-135) public static final int SWAP = 131; + // endregion - // 5. Memory Operations (151–) + // endregion + // region 5. Memory Operations (151–166) /** * I_STORE Opcode: Represents a store operation that saves an int32 value from the operand stack into the local variable store. * @@ -1576,8 +1566,6 @@ public class VMOpCode { * */ public static final int I_STORE = 151; - - /** * L_STORE Opcode: Represents a store operation that stores a long64 value from the operand stack into the local variable store. *

    This opcode is implemented by the {@link LStoreCommand} class, which defines its specific execution logic.

    @@ -1598,8 +1586,6 @@ public class VMOpCode { * */ public static final int L_STORE = 152; - - /** * S_STORE Opcode: Represents a store operation that stores a short16 value from the operand stack into the local variable store. *

    This opcode is implemented by the {@link SStoreCommand} class, which defines its specific execution logic.

    @@ -1620,8 +1606,6 @@ public class VMOpCode { * */ public static final int S_STORE = 153; - - /** * B_STORE Opcode: Represents a store operation that stores a byte8 value from the operand stack into the local variable store. *

    This opcode is implemented by the {@link BStoreCommand} class, which defines its specific execution logic.

    @@ -1642,8 +1626,6 @@ public class VMOpCode { * */ public static final int B_STORE = 154; - - /** * D_STORE Opcode: Represents a store operation that stores a double64 value from the operand stack into the local variable store. *

    This opcode is implemented by the {@link DStoreCommand} class, which defines its specific execution logic.

    @@ -1664,7 +1646,6 @@ public class VMOpCode { * */ public static final int D_STORE = 155; - /** * F_STORE Opcode: Represents a store operation that stores a float32 value from the operand stack into the local variable store. *

    This opcode is implemented by the {@link FStoreCommand} class, which defines its specific execution logic.

    @@ -1685,8 +1666,6 @@ public class VMOpCode { * */ public static final int F_STORE = 156; - - /** * I_LOAD Opcode: Represents a load operation that retrieves an int32 value from the local variable store and pushes it onto the operand stack. *

    This opcode is implemented by the {@link ILoadCommand} class, which defines its specific execution logic.

    @@ -1828,6 +1807,8 @@ public class VMOpCode { * */ public static final int MOV = 171; + // 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.

    @@ -1885,9 +1866,7 @@ public class VMOpCode { * */ public static final int HALT = 255; - - - // VI. Function Operations (50–59) + // endregion /** * Default constructor for creating an instance of VMOpCode.