!17 fix:更正 int 与 long 操作数的比较跳转前缀

Merge pull request !17 from Luke/bugfix/compare-prefix-int-long
This commit is contained in:
Luke 2025-06-27 03:44:31 +00:00 committed by Gitee
commit ccd9923102
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
68 changed files with 2379 additions and 400 deletions

17
.run/Demo10.run.xml Normal file
View File

@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo10" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo10" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

17
.run/Demo9.run.xml Normal file
View File

@ -0,0 +1,17 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Demo9" type="Application" factoryName="Application" folderName="Demo" activateToolWindowBeforeRun="false">
<option name="ALTERNATIVE_JRE_PATH" value="graalvm-ce-23" />
<option name="MAIN_CLASS_NAME" value="org.jcnc.snow.cli.SnowCLI" />
<module name="Snow" />
<option name="PROGRAM_PARAMETERS" value="compile run -d playground/Demo9" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="org.jcnc.snow.compiler.parser.preprocessor.lexer.impl.api.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@ -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

View File

@ -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

View File

@ -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.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator; import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
import org.jcnc.snow.compiler.backend.util.IROpCodeMapper; import org.jcnc.snow.compiler.backend.utils.IROpCodeMapper;
import org.jcnc.snow.compiler.backend.util.OpHelper; import org.jcnc.snow.compiler.backend.utils.OpHelper;
import org.jcnc.snow.compiler.ir.core.IRValue; import org.jcnc.snow.compiler.ir.core.IRValue;
import org.jcnc.snow.compiler.ir.instruction.BinaryOperationInstruction; import org.jcnc.snow.compiler.ir.instruction.BinaryOperationInstruction;
import org.jcnc.snow.compiler.ir.value.IRConstant; import org.jcnc.snow.compiler.ir.value.IRConstant;

View File

@ -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.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator; 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.instruction.CallInstruction;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister; import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;

View File

@ -1,7 +1,7 @@
package org.jcnc.snow.compiler.backend.generator; package org.jcnc.snow.compiler.backend.generator;
import org.jcnc.snow.compiler.backend.util.IROpCodeMapper; import org.jcnc.snow.compiler.backend.utils.IROpCodeMapper;
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.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator; import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
import org.jcnc.snow.compiler.ir.instruction.IRCompareJumpInstruction; import org.jcnc.snow.compiler.ir.instruction.IRCompareJumpInstruction;
@ -10,18 +10,26 @@ import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import java.util.Map; import java.util.Map;
/** /**
* 条件比较跳转指令生成器 * <b>条件比较跳转指令生成器</b>
* <p> * <p>
* 该类实现了 {@link InstructionGenerator} 接口用于将 IR 中的条件比较跳转指令 * 该类实现了 {@link InstructionGenerator} 接口
* 转换为虚拟机可执行的指令序列主要流程是先将比较操作数加载到虚拟机栈中生成比较操作码 * 负责将 IR 中的 {@link IRCompareJumpInstruction}条件比较并跳转指令
* 并发出跳转到目标标签的指令 * 转换为目标虚拟机VM可执行的指令序列
* </p>
*
* <b>主要功能</b>
* <ul>
* <li>根据 IR 比较指令左右操作数的类型自动进行类型提升与转换</li>
* <li>生成相应的 VM 加载类型转换比较与跳转指令</li>
* <li>保证指令的类型前缀与操作数类型一致提升兼容性与正确性</li>
* </ul>
*/ */
public class CmpJumpGenerator implements InstructionGenerator<IRCompareJumpInstruction> { public class CmpJumpGenerator implements InstructionGenerator<IRCompareJumpInstruction> {
/** /**
* 返回该生成器所支持的指令类型 * 返回本生成器支持的 IR 指令类型
* *
* @return {@link IRCompareJumpInstruction} 的类对象 * @return IRCompareJumpInstruction 的类对象
*/ */
@Override @Override
public Class<IRCompareJumpInstruction> supportedClass() { public Class<IRCompareJumpInstruction> supportedClass() {
@ -29,7 +37,19 @@ public class CmpJumpGenerator implements InstructionGenerator<IRCompareJumpInstr
} }
/** /**
* 类型优先级D &gt; F &gt; L &gt; I &gt; S &gt; B * <b>类型宽度优先级</b>D > F > L > I > S > B
* <ul>
* <li>Ddouble6</li>
* <li>Ffloat5</li>
* <li>Llong4</li>
* <li>Iint3</li>
* <li>Sshort2</li>
* <li>Bbyte1</li>
* <li>未识别类型0</li>
* </ul>
*
* @param p 类型标记字符
* @return 优先级数值越大类型越宽
*/ */
private static int rank(char p) { private static int rank(char p) {
return switch (p) { return switch (p) {
@ -39,27 +59,40 @@ public class CmpJumpGenerator implements InstructionGenerator<IRCompareJumpInstr
case 'I' -> 3; case 'I' -> 3;
case 'S' -> 2; case 'S' -> 2;
case 'B' -> 1; case 'B' -> 1;
default -> 0; default -> 0;
}; };
} }
/** /**
* 返回优先级更高的类型字符 * 返回更的公共类型即优先级高的类型
*
* @param a 类型标记字符 1
* @param b 类型标记字符 2
* @return 宽度更高的类型标记字符
*/ */
private static char promote(char a, char b) { private static char promote(char a, char b) {
return rank(a) >= rank(b) ? a : b; return rank(a) >= rank(b) ? a : b;
} }
/** /**
* 单字符转字符串 * 单字符类型标记转字符串
*
* @param p 类型标记字符
* @return 类型字符串
*/ */
private static String str(char p) { private static String str(char p) {
return String.valueOf(p); return String.valueOf(p);
} }
/** /**
* 获取从类型 {@code from} {@code to} 的转换指令名 * 获取 {@code from to} 的类型转换指令名如不需转换则返回 {@code null}
* 相同类型或无显式转换需求返回 {@code null} * <p>
* 仅覆盖目前常见的整数与浮点类型提升与转换后续有新类型可补充
* </p>
*
* @param from 源类型标记字符
* @param to 目标类型标记字符
* @return 转换指令名L2I无转换返回 {@code null}
*/ */
private static String convert(char from, char to) { private static String convert(char from, char to) {
if (from == to) return null; if (from == to) return null;
@ -78,46 +111,64 @@ public class CmpJumpGenerator implements InstructionGenerator<IRCompareJumpInstr
case "DF" -> "D2F"; case "DF" -> "D2F";
case "SI" -> "S2I"; case "SI" -> "S2I";
case "BI" -> "B2I"; case "BI" -> "B2I";
default -> null; default -> null;
}; };
} }
/** /**
* 生成条件比较跳转相关的虚拟机指令 * 生成 IR 条件比较跳转指令的 VM 指令序列
* <ol>
* <li>确定左右操作数的槽位及静态类型</li>
* <li>加载并按需类型提升转换</li>
* <li>根据公共类型调整比较指令前缀</li>
* <li>发出最终比较和跳转指令</li>
* </ol>
* *
* @param ins 需要生成的条件比较跳转中间指令IR * @param ins IR 条件比较跳转指令
* @param out 虚拟机程序构建器用于输出生成的指令 * @param out VMProgramBuilder用于发出 VM 指令
* @param slotMap 虚拟寄存器到实际槽slot编号的映射表 * @param slotMap 虚拟寄存器到 VM 槽位的映射表
* @param currentFn 当前处理的函数名可用于调试或作用域标识 * @param currentFn 当前处理的函数名调试用当前未使用
*/ */
@Override @Override
public void generate(IRCompareJumpInstruction ins, public void generate(IRCompareJumpInstruction ins,
VMProgramBuilder out, VMProgramBuilder out,
Map<IRVirtualRegister, Integer> slotMap, Map<IRVirtualRegister,Integer> slotMap,
String currentFn) { String currentFn) {
// 获取左操作数所在的寄存器槽编号
int leftSlot = slotMap.get(ins.left());
// 获取右操作数所在的寄存器槽编号
int rightSlot = slotMap.get(ins.right());
char lType = out.getSlotType(leftSlot); // 未登记默认 'I' // 1. 获取左右操作数的槽位与静态类型
char rType = out.getSlotType(rightSlot); 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); out.emit(OpHelper.opcode(str(lType) + "_LOAD") + " " + leftSlot);
String cvt = convert(lType, tType); 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); out.emit(OpHelper.opcode(str(rType) + "_LOAD") + " " + rightSlot);
cvt = convert(rType, tType); 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()); 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()); out.emitBranch(OpHelper.opcode(cmpOp), ins.label());
} }
} }

View File

@ -1,6 +1,6 @@
package org.jcnc.snow.compiler.backend.generator; 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.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator; import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
import org.jcnc.snow.compiler.ir.instruction.IRJumpInstruction; import org.jcnc.snow.compiler.ir.instruction.IRJumpInstruction;

View File

@ -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.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator; 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.instruction.LoadConstInstruction;
import org.jcnc.snow.compiler.ir.value.IRConstant; import org.jcnc.snow.compiler.ir.value.IRConstant;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister; import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;

View File

@ -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.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator; 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.instruction.ReturnInstruction;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister; import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;

View File

@ -1,7 +1,7 @@
package org.jcnc.snow.compiler.backend.generator; package org.jcnc.snow.compiler.backend.generator;
import org.jcnc.snow.compiler.backend.util.IROpCodeMapper; import org.jcnc.snow.compiler.backend.utils.IROpCodeMapper;
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.builder.VMProgramBuilder;
import org.jcnc.snow.compiler.backend.core.InstructionGenerator; import org.jcnc.snow.compiler.backend.core.InstructionGenerator;
import org.jcnc.snow.compiler.ir.instruction.UnaryOperationInstruction; import org.jcnc.snow.compiler.ir.instruction.UnaryOperationInstruction;

View File

@ -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; import org.jcnc.snow.compiler.ir.core.IROpCode;
@ -83,12 +83,12 @@ public final class IROpCodeMapper {
// 比较运算映射 // 比较运算映射
// 整形32位比较运算映射 // 整形32位比较运算映射
opcodeMap.put(IROpCode.CMP_EQ, "IC_E"); // 相等 opcodeMap.put(IROpCode.CMP_IEQ, "IC_E"); // 相等
opcodeMap.put(IROpCode.CMP_NE, "IC_NE"); // 不等 opcodeMap.put(IROpCode.CMP_INE, "IC_NE"); // 不等
opcodeMap.put(IROpCode.CMP_LT, "IC_L"); // 小于 opcodeMap.put(IROpCode.CMP_ILT, "IC_L"); // 小于
opcodeMap.put(IROpCode.CMP_GT, "IC_G"); // 大于 opcodeMap.put(IROpCode.CMP_IGT, "IC_G"); // 大于
opcodeMap.put(IROpCode.CMP_LE, "IC_LE"); // 小于等于 opcodeMap.put(IROpCode.CMP_ILE, "IC_LE"); // 小于等于
opcodeMap.put(IROpCode.CMP_GE, "IC_GE"); // 大于等于 opcodeMap.put(IROpCode.CMP_IGE, "IC_GE"); // 大于等于
// 整形64位比较运算映射 // 整形64位比较运算映射
opcodeMap.put(IROpCode.CMP_LEQ, "LC_E"); // 相等 opcodeMap.put(IROpCode.CMP_LEQ, "LC_E"); // 相等

View File

@ -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; import org.jcnc.snow.vm.engine.VMOpCode;

View File

@ -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.CallInstruction;
import org.jcnc.snow.compiler.ir.instruction.LoadConstInstruction; import org.jcnc.snow.compiler.ir.instruction.LoadConstInstruction;
import org.jcnc.snow.compiler.ir.instruction.UnaryOperationInstruction; 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.IRConstant;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister; import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import org.jcnc.snow.compiler.ir.utils.ExpressionUtils; import org.jcnc.snow.compiler.ir.utils.ExpressionUtils;
@ -90,7 +91,7 @@ public record ExpressionBuilder(IRContext ctx) {
// !x (x == 0) // !x (x == 0)
if (op.equals("!")) { if (op.equals("!")) {
IRVirtualRegister zero = InstructionFactory.loadConst(ctx, 0); 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); throw new IllegalStateException("未知一元运算符: " + op);
@ -137,13 +138,18 @@ public record ExpressionBuilder(IRContext ctx) {
*/ */
private IRVirtualRegister buildBinary(BinaryExpressionNode bin) { private IRVirtualRegister buildBinary(BinaryExpressionNode bin) {
String op = bin.operator(); String op = bin.operator();
IRVirtualRegister left = build(bin.left()); IRVirtualRegister left = build(bin.left());
IRVirtualRegister right = build(bin.right()); IRVirtualRegister right = build(bin.right());
// 处理比较操作符
if (ExpressionUtils.isComparisonOperator(op)) { // 1. 比较运算
return InstructionFactory.binOp(ctx, ExpressionUtils.cmpOp(op), left, right); 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()); IROpCode code = ExpressionUtils.resolveOpCode(op, bin.left(), bin.right());
if (code == null) throw new IllegalStateException("不支持的运算符: " + op); if (code == null) throw new IllegalStateException("不支持的运算符: " + op);
return InstructionFactory.binOp(ctx, code, left, right); return InstructionFactory.binOp(ctx, code, left, right);
@ -161,8 +167,12 @@ public record ExpressionBuilder(IRContext ctx) {
IRVirtualRegister a = build(bin.left()); IRVirtualRegister a = build(bin.left());
IRVirtualRegister b = build(bin.right()); IRVirtualRegister b = build(bin.right());
String op = bin.operator(); 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 { } else {
IROpCode code = ExpressionUtils.resolveOpCode(op, bin.left(), bin.right()); IROpCode code = ExpressionUtils.resolveOpCode(op, bin.left(), bin.right());
if (code == null) throw new IllegalStateException("不支持的运算符: " + op); if (code == null) throw new IllegalStateException("不支持的运算符: " + op);

View File

@ -1,7 +1,7 @@
package org.jcnc.snow.compiler.ir.builder; package org.jcnc.snow.compiler.ir.builder;
import org.jcnc.snow.compiler.ir.core.IROpCode; 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.utils.IROpCodeUtils;
import org.jcnc.snow.compiler.ir.value.IRVirtualRegister; import org.jcnc.snow.compiler.ir.value.IRVirtualRegister;
import org.jcnc.snow.compiler.parser.ast.*; import org.jcnc.snow.compiler.parser.ast.*;
@ -18,23 +18,41 @@ import java.util.Locale;
*/ */
public class StatementBuilder { public class StatementBuilder {
/** 当前 IR 上下文,包含作用域、指令序列等信息。 */ /**
* 当前 IR 上下文包含作用域指令序列等信息
*/
private final IRContext ctx; private final IRContext ctx;
/** 表达式 IR 构建器,用于将表达式节点转为 IR 指令。 */ /**
* 表达式 IR 构建器用于将表达式节点转为 IR 指令
*/
private final ExpressionBuilder expr; private final ExpressionBuilder expr;
/** /**
* 构造方法 * 构造方法
*
* @param ctx IR 编译上下文环境 * @param ctx IR 编译上下文环境
*/ */
public StatementBuilder(IRContext ctx) { public StatementBuilder(IRContext ctx) {
this.ctx = ctx; this.ctx = ctx;
this.expr = new ExpressionBuilder(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 指令序列 * 将一个 AST 语句节点转为 IR 指令序列
* 根据节点类型分发到对应的处理方法 * 根据节点类型分发到对应的处理方法
*
* @param stmt 待转换的语句节点 * @param stmt 待转换的语句节点
*/ */
public void build(StatementNode stmt) { public void build(StatementNode stmt) {
@ -107,6 +125,7 @@ public class StatementBuilder {
/** /**
* 获取变量名对应的寄存器不存在则声明一个新的 * 获取变量名对应的寄存器不存在则声明一个新的
*
* @param name 变量名 * @param name 变量名
* @return 变量对应的虚拟寄存器 * @return 变量对应的虚拟寄存器
*/ */
@ -121,6 +140,7 @@ public class StatementBuilder {
/** /**
* 批量构建一组语句节点顺序处理每个语句 * 批量构建一组语句节点顺序处理每个语句
*
* @param stmts 语句节点集合 * @param stmts 语句节点集合
*/ */
private void buildStatements(Iterable<StatementNode> stmts) { private void buildStatements(Iterable<StatementNode> stmts) {
@ -130,12 +150,13 @@ public class StatementBuilder {
/** /**
* 构建循环语句for/while * 构建循环语句for/while
* 处理流程初始语句 条件判断 循环体 更新语句 跳回条件 * 处理流程初始语句 条件判断 循环体 更新语句 跳回条件
*
* @param loop 循环节点 * @param loop 循环节点
*/ */
private void buildLoop(LoopNode loop) { private void buildLoop(LoopNode loop) {
if (loop.initializer() != null) build(loop.initializer()); if (loop.initializer() != null) build(loop.initializer());
String lblStart = ctx.newLabel(); String lblStart = ctx.newLabel();
String lblEnd = ctx.newLabel(); String lblEnd = ctx.newLabel();
// 循环开始标签 // 循环开始标签
InstructionFactory.label(ctx, lblStart); InstructionFactory.label(ctx, lblStart);
@ -155,11 +176,12 @@ public class StatementBuilder {
/** /**
* 构建分支语句if/else * 构建分支语句if/else
* 处理流程条件判断 then 分支 else 分支可选 * 处理流程条件判断 then 分支 else 分支可选
*
* @param ifNode if 语句节点 * @param ifNode if 语句节点
*/ */
private void buildIf(IfNode ifNode) { private void buildIf(IfNode ifNode) {
String lblElse = ctx.newLabel(); String lblElse = ctx.newLabel();
String lblEnd = ctx.newLabel(); String lblEnd = ctx.newLabel();
// 条件不成立则跳转到 else // 条件不成立则跳转到 else
emitConditionalJump(ifNode.condition(), lblElse); emitConditionalJump(ifNode.condition(), lblElse);
@ -178,35 +200,30 @@ public class StatementBuilder {
/** /**
* 条件跳转指令的生成 * 条件跳转指令的生成
* 如果是二元比较表达式直接使用对应比较操作码否则等价于与 0 比较 * 如果是二元比较表达式直接使用对应比较操作码否则等价于与 0 比较
* @param cond 条件表达式 *
* @param cond 条件表达式
* @param falseLabel 条件不成立时跳转到的标签 * @param falseLabel 条件不成立时跳转到的标签
*/ */
private void emitConditionalJump(ExpressionNode cond, String falseLabel) { private void emitConditionalJump(ExpressionNode cond, String falseLabel) {
if (cond instanceof BinaryExpressionNode(ExpressionNode left, String operator, ExpressionNode right) if (cond instanceof BinaryExpressionNode(
&& ExpressionUtils.isComparisonOperator(operator)) { ExpressionNode left,
// 如果是比较操作 ==, >, <直接生成对应的条件跳转 String operator,
ExpressionNode right
)
&& ComparisonUtils.isComparisonOperator(operator)) {
IRVirtualRegister a = expr.build(left); IRVirtualRegister a = expr.build(left);
IRVirtualRegister b = expr.build(right); 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); InstructionFactory.cmpJump(ctx, falseOp, a, b, falseLabel);
} else { } else {
// 否则将 cond 0 比较相等则跳转
IRVirtualRegister condReg = expr.build(cond); IRVirtualRegister condReg = expr.build(cond);
IRVirtualRegister zero = InstructionFactory.loadConst(ctx, 0); IRVirtualRegister zero = InstructionFactory.loadConst(ctx, 0);
InstructionFactory.cmpJump(ctx, IROpCode.CMP_EQ, condReg, zero, falseLabel); 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 整型处理
};
}
} }

View File

@ -67,12 +67,12 @@ public enum IROpCode {
NEG_D64, // 64位浮点取负 NEG_D64, // 64位浮点取负
/* ───── 逻辑与比较运算指令32位整数int ───── */ /* ───── 逻辑与比较运算指令32位整数int ───── */
CMP_EQ, // 32位相等比较a == b CMP_IEQ, // 32位相等比较a == b
CMP_NE, // 32位不等比较a != b CMP_INE, // 32位不等比较a != b
CMP_LT, // 32位小于比较a < b CMP_ILT, // 32位小于比较a < b
CMP_GT, // 32位大于比较a > b CMP_IGT, // 32位大于比较a > b
CMP_LE, // 32位小于等于a <= b CMP_ILE, // 32位小于等于a <= b
CMP_GE, // 32位大于等于a >= b CMP_IGE, // 32位大于等于a >= b
/* ───── 逻辑与比较运算指令64位整数long ───── */ /* ───── 逻辑与比较运算指令64位整数long ───── */
CMP_LEQ, // 64位相等比较a == b CMP_LEQ, // 64位相等比较a == b

View File

@ -9,12 +9,12 @@ public final class IROpCodeMappings {
private IROpCodeMappings() {} // 禁止实例化 private IROpCodeMappings() {} // 禁止实例化
// 8位整型运算符映射 // 8位整型运算符映射
public static final Map<String, IROpCode> OP_I8 = Map.of( public static final Map<String, IROpCode> OP_B8 = Map.of(
"+", IROpCode.ADD_B8, "-", IROpCode.SUB_B8, "+", IROpCode.ADD_B8, "-", IROpCode.SUB_B8,
"*", IROpCode.MUL_B8, "/", IROpCode.DIV_B8 "*", IROpCode.MUL_B8, "/", IROpCode.DIV_B8
); );
// 16位整型 // 16位整型
public static final Map<String, IROpCode> OP_I16 = Map.of( public static final Map<String, IROpCode> OP_S16 = Map.of(
"+", IROpCode.ADD_S16, "-", IROpCode.SUB_S16, "+", IROpCode.ADD_S16, "-", IROpCode.SUB_S16,
"*", IROpCode.MUL_S16, "/", IROpCode.DIV_S16 "*", IROpCode.MUL_S16, "/", IROpCode.DIV_S16
); );
@ -38,8 +38,20 @@ public final class IROpCodeMappings {
"+", IROpCode.ADD_D64, "-", IROpCode.SUB_D64, "+", IROpCode.ADD_D64, "-", IROpCode.SUB_D64,
"*", IROpCode.MUL_D64, "/", IROpCode.DIV_D64 "*", IROpCode.MUL_D64, "/", IROpCode.DIV_D64
); );
// 比较操作符映射
public static final Map<String, IROpCode> CMP = Map.of( /* ────── 比较运算符映射 ────── */
/** 32-bitint比较 */
public static final Map<String, IROpCode> CMP_I32 = Map.of(
"==", IROpCode.CMP_IEQ,
"!=", IROpCode.CMP_INE,
"<", IROpCode.CMP_ILT,
">", IROpCode.CMP_IGT,
"<=", IROpCode.CMP_ILE,
">=", IROpCode.CMP_IGE
);
/** 64-bitlong比较 */
public static final Map<String, IROpCode> CMP_L64 = Map.of(
"==", IROpCode.CMP_LEQ, "==", IROpCode.CMP_LEQ,
"!=", IROpCode.CMP_LNE, "!=", IROpCode.CMP_LNE,
"<", IROpCode.CMP_LLT, "<", IROpCode.CMP_LLT,
@ -47,4 +59,6 @@ public final class IROpCodeMappings {
"<=", IROpCode.CMP_LLE, "<=", IROpCode.CMP_LLE,
">=", IROpCode.CMP_LGE ">=", IROpCode.CMP_LGE
); );
} }

View File

@ -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;
/**
* 比较运算辅助工具
* 根据左右操作数类型目前通过字面量后缀 <code>L/l</code> 判定选择
* 正确的 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<String, IROpCode> 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; // 变量暂不处理后续可扩展符号表查询
}
}

View File

@ -12,99 +12,83 @@ import java.util.Map;
/** /**
* 表达式分析与运算符辅助工具类 * 表达式分析与运算符辅助工具类
* <p> *
* 主要功能包括 * <p>主要功能</p>
* <ul> * <ul>
* <li>字面量常量的解析与类型推断</li> * <li>字面量常量的解析与类型推断</li>
* <li>自动匹配操作码</li> * <li>自动匹配算术/比较操作码</li>
* <li>表达式类型合并与判定</li> * <li>表达式类型合并与提升</li>
* </ul> * </ul>
*/ */
public class ExpressionUtils { public final class ExpressionUtils {
/** 用于存储默认的类型后缀(如函数返回类型),线程隔离。 */ private ExpressionUtils() {}
/* ────────────────── 线程级默认类型后缀 ────────────────── */
/** 默认类型后缀(如当前函数返回类型),线程隔离。 */
private static final ThreadLocal<Character> DEFAULT_SUFFIX = private static final ThreadLocal<Character> DEFAULT_SUFFIX =
ThreadLocal.withInitial(() -> '\0'); ThreadLocal.withInitial(() -> '\0');
/** public static void setDefaultSuffix(char suffix) { DEFAULT_SUFFIX.set(suffix); }
* 在进入函数 IR 构建前设置默认的类型后缀比如函数返回类型
* @param suffix 默认后缀字符 'i', 'l', 'f', 'd'
*/
public static void setDefaultSuffix(char suffix) {
DEFAULT_SUFFIX.set(suffix);
}
/** public static void clearDefaultSuffix() { DEFAULT_SUFFIX.set('\0'); }
* 在函数 IR 构建结束后清除默认后缀避免影响后续分析
*/ /* ───────────────────── 字面量 & 常量 ───────────────────── */
public static void clearDefaultSuffix() {
DEFAULT_SUFFIX.set('\0');
}
/** /**
* 解析整数字面量字符串自动去除类型后缀b/s/l/f/d/B/S/L/F/D并转换为 int * 解析整数字面量字符串自动去除类型后缀b/s/l/f/d/B/S/L/F/D并转换为 int
*
* @param literal 字面量字符串 "123", "123l", "42B"
* @return 解析得到的 int 整数
*/ */
public static int parseIntSafely(String literal) { public static int parseIntSafely(String literal) {
// 去掉类型后缀只保留数字部分
String digits = literal.replaceAll("[bslfdBSDLF]$", ""); String digits = literal.replaceAll("[bslfdBSDLF]$", "");
return Integer.parseInt(digits); return Integer.parseInt(digits);
} }
/** /**
* 根据数字字面量字符串自动判断类型生成对应类型的 IRConstant * 根据数字字面量字符串自动判断类型生成对应类型的 {@link IRConstant}
* 支持 b/s/l/f/d 类型后缀与浮点格式自动分配合适类型 * 支持 b/s/l/f/d 后缀与浮点格式
*
* @param ctx IR 编译上下文环境
* @param value 字面量字符串 "1", "2l", "3.14f", "5D"
* @return 生成的 IRConstant 对象包含正确类型
*/ */
public static IRConstant buildNumberConstant(IRContext ctx, String value) { 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) { String digits = switch (suffix) {
case 'b','s','l','f','d' -> value.substring(0, value.length() - 1); case 'b','s','l','f','d' -> value.substring(0, value.length() - 1);
default -> { default -> {
/* 如果字面量本身没有后缀,则回退到变量目标类型(如声明语句左值) */
if (ctx.getVarType() != null) { if (ctx.getVarType() != null) {
final var receiverType = ctx.getVarType(); String t = ctx.getVarType();
switch (receiverType) { suffix = switch (t) {
case "byte" -> suffix = 'b'; case "byte" -> 'b';
case "short" -> suffix = 's'; case "short" -> 's';
case "int" -> suffix = 'i'; case "int" -> 'i';
case "long" -> suffix = 'l'; case "long" -> 'l';
case "float" -> suffix = 'f'; case "float" -> 'f';
case "double" -> suffix = 'd'; case "double" -> 'd';
} default -> '\0';
};
} }
yield value; yield value;
} }
}; };
// 根据类型后缀或数值格式创建常量
/* 创建常量 */
return switch (suffix) { return switch (suffix) {
case 'b' -> new IRConstant(Byte.parseByte(digits)); case 'b' -> new IRConstant(Byte.parseByte(digits));
case 's' -> new IRConstant(Short.parseShort(digits)); case 's' -> new IRConstant(Short.parseShort(digits));
case 'l' -> new IRConstant(Long.parseLong(digits)); case 'l' -> new IRConstant(Long.parseLong(digits));
case 'f' -> new IRConstant(Float.parseFloat(digits)); case 'f' -> new IRConstant(Float.parseFloat(digits));
case 'd' -> new IRConstant(Double.parseDouble(digits)); case 'd' -> new IRConstant(Double.parseDouble(digits));
default -> looksLikeFloat(digits) default -> looksLikeFloat(digits)
? new IRConstant(Double.parseDouble(digits)) ? new IRConstant(Double.parseDouble(digits))
: new IRConstant(Integer.parseInt(digits)); : new IRConstant(Integer.parseInt(digits));
}; };
} }
/* ────────────────────── 一元运算 ────────────────────── */
/** /**
* 根据表达式节点推断一元取负-运算应使用的操作码 * 推断一元取负-运算应使用的 {@link IROpCode}
*
* <p>优先级与 {@link #resolveOpCode} 使用的类型提升规则保持一致</p>
* <ul>
* <li>字面量或标识符带显式后缀时直接以后缀决定位宽</li>
* <li>未显式指定时默认使用 32 位整型 {@link IROpCode#NEG_I32}</li>
* </ul>
*
* @param operand 一元取负运算的操作数
* @return 匹配的 {@link IROpCode}
*/ */
public static IROpCode negOp(ExpressionNode operand) { public static IROpCode negOp(ExpressionNode operand) {
char t = typeChar(operand); char t = typeChar(operand);
@ -114,113 +98,82 @@ public class ExpressionUtils {
case 'l' -> IROpCode.NEG_L64; case 'l' -> IROpCode.NEG_L64;
case 'f' -> IROpCode.NEG_F32; case 'f' -> IROpCode.NEG_F32;
case 'd' -> IROpCode.NEG_D64; case 'd' -> IROpCode.NEG_D64;
default -> IROpCode.NEG_I32; default -> IROpCode.NEG_I32; // '\0' 'i'
}; };
} }
/* =================== 类型推断与操作符匹配 =================== */ /* ────────────────── 比较运算(已适配 long ────────────────── */
/** /** 判断给定字符串是否是比较运算符(==, !=, <, >, <=, >=)。 */
* 递归推断单个表达式节点的类型后缀b/s/l/f/d public static boolean isComparisonOperator(String op) {
* 对于二元表达式将左右两侧的类型自动提升合并遵循优先级顺序d > f > l > s > b > '\0' return ComparisonUtils.isComparisonOperator(op);
*
* @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';
} }
/** /**
* 推断两个表达式节点合并后的类型后缀 * 兼容旧调用仅凭操作符返回 <em>int32</em> 比较指令
* 返回优先级更高的类型后缀字符
*
* @param left 左表达式节点
* @param right 右表达式节点
* @return 合并后类型的后缀字符
*/ */
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) { public static char resolveSuffix(ExpressionNode left, ExpressionNode right) {
return maxTypeChar(typeChar(left), typeChar(right)); return maxTypeChar(typeChar(left), typeChar(right));
} }
/** /** 类型优先级d > f > l > i > s > b > '\0' */
* 在两个类型后缀中选取精度更高的一个
* 优先级依次为d > f > l > s > b > '\0'
*
* @param l 左类型后缀
* @param r 右类型后缀
* @return 更高优先级的类型后缀字符
*/
private static char maxTypeChar(char l, char r) { private static char maxTypeChar(char l, char r) {
if (l == 'd' || r == 'd') return 'd'; if (l == 'd' || r == 'd') return 'd';
if (l == 'f' || r == 'f') return 'f'; if (l == 'f' || r == 'f') return 'f';
if (l == 'l' || r == 'l') return 'l'; if (l == 'l' || r == 'l') return 'l';
if (l == 'i' || r == 'i') return 'i';
if (l == 's' || r == 's') return 's'; if (l == 's' || r == 's') return 's';
if (l == 'b' || r == 'b') return 'b'; if (l == 'b' || r == 'b') return 'b';
return '\0'; return '\0';
} }
/** /**
* 判断给定字符串是否为比较运算符 >, <, == * 根据操作符和两侧表达式选择正确的算术 {@link IROpCode}
*
* @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
* 首先根据参与表达式类型推断后缀若无法推断则回退到函数默认类型
* 还无法推断则默认使用 i3232位整型
*
* @param op 操作符字符串 "+"
* @param left 左侧表达式节点
* @param right 右侧表达式节点
* @return 匹配的 IROpCode如果不存在则返回 null
*/ */
public static IROpCode resolveOpCode(String op, public static IROpCode resolveOpCode(String op,
ExpressionNode left, ExpressionNode left,
ExpressionNode right) { ExpressionNode right) {
/* 1) 尝试从参与者常量字面量推断 */ /* 1. 尝试根据字面量推断 */
char suffix = resolveSuffix(left, right); char suffix = resolveSuffix(left, right);
/* 2) 若无法推断退回到函数返回类型DEFAULT_SUFFIX */ /* 2. 若失败则使用函数级默认类型 */
if (suffix == '\0') { if (suffix == '\0') suffix = DEFAULT_SUFFIX.get();
suffix = DEFAULT_SUFFIX.get();
}
/* 3) 再次失败则默认为 i32 */ /* 3. 仍失败则默认为 int32 */
Map<String, IROpCode> table = switch (suffix) { Map<String, IROpCode> table = switch (suffix) {
case 'b' -> IROpCodeMappings.OP_I8; case 'b' -> IROpCodeMappings.OP_B8;
case 's' -> IROpCodeMappings.OP_I16; case 's' -> IROpCodeMappings.OP_S16;
case 'i' -> IROpCodeMappings.OP_I32;
case 'l' -> IROpCodeMappings.OP_L64; case 'l' -> IROpCodeMappings.OP_L64;
case 'f' -> IROpCodeMappings.OP_F32; case 'f' -> IROpCodeMappings.OP_F32;
case 'd' -> IROpCodeMappings.OP_D64; case 'd' -> IROpCodeMappings.OP_D64;
@ -230,13 +183,12 @@ public class ExpressionUtils {
return table.get(op); return table.get(op);
} }
/** /* ────────────────────────── 工具 ───────────────────────── */
* 判断字符串是否为浮点数形式即包含小数点或科学计数法 e/E
* /** 是否像浮点字面量(包含 '.' 或 e/E。 */
* @param digits 数字字符串
* @return 如果看起来像浮点数则返回 true否则返回 false
*/
private static boolean looksLikeFloat(String digits) { 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;
} }
} }

View File

@ -8,13 +8,21 @@ import java.util.Map;
* IR 操作码辅助工具 * IR 操作码辅助工具
*/ */
public class IROpCodeUtils { public class IROpCodeUtils {
private static final Map<IROpCode, IROpCode> INVERT = Map.of( private static final Map<IROpCode, IROpCode> INVERT = Map.ofEntries(
IROpCode.CMP_LEQ, IROpCode.CMP_LNE, // 32-bit
IROpCode.CMP_LNE, IROpCode.CMP_LEQ, Map.entry(IROpCode.CMP_IEQ, IROpCode.CMP_INE),
IROpCode.CMP_LLT, IROpCode.CMP_LGE, Map.entry(IROpCode.CMP_INE, IROpCode.CMP_IEQ),
IROpCode.CMP_LGE, IROpCode.CMP_LLT, Map.entry(IROpCode.CMP_ILT, IROpCode.CMP_IGE),
IROpCode.CMP_LGT, IROpCode.CMP_LLE, Map.entry(IROpCode.CMP_IGE, IROpCode.CMP_ILT),
IROpCode.CMP_LLE, IROpCode.CMP_LGT 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)
); );
/** /**

View File

@ -11,79 +11,75 @@ import org.jcnc.snow.compiler.semantic.type.BuiltinType;
import org.jcnc.snow.compiler.semantic.type.Type; import org.jcnc.snow.compiler.semantic.type.Type;
/** /**
* {@code BinaryExpressionAnalyzer} 是一个用于分析二元表达式的语义分析器 * {@code BinaryExpressionAnalyzer} 负责对二元表达式做语义分析并返回其类型
* <p> * <p>
* 支持的特性包括 * 支持特性
* <ul> * 1. 字符串拼接+
* <li>字符串拼接当运算符为加号 "+" 且任一操作数为字符串类型时</li> * 2. 数值运算与自动宽化
* <li>数值类型的自动宽化转换 int float 运算将转换为 float</li> * 3. 比较 / 关系运算
* <li>基本的数值运算符 +, -, *, /, %</li> * 4. 布尔值比较== / !=
* <li>关系运算符和比较运算符 <, <=, >, >=, ==, !=</li>
* </ul>
* 对于不支持的运算符或不兼容的类型组合将记录语义错误并默认返回 {@code BuiltinType.INT} 以保持分析过程的连续性
* <p> * <p>
* 实现类遵循 {@code ExpressionAnalyzer<BinaryExpressionNode>} 接口规范 * 如遇不支持的运算符或不兼容的类型组合将记录语义错误
* 并以 {@code int} 作为回退类型保持后续分析不中断
*/ */
public class BinaryExpressionAnalyzer implements ExpressionAnalyzer<BinaryExpressionNode> { public class BinaryExpressionAnalyzer implements ExpressionAnalyzer<BinaryExpressionNode> {
/**
* 分析给定的二元表达式节点返回其表达式类型
*
* @param ctx 当前语义分析上下文用于访问日志记录错误收集注册表等服务
* @param mi 当前模块信息包含模块级别的符号与类型定义
* @param fn 当前正在分析的函数节点
* @param locals 当前函数作用域内的符号表用于变量查找
* @param bin 要分析的二元表达式节点
* @return 分析后推断出的表达式类型
*/
@Override @Override
public Type analyze(Context ctx, public Type analyze(Context ctx,
ModuleInfo mi, ModuleInfo mi,
FunctionNode fn, FunctionNode fn,
SymbolTable locals, SymbolTable locals,
BinaryExpressionNode bin) { BinaryExpressionNode bin) {
ctx.log("检查二元表达式: " + bin.operator()); 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()); .analyze(ctx, mi, fn, locals, bin.left());
// 获取右侧表达式类型 Type right = ctx.getRegistry()
Type right = ctx.getRegistry().getExpressionAnalyzer(bin.right()) .getExpressionAnalyzer(bin.right())
.analyze(ctx, mi, fn, locals, bin.right()); .analyze(ctx, mi, fn, locals, bin.right());
String op = bin.operator(); String op = bin.operator();
// 情况 1字符串拼接+ 操作符且任一操作数为字符串类型 /* ----------- 情况 1字符串拼接 ----------- */
if (op.equals("+") && if (op.equals("+") &&
(left == BuiltinType.STRING || right == BuiltinType.STRING)) { (left == BuiltinType.STRING || right == BuiltinType.STRING)) {
return 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 ("+-*/%".contains(op) || ("<<=>>===!=").contains(op)) {
if (left.isNumeric() && right.isNumeric()) { if (left.isNumeric() && right.isNumeric()) {
// 自动宽化到更宽的数值类型 int + float => float // 自动数值宽化 int + float float
Type wide = Type.widen(left, right); Type wide = Type.widen(left, right);
if (wide == null) wide = BuiltinType.INT; // 容错降级为 int if (wide == null) wide = BuiltinType.INT; // 容错降级
// 若为比较运算符统一返回 boolean 类型作为布尔值表示 // 比较运算统一返回 boolean
if ("< <= > >= == !=".contains(op)) { if ("< <= > >= == !=".contains(op)) {
return BuiltinType.BOOLEAN; return BuiltinType.BOOLEAN;
} }
return wide; return wide;
} }
} }
// 情况 3不支持的类型组合记录语义错误 /* ----------- 情况 3不支持的类型组合 ----------- */
ctx.getErrors().add(new SemanticError( ctx.getErrors().add(new SemanticError(
bin, bin,
String.format("运算符 '%s' 不支持类型: %s 和 %s", op, left, right) String.format("运算符 '%s' 不支持类型: %s 和 %s", op, left, right)
)); ));
ctx.log("错误: 运算符 '" + op + "' 不支持类型: " + left + ", " + right); ctx.log("错误: 运算符 '" + op + "' 不支持类型: " + left + ", " + right);
// 错误情况下默认返回 int 类型以保证语义分析不中断 // 回退类型
return BuiltinType.INT; return BuiltinType.INT;
} }
} }

View File

@ -50,7 +50,7 @@ public class BAddCommand implements Command {
byte a = (byte) operandStack.pop(); byte a = (byte) operandStack.pop();
// Perform the addition and push the result back onto the stack // 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 the updated program counter (next instruction)
return currentPC + 1; return currentPC + 1;

View File

@ -56,7 +56,7 @@ public class BDivCommand implements Command {
} }
// Perform the division and push the result back onto the stack // 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 the updated program counter (next instruction)
return currentPC + 1; return currentPC + 1;

View File

@ -50,7 +50,7 @@ public class BModCommand implements Command {
byte a = (byte) operandStack.pop(); byte a = (byte) operandStack.pop();
// Perform the modulus operation and push the result back onto the stack // 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 the updated program counter (next instruction)
return currentPC + 1; return currentPC + 1;

View File

@ -50,7 +50,7 @@ public class BMulCommand implements Command {
byte a = (byte) operandStack.pop(); byte a = (byte) operandStack.pop();
// Perform the multiplication and push the result back onto the stack // 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 the updated program counter (next instruction)
return currentPC + 1; return currentPC + 1;

View File

@ -50,7 +50,7 @@ public class BSubCommand implements Command {
byte a = (byte) operandStack.pop(); byte a = (byte) operandStack.pop();
// Perform the subtraction and push the result back onto the stack // 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 the updated program counter (next instruction)
return currentPC + 1; return currentPC + 1;

View File

@ -46,11 +46,11 @@ public class SAddCommand implements Command {
@Override @Override
public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) {
// Pop the top two operands from the stack // Pop the top two operands from the stack
Short b = (Short) operandStack.pop(); short b = (short) operandStack.pop();
Short a = (Short) operandStack.pop(); short a = (short) operandStack.pop();
// Perform the addition and push the result back onto the stack // 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 the updated program counter (next instruction)
return currentPC + 1; return currentPC + 1;

View File

@ -56,7 +56,7 @@ public class SDivCommand implements Command {
} }
// Perform the division and push the result back onto the stack // 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 the updated program counter (next instruction)
return currentPC + 1; return currentPC + 1;

View File

@ -50,7 +50,7 @@ public class SModCommand implements Command {
short a = (short) operandStack.pop(); short a = (short) operandStack.pop();
// Perform the modulus operation and push the result back onto the stack // 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 the updated program counter (next instruction)
return currentPC + 1; return currentPC + 1;

View File

@ -50,7 +50,7 @@ public class SMulCommand implements Command {
short a = (short) operandStack.pop(); short a = (short) operandStack.pop();
// Perform the multiplication and push the result back onto the stack // 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 the updated program counter (next instruction)
return currentPC + 1; return currentPC + 1;

View File

@ -50,7 +50,7 @@ public class SSubCommand implements Command {
short a = (short) operandStack.pop(); short a = (short) operandStack.pop();
// Perform the subtraction and push the result back onto the stack // 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 the updated program counter (next instruction)
return currentPC + 1; return currentPC + 1;

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two byte8 from the virtual machine stack.</li>
* <li>If the two byte8 are equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two byte8 from the virtual machine stack.</li>
* <li>If the first byte8 is greater than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two byte8 from the virtual machine stack.</li>
* <li>If the first byte8 is greater than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two byte8 from the virtual machine stack.</li>
* <li>If the first byte8 is less than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two byte8 from the virtual machine stack.</li>
* <li>If the first byte8 is less than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two byte8 from the virtual machine stack.</li>
* <li>If the two byte8 are not equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two double64 from the virtual machine stack.</li>
* <li>If the two double64 are equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two double64 from the virtual machine stack.</li>
* <li>If the first double64 is greater than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two double64 from the virtual machine stack.</li>
* <li>If the first double64 is greater than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two double64 from the virtual machine stack.</li>
* <li>If the first double64 is less than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two double64 from the virtual machine stack.</li>
* <li>If the first double64 is less than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two double64 from the virtual machine stack.</li>
* <li>If the two double64 are not equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two float32 from the virtual machine stack.</li>
* <li>If the two float32 are equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two float32 from the virtual machine stack.</li>
* <li>If the first float32 is greater than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two float32 from the virtual machine stack.</li>
* <li>If the first float32 is greater than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two float32 from the virtual machine stack.</li>
* <li>If the first float32 is less than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two float32 from the virtual machine stack.</li>
* <li>If the first float32 is less than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two float32 from the virtual machine stack.</li>
* <li>If the two float32 are not equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two int32 from the virtual machine stack.</li>
* <li>If the two integers are equal, jumps to the target command.</li> * <li>If the two int32 are equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two int32 from the virtual machine stack.</li>
* <li>If the first integer is greater than the second, jumps to the target command.</li> * <li>If the first int32 is greater than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two int32 from the virtual machine stack.</li>
* <li>If the first integer is greater than or equal to the second, jumps to the target command.</li> * <li>If the first int32 is greater than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two int32 from the virtual machine stack.</li>
* <li>If the first integer is less than the second, jumps to the target command.</li> * <li>If the first int32 is less than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two int32 from the virtual machine stack.</li>
* <li>If the first integer is less than or equal to the second, jumps to the target command.</li> * <li>If the first int32 is less than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.module.OperandStack;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two int32 from the virtual machine stack.</li>
* <li>If the two integers are not equal, jumps to the target command.</li> * <li>If the two int32 are not equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two long64 from the virtual machine stack.</li>
* <li>If the two integers are equal, jumps to the target command.</li> * <li>If the two long64 are equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two long64 from the virtual machine stack.</li>
* <li>If the first integer is greater than the second, jumps to the target command.</li> * <li>If the first long64 is greater than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two long64 from the virtual machine stack.</li>
* <li>If the first integer is greater than or equal to the second, jumps to the target command.</li> * <li>If the first long64 is greater than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two long64 from the virtual machine stack.</li>
* <li>If the first integer is less than the second, jumps to the target command.</li> * <li>If the first long64 is less than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two long64 from the virtual machine stack.</li>
* <li>If the first integer is less than or equal to the second, jumps to the target command.</li> * <li>If the first long64 is less than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -12,8 +12,8 @@ import org.jcnc.snow.vm.utils.LoggingUtils;
* *
* <p>Specific behavior:</p> * <p>Specific behavior:</p>
* <ul> * <ul>
* <li>Pops two integers from the virtual machine stack.</li> * <li>Pops two long64 from the virtual machine stack.</li>
* <li>If the two integers are not equal, jumps to the target command.</li> * <li>If the two long64 are not equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li> * <li>Otherwise, the program continues with the next command.</li>
* </ul> * </ul>
*/ */

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two short16 from the virtual machine stack.</li>
* <li>If the two short16 are equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two short16 from the virtual machine stack.</li>
* <li>If the first short16 is greater than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two short16 from the virtual machine stack.</li>
* <li>If the first short16 is greater than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two short16 from the virtual machine stack.</li>
* <li>If the first short16 is less than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two short16 from the virtual machine stack.</li>
* <li>If the first short16 is less than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two short16 from the virtual machine stack.</li>
* <li>If the two short16 are not equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -47,8 +47,8 @@ import org.jcnc.snow.vm.module.LocalVariableStore;
* <p>Each opcode represents a specific operation executed by the virtual machine.</p> * <p>Each opcode represents a specific operation executed by the virtual machine.</p>
*/ */
public class VMOpCode { public class VMOpCode {
// 1 Arithmetic Operations (180) // region 1. Arithmetic Operations (1100)
// 1.1 int32 (1-10) // region 1.1 int32 (0-9)
/** /**
* I_ADD Opcode: Represents the int32 addition operation in the virtual machine. * I_ADD Opcode: Represents the int32 addition operation in the virtual machine.
* <p>This opcode is implemented by the {@link IAddCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link IAddCommand} class, which defines its specific execution logic.</p>
@ -63,7 +63,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic int32 addition tasks.</p> * primarily used to handle basic int32 addition tasks.</p>
*/ */
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. * I_SUB Opcode: Represents the int32 subtraction operation in the virtual machine.
* <p>This opcode is implemented by the {@link ISubCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link ISubCommand} class, which defines its specific execution logic.</p>
@ -78,7 +78,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic int32 subtraction tasks.</p> * primarily used to handle basic int32 subtraction tasks.</p>
*/ */
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. * I_MUL Opcode: Represents the int32 multiplication operation in the virtual machine.
* <p>This opcode is implemented by the {@link IMulCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link IMulCommand} class, which defines its specific execution logic.</p>
@ -93,7 +93,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic int32 multiplication tasks.</p> * primarily used to handle basic int32 multiplication tasks.</p>
*/ */
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. * I_DIV Opcode: Represents the int32 division operation in the virtual machine.
* <p>This opcode is implemented by the {@link IDivCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link IDivCommand} class, which defines its specific execution logic.</p>
@ -109,7 +109,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic int32 division tasks.</p> * primarily used to handle basic int32 division tasks.</p>
*/ */
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. * I_MOD Opcode: Represents the int32 modulus (remainder) operation in the virtual machine.
* <p>This opcode is implemented by the {@link IModCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link IModCommand} class, which defines its specific execution logic.</p>
@ -125,7 +125,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic int32 modulus (remainder) tasks.</p> * primarily used to handle basic int32 modulus (remainder) tasks.</p>
*/ */
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. * I_INC Opcode: Represents the int32 increment operation for a local variable in the virtual machine.
* <p>This opcode is implemented by the {@link IIncCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link IIncCommand} class, which defines its specific execution logic.</p>
@ -142,8 +142,7 @@ public class VMOpCode {
* *
* <p>This opcode is particularly useful for optimizing scenarios where a local variable, such as a counter or loop index, is frequently incremented.</p> * <p>This opcode is particularly useful for optimizing scenarios where a local variable, such as a counter or loop index, is frequently incremented.</p>
*/ */
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. * I_NEG Opcode: Represents the int32 negation operation in the virtual machine.
* <p>This opcode is implemented by the {@link INegCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link INegCommand} class, which defines its specific execution logic.</p>
@ -157,8 +156,10 @@ public class VMOpCode {
* *
* <p>This opcode is typically used to negate an int32 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p> * <p>This opcode is typically used to negate an int32 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/ */
public static final int I_NEG = 7; public static final int I_NEG = 6;
// 1.2 long64 (11-20) // endregion
// region 1.2 long64 (10-19)
/** /**
* L_ADD Opcode: Represents the long64 addition operation in the virtual machine. * L_ADD Opcode: Represents the long64 addition operation in the virtual machine.
* <p>This opcode is implemented by the {@link LAddCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link LAddCommand} class, which defines its specific execution logic.</p>
@ -173,8 +174,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic long64 addition tasks.</p> * primarily used to handle basic long64 addition tasks.</p>
*/ */
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. * L_SUB Opcode: Represents the long64 subtraction operation in the virtual machine.
* <p>This opcode is implemented by the {@link LSubCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link LSubCommand} class, which defines its specific execution logic.</p>
@ -189,8 +189,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic long64 subtraction tasks.</p> * primarily used to handle basic long64 subtraction tasks.</p>
*/ */
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. * L_MUL Opcode: Represents the long64 multiplication operation in the virtual machine.
* <p>This opcode is implemented by the {@link LMulCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link LMulCommand} class, which defines its specific execution logic.</p>
@ -205,8 +204,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic long64 multiplication tasks.</p> * primarily used to handle basic long64 multiplication tasks.</p>
*/ */
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. * L_DIV Opcode: Represents the long64 division operation in the virtual machine.
* <p>This opcode is implemented by the {@link LDivCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link LDivCommand} class, which defines its specific execution logic.</p>
@ -222,8 +220,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic long64 division tasks.</p> * primarily used to handle basic long64 division tasks.</p>
*/ */
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. * L_MOD Opcode: Represents the long64 modulus (remainder) operation in the virtual machine.
* <p>This opcode is implemented by the {@link LModCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link LModCommand} class, which defines its specific execution logic.</p>
@ -239,8 +236,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic long64 modulus (remainder) tasks.</p> * primarily used to handle basic long64 modulus (remainder) tasks.</p>
*/ */
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. * L_INC Opcode: Represents the long64 increment operation for a local variable in the virtual machine.
* <p>This opcode is implemented by the {@link LIncCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link LIncCommand} class, which defines its specific execution logic.</p>
@ -257,9 +253,7 @@ public class VMOpCode {
* *
* <p>This opcode is particularly useful for optimizing scenarios where a local `long64` variable, such as a counter or loop index, is frequently incremented.</p> * <p>This opcode is particularly useful for optimizing scenarios where a local `long64` variable, such as a counter or loop index, is frequently incremented.</p>
*/ */
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. * L_NEG Opcode: Represents the long64 negation operation in the virtual machine.
* <p>This opcode is implemented by the {@link LNegCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link LNegCommand} class, which defines its specific execution logic.</p>
@ -273,9 +267,10 @@ public class VMOpCode {
* *
* <p>This opcode is typically used to negate a long64 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p> * <p>This opcode is typically used to negate a long64 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/ */
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. * S_ADD Opcode: Represents the short16 addition operation in the virtual machine.
* <p>This opcode is implemented by the {@link SAddCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link SAddCommand} class, which defines its specific execution logic.</p>
@ -290,8 +285,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic short16 addition tasks.</p> * primarily used to handle basic short16 addition tasks.</p>
*/ */
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. * S_SUB Opcode: Represents the short16 subtraction operation in the virtual machine.
* <p>This opcode is implemented by the {@link SSubCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link SSubCommand} class, which defines its specific execution logic.</p>
@ -306,8 +300,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic short16 subtraction tasks.</p> * primarily used to handle basic short16 subtraction tasks.</p>
*/ */
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. * S_MUL Opcode: Represents the short16 multiplication operation in the virtual machine.
* <p>This opcode is implemented by the {@link SMulCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link SMulCommand} class, which defines its specific execution logic.</p>
@ -322,8 +315,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic short16 multiplication tasks.</p> * primarily used to handle basic short16 multiplication tasks.</p>
*/ */
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. * S_DIV Opcode: Represents the short16 division operation in the virtual machine.
* <p>This opcode is implemented by the {@link SDivCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link SDivCommand} class, which defines its specific execution logic.</p>
@ -339,8 +331,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic short16 division tasks.</p> * primarily used to handle basic short16 division tasks.</p>
*/ */
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. * S_MOD Opcode: Represents the short16 modulus (remainder) operation in the virtual machine.
* <p>This opcode is implemented by the {@link SModCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link SModCommand} class, which defines its specific execution logic.</p>
@ -356,8 +347,7 @@ public class VMOpCode {
* <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, * <p>This opcode is a fundamental arithmetic operation within the virtual machine's instruction set,
* primarily used to handle basic short16 modulus (remainder) tasks.</p> * primarily used to handle basic short16 modulus (remainder) tasks.</p>
*/ */
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. * S_INC Opcode: Represents the short16 increment operation in the virtual machine.
* <p>This opcode is implemented by the {@link SIncCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link SIncCommand} class, which defines its specific execution logic.</p>
@ -375,8 +365,7 @@ public class VMOpCode {
* <p>This opcode is useful for scenarios where a local variable needs to be incremented, such as counters within loops, * <p>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.</p> * or for optimizing the modification of variables in tight loops.</p>
*/ */
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. * S_NEG Opcode: Represents the short16 negation operation in the virtual machine.
* <p>This opcode is implemented by the {@link SNegCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link SNegCommand} class, which defines its specific execution logic.</p>
@ -390,9 +379,10 @@ public class VMOpCode {
* *
* <p>This opcode is typically used to negate a short16 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p> * <p>This opcode is typically used to negate a short16 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/ */
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. * B_ADD Opcode: Represents the byte8 addition operation in the virtual machine.
* <p>This opcode is implemented by the {@link BAddCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link BAddCommand} class, which defines its specific execution logic.</p>
@ -408,7 +398,6 @@ public class VMOpCode {
* primarily used to handle basic byte8 addition tasks.</p> * primarily used to handle basic byte8 addition tasks.</p>
*/ */
public static final int B_ADD = 31; public static final int B_ADD = 31;
/** /**
* B_SUB Opcode: Represents the byte8 subtraction operation in the virtual machine. * B_SUB Opcode: Represents the byte8 subtraction operation in the virtual machine.
* <p>This opcode is implemented by the {@link BSubCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link BSubCommand} class, which defines its specific execution logic.</p>
@ -424,7 +413,6 @@ public class VMOpCode {
* primarily used to handle basic byte8 subtraction tasks.</p> * primarily used to handle basic byte8 subtraction tasks.</p>
*/ */
public static final int B_SUB = 32; public static final int B_SUB = 32;
/** /**
* B_MUL Opcode: Represents the byte8 multiplication operation in the virtual machine. * B_MUL Opcode: Represents the byte8 multiplication operation in the virtual machine.
* <p>This opcode is implemented by the {@link BMulCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link BMulCommand} class, which defines its specific execution logic.</p>
@ -440,7 +428,6 @@ public class VMOpCode {
* primarily used to handle basic byte8 multiplication tasks.</p> * primarily used to handle basic byte8 multiplication tasks.</p>
*/ */
public static final int B_MUL = 33; public static final int B_MUL = 33;
/** /**
* B_DIV Opcode: Represents the byte8 division operation in the virtual machine. * B_DIV Opcode: Represents the byte8 division operation in the virtual machine.
* <p>This opcode is implemented by the {@link BDivCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link BDivCommand} class, which defines its specific execution logic.</p>
@ -457,7 +444,6 @@ public class VMOpCode {
* primarily used to handle basic byte8 division tasks.</p> * primarily used to handle basic byte8 division tasks.</p>
*/ */
public static final int B_DIV = 34; public static final int B_DIV = 34;
/** /**
* B_MOD Opcode: Represents the byte8 modulus (remainder) operation in the virtual machine. * B_MOD Opcode: Represents the byte8 modulus (remainder) operation in the virtual machine.
* <p>This opcode is implemented by the {@link BModCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link BModCommand} class, which defines its specific execution logic.</p>
@ -474,7 +460,6 @@ public class VMOpCode {
* primarily used to handle basic byte8 modulus (remainder) tasks.</p> * primarily used to handle basic byte8 modulus (remainder) tasks.</p>
*/ */
public static final int B_MOD = 35; public static final int B_MOD = 35;
/** /**
* B_INC Opcode: Represents the byte8 increment operation for a local variable in the virtual machine. * B_INC Opcode: Represents the byte8 increment operation for a local variable in the virtual machine.
* <p>This opcode is implemented by the {@link BIncCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link BIncCommand} class, which defines its specific execution logic.</p>
@ -492,8 +477,6 @@ public class VMOpCode {
* <p>This opcode is particularly useful for optimizing scenarios where a local `byte8` variable, such as a counter or loop index, is frequently incremented.</p> * <p>This opcode is particularly useful for optimizing scenarios where a local `byte8` variable, such as a counter or loop index, is frequently incremented.</p>
*/ */
public static final int B_INC = 36; public static final int B_INC = 36;
/** /**
* B_NEG Opcode: Represents the byte8 negation operation in the virtual machine. * B_NEG Opcode: Represents the byte8 negation operation in the virtual machine.
* <p>This opcode is implemented by the {@link BNegCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link BNegCommand} class, which defines its specific execution logic.</p>
@ -508,8 +491,9 @@ public class VMOpCode {
* <p>This opcode is typically used to negate a byte8 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p> * <p>This opcode is typically used to negate a byte8 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/ */
public static final int B_NEG = 37; 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. * D_ADD Opcode: Represents the double64 precision floating-point addition operation in the virtual machine.
* <p>This opcode is implemented by the {@link DAddCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link DAddCommand} class, which defines its specific execution logic.</p>
@ -525,7 +509,6 @@ public class VMOpCode {
* primarily used to handle basic double64 precision floating-point addition tasks.</p> * primarily used to handle basic double64 precision floating-point addition tasks.</p>
*/ */
public static final int D_ADD = 41; public static final int D_ADD = 41;
/** /**
* D_SUB Opcode: Represents the double64 precision floating-point subtraction operation in the virtual machine. * D_SUB Opcode: Represents the double64 precision floating-point subtraction operation in the virtual machine.
* <p>This opcode is implemented by the {@link DSubCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link DSubCommand} class, which defines its specific execution logic.</p>
@ -541,7 +524,6 @@ public class VMOpCode {
* primarily used to handle basic double64 precision floating-point subtraction tasks.</p> * primarily used to handle basic double64 precision floating-point subtraction tasks.</p>
*/ */
public static final int D_SUB = 42; public static final int D_SUB = 42;
/** /**
* D_MUL Opcode: Represents the double64 precision floating-point multiplication operation in the virtual machine. * D_MUL Opcode: Represents the double64 precision floating-point multiplication operation in the virtual machine.
* <p>This opcode is implemented by the {@link DMulCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link DMulCommand} class, which defines its specific execution logic.</p>
@ -557,7 +539,6 @@ public class VMOpCode {
* primarily used to handle basic double64 precision floating-point multiplication tasks.</p> * primarily used to handle basic double64 precision floating-point multiplication tasks.</p>
*/ */
public static final int D_MUL = 43; public static final int D_MUL = 43;
/** /**
* D_DIV Opcode: Represents the double64 precision floating-point division operation in the virtual machine. * D_DIV Opcode: Represents the double64 precision floating-point division operation in the virtual machine.
* <p>This opcode is implemented by the {@link DDivCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link DDivCommand} class, which defines its specific execution logic.</p>
@ -574,7 +555,6 @@ public class VMOpCode {
* primarily used to handle basic double64 precision floating-point division tasks.</p> * primarily used to handle basic double64 precision floating-point division tasks.</p>
*/ */
public static final int D_DIV = 44; public static final int D_DIV = 44;
/** /**
* D_MOD Opcode: Represents the double64 precision floating-point modulus (remainder) operation in the virtual machine. * D_MOD Opcode: Represents the double64 precision floating-point modulus (remainder) operation in the virtual machine.
* <p>This opcode is implemented by the {@link DModCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link DModCommand} class, which defines its specific execution logic.</p>
@ -591,7 +571,6 @@ public class VMOpCode {
* primarily used to handle basic double64 precision floating-point modulus (remainder) tasks.</p> * primarily used to handle basic double64 precision floating-point modulus (remainder) tasks.</p>
*/ */
public static final int D_MOD = 45; public static final int D_MOD = 45;
/** /**
* D_INC Opcode: Represents the double64 increment operation for a local variable in the virtual machine. * D_INC Opcode: Represents the double64 increment operation for a local variable in the virtual machine.
* <p>This opcode is implemented by the {@link DIncCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link DIncCommand} class, which defines its specific execution logic.</p>
@ -609,7 +588,6 @@ public class VMOpCode {
* <p>This opcode is particularly useful for optimizing scenarios where a local `double64` variable, such as a counter or loop index, is frequently incremented.</p> * <p>This opcode is particularly useful for optimizing scenarios where a local `double64` variable, such as a counter or loop index, is frequently incremented.</p>
*/ */
public static final int D_INC = 46; public static final int D_INC = 46;
/** /**
* D_NEG Opcode: Represents the double64 precision floating-point negation operation in the virtual machine. * D_NEG Opcode: Represents the double64 precision floating-point negation operation in the virtual machine.
* <p>This opcode is implemented by the {@link DNegCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link DNegCommand} class, which defines its specific execution logic.</p>
@ -624,8 +602,9 @@ public class VMOpCode {
* <p>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.</p> * <p>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.</p>
*/ */
public static final int D_NEG = 47; 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. * F_ADD Opcode: Represents the float32 addition operation in the virtual machine.
* <p>This opcode is implemented by the {@link FAddCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link FAddCommand} class, which defines its specific execution logic.</p>
@ -720,7 +699,6 @@ public class VMOpCode {
* <p>This opcode is particularly useful for optimizing scenarios where a local `float32` variable, such as a counter or loop index, is frequently incremented.</p> * <p>This opcode is particularly useful for optimizing scenarios where a local `float32` variable, such as a counter or loop index, is frequently incremented.</p>
*/ */
public static final int F_INC = 56; public static final int F_INC = 56;
/** /**
* F_NEG Opcode: Represents the float32 negation operation in the virtual machine. * F_NEG Opcode: Represents the float32 negation operation in the virtual machine.
* <p>This opcode is implemented by the {@link FNegCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link FNegCommand} class, which defines its specific execution logic.</p>
@ -735,7 +713,10 @@ public class VMOpCode {
* <p>This opcode is typically used to negate a float32 value, making it a fundamental operation for float32 arithmetic logic within the virtual machine.</p> * <p>This opcode is typically used to negate a float32 value, making it a fundamental operation for float32 arithmetic logic within the virtual machine.</p>
*/ */
public static final int F_NEG = 57; 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. * I2L Opcode: Represents the type conversion operation from int32 to long64 in the virtual machine.
* <p>This opcode is implemented by the {@link I2LCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link I2LCommand} class, which defines its specific execution logic.</p>
@ -750,7 +731,6 @@ public class VMOpCode {
* <p>This opcode is commonly used to widen an int32 value to a long64 type to accommodate larger numeric ranges.</p> * <p>This opcode is commonly used to widen an int32 value to a long64 type to accommodate larger numeric ranges.</p>
*/ */
public static final int I2L = 61; public static final int I2L = 61;
/** /**
* I2S Opcode: Represents the type conversion operation from int32 to short16 in the virtual machine. * I2S Opcode: Represents the type conversion operation from int32 to short16 in the virtual machine.
* <p>This opcode is implemented by the {@link I2SCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link I2SCommand} class, which defines its specific execution logic.</p>
@ -765,7 +745,6 @@ public class VMOpCode {
* <p>This opcode is typically used to narrow an int32 value to a short16 type when a smaller data representation is needed.</p> * <p>This opcode is typically used to narrow an int32 value to a short16 type when a smaller data representation is needed.</p>
*/ */
public static final int I2S = 62; public static final int I2S = 62;
/** /**
* I2B Opcode: Represents the type conversion operation from int32 to byte8 in the virtual machine. * I2B Opcode: Represents the type conversion operation from int32 to byte8 in the virtual machine.
* <p>This opcode is implemented by the {@link I2BCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link I2BCommand} class, which defines its specific execution logic.</p>
@ -780,7 +759,6 @@ public class VMOpCode {
* <p>This opcode is used to narrow an int32 value to a byte8 type, suitable when a smaller numeric type is required.</p> * <p>This opcode is used to narrow an int32 value to a byte8 type, suitable when a smaller numeric type is required.</p>
*/ */
public static final int I2B = 63; public static final int I2B = 63;
/** /**
* I2D Opcode: Represents the type conversion operation from int32 to double64 in the virtual machine. * I2D Opcode: Represents the type conversion operation from int32 to double64 in the virtual machine.
* <p>This opcode is implemented by the {@link I2DCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link I2DCommand} class, which defines its specific execution logic.</p>
@ -795,7 +773,6 @@ public class VMOpCode {
* <p>This opcode is used to widen an int32 value to a double64 type, providing high-precision floating-point calculations.</p> * <p>This opcode is used to widen an int32 value to a double64 type, providing high-precision floating-point calculations.</p>
*/ */
public static final int I2D = 64; public static final int I2D = 64;
/** /**
* I2F Opcode: Represents the type conversion operation from int32 to float32 in the virtual machine. * I2F Opcode: Represents the type conversion operation from int32 to float32 in the virtual machine.
* <p>This opcode is implemented by the {@link I2FCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link I2FCommand} class, which defines its specific execution logic.</p>
@ -810,7 +787,6 @@ public class VMOpCode {
* <p>This opcode is used to convert an int32 value to a float32 type when floating-point arithmetic is required.</p> * <p>This opcode is used to convert an int32 value to a float32 type when floating-point arithmetic is required.</p>
*/ */
public static final int I2F = 65; public static final int I2F = 65;
/** /**
* L2I Opcode: Represents the type conversion operation from long64 to int32 in the virtual machine. * L2I Opcode: Represents the type conversion operation from long64 to int32 in the virtual machine.
* <p>This opcode is implemented by the {@link L2ICommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link L2ICommand} class, which defines its specific execution logic.</p>
@ -825,7 +801,6 @@ public class VMOpCode {
* <p>This opcode is typically used to narrow a long64 value to an int32 type for further integer operations.</p> * <p>This opcode is typically used to narrow a long64 value to an int32 type for further integer operations.</p>
*/ */
public static final int L2I = 66; public static final int L2I = 66;
/** /**
* L2D Opcode: Represents the type conversion operation from long64 to double64 in the virtual machine. * L2D Opcode: Represents the type conversion operation from long64 to double64 in the virtual machine.
* <p>This opcode is implemented by the {@link L2DCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link L2DCommand} class, which defines its specific execution logic.</p>
@ -975,11 +950,10 @@ public class VMOpCode {
* <p>This opcode is used to widen a byte8 value to an int32 type to ensure compatibility with integer-based operations.</p> * <p>This opcode is used to widen a byte8 value to an int32 type to ensure compatibility with integer-based operations.</p>
*/ */
public static final int B2I = 76; public static final int B2I = 76;
// endregion
// region 2. Bitwise Operations (8190)
// region 2.1 int32 (81-85)
// 2. Bitwise Operations (8190)
// 2.1 int32 (81-85)
/** /**
* I_AND Opcode: Represents the int32 bitwise AND operation in the virtual machine. * I_AND Opcode: Represents the int32 bitwise AND operation in the virtual machine.
* <p>This opcode is implemented by the {@link IAndCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link IAndCommand} class, which defines its specific execution logic.</p>
@ -1039,7 +1013,8 @@ public class VMOpCode {
*/ */
public static final int I_XOR = 83; 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. * L_AND Opcode: Represents the long64 bitwise AND operation in the virtual machine.
* <p>This opcode is implemented by the {@link LAndCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link LAndCommand} class, which defines its specific execution logic.</p>
@ -1100,8 +1075,10 @@ public class VMOpCode {
public static final int L_XOR = 88; public static final int L_XOR = 88;
// 3. Control Flow Operations (91110) // endregion
// 3.1 JUMP (91-91) // endregion
// region 3. Control Flow Operations (91110)
// region 3.1 JUMP (91-91)
/** /**
* JUMP Opcode: Represents an unconditional jump to a target instruction address. * JUMP Opcode: Represents an unconditional jump to a target instruction address.
* <p>This opcode is implemented by the {@link JumpCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link JumpCommand} class, which defines its specific execution logic.</p>
@ -1121,7 +1098,9 @@ public class VMOpCode {
* </ul> * </ul>
*/ */
public static final int JUMP = 91; 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. * IC_E Opcode: Represents a conditional jump based on int32 equality.
* <p>This opcode is implemented by the {@link ICECommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link ICECommand} class, which defines its specific execution logic.</p>
@ -1248,7 +1227,9 @@ public class VMOpCode {
* </ul> * </ul>
*/ */
public static final int IC_LE = 97; 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. * LC_E Opcode: Represents a conditional jump based on long64 equality.
* <p>This opcode is implemented by the {@link ICECommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link ICECommand} class, which defines its specific execution logic.</p>
@ -1376,8 +1357,10 @@ public class VMOpCode {
*/ */
public static final int LC_LE = 103; public static final int LC_LE = 103;
// 4. Stack Operations (111150) // endregion
// 4.1 PUSH (111-120) // endregion
// region 4. Stack Operations (111150)
// region 4.1 PUSH (111-120)
/** /**
* I_PUSH Opcode: Represents a stack operation that pushes an int32 value onto the operand stack. * I_PUSH Opcode: Represents a stack operation that pushes an int32 value onto the operand stack.
* <p>This opcode is implemented by the {@link IPushCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link IPushCommand} class, which defines its specific execution logic.</p>
@ -1492,6 +1475,8 @@ public class VMOpCode {
* </ul> * </ul>
*/ */
public static final int F_PUSH = 116; 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. * I_POP Opcode: Represents a stack operation that removes the top element from the operand stack.
* <p>This opcode is implemented by the {@link PopCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link PopCommand} class, which defines its specific execution logic.</p>
@ -1510,8 +1495,9 @@ public class VMOpCode {
* <li>Ensuring stack balance during function calls or control flow transitions.</li> * <li>Ensuring stack balance during function calls or control flow transitions.</li>
* </ul> * </ul>
*/ */
// 4.2 POP (121-125)
public static final int POP = 121; 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. * DUP Opcode: Represents a stack operation that duplicates the top element of the operand stack.
* <p>This opcode is implemented by the {@link DupCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link DupCommand} class, which defines its specific execution logic.</p>
@ -1530,8 +1516,11 @@ public class VMOpCode {
* <li>Managing stack balance when performing operations that require repeated access to the same data.</li> * <li>Managing stack balance when performing operations that require repeated access to the same data.</li>
* </ul> * </ul>
*/ */
// 4.3 DUP (126-130)
public static final int DUP = 126; 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. * SWAP Opcode: Represents a stack operation that swaps the top two values of the operand stack.
* <p>This opcode is implemented by the {@link SwapCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link SwapCommand} class, which defines its specific execution logic.</p>
@ -1551,10 +1540,11 @@ public class VMOpCode {
* <li>Ensuring proper operand placement for later instructions that depend on the order of stack elements.</li> * <li>Ensuring proper operand placement for later instructions that depend on the order of stack elements.</li>
* </ul> * </ul>
*/ */
// 4.4 SWAP (131-135)
public static final int SWAP = 131; public static final int SWAP = 131;
// endregion
// 5. Memory Operations (151) // endregion
// region 5. Memory Operations (151166)
/** /**
* I_STORE Opcode: Represents a store operation that saves an int32 value from the operand stack into the local variable store. * 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 {
* </ul> * </ul>
*/ */
public static final int I_STORE = 151; 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. * L_STORE Opcode: Represents a store operation that stores a long64 value from the operand stack into the local variable store.
* <p>This opcode is implemented by the {@link LStoreCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link LStoreCommand} class, which defines its specific execution logic.</p>
@ -1598,8 +1586,6 @@ public class VMOpCode {
* </ul> * </ul>
*/ */
public static final int L_STORE = 152; 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. * S_STORE Opcode: Represents a store operation that stores a short16 value from the operand stack into the local variable store.
* <p>This opcode is implemented by the {@link SStoreCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link SStoreCommand} class, which defines its specific execution logic.</p>
@ -1620,8 +1606,6 @@ public class VMOpCode {
* </ul> * </ul>
*/ */
public static final int S_STORE = 153; 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. * B_STORE Opcode: Represents a store operation that stores a byte8 value from the operand stack into the local variable store.
* <p>This opcode is implemented by the {@link BStoreCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link BStoreCommand} class, which defines its specific execution logic.</p>
@ -1642,8 +1626,6 @@ public class VMOpCode {
* </ul> * </ul>
*/ */
public static final int B_STORE = 154; 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. * D_STORE Opcode: Represents a store operation that stores a double64 value from the operand stack into the local variable store.
* <p>This opcode is implemented by the {@link DStoreCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link DStoreCommand} class, which defines its specific execution logic.</p>
@ -1664,7 +1646,6 @@ public class VMOpCode {
* </ul> * </ul>
*/ */
public static final int D_STORE = 155; 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. * F_STORE Opcode: Represents a store operation that stores a float32 value from the operand stack into the local variable store.
* <p>This opcode is implemented by the {@link FStoreCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link FStoreCommand} class, which defines its specific execution logic.</p>
@ -1685,8 +1666,6 @@ public class VMOpCode {
* </ul> * </ul>
*/ */
public static final int F_STORE = 156; 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. * I_LOAD Opcode: Represents a load operation that retrieves an int32 value from the local variable store and pushes it onto the operand stack.
* <p>This opcode is implemented by the {@link ILoadCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link ILoadCommand} class, which defines its specific execution logic.</p>
@ -1828,6 +1807,8 @@ public class VMOpCode {
* </ul> * </ul>
*/ */
public static final int MOV = 171; 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. * CALL Opcode: Represents a function or subroutine call operation that transfers control to a specified function address.
* <p>This opcode is implemented by the {@link CallCommand} class, which defines its specific execution logic.</p> * <p>This opcode is implemented by the {@link CallCommand} class, which defines its specific execution logic.</p>
@ -1885,9 +1866,7 @@ public class VMOpCode {
* </ul> * </ul>
*/ */
public static final int HALT = 255; public static final int HALT = 255;
// endregion
// VI. Function Operations (5059)
/** /**
* Default constructor for creating an instance of VMOpCode. * Default constructor for creating an instance of VMOpCode.