diff --git a/opcode b/opcode index 1c72dcd..454973c 100644 --- a/opcode +++ b/opcode @@ -1,69 +1,16 @@ module: CommonTasks - function: add_numbers - parameter: - declare num1: int - declare num2: int - return_type: int - body: - return num1 + num2 - end body - end function -end module - -module: MathUtils - function: square_number - parameter: - declare number: int - return_type: int - body: - return number * number - end body - end function -end module - -module: StringUtils - function: concatenate - parameter: - declare first_str: string - declare second_str: string - return_type: string - body: - return first_str + second_str - end body - end function -end module - -module: MainModule - import: CommonTasks, MathUtils, StringUtils, BuiltinUtils - function: main parameter: - args: string - return_type: void + declare num1: int + declare num2: int + return_type: int + body: - loop: - initializer: - declare counter: int = 5 - condition: - counter > 0 - update: - counter = counter - 1 - body: - BuiltinUtils.print(counter) - end body - end loop + declare sum: int = num1 + num2 - declare input_number: int = BuiltinUtils.to_int(args) - if input_number == 0 then - input_number = 999 - end if + declare doubled: int = sum * 2 - declare sum_result: int = CommonTasks.add_numbers(input_number, 20) - - declare squared_result: int = MathUtils.square_number(sum_result) - - declare final_message: string = StringUtils.concatenate("Result:",BuiltinUtils.to_string(squared_result)) - BuiltinUtils.print(final_message) + return doubled end body end function end module diff --git a/src/main/java/org/jcnc/snow/compiler/backend/RegisterAllocator.java b/src/main/java/org/jcnc/snow/compiler/backend/RegisterAllocator.java new file mode 100644 index 0000000..1c425f0 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/backend/RegisterAllocator.java @@ -0,0 +1,24 @@ +// ────────────────────────────────────────── +// file: compiler/backend/RegisterAllocator.java +package org.jcnc.snow.compiler.backend; + +import org.jcnc.snow.compiler.ir.*; +import org.jcnc.snow.compiler.ir.instr.IRFunction; + +import java.util.HashMap; +import java.util.Map; + +/** 线性扫描寄存器分配(演示级) */ +public final class RegisterAllocator { + private final Map map = new HashMap<>(); + + public Map allocate(IRFunction fn){ + int next = 0; + for (IRInstruction i : fn.body()){ + if(i.dest()!=null && !map.containsKey(i.dest())) map.put(i.dest(), next++); + for(IRValue v : i.operands()) + if(v instanceof VirtualRegister r && !map.containsKey(r)) map.put(r, next++); + } + return map; + } +} diff --git a/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java b/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java new file mode 100644 index 0000000..f61fd34 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/backend/VMCodeGenerator.java @@ -0,0 +1,117 @@ +package org.jcnc.snow.compiler.backend; + +import org.jcnc.snow.compiler.ir.*; +import org.jcnc.snow.compiler.ir.instr.*; +import org.jcnc.snow.vm.engine.VMOpCode; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * 将 IRFunction 转译为 SVM 指令文本。 + * 目前支持:int32 常量、+ - * /、一元 -、return。 + */ +public final class VMCodeGenerator { + + private final Map slotMap; + private final List code = new ArrayList<>(); + + private String currentFnName; // ← 当前正在生成的函数名 + + public VMCodeGenerator(Map slotMap){ + this.slotMap = slotMap; + } + + /** 主入口:IR → 指令序列 */ + public List generate(IRFunction fn){ + currentFnName = fn.name(); // ← 保存函数名 + + for (IRInstruction inst : fn.body()) { + switch (inst) { + case LoadConstInstruction c -> genLoadConst(c); + case BinOpInstruction b -> genBinOp(b); + case UnaryOpInstruction u -> genUnary(u); + case ReturnInstruction r -> genRet(r); + default -> throw new IllegalStateException("Unsupported IR: "+inst); + } + } + /* 注意:不再额外添加 HALT,结束行为由 genRet 决定 */ + return code; + } + + /* ───────────── 指令生成 ───────────── */ + + private void genLoadConst(LoadConstInstruction c){ + Constant k = (Constant)c.operands().get(0); + emit(op("I_PUSH"), k.value().toString()); + emit(op("I_STORE"), slot(c.dest())+""); + } + + private void genBinOp(BinOpInstruction b){ + emit(op("I_LOAD"), slot((VirtualRegister)b.operands().get(0))+""); + emit(op("I_LOAD"), slot((VirtualRegister)b.operands().get(1))+""); + + String opcode = switch (b.op()){ + case ADD_I32 -> "I_ADD"; + case SUB_I32 -> "I_SUB"; + case MUL_I32 -> "I_MUL"; + case DIV_I32 -> "I_DIV"; + default -> throw new IllegalStateException("Unsupported bin op "+b.op()); + }; + emit(op(opcode)); + emit(op("I_STORE"), slot(b.dest())+""); + } + + private void genUnary(UnaryOpInstruction u){ + emit(op("I_LOAD"), slot((VirtualRegister)u.operands().get(0))+""); + + String opcode = switch (u.op()){ + case NEG_I32 -> "I_NEG"; + default -> throw new IllegalStateException("Unsupported unary op "+u.op()); + }; + emit(op(opcode)); + emit(op("I_STORE"), slot(u.dest())+""); + } + + private void genRet(ReturnInstruction r){ + /* — 主函数:加载返回值(若有) → HALT — */ + if ("main".equals(currentFnName)) { + if (r.value() != null) { + emit(op("I_LOAD"), slot(r.value())+""); + } + emit(op("HALT")); // 结束整个程序 + return; + } + + /* — 普通函数:LOAD (可选) → RET — */ + if (r.value() != null) { + emit(op("I_LOAD"), slot(r.value())+""); + } + emit(op("RET")); + } + + /* ───────────── 工具函数 ───────────── */ + + private int slot(VirtualRegister r){ + Integer s = slotMap.get(r); + if (s == null) throw new IllegalStateException("Register "+r+" 未映射槽位"); + return s; + } + + private String op(String name){ + try { + Field f = VMOpCode.class.getField(name); + return f.get(null).toString(); + } catch (Exception e){ + throw new RuntimeException("Unknown opcode "+name, e); + } + } + + private void emit(String opcode, String... args){ + StringBuilder sb = new StringBuilder(opcode); + for (String a : args) sb.append(' ').append(a); + code.add(sb.toString()); + } +} diff --git a/src/main/java/org/jcnc/snow/compiler/cli/SnowCompiler.java b/src/main/java/org/jcnc/snow/compiler/cli/SnowCompiler.java index ae076f5..e185b4b 100644 --- a/src/main/java/org/jcnc/snow/compiler/cli/SnowCompiler.java +++ b/src/main/java/org/jcnc/snow/compiler/cli/SnowCompiler.java @@ -1,11 +1,18 @@ package org.jcnc.snow.compiler.cli; +import org.jcnc.snow.compiler.backend.RegisterAllocator; +import org.jcnc.snow.compiler.backend.VMCodeGenerator; +import org.jcnc.snow.compiler.ir.BasicIRBuilder; +import org.jcnc.snow.compiler.ir.IRProgram; +import org.jcnc.snow.compiler.ir.instr.IRFunction; import org.jcnc.snow.compiler.lexer.core.LexerEngine; import org.jcnc.snow.compiler.lexer.token.Token; -import org.jcnc.snow.compiler.parser.core.ParserEngine; -import org.jcnc.snow.compiler.parser.context.ParserContext; import org.jcnc.snow.compiler.parser.ast.base.Node; +import org.jcnc.snow.compiler.parser.context.ParserContext; +import org.jcnc.snow.compiler.parser.core.ParserEngine; import org.jcnc.snow.compiler.semantic.core.SemanticAnalyzerRunner; +import org.jcnc.snow.vm.engine.VMMode; +import org.jcnc.snow.vm.engine.VirtualMachineEngine; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -14,29 +21,59 @@ import java.nio.file.Path; import java.util.List; public class SnowCompiler { + public static void main(String[] args) throws IOException { - // 读取源文件 - String source = Files.readString(Path.of(args[0]), StandardCharsets.UTF_8); + /* ───── 读取源码 ───── */ + if (args.length == 0 || args[0].isBlank()) { + System.err.println("Usage: SnowCompiler "); + return; + } + Path srcPath = Path.of(args[0]); + if (!Files.exists(srcPath)) { + System.err.println("File not found: " + srcPath); + return; + } + String source = Files.readString(srcPath, StandardCharsets.UTF_8); - // 1. 词法分析 - LexerEngine lexerEngine = new LexerEngine(source); - List tokens = lexerEngine.getAllTokens(); + /* 1. 词法分析 */ + LexerEngine lexer = new LexerEngine(source); + List tokens = lexer.getAllTokens(); - // 2. 语法分析 + /* 2. 语法分析 */ ParserContext ctx = new ParserContext(tokens); - List ast = new ParserEngine(ctx).parse(); + List ast = new ParserEngine(ctx).parse(); - // 3. 语义分析 - SemanticAnalyzerRunner.runSemanticAnalysis(ast,true); + /* 3. 语义分析 */ + SemanticAnalyzerRunner.runSemanticAnalysis(ast, true); + + /* 4. AST → IRProgram */ + IRProgram program = new BasicIRBuilder().buildProgram(ast); + System.out.println("=== IR ==="); + System.out.println(program); + + /* 5. 后端:寄存器分配 & 代码生成 + VM 执行 */ + for (IRFunction fn : program.functions()) { + var alloc = new RegisterAllocator(); + var slotM = alloc.allocate(fn); + + var gen = new VMCodeGenerator(slotM); + var code = gen.generate(fn); + + System.out.println("== VM code for " + fn.name() + " =="); + code.forEach(System.out::println); + /* 只执行 main 函数 */ + if ("main".equals(fn.name())) { + VirtualMachineEngine vm = new VirtualMachineEngine(VMMode.RUN); - // 打印 -// System.out.println(source); -// TokenPrinter.print(tokens); // 打印 Token 列表 -// ASTPrinter.print(ast); // 打印 AST -// ASTPrinter.printJson(ast); // 打印JSON AST + vm.execute(code); // 运行指令 + vm.printStack(); // 打印 Operand-/Call-Stack + vm.printLocalVariables(); // 打印局部变量槽 + System.out.println("Process has ended"); + } + } } -} \ No newline at end of file +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/BasicIRBuilder.java b/src/main/java/org/jcnc/snow/compiler/ir/BasicIRBuilder.java new file mode 100644 index 0000000..3b0995f --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/BasicIRBuilder.java @@ -0,0 +1,142 @@ +package org.jcnc.snow.compiler.ir; + +import org.jcnc.snow.compiler.ir.instr.*; +import org.jcnc.snow.compiler.parser.ast.*; +import org.jcnc.snow.compiler.parser.ast.base.ExpressionNode; +import org.jcnc.snow.compiler.parser.ast.base.Node; +import org.jcnc.snow.compiler.parser.ast.base.StatementNode; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 把 AST 转为 IR。 + * • 递归处理 Module → Function → Statement → Expression(分而治之) + * • 目前只支持整数字面量、标识符、+ - * /、变量声明/赋值、return + */ +public final class BasicIRBuilder { + + /* ───────────────── 顶层 API ───────────────── */ + + /** 把整棵 AST(可能含模块/多函数)转换为 IRProgram */ + public IRProgram buildProgram(List roots) { + IRProgram prog = new IRProgram(); + for (Node n : roots) dispatchTop(n, prog); + return prog; + } + + /* ───────────────── 内部实现 ───────────────── */ + + /** 处理模块 / 顶层函数 / 单条语句 */ + private void dispatchTop(Node n, IRProgram prog) { + switch (n) { + /* module { fun* } */ + case ModuleNode m -> m.functions().forEach(f -> dispatchTop(f, prog)); + + /* fun foo(...) { stmts } */ + case FunctionNode f -> prog.add(buildFunction(f)); + + /* 若直接给了一堆语句,也视作匿名主函数 */ + case StatementNode s -> { + FunctionNode fake = new FunctionNode("main", List.of(), "void", List.of(s)); + prog.add(buildFunction(fake)); + } + + default -> throw new IllegalStateException("Unsupported top-level node: " + n); + } + } + + /** 将单个 FunctionNode 转成 IRFunction */ + private IRFunction buildFunction(FunctionNode fn) { + currentFn = new IRFunction(fn.name()); + variables.clear(); + + /* 参数映射到寄存器(暂未用到,保留扩展) */ + for (ParameterNode p : fn.parameters()) { + variables.put(p.name(), currentFn.newRegister()); + } + + /* 编译函数体 */ + for (StatementNode stmt : fn.body()) stmt(stmt); + + /* 若无显式 return,补一个 void return */ + if (currentFn.body().isEmpty() || + !(currentFn.body().get(currentFn.body().size() - 1) instanceof ReturnInstruction)) + currentFn.add(new ReturnInstruction(null)); + + return currentFn; + } + + /* ─────────────── 函数体级别状态 ─────────────── */ + + private IRFunction currentFn; // 正在构建的函数 + private final Map variables = new HashMap<>(); + + /* ─── 语句 ─── */ + private void stmt(StatementNode n) { + switch (n) { + case ExpressionStatementNode es -> expr(es.expression()); + + case AssignmentNode as -> { + VirtualRegister rhs = expr(as.value()); + variables.put(as.variable(), rhs); + } + + case DeclarationNode d -> { + if (d.getInitializer().isPresent()) { + VirtualRegister init = expr(d.getInitializer().get()); + variables.put(d.getName(), init); + } else { + variables.put(d.getName(), currentFn.newRegister()); + } + } + + case ReturnNode r -> { + if (r.getExpression().isPresent()) + currentFn.add(new ReturnInstruction(expr(r.getExpression().get()))); + else + currentFn.add(new ReturnInstruction(null)); + } + + default -> throw new IllegalStateException("Unsupported stmt: " + n); + } + } + + /* ─── 表达式 ─── */ + private VirtualRegister expr(ExpressionNode e) { + return switch (e) { + case BinaryExpressionNode b -> bin(b); + case NumberLiteralNode n -> number(n); + case IdentifierNode id-> { + VirtualRegister v = variables.get(id.name()); + if (v == null) throw new IllegalStateException("变量 " + id.name() + " 未定义"); + yield v; + } + default -> throw new IllegalStateException("Unsupported expr: " + e); + }; + } + + private VirtualRegister bin(BinaryExpressionNode b) { + VirtualRegister l = expr(b.left()); + VirtualRegister r = expr(b.right()); + VirtualRegister d = currentFn.newRegister(); + + IROp op = switch (b.operator()) { + case "+" -> IROp.ADD_I32; + case "-" -> IROp.SUB_I32; + case "*" -> IROp.MUL_I32; + case "/" -> IROp.DIV_I32; + default -> throw new IllegalStateException("未知运算符 " + b.operator()); + }; + + currentFn.add(new BinOpInstruction(op, d, l, r)); + return d; + } + + private VirtualRegister number(NumberLiteralNode n) { + VirtualRegister d = currentFn.newRegister(); + currentFn.add(new LoadConstInstruction(d, new Constant(Integer.parseInt(n.value())))); + return d; + } +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/Constant.java b/src/main/java/org/jcnc/snow/compiler/ir/Constant.java new file mode 100644 index 0000000..b134a06 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/Constant.java @@ -0,0 +1,6 @@ +// file: compiler/ir/Constant.java +package org.jcnc.snow.compiler.ir; + +public record Constant(Object value) implements IRValue { + @Override public String toString() { return value.toString(); } +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/IRInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/IRInstruction.java new file mode 100644 index 0000000..66def4a --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/IRInstruction.java @@ -0,0 +1,12 @@ +// ────────────────────────────────────────── +// file: compiler/ir/IRInstruction.java +package org.jcnc.snow.compiler.ir; + +import java.util.List; + +/** 全部 IR 指令的抽象父类 */ +public abstract class IRInstruction { + public abstract IROp op(); + public VirtualRegister dest() { return null; } // 若无结果可返回 null + public List operands() { return List.of(); } // 默认无操作数 +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/IROp.java b/src/main/java/org/jcnc/snow/compiler/ir/IROp.java new file mode 100644 index 0000000..498c073 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/IROp.java @@ -0,0 +1,17 @@ +// ────────────────────────────────────────── +// file: compiler/ir/IROp.java +package org.jcnc.snow.compiler.ir; + +/** IR 支持的操作码(可按需继续扩展) */ +public enum IROp { + /* 算术 */ + ADD_I32, SUB_I32, MUL_I32, DIV_I32, NEG_I32, + /* 逻辑/比较 */ + CMP_EQ, CMP_NE, CMP_LT, CMP_GT, CMP_LE, CMP_GE, + /* 数据搬运 */ + LOAD, STORE, CONST, + /* 控制流 */ + JUMP, JUMP_IF_ZERO, LABEL, + /* 函数 */ + CALL, RET +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/IRProgram.java b/src/main/java/org/jcnc/snow/compiler/ir/IRProgram.java new file mode 100644 index 0000000..ddc0c35 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/IRProgram.java @@ -0,0 +1,24 @@ +package org.jcnc.snow.compiler.ir; + +import org.jcnc.snow.compiler.ir.instr.IRFunction; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * 一份完整的中间代码程序,包含多个函数级 IR。 + */ +public final class IRProgram { + private final List functions = new ArrayList<>(); + + public void add(IRFunction fn) { functions.add(fn); } + + public List functions() { return Collections.unmodifiableList(functions); } + + @Override public String toString() { + StringBuilder sb = new StringBuilder(); + for (IRFunction f : functions) sb.append(f).append('\n'); + return sb.toString(); + } +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/IRValue.java b/src/main/java/org/jcnc/snow/compiler/ir/IRValue.java new file mode 100644 index 0000000..4f1ac13 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/IRValue.java @@ -0,0 +1,6 @@ +// ────────────────────────────────────────── +// file: compiler/ir/IRValue.java +package org.jcnc.snow.compiler.ir; + +/** 常量、寄存器、标签的共同父接口 */ +public sealed interface IRValue permits VirtualRegister, Constant, Label {} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/Label.java b/src/main/java/org/jcnc/snow/compiler/ir/Label.java new file mode 100644 index 0000000..e95df1d --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/Label.java @@ -0,0 +1,6 @@ +// file: compiler/ir/Label.java +package org.jcnc.snow.compiler.ir; + +public record Label(String name) implements IRValue { + @Override public String toString() { return name + ":"; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/VirtualRegister.java b/src/main/java/org/jcnc/snow/compiler/ir/VirtualRegister.java new file mode 100644 index 0000000..2f8cade --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/VirtualRegister.java @@ -0,0 +1,7 @@ +// file: compiler/ir/VirtualRegister.java +package org.jcnc.snow.compiler.ir; + +/** SSA 虚拟寄存器 */ +public record VirtualRegister(int id) implements IRValue { + @Override public String toString() { return "%" + id; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instr/BinOpInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instr/BinOpInstruction.java new file mode 100644 index 0000000..77b3987 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/instr/BinOpInstruction.java @@ -0,0 +1,26 @@ +// file: compiler/ir/instr/BinOpInstruction.java +package org.jcnc.snow.compiler.ir.instr; + +import org.jcnc.snow.compiler.ir.*; + +import java.util.List; + +/** 二元运算:dest = lhs (OP) rhs */ +public final class BinOpInstruction extends IRInstruction { + private final IROp op; + private final VirtualRegister dest; + private final IRValue lhs; + private final IRValue rhs; + + public BinOpInstruction(IROp op, VirtualRegister dest, IRValue lhs, IRValue rhs) { + this.op = op; + this.dest = dest; + this.lhs = lhs; + this.rhs = rhs; + } + @Override public IROp op() { return op; } + @Override public VirtualRegister dest() { return dest; } + @Override public List operands() { return List.of(lhs, rhs); } + + @Override public String toString() { return dest + " = " + op + " " + lhs + ", " + rhs; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instr/IRFunction.java b/src/main/java/org/jcnc/snow/compiler/ir/instr/IRFunction.java new file mode 100644 index 0000000..c801c46 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/instr/IRFunction.java @@ -0,0 +1,31 @@ +// ────────────────────────────────────────── +// file: compiler/ir/IRFunction.java +package org.jcnc.snow.compiler.ir.instr; + +import org.jcnc.snow.compiler.ir.IRInstruction; +import org.jcnc.snow.compiler.ir.VirtualRegister; + +import java.util.ArrayList; +import java.util.List; + +/** 函数字节码级 IR */ +public class IRFunction { + private final String name; + private final List body = new ArrayList<>(); + private int regCounter = 0; + + public IRFunction(String name){ this.name = name; } + + /* —— API —— */ + public VirtualRegister newRegister(){ return new VirtualRegister(regCounter++); } + public void add(IRInstruction inst){ body.add(inst); } + public List body(){ return body; } + public String name(){ return name; } + public int registerCount(){ return regCounter; } + + @Override public String toString(){ + StringBuilder sb=new StringBuilder("func "+name+" {\\n"); + body.forEach(i->sb.append(" ").append(i).append("\\n")); + return sb.append('}').toString(); + } +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instr/LoadConstInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instr/LoadConstInstruction.java new file mode 100644 index 0000000..8654ac1 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/instr/LoadConstInstruction.java @@ -0,0 +1,22 @@ +// file: compiler/ir/instr/LoadConstInstruction.java +package org.jcnc.snow.compiler.ir.instr; + +import org.jcnc.snow.compiler.ir.*; + +import java.util.List; + +/** 常量加载:dest = CONST k */ +public final class LoadConstInstruction extends IRInstruction { + private final Constant k; + private final VirtualRegister dest; + + public LoadConstInstruction(VirtualRegister dest, Constant k) { + this.dest = dest; + this.k = k; + } + @Override public IROp op() { return IROp.CONST; } + @Override public VirtualRegister dest() { return dest; } + @Override public List operands() { return List.of(k); } + + @Override public String toString() { return dest + " = CONST " + k; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instr/ReturnInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instr/ReturnInstruction.java new file mode 100644 index 0000000..d3d9baa --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/instr/ReturnInstruction.java @@ -0,0 +1,18 @@ +// file: compiler/ir/instr/ReturnInstruction.java +package org.jcnc.snow.compiler.ir.instr; + +import org.jcnc.snow.compiler.ir.*; + +import java.util.List; + +/** return [val] */ +public final class ReturnInstruction extends IRInstruction { + private final VirtualRegister value; // void 时为 null + public ReturnInstruction(VirtualRegister value){ this.value = value; } + + @Override public IROp op() { return IROp.RET; } + @Override public List operands() { return value==null? List.of() : List.of(value); } + public VirtualRegister value() { return value; } + + @Override public String toString(){ return value==null? "RET" : "RET " + value; } +} diff --git a/src/main/java/org/jcnc/snow/compiler/ir/instr/UnaryOpInstruction.java b/src/main/java/org/jcnc/snow/compiler/ir/instr/UnaryOpInstruction.java new file mode 100644 index 0000000..bb78032 --- /dev/null +++ b/src/main/java/org/jcnc/snow/compiler/ir/instr/UnaryOpInstruction.java @@ -0,0 +1,24 @@ +// file: compiler/ir/instr/UnaryOpInstruction.java +package org.jcnc.snow.compiler.ir.instr; + +import org.jcnc.snow.compiler.ir.*; + +import java.util.List; + +/** 一元运算:dest = OP val */ +public final class UnaryOpInstruction extends IRInstruction { + private final IROp op; + private final VirtualRegister dest; + private final IRValue val; + + public UnaryOpInstruction(IROp op, VirtualRegister dest, IRValue val) { + this.op = op; + this.dest = dest; + this.val = val; + } + @Override public IROp op() { return op; } + @Override public VirtualRegister dest() { return dest; } + @Override public List operands() { return List.of(val); } + + @Override public String toString() { return dest + " = " + op + " " + val; } +} diff --git a/src/main/java/org/jcnc/snow/vm/VMInitializer.java b/src/main/java/org/jcnc/snow/vm/VMInitializer.java new file mode 100644 index 0000000..fc1ce08 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/VMInitializer.java @@ -0,0 +1,64 @@ +package org.jcnc.snow.vm; + +import org.jcnc.snow.vm.execution.CommandLoader; +import org.jcnc.snow.vm.engine.VMCommandExecutor; +import org.jcnc.snow.vm.engine.VMMode; +import org.jcnc.snow.vm.engine.VirtualMachineEngine; +import org.jcnc.snow.vm.io.FilePathResolver; +import org.jcnc.snow.vm.utils.VMStateLogger; + +import java.util.List; + +/** + * Virtual Machine Initialization Class, responsible for the VM startup process, including: + *
    + *
  • Retrieving and validating the file path
  • + *
  • Loading the instruction set
  • + *
  • Executing the instructions
  • + *
  • Printing the virtual machine's state
  • + *
+ *

+ * This class contains the main method `main(String[] args)`, which initiates the virtual machine execution flow. + *

+ *

The main process:

+ *
    + *
  1. Retrieve and parse the file path from command-line arguments
  2. + *
  3. Load the instructions from the specified file path
  4. + *
  5. Execute the loaded instructions using the virtual machine engine
  6. + *
  7. Print the virtual machine's current state
  8. + *
+ */ +public class VMInitializer { + /** + * Default constructor for creating an instance of VMInitializer. + * This constructor is empty as no specific initialization is required. + */ + public VMInitializer() { + // Empty constructor + } + + /** + * Initializes the virtual machine by processing the file path, loading instructions, executing them, + * and printing the virtual machine's state. + * + * @param args Command-line arguments containing the file path of the virtual machine instructions + * @param vmMode The mode in which the virtual machine should operate. + * This can be used to specify different operational modes (e.g., debug mode, normal mode). + */ + public static void initializeAndRunVM(String[] args, VMMode vmMode) { + // Retrieve and validate file path + String filePath = FilePathResolver.getFilePath(args); + if (filePath == null) return; + + // Load commands from the file + List commands = CommandLoader.loadInstructions(filePath); + if (commands.isEmpty()) return; + + // Execute the commands using the virtual machine engine + VirtualMachineEngine virtualMachineEngine = new VirtualMachineEngine(vmMode); + VMCommandExecutor.executeInstructions(virtualMachineEngine, commands); + + // Print the virtual machine's state + VMStateLogger.printVMState(virtualMachineEngine); + } +} diff --git a/src/main/java/org/jcnc/snow/vm/VMLauncher.java b/src/main/java/org/jcnc/snow/vm/VMLauncher.java new file mode 100644 index 0000000..bbcfca8 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/VMLauncher.java @@ -0,0 +1,49 @@ +package org.jcnc.snow.vm; + +import org.jcnc.snow.vm.engine.VMMode; + +import static org.jcnc.snow.vm.VMInitializer.initializeAndRunVM; + +/** + * The {@code VMLauncher} class is responsible for initiating the virtual machine (VM) execution process. + * It processes command-line arguments, loads the instruction set, and invokes the virtual machine engine to + * execute the instructions. It then prints the virtual machine's current state, allowing users to observe + * the VM's progress and results. + * + *

This class provides the entry point to launch the virtual machine. The main method retrieves the file path + * of the VM instructions from the command-line arguments, initializes the VM engine, and runs the VM in the + * specified mode (e.g., {@link VMMode#DEBUG}).

+ */ +public class VMLauncher { + + /** + * Default constructor for creating an instance of {@code VMLauncher}. + *

This constructor is empty as no specific initialization is required + * for the {@code VMLauncher} class.

+ */ + public VMLauncher() { + // Empty constructor + } + + /** + * The main method serves as the entry point to start the virtual machine execution process. + * It processes the command-line arguments to retrieve the file path for the virtual machine's + * instruction set, loads the instructions from the specified file, and executes them using + * the virtual machine engine. + * + *

The sequence of operations in this method is as follows:

+ *
    + *
  1. Retrieve and validate the file path from the command-line arguments.
  2. + *
  3. Load the instruction set from the specified file.
  4. + *
  5. Execute the instructions using the virtual machine engine.
  6. + *
  7. Output the current state of the virtual machine.
  8. + *
+ * + * @param args Command-line arguments passed to the program. The primary argument expected + * is the file path pointing to the virtual machine's instruction set. + */ + public static void main(String[] args) { + // Call the method that initializes and runs the VM in DEBUG mode + initializeAndRunVM(args, VMMode.DEBUG); + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BAddCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BAddCommand.java new file mode 100644 index 0000000..b05f809 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BAddCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * BAddCommand Opcode: Represents the byte8 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two byte8 values from the operand stack.
  2. + *
  3. Performs the addition of the two values (i.e., a + b).
  4. + *
  5. Pushes the sum back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to add two byte8 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class BAddCommand implements Command { + + /** + * Default constructor for creating an instance of BAddCommand. + * This constructor is empty as no specific initialization is required. + */ + public BAddCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for adding two byte8 values. + * + *

This method retrieves the two byte8 values from the operand stack, adds them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // Perform the addition and push the result back onto the stack + operandStack.push(a + b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BDivCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BDivCommand.java new file mode 100644 index 0000000..ad24912 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BDivCommand.java @@ -0,0 +1,64 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * BDivCommand Opcode: Represents the byte8 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two byte8 values from the operand stack.
  2. + *
  3. Performs the division operation (i.e., a / b).
  4. + *
  5. Checks for division by zero to prevent errors.
  6. + *
  7. Pushes the result of the division back onto the operand stack for subsequent instructions to use.
  8. + *
+ * + *

This opcode is typically used to divide one byte8 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class BDivCommand implements Command { + + /** + * Default constructor for creating an instance of BDivCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public BDivCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for dividing two byte8 values. + * + *

This method retrieves the two byte8 values from the operand stack, checks for division by zero, performs the division, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // Check for division by zero + if (b == 0) { + throw new ArithmeticException("Division by zero is not allowed."); + } + + // Perform the division and push the result back onto the stack + operandStack.push(a / b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BIncCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BIncCommand.java new file mode 100644 index 0000000..8d2dd72 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BIncCommand.java @@ -0,0 +1,70 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * BIncCommand Opcode: Represents the byte8 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Extracts the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Retrieves the current value of the local variable at the given index.
  4. + *
  5. Increments the value of the local variable by the specified increment value (i.e., localVariables[index] += increment).
  6. + *
  7. Updates the local variable with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.
  10. + *
+ * + *

This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.

+ */ +public class BIncCommand implements Command { + + /** + * Default constructor for creating an instance of BIncCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public BIncCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for incrementing a local variable. + * + *

This method retrieves the necessary data (index of the local variable and the increment value) from the instruction parameters, + * performs the increment operation on the specified local variable, and returns the updated program counter (PC) value.

+ * + * @param parts The array of instruction parameters, which includes the index of the local variable and + * the increment value (passed directly as bytecode parameters). + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, including the one being incremented. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the index of the local variable and the increment value from the parameters + + int localVariableIndex = Integer.parseInt(parts[1]); // Index of the local variable to be incremented + + byte incrementValue = Byte.parseByte(parts[2]); // The value by which to increment the local variable + + // Get the current value of the local variable at the specified index + byte currentValue = (byte) callStack.peekFrame().getLocalVariableStore().getVariable(localVariableIndex); + + // Increment the local variable value by the specified increment + byte newValue = (byte) (currentValue + incrementValue); + + // Update the local variable with the new incremented value + callStack.peekFrame().getLocalVariableStore().setVariable(localVariableIndex, newValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BModCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BModCommand.java new file mode 100644 index 0000000..88b12bd --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BModCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * BModCommand Opcode: Represents the byte8 modulus operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two byte8 values from the operand stack.
  2. + *
  3. Performs the modulus operation to calculate the remainder (i.e., a % b).
  4. + *
  5. Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to calculate the remainder of the division of two byte8 values, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class BModCommand implements Command { + + /** + * Default constructor for creating an instance of BModCommand. + * This constructor is empty as no specific initialization is required. + */ + public BModCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for performing a modulus operation between two byte8 values. + * + *

This method retrieves the two byte8 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // Perform the modulus operation and push the result back onto the stack + operandStack.push(a % b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BMulCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BMulCommand.java new file mode 100644 index 0000000..e5de63a --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BMulCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * BMulCommand Opcode: Represents the byte8 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two byte8 values from the operand stack.
  2. + *
  3. Performs the multiplication of the two values (i.e., a * b).
  4. + *
  5. Pushes the result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to multiply two byte8 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class BMulCommand implements Command { + + /** + * Default constructor for creating an instance of BMulCommand. + * This constructor is empty as no specific initialization is required. + */ + public BMulCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for multiplying two byte8 values. + * + *

This method retrieves the two byte8 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // Perform the multiplication and push the result back onto the stack + operandStack.push(a * b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BNegCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BNegCommand.java new file mode 100644 index 0000000..7a94547 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BNegCommand.java @@ -0,0 +1,60 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * BNegCommand Opcode: Represents the byte8 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top byte8 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate an byte8 value, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class BNegCommand implements Command { + + /** + * Default constructor for creating an instance of BNegCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public BNegCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for negating an byte8 value. + * + *

This method retrieves the byte8 value from the operand stack, negates it, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top byte8 value from the operand stack + byte value = (byte) operandStack.pop(); + + // Perform the negation of the value + byte negatedValue = (byte) -value; + + // Push the negated result back onto the operand stack + operandStack.push(negatedValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BSubCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BSubCommand.java new file mode 100644 index 0000000..091cafd --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/byte8/BSubCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * BSubCommand Opcode: Represents the byte8 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two byte8 values from the operand stack.
  2. + *
  3. Performs the subtraction of the second popped value from the first (i.e., a - b).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to subtract one byte8 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class BSubCommand implements Command { + + /** + * Default constructor for creating an instance of BSubCommand. + * This constructor is empty as no specific initialization is required. + */ + public BSubCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for subtracting two byte8 values. + * + *

This method retrieves the two byte8 values from the operand stack, subtracts the second value from the first, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + byte b = (byte) operandStack.pop(); + byte a = (byte) operandStack.pop(); + + // Perform the subtraction and push the result back onto the stack + operandStack.push(a - b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/B2ICommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/B2ICommand.java new file mode 100644 index 0000000..1f04f6a --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/B2ICommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * B2ICommand Opcode: Represents the type conversion operation from byte8 to int32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top byte8 value from the operand stack.
  2. + *
  3. Convert the byte8 value to an int32 value.
  4. + *
  5. Push the converted int32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to widen a byte8 value to an int32 type to ensure compatibility with integer-based operations.

+ */ +public class B2ICommand implements Command { + + /** + * Default constructor for creating an instance of B2ICommand. + */ + public B2ICommand() { + // Empty constructor + } + + /** + * Executes the byte8 to int32 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + byte value = (byte) operandStack.pop(); + int convertedValue = (int) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/D2FCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/D2FCommand.java new file mode 100644 index 0000000..3ed687f --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/D2FCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * D2FCommand Opcode: Represents the type conversion operation from double64 to float32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top double64 value from the operand stack.
  2. + *
  3. Convert the double64 value to a float32 value.
  4. + *
  5. Push the converted float32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to narrow a double64 value to a float32 type when lower precision floating-point arithmetic is acceptable.

+ */ +public class D2FCommand implements Command { + + /** + * Default constructor for creating an instance of D2FCommand. + */ + public D2FCommand() { + // Empty constructor + } + + /** + * Executes the double64 to float32 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + double value = (double) operandStack.pop(); + float convertedValue = (float) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/D2ICommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/D2ICommand.java new file mode 100644 index 0000000..b0c706c --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/D2ICommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * D2ICommand Opcode: Represents the type conversion operation from double64 to int32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top double64 value from the operand stack.
  2. + *
  3. Convert the double64 value to an int32 value (this may involve truncation).
  4. + *
  5. Push the converted int32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to narrow a double64 value to an int32 type for further integer-based operations.

+ */ +public class D2ICommand implements Command { + + /** + * Default constructor for creating an instance of D2ICommand. + */ + public D2ICommand() { + // Empty constructor + } + + /** + * Executes the double64 to int32 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + double value = (double) operandStack.pop(); + int convertedValue = (int) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/D2LCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/D2LCommand.java new file mode 100644 index 0000000..eb38865 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/D2LCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * D2LCommand Opcode: Represents the type conversion operation from double64 to long64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top double64 value from the operand stack.
  2. + *
  3. Convert the double64 value to a long64 value (this may involve truncation).
  4. + *
  5. Push the converted long64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to narrow a double64 value to a long64 type, which can then be used for integer operations.

+ */ +public class D2LCommand implements Command { + + /** + * Default constructor for creating an instance of D2LCommand. + */ + public D2LCommand() { + // Empty constructor + } + + /** + * Executes the double64 to long64 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + double value = (double) operandStack.pop(); + long convertedValue = (long) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/F2DCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/F2DCommand.java new file mode 100644 index 0000000..1cdcfbd --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/F2DCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * F2DCommand Opcode: Represents the type conversion operation from float32 to double64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top float32 value from the operand stack.
  2. + *
  3. Convert the float32 value to a double64 value.
  4. + *
  5. Push the converted double64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to promote a float32 value to a double64 type, thereby increasing precision for floating-point computations.

+ */ +public class F2DCommand implements Command { + + /** + * Default constructor for creating an instance of F2DCommand. + */ + public F2DCommand() { + // Empty constructor + } + + /** + * Executes the float32 to double64 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + float value = (float) operandStack.pop(); + double convertedValue = (double) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/F2ICommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/F2ICommand.java new file mode 100644 index 0000000..26cf949 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/F2ICommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * F2ICommand Opcode: Represents the type conversion operation from float32 to int32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top float32 value from the operand stack.
  2. + *
  3. Convert the float32 value to an int32 value (this may involve truncation).
  4. + *
  5. Push the converted int32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to convert a float32 value to an int32 type for further integer operations or comparisons.

+ */ +public class F2ICommand implements Command { + + /** + * Default constructor for creating an instance of F2ICommand. + */ + public F2ICommand() { + // Empty constructor + } + + /** + * Executes the float32 to int32 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + float value = (float) operandStack.pop(); + int convertedValue = (int) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/F2LCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/F2LCommand.java new file mode 100644 index 0000000..55abcbc --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/F2LCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * F2LCommand Opcode: Represents the type conversion operation from float32 to long64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top float32 value from the operand stack.
  2. + *
  3. Convert the float32 value to a long64 value.
  4. + *
  5. Push the converted long64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to widen a float32 value to a long64 type for operations requiring a larger numeric range.

+ */ +public class F2LCommand implements Command { + + /** + * Default constructor for creating an instance of F2LCommand. + */ + public F2LCommand() { + // Empty constructor + } + + /** + * Executes the float32 to long64 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + float value = (float) operandStack.pop(); + long convertedValue = (long) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2BCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2BCommand.java new file mode 100644 index 0000000..84e2e92 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2BCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * I2BCommand Opcode: Represents the type conversion operation from int32 to byte8 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top int32 value from the operand stack.
  2. + *
  3. Convert the int32 value to a byte8 value (this may involve truncation).
  4. + *
  5. Push the converted byte8 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to narrow an int32 value to a byte8 type when a smaller numeric representation is required.

+ */ +public class I2BCommand implements Command { + + /** + * Default constructor for creating an instance of I2BCommand. + */ + public I2BCommand() { + // Empty constructor + } + + /** + * Executes the int32 to byte8 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + int value = (int) operandStack.pop(); + byte convertedValue = (byte) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2DCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2DCommand.java new file mode 100644 index 0000000..44afc2e --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2DCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * I2DCommand Opcode: Represents the type conversion operation from int32 to double64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top int32 value from the operand stack.
  2. + *
  3. Convert the int32 value to a double64 value.
  4. + *
  5. Push the converted double64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to widen an int32 value to a double64 type, providing high-precision floating-point calculations.

+ */ +public class I2DCommand implements Command { + + /** + * Default constructor for creating an instance of I2DCommand. + */ + public I2DCommand() { + // Empty constructor + } + + /** + * Executes the int32 to double64 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + int value = (int) operandStack.pop(); + double convertedValue = (double) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2FCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2FCommand.java new file mode 100644 index 0000000..f21e379 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2FCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * I2FCommand Opcode: Represents the type conversion operation from int32 to float32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top int32 value from the operand stack.
  2. + *
  3. Convert the int32 value to a float32 value.
  4. + *
  5. Push the converted float32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to convert an int32 value to a float32 type when floating-point arithmetic is required.

+ */ +public class I2FCommand implements Command { + + /** + * Default constructor for creating an instance of I2FCommand. + */ + public I2FCommand() { + // Empty constructor + } + + /** + * Executes the int32 to float32 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + int value = (int) operandStack.pop(); + float convertedValue = (float) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2LCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2LCommand.java new file mode 100644 index 0000000..49f65ae --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2LCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * I2LCommand Opcode: Represents the type conversion operation from int32 to long64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top int32 value from the operand stack.
  2. + *
  3. Convert the int32 value to a long64 value.
  4. + *
  5. Push the converted long64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is commonly used to widen an int32 value to a long64 type to accommodate larger numeric ranges.

+ */ +public class I2LCommand implements Command { + + /** + * Default constructor for creating an instance of I2LCommand. + */ + public I2LCommand() { + // Empty constructor + } + + /** + * Executes the int32 to long64 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + int value = (int) operandStack.pop(); + long convertedValue = (long) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2SCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2SCommand.java new file mode 100644 index 0000000..f11f119 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/I2SCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * I2SCommand Opcode: Represents the type conversion operation from int32 to short16 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top int32 value from the operand stack.
  2. + *
  3. Convert the int32 value to a short16 value (this may involve truncation).
  4. + *
  5. Push the converted short16 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is typically used to narrow an int32 value to a short16 type when a smaller data representation is required.

+ */ +public class I2SCommand implements Command { + + /** + * Default constructor for creating an instance of I2SCommand. + */ + public I2SCommand() { + // Empty constructor + } + + /** + * Executes the int32 to short16 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + int value = (int) operandStack.pop(); + short convertedValue = (short) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/L2DCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/L2DCommand.java new file mode 100644 index 0000000..7c551db --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/L2DCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * L2DCommand Opcode: Represents the type conversion operation from long64 to double64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top long64 value from the operand stack.
  2. + *
  3. Convert the long64 value to a double64 value.
  4. + *
  5. Push the converted double64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to widen a long64 value to a double64 type for high-precision floating-point computations.

+ */ +public class L2DCommand implements Command { + + /** + * Default constructor for creating an instance of L2DCommand. + */ + public L2DCommand() { + // Empty constructor + } + + /** + * Executes the long64 to double64 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + long value = (long) operandStack.pop(); + double convertedValue = (double) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/L2FCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/L2FCommand.java new file mode 100644 index 0000000..f2cbfc2 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/L2FCommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * L2FCommand Opcode: Represents the type conversion operation from long64 to float32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top long64 value from the operand stack.
  2. + *
  3. Convert the long64 value to a float32 value.
  4. + *
  5. Push the converted float32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to convert a long64 value to a float32 type, typically for floating-point arithmetic involving long values.

+ */ +public class L2FCommand implements Command { + + /** + * Default constructor for creating an instance of L2FCommand. + */ + public L2FCommand() { + // Empty constructor + } + + /** + * Executes the long64 to float32 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + long value = (long) operandStack.pop(); + float convertedValue = (float) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/L2ICommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/L2ICommand.java new file mode 100644 index 0000000..ee9f494 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/L2ICommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * L2ICommand Opcode: Represents the type conversion operation from long64 to int32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top long64 value from the operand stack.
  2. + *
  3. Convert the long64 value to an int32 value (this may involve truncation).
  4. + *
  5. Push the converted int32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is typically used to narrow a long64 value to an int32 type for further integer operations.

+ */ +public class L2ICommand implements Command { + + /** + * Default constructor for creating an instance of L2ICommand. + */ + public L2ICommand() { + // Empty constructor + } + + /** + * Executes the long64 to int32 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + long value = (long) operandStack.pop(); + int convertedValue = (int) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/S2ICommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/S2ICommand.java new file mode 100644 index 0000000..c7b0eb1 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/conversion/S2ICommand.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.commands.arithmetic.conversion; + +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; + +/** + * S2ICommand Opcode: Represents the type conversion operation from short16 to int32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top short16 value from the operand stack.
  2. + *
  3. Convert the short16 value to an int32 value.
  4. + *
  5. Push the converted int32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to widen a short16 value to an int32 type, facilitating subsequent integer arithmetic or comparison operations.

+ */ +public class S2ICommand implements Command { + + /** + * Default constructor for creating an instance of S2ICommand. + */ + public S2ICommand() { + // Empty constructor + } + + /** + * Executes the short16 to int32 conversion operation. + * + * @param parts The array of instruction parameters, which is not used in this operation. + * @param currentPC The current program counter, representing the instruction address. + * @param operandStack The operand stack of the virtual machine. + * @param localVariableStore The local variable store for managing method-local variables. + * @param callStack The call stack of the virtual machine. + * @return The updated program counter after execution. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, + LocalVariableStore localVariableStore, CallStack callStack) { + short value = (short) operandStack.pop(); + int convertedValue = (int) value; + operandStack.push(convertedValue); + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DAddCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DAddCommand.java new file mode 100644 index 0000000..76d8b69 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DAddCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * DAddCommand Opcode: Represents the double64 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two double64 values from the operand stack.
  2. + *
  3. Performs the addition of the two values (i.e., a + b).
  4. + *
  5. Pushes the sum back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to add two double64 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class DAddCommand implements Command { + + /** + * Default constructor for creating an instance of DAddCommand. + * This constructor is empty as no specific initialization is required. + */ + public DAddCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for adding two double64 values. + * + *

This method retrieves the two double64 values from the operand stack, adds them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // Perform the addition and push the result back onto the stack + operandStack.push(a + b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DDivCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DDivCommand.java new file mode 100644 index 0000000..1a70f9a --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DDivCommand.java @@ -0,0 +1,64 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * DDivCommand Opcode: Represents the double64 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two double64 values from the operand stack.
  2. + *
  3. Performs the division operation (i.e., a / b).
  4. + *
  5. Checks for division by zero to prevent errors.
  6. + *
  7. Pushes the result of the division back onto the operand stack for subsequent instructions to use.
  8. + *
+ * + *

This opcode is typically used to divide one double64 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class DDivCommand implements Command { + + /** + * Default constructor for creating an instance of DDivCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public DDivCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for dividing two double64 values. + * + *

This method retrieves the two double64 values from the operand stack, checks for division by zero, performs the division, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // Check for division by zero + if (b == 0) { + throw new ArithmeticException("Division by zero is not allowed."); + } + + // Perform the division and push the result back onto the stack + operandStack.push(a / b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DIncCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DIncCommand.java new file mode 100644 index 0000000..3f9c672 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DIncCommand.java @@ -0,0 +1,70 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * DIncCommand Opcode: Represents the double64 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Extracts the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Retrieves the current value of the local variable at the given index.
  4. + *
  5. Increments the value of the local variable by the specified increment value (i.e., localVariables[index] += increment).
  6. + *
  7. Updates the local variable with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.
  10. + *
+ * + *

This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.

+ */ +public class DIncCommand implements Command { + + /** + * Default constructor for creating an instance of DIncCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public DIncCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for incrementing a local variable. + * + *

This method retrieves the necessary data (index of the local variable and the increment value) from the instruction parameters, + * performs the increment operation on the specified local variable, and returns the updated program counter (PC) value.

+ * + * @param parts The array of instruction parameters, which includes the index of the local variable and + * the increment value (passed directly as bytecode parameters). + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, including the one being incremented. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the index of the local variable and the increment value from the parameters + + int localVariableIndex = Integer.parseInt(parts[1]); // Index of the local variable to be incremented + + double incrementValue = Double.parseDouble(parts[2]); // The value by which to increment the local variable + + // Get the current value of the local variable at the specified index + double currentValue = (double) callStack.peekFrame().getLocalVariableStore().getVariable(localVariableIndex); + + // Increment the local variable value by the specified increment + double newValue = currentValue + incrementValue; + + // Update the local variable with the new incremented value + callStack.peekFrame().getLocalVariableStore().setVariable(localVariableIndex, newValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DModCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DModCommand.java new file mode 100644 index 0000000..df8cbd7 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DModCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * DModCommand Opcode: Represents the double64 modulus operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two double64 values from the operand stack.
  2. + *
  3. Performs the modulus operation to calculate the remainder (i.e., a % b).
  4. + *
  5. Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to calculate the remainder of the division of two double64 values, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class DModCommand implements Command { + + /** + * Default constructor for creating an instance of DModCommand. + * This constructor is empty as no specific initialization is required. + */ + public DModCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for performing a modulus operation between two double64 values. + * + *

This method retrieves the two double64 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // Perform the modulus operation and push the result back onto the stack + operandStack.push(a % b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DMulCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DMulCommand.java new file mode 100644 index 0000000..d5adb01 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DMulCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * DMulCommand Opcode: Represents the double64 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two double64 values from the operand stack.
  2. + *
  3. Performs the multiplication of the two values (i.e., a * b).
  4. + *
  5. Pushes the result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to multiply two double64 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class DMulCommand implements Command { + + /** + * Default constructor for creating an instance of DMulCommand. + * This constructor is empty as no specific initialization is required. + */ + public DMulCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for multiplying two double64 values. + * + *

This method retrieves the two double64 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // Perform the multiplication and push the result back onto the stack + operandStack.push(a * b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DNegCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DNegCommand.java new file mode 100644 index 0000000..9720c3e --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DNegCommand.java @@ -0,0 +1,60 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * DNegCommand Opcode: Represents the double64 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top double64 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate an double64 value, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class DNegCommand implements Command { + + /** + * Default constructor for creating an instance of DNegCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public DNegCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for negating an double64 value. + * + *

This method retrieves the double64 value from the operand stack, negates it, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top double64 value from the operand stack + double value = (double) operandStack.pop(); + + // Perform the negation of the value + double negatedValue = -value; + + // Push the negated result back onto the operand stack + operandStack.push(negatedValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DSubCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DSubCommand.java new file mode 100644 index 0000000..72d2bda --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/double64/DSubCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * DSubCommand Opcode: Represents the double64 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two double64 values from the operand stack.
  2. + *
  3. Performs the subtraction of the second popped value from the first (i.e., a - b).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to subtract one double64 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class DSubCommand implements Command { + + /** + * Default constructor for creating an instance of DSubCommand. + * This constructor is empty as no specific initialization is required. + */ + public DSubCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for subtracting two double64 values. + * + *

This method retrieves the two double64 values from the operand stack, subtracts the second value from the first, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + double b = (double) operandStack.pop(); + double a = (double) operandStack.pop(); + + // Perform the subtraction and push the result back onto the stack + operandStack.push(a - b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FAddCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FAddCommand.java new file mode 100644 index 0000000..3c6e3cb --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FAddCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * FAddCommand Opcode: Represents the float32 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two float32 values from the operand stack.
  2. + *
  3. Performs the addition of the two values (i.e., a + b).
  4. + *
  5. Pushes the sum back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to add two float32 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class FAddCommand implements Command { + + /** + * Default constructor for creating an instance of FAddCommand. + * This constructor is empty as no specific initialization is required. + */ + public FAddCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for adding two float32 values. + * + *

This method retrieves the two float32 values from the operand stack, adds them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // Perform the addition and push the result back onto the stack + operandStack.push(a + b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FDivCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FDivCommand.java new file mode 100644 index 0000000..5c3fbda --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FDivCommand.java @@ -0,0 +1,64 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * FDivCommand Opcode: Represents the float32 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two float32 values from the operand stack.
  2. + *
  3. Performs the division operation (i.e., a / b).
  4. + *
  5. Checks for division by zero to prevent errors.
  6. + *
  7. Pushes the result of the division back onto the operand stack for subsequent instructions to use.
  8. + *
+ * + *

This opcode is typically used to divide one float32 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class FDivCommand implements Command { + + /** + * Default constructor for creating an instance of FDivCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public FDivCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for dividing two float32 values. + * + *

This method retrieves the two float32 values from the operand stack, checks for division by zero, performs the division, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // Check for division by zero + if (b == 0) { + throw new ArithmeticException("Division by zero is not allowed."); + } + + // Perform the division and push the result back onto the stack + operandStack.push(a / b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FIncCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FIncCommand.java new file mode 100644 index 0000000..4061ebd --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FIncCommand.java @@ -0,0 +1,68 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * FIncCommand Opcode: Represents the float32 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Extracts the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Retrieves the current value of the local variable at the given index.
  4. + *
  5. Increments the value of the local variable by the specified increment value (i.e., localVariables[index] += increment).
  6. + *
  7. Updates the local variable with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.
  10. + *
+ * + *

This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.

+ */ +public class FIncCommand implements Command { + + /** + * Default constructor for creating an instance of FIncCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public FIncCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for incrementing a local variable. + * + *

This method retrieves the necessary data (index of the local variable and the increment value) from the instruction parameters, + * performs the increment operation on the specified local variable, and returns the updated program counter (PC) value.

+ * + * @param parts The array of instruction parameters, which includes the index of the local variable and + * the increment value (passed directly as bytecode parameters). + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, including the one being incremented. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the index of the local variable and the increment value from the parameters + int localVariableIndex = Integer.parseInt(parts[1]); // Index of the local variable to be incremented + float incrementValue = Float.parseFloat(parts[2]); // The value by which to increment the local variable + + // Get the current value of the local variable at the specified index + float currentValue = (float) callStack.peekFrame().getLocalVariableStore().getVariable(localVariableIndex); + + // Increment the local variable value by the specified increment + float newValue = currentValue + incrementValue; + + // Update the local variable with the new incremented value + callStack.peekFrame().getLocalVariableStore().setVariable(localVariableIndex, newValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FModCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FModCommand.java new file mode 100644 index 0000000..fc0c537 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FModCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * FModCommand Opcode: Represents the float32 modulus operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two float32 values from the operand stack.
  2. + *
  3. Performs the modulus operation to calculate the remainder (i.e., a % b).
  4. + *
  5. Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to calculate the remainder of the division of two float32 values, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class FModCommand implements Command { + + /** + * Default constructor for creating an instance of FModCommand. + * This constructor is empty as no specific initialization is required. + */ + public FModCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for performing a modulus operation between two float32 values. + * + *

This method retrieves the two float32 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // Perform the modulus operation and push the result back onto the stack + operandStack.push(a % b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FMulCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FMulCommand.java new file mode 100644 index 0000000..34dfd8b --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FMulCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * FMulCommand Opcode: Represents the float32 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two float32 values from the operand stack.
  2. + *
  3. Performs the multiplication of the two values (i.e., a * b).
  4. + *
  5. Pushes the result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to multiply two float32 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class FMulCommand implements Command { + + /** + * Default constructor for creating an instance of FMulCommand. + * This constructor is empty as no specific initialization is required. + */ + public FMulCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for multiplying two float32 values. + * + *

This method retrieves the two float32 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // Perform the multiplication and push the result back onto the stack + operandStack.push(a * b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FNegCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FNegCommand.java new file mode 100644 index 0000000..ceb17ed --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FNegCommand.java @@ -0,0 +1,60 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * FNegCommand Opcode: Represents the float32 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top float32 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate an float32 value, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class FNegCommand implements Command { + + /** + * Default constructor for creating an instance of FNegCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public FNegCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for negating an float32 value. + * + *

This method retrieves the float32 value from the operand stack, negates it, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top float32 value from the operand stack + float value = (float) operandStack.pop(); + + // Perform the negation of the value + float negatedValue = -value; + + // Push the negated result back onto the operand stack + operandStack.push(negatedValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FSubCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FSubCommand.java new file mode 100644 index 0000000..dd73714 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/float32/FSubCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * FSubCommand Opcode: Represents the float32 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two float32 values from the operand stack.
  2. + *
  3. Performs the subtraction of the second popped value from the first (i.e., a - b).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to subtract one float32 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class FSubCommand implements Command { + + /** + * Default constructor for creating an instance of FSubCommand. + * This constructor is empty as no specific initialization is required. + */ + public FSubCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for subtracting two float32 values. + * + *

This method retrieves the two float32 values from the operand stack, subtracts the second value from the first, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + float b = (float) operandStack.pop(); + float a = (float) operandStack.pop(); + + // Perform the subtraction and push the result back onto the stack + operandStack.push(a - b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IAddCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IAddCommand.java new file mode 100644 index 0000000..36375e3 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IAddCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.int32; + +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; + +/** + * IAddCommand Opcode: Represents the int32 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack.
  2. + *
  3. Performs the addition of the two values (i.e., a + b).
  4. + *
  5. Pushes the sum back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to add two int32 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class IAddCommand implements Command { + + /** + * Default constructor for creating an instance of IAddCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public IAddCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for adding two int32 values. + * + *

This method retrieves the two int32 values from the operand stack, adds them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + int b = (int) operandStack.pop(); + int a = (int) operandStack.pop(); + + // Perform the addition and push the result back onto the stack + operandStack.push(a + b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IDivCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IDivCommand.java new file mode 100644 index 0000000..ea5c9cf --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IDivCommand.java @@ -0,0 +1,64 @@ +package org.jcnc.snow.vm.commands.arithmetic.int32; + +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; + +/** + * IDivCommand Opcode: Represents the int32 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack.
  2. + *
  3. Performs the division operation (i.e., a / b).
  4. + *
  5. Checks for division by zero to prevent errors.
  6. + *
  7. Pushes the result of the division back onto the operand stack for subsequent instructions to use.
  8. + *
+ * + *

This opcode is typically used to divide one int32 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class IDivCommand implements Command { + + /** + * Default constructor for creating an instance of IDivCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public IDivCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for dividing two int32 values. + * + *

This method retrieves the two int32 values from the operand stack, checks for division by zero, performs the division, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + int b = (int) operandStack.pop(); + int a = (int) operandStack.pop(); + + // Check for division by zero + if (b == 0) { + throw new ArithmeticException("Division by zero is not allowed."); + } + + // Perform the division and push the result back onto the stack + operandStack.push(a / b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IIncCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IIncCommand.java new file mode 100644 index 0000000..ac1c150 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IIncCommand.java @@ -0,0 +1,68 @@ +package org.jcnc.snow.vm.commands.arithmetic.int32; + +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; + +/** + * IIncCommand Opcode: Represents the int32 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Extracts the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Retrieves the current value of the local variable at the given index.
  4. + *
  5. Increments the value of the local variable by the specified increment value (i.e., localVariables[index] += increment).
  6. + *
  7. Updates the local variable with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.
  10. + *
+ * + *

This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.

+ */ +public class IIncCommand implements Command { + + /** + * Default constructor for creating an instance of IIncCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public IIncCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for incrementing a local variable. + * + *

This method retrieves the necessary data (index of the local variable and the increment value) from the instruction parameters, + * performs the increment operation on the specified local variable, and returns the updated program counter (PC) value.

+ * + * @param parts The array of instruction parameters, which includes the index of the local variable and + * the increment value (passed directly as bytecode parameters). + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, including the one being incremented. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the index of the local variable and the increment value from the parameters + int localVariableIndex = Integer.parseInt(parts[1]); // Index of the local variable to be incremented + int incrementValue = Integer.parseInt(parts[2]); // The value by which to increment the local variable + + // Get the current value of the local variable at the specified index + int currentValue = (int) callStack.peekFrame().getLocalVariableStore().getVariable(localVariableIndex); + + // Increment the local variable value by the specified increment + int newValue = currentValue + incrementValue; + + // Update the local variable with the new incremented value + callStack.peekFrame().getLocalVariableStore().setVariable(localVariableIndex, newValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IModCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IModCommand.java new file mode 100644 index 0000000..0cb9bd0 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IModCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.int32; + +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; + +/** + * IModCommand Opcode: Represents the int32 modulus operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack.
  2. + *
  3. Performs the modulus operation to calculate the remainder (i.e., a % b).
  4. + *
  5. Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to calculate the remainder of the division of two int32 values, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class IModCommand implements Command { + + /** + * Default constructor for creating an instance of IModCommand. + * This constructor is empty as no specific initialization is required. + */ + public IModCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for performing a modulus operation between two int32 values. + * + *

This method retrieves the two int32 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + int b = (int) operandStack.pop(); + int a = (int) operandStack.pop(); + + // Perform the modulus operation and push the result back onto the stack + operandStack.push(a % b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IMulCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IMulCommand.java new file mode 100644 index 0000000..a559759 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/IMulCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.int32; + +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; + +/** + * IMulCommand Opcode: Represents the int32 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack.
  2. + *
  3. Performs the multiplication of the two values (i.e., a * b).
  4. + *
  5. Pushes the result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to multiply two int32 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class IMulCommand implements Command { + + /** + * Default constructor for creating an instance of IMulCommand. + * This constructor is empty as no specific initialization is required. + */ + public IMulCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for multiplying two int32 values. + * + *

This method retrieves the two int32 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + int b = (int) operandStack.pop(); + int a = (int) operandStack.pop(); + + // Perform the multiplication and push the result back onto the stack + operandStack.push(a * b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/INegCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/INegCommand.java new file mode 100644 index 0000000..2746adb --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/INegCommand.java @@ -0,0 +1,60 @@ +package org.jcnc.snow.vm.commands.arithmetic.int32; + +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; + +/** + * INegCommand Opcode: Represents the int32 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top int32 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate an int32 value, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class INegCommand implements Command { + + /** + * Default constructor for creating an instance of INegCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public INegCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for negating an int32 value. + * + *

This method retrieves the int32 value from the operand stack, negates it, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top int32 value from the operand stack + int value = (int) operandStack.pop(); + + // Perform the negation of the value + int negatedValue = -value; + + // Push the negated result back onto the operand stack + operandStack.push(negatedValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/ISubCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/ISubCommand.java new file mode 100644 index 0000000..f910e2b --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/int32/ISubCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.int32; + +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; + +/** + * ISubCommand Opcode: Represents the int32 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack.
  2. + *
  3. Performs the subtraction of the second popped value from the first (i.e., a - b).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to subtract one int32 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class ISubCommand implements Command { + + /** + * Default constructor for creating an instance of ISubCommand. + * This constructor is empty as no specific initialization is required. + */ + public ISubCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for subtracting two int32 values. + * + *

This method retrieves the two int32 values from the operand stack, subtracts the second value from the first, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + int b = (int) operandStack.pop(); + int a = (int) operandStack.pop(); + + // Perform the subtraction and push the result back onto the stack + operandStack.push(a - b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LAddCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LAddCommand.java new file mode 100644 index 0000000..c97a6a1 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LAddCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.long64; + +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; + +/** + * LAddCommand Opcode: Represents the long64 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack.
  2. + *
  3. Performs the addition of the two values (i.e., a + b).
  4. + *
  5. Pushes the sum back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to add two long64 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class LAddCommand implements Command { + + /** + * Default constructor for creating an instance of LAddCommand. + * This constructor is empty as no specific initialization is required. + */ + public LAddCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for adding two long64 values. + * + *

This method retrieves the two long64 values from the operand stack, adds them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + long b = (long) operandStack.pop(); + long a = (long) operandStack.pop(); + + // Perform the addition and push the result back onto the stack + operandStack.push(a + b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LDivCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LDivCommand.java new file mode 100644 index 0000000..7d66218 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LDivCommand.java @@ -0,0 +1,64 @@ +package org.jcnc.snow.vm.commands.arithmetic.long64; + +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; + +/** + * LDivCommand Opcode: Represents the long64 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack.
  2. + *
  3. Performs the division operation (i.e., a / b).
  4. + *
  5. Checks for division by zero to prevent errors.
  6. + *
  7. Pushes the result of the division back onto the operand stack for subsequent instructions to use.
  8. + *
+ * + *

This opcode is typically used to divide one long64 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class LDivCommand implements Command { + + /** + * Default constructor for creating an instance of LDivCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public LDivCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for dividing two long64 values. + * + *

This method retrieves the two long64 values from the operand stack, checks for division by zero, performs the division, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + long b = (long) operandStack.pop(); + long a = (long) operandStack.pop(); + + // Check for division by zero + if (b == 0) { + throw new ArithmeticException("Division by zero is not allowed."); + } + + // Perform the division and push the result back onto the stack + operandStack.push(a / b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LIncCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LIncCommand.java new file mode 100644 index 0000000..18715d3 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LIncCommand.java @@ -0,0 +1,68 @@ +package org.jcnc.snow.vm.commands.arithmetic.long64; + +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; + +/** + * LIncCommand Opcode: Represents the long64 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Extracts the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Retrieves the current value of the local variable at the given index.
  4. + *
  5. Increments the value of the local variable by the specified increment value (i.e., localVariables[index] += increment).
  6. + *
  7. Updates the local variable with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.
  10. + *
+ * + *

This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.

+ */ +public class LIncCommand implements Command { + + /** + * Default constructor for creating an instance of LIncCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public LIncCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for incrementing a local variable. + * + *

This method retrieves the necessary data (index of the local variable and the increment value) from the instruction parameters, + * performs the increment operation on the specified local variable, and returns the updated program counter (PC) value.

+ * + * @param parts The array of instruction parameters, which includes the index of the local variable and + * the increment value (passed directly as bytecode parameters). + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, including the one being incremented. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the index of the local variable and the increment value from the parameters + int localVariableIndex = Integer.parseInt(parts[1]); // Index of the local variable to be incremented + long incrementValue = Long.parseLong(parts[2]); // The value by which to increment the local variable + + // Get the current value of the local variable at the specified index + long currentValue = (long) callStack.peekFrame().getLocalVariableStore().getVariable(localVariableIndex); + + // Increment the local variable value by the specified increment + long newValue = currentValue + incrementValue; + + // Update the local variable with the new incremented value + callStack.peekFrame().getLocalVariableStore().setVariable(localVariableIndex, newValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LModCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LModCommand.java new file mode 100644 index 0000000..345c2e5 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LModCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.long64; + +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; + +/** + * LModCommand Opcode: Represents the long64 modulus operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack.
  2. + *
  3. Performs the modulus operation to calculate the remainder (i.e., a % b).
  4. + *
  5. Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to calculate the remainder of the division of two long64 values, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class LModCommand implements Command { + + /** + * Default constructor for creating an instance of LModCommand. + * This constructor is empty as no specific initialization is required. + */ + public LModCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for performing a modulus operation between two long64 values. + * + *

This method retrieves the two long64 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + long b = (long) operandStack.pop(); + long a = (long) operandStack.pop(); + + // Perform the modulus operation and push the result back onto the stack + operandStack.push(a % b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LMulCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LMulCommand.java new file mode 100644 index 0000000..b5e68aa --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LMulCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.long64; + +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; + +/** + * LMulCommand Opcode: Represents the long64 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack.
  2. + *
  3. Performs the multiplication of the two values (i.e., a * b).
  4. + *
  5. Pushes the result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to multiply two long64 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class LMulCommand implements Command { + + /** + * Default constructor for creating an instance of LMulCommand. + * This constructor is empty as no specific initialization is required. + */ + public LMulCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for multiplying two long64 values. + * + *

This method retrieves the two long64 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + long b = (long) operandStack.pop(); + long a = (long) operandStack.pop(); + + // Perform the multiplication and push the result back onto the stack + operandStack.push(a * b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LNegCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LNegCommand.java new file mode 100644 index 0000000..2691fa6 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LNegCommand.java @@ -0,0 +1,60 @@ +package org.jcnc.snow.vm.commands.arithmetic.long64; + +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; + +/** + * LNegCommand Opcode: Represents the long64 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top long64 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate an long64 value, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class LNegCommand implements Command { + + /** + * Default constructor for creating an instance of LNegCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public LNegCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for negating an long64 value. + * + *

This method retrieves the long64 value from the operand stack, negates it, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top long64 value from the operand stack + long value = (long) operandStack.pop(); + + // Perform the negation of the value + long negatedValue = -value; + + // Push the negated result back onto the operand stack + operandStack.push(negatedValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LSubCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LSubCommand.java new file mode 100644 index 0000000..f710b10 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/long64/LSubCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.long64; + +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; + +/** + * LSubCommand Opcode: Represents the long64 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack.
  2. + *
  3. Performs the subtraction of the second popped value from the first (i.e., a - b).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to subtract one long64 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class LSubCommand implements Command { + + /** + * Default constructor for creating an instance of LSubCommand. + * This constructor is empty as no specific initialization is required. + */ + public LSubCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for subtracting two long64 values. + * + *

This method retrieves the two long64 values from the operand stack, subtracts the second value from the first, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + long b = (long) operandStack.pop(); + long a = (long) operandStack.pop(); + + // Perform the subtraction and push the result back onto the stack + operandStack.push(a - b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SAddCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SAddCommand.java new file mode 100644 index 0000000..4137a01 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SAddCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * SAddCommand Opcode: Represents the short16 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two short16 values from the operand stack.
  2. + *
  3. Performs the addition of the two values (i.e., a + b).
  4. + *
  5. Pushes the sum back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to add two short16 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class SAddCommand implements Command { + + /** + * Default constructor for creating an instance of SAddCommand. + * This constructor is empty as no specific initialization is required. + */ + public SAddCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for adding two short16 values. + * + *

This method retrieves the two short16 values from the operand stack, adds them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + Short b = (Short) operandStack.pop(); + Short a = (Short) operandStack.pop(); + + // Perform the addition and push the result back onto the stack + operandStack.push(a + b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SDivCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SDivCommand.java new file mode 100644 index 0000000..f14cefa --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SDivCommand.java @@ -0,0 +1,64 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * SDivCommand Opcode: Represents the short16 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two short16 values from the operand stack.
  2. + *
  3. Performs the division operation (i.e., a / b).
  4. + *
  5. Checks for division by zero to prevent errors.
  6. + *
  7. Pushes the result of the division back onto the operand stack for subsequent instructions to use.
  8. + *
+ * + *

This opcode is typically used to divide one short16 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class SDivCommand implements Command { + + /** + * Default constructor for creating an instance of SDivCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public SDivCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for dividing two short16 values. + * + *

This method retrieves the two short16 values from the operand stack, checks for division by zero, performs the division, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + short b = (short) operandStack.pop(); + short a = (short) operandStack.pop(); + + // Check for division by zero + if (b == 0) { + throw new ArithmeticException("Division by zero is not allowed."); + } + + // Perform the division and push the result back onto the stack + operandStack.push(a / b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SIncCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SIncCommand.java new file mode 100644 index 0000000..8da3133 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SIncCommand.java @@ -0,0 +1,68 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * SIncCommand Opcode: Represents the short16 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Extracts the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Retrieves the current value of the local variable at the given index.
  4. + *
  5. Increments the value of the local variable by the specified increment value (i.e., localVariables[index] += increment).
  6. + *
  7. Updates the local variable with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.
  10. + *
+ * + *

This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.

+ */ +public class SIncCommand implements Command { + + /** + * Default constructor for creating an instance of SIncCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public SIncCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for incrementing a local variable. + * + *

This method retrieves the necessary data (index of the local variable and the increment value) from the instruction parameters, + * performs the increment operation on the specified local variable, and returns the updated program counter (PC) value.

+ * + * @param parts The array of instruction parameters, which includes the index of the local variable and + * the increment value (passed directly as bytecode parameters). + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, including the one being incremented. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the index of the local variable and the increment value from the parameters + int localVariableIndex = Integer.parseInt(parts[1]); // Index of the local variable to be incremented + short incrementValue = Short.parseShort(parts[2]); // The value by which to increment the local variable + + // Get the current value of the local variable at the specified index + short currentValue = (short) callStack.peekFrame().getLocalVariableStore().getVariable(localVariableIndex); + + // Increment the local variable value by the specified increment + short newValue = (short) (currentValue + incrementValue); + + // Update the local variable with the new incremented value + callStack.peekFrame().getLocalVariableStore().setVariable(localVariableIndex, newValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SModCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SModCommand.java new file mode 100644 index 0000000..0047449 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SModCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * SModCommand Opcode: Represents the short16 modulus operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two short16 values from the operand stack.
  2. + *
  3. Performs the modulus operation to calculate the remainder (i.e., a % b).
  4. + *
  5. Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to calculate the remainder of the division of two short16 values, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class SModCommand implements Command { + + /** + * Default constructor for creating an instance of SModCommand. + * This constructor is empty as no specific initialization is required. + */ + public SModCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for performing a modulus operation between two short16 values. + * + *

This method retrieves the two short16 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + short b = (short) operandStack.pop(); + short a = (short) operandStack.pop(); + + // Perform the modulus operation and push the result back onto the stack + operandStack.push(a % b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SMulCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SMulCommand.java new file mode 100644 index 0000000..1a2ac4e --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SMulCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * SMulCommand Opcode: Represents the short16 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two short16 values from the operand stack.
  2. + *
  3. Performs the multiplication of the two values (i.e., a * b).
  4. + *
  5. Pushes the result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to multiply two short16 values together, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class SMulCommand implements Command { + + /** + * Default constructor for creating an instance of SMulCommand. + * This constructor is empty as no specific initialization is required. + */ + public SMulCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for multiplying two short16 values. + * + *

This method retrieves the two short16 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + short b = (short) operandStack.pop(); + short a = (short) operandStack.pop(); + + // Perform the multiplication and push the result back onto the stack + operandStack.push(a * b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SNegCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SNegCommand.java new file mode 100644 index 0000000..6e9d969 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SNegCommand.java @@ -0,0 +1,60 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * SNegCommand Opcode: Represents the short16 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top short16 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate an short16 value, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class SNegCommand implements Command { + + /** + * Default constructor for creating an instance of SNegCommand. + * This constructor does not perform any specific initialization, as the command's parameters are passed during execution. + */ + public SNegCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for negating an short16 value. + * + *

This method retrieves the short16 value from the operand stack, negates it, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top short16 value from the operand stack + short value = (short) operandStack.pop(); + + // Perform the negation of the value + short negatedValue = (short) -value; + + // Push the negated result back onto the operand stack + operandStack.push(negatedValue); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SSubCommand.java b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SSubCommand.java new file mode 100644 index 0000000..66c3295 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/arithmetic/short16/SSubCommand.java @@ -0,0 +1,58 @@ +package org.jcnc.snow.vm.commands.arithmetic.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; + +/** + * SSubCommand Opcode: Represents the short16 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two short16 values from the operand stack.
  2. + *
  3. Performs the subtraction of the second popped value from the first (i.e., a - b).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.
  6. + *
+ * + *

This opcode is typically used to subtract one short16 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ +public class SSubCommand implements Command { + + /** + * Default constructor for creating an instance of SSubCommand. + * This constructor is empty as no specific initialization is required. + */ + public SSubCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation for subtracting two short16 values. + * + *

This method retrieves the two short16 values from the operand stack, subtracts the second value from the first, and pushes the result back onto the operand stack.

+ * + * @param parts The array of instruction parameters, which is not used in this case since no additional arguments are needed for this operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically incremented after execution to point to the next instruction. + * @param operandStack The operand stack manager of the virtual machine, responsible for operations such as push, pop, and peek. + * @param localVariableStore The local variable store, used to manage method-local variables during execution. + * It allows access to and modification of local variables, but is not used in this particular operation. + * @param callStack The virtual machine's call stack, keeping track of the method invocation hierarchy. + * Used by instructions that involve method calls or returns (e.g., `CALL` and `RETURN`). + * @return The updated program counter-value, which is typically the current PC incremented by 1, unless control flow is altered. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop the top two operands from the stack + short b = (short) operandStack.pop(); + short a = (short) operandStack.pop(); + + // Perform the subtraction and push the result back onto the stack + operandStack.push(a - b); + + // Return the updated program counter (next instruction) + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/bitwise/int32/IAndCommand.java b/src/main/java/org/jcnc/snow/vm/commands/bitwise/int32/IAndCommand.java new file mode 100644 index 0000000..f43b8c6 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/bitwise/int32/IAndCommand.java @@ -0,0 +1,56 @@ +package org.jcnc.snow.vm.commands.bitwise.int32; + +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; + +/** + * The IAndCommand class implements the {@link Command} interface and represents the int32 bitwise AND (`&`) operation command. + * This class performs an int32 bitwise AND operation in the virtual machine by popping the top two values from the stack, + * computing their int32 bitwise AND operation, and then pushing the result back onto the stack. It is a basic operation command within the virtual machine. + * + *

Specific behavior:

+ *
    + *
  • Pops two operands from the virtual machine stack.
  • + *
  • Performs the int32 bitwise AND (`&`) operation.
  • + *
  • Pushes the result back onto the virtual machine stack.
  • + *
+ */ +public class IAndCommand implements Command { + /** + * Default constructor for creating an instance of {@code IAndCommand}. + * This constructor is empty as no specific initialization is required. + */ + public IAndCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * @param operandStack The virtual machine's operand stack manager, responsible for pushing and popping values. + * @param localVariableStore The local variable store, typically used to manage method-local variables. + * @param callStack The virtual machine's call stack, used for managing method calls and returns. + * @return The updated program counter-value, typically `currentPC + 1` unless a control flow instruction is executed. + * @throws IllegalStateException if there are not enough operands on the stack to perform the operation. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Ensure the stack has at least two operands + if (operandStack.size() < 2) { + throw new IllegalStateException("Not enough operands on the stack for IAND operation."); + } + + // Pop the top two operands from the stack + final int b = (int) operandStack.pop(); + final int a = (int) operandStack.pop(); + + // Perform the int32 bitwise AND operation and push the result back onto the stack + operandStack.push(a & b); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/bitwise/int32/IOrCommand.java b/src/main/java/org/jcnc/snow/vm/commands/bitwise/int32/IOrCommand.java new file mode 100644 index 0000000..2fe93e3 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/bitwise/int32/IOrCommand.java @@ -0,0 +1,56 @@ +package org.jcnc.snow.vm.commands.bitwise.int32; + +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; + +/** + * The {@code IOrCommand} class implements the {@link Command} interface and represents the int32 bitwise OR (`|`) operation command. + * This class performs an int32 bitwise OR operation in the virtual machine by popping the top two values from the stack, + * computing their OR, and then pushing the result back onto the stack. It is a basic operation command within the virtual machine. + * + *

Operation details:

+ *
    + *
  • Pops two operands from the virtual machine stack.
  • + *
  • Performs the int32 bitwise OR (`|`) operation.
  • + *
  • Pushes the result back onto the virtual machine stack.
  • + *
+ */ +public class IOrCommand implements Command { + /** + * Default constructor for creating an instance of {@code IOrCommand}. + * This constructor is empty as no specific initialization is required. + */ + public IOrCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * @param operandStack The virtual machine's operand stack manager, responsible for performing stack operations. + * @param localVariableStore The local variable store, typically used to manage method-local variables. + * @param callStack The virtual machine's call stack, which keeps track of method invocations. + * @return The updated program counter-value, typically {@code currentPC + 1}, unless a control flow instruction is executed. + * @throws IllegalStateException if there are not enough operands on the stack to perform the operation. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Ensure the stack has at least two operands + if (operandStack.size() < 2) { + throw new IllegalStateException("Not enough operands on the stack for IOR operation."); + } + + // Pop the top two operands from the stack + final int b = (int) operandStack.pop(); + final int a = (int) operandStack.pop(); + + // Perform the int32 bitwise OR operation and push the result back onto the stack + operandStack.push(a | b); + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/bitwise/int32/IXorCommand.java b/src/main/java/org/jcnc/snow/vm/commands/bitwise/int32/IXorCommand.java new file mode 100644 index 0000000..0502e0a --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/bitwise/int32/IXorCommand.java @@ -0,0 +1,56 @@ +package org.jcnc.snow.vm.commands.bitwise.int32; + +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; + +/** + * The {@code IXorCommand} class implements the {@link Command} interface and represents the int32 bitwise XOR (`^`) operation command. + * This class performs an int32 bitwise XOR operation in the virtual machine by popping the top two values from the stack, + * computing their XOR, and then pushing the result back onto the stack. It is a basic operation command within the virtual machine. + * + *

Operation details:

+ *
    + *
  • Pops two operands from the virtual machine stack.
  • + *
  • Performs the int32 bitwise XOR (`^`) operation.
  • + *
  • Pushes the result back onto the virtual machine stack.
  • + *
+ */ +public class IXorCommand implements Command { + /** + * Default constructor for creating an instance of {@code IXorCommand}. + * This constructor is empty as no specific initialization is required. + */ + public IXorCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * @param operandStack The virtual machine's operand stack manager, responsible for performing stack operations. + * @param localVariableStore The local variable store, typically used to manage method-local variables. + * @param callStack The virtual machine's call stack, which keeps track of method invocations. + * @return The updated program counter-value, typically {@code currentPC + 1}, unless a control flow instruction is executed. + * @throws IllegalStateException if there are not enough operands on the stack to perform the operation. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Ensure the stack has at least two operands + if (operandStack.size() < 2) { + throw new IllegalStateException("Not enough operands on the stack for IXOR operation."); + } + + // Pop the top two operands from the stack + final int b = (int) operandStack.pop(); + final int a = (int) operandStack.pop(); + + // Perform the int32 bitwise XOR operation and push the result back onto the stack + operandStack.push(a ^ b); + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LAndCommand.java b/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LAndCommand.java new file mode 100644 index 0000000..dd79d10 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LAndCommand.java @@ -0,0 +1,56 @@ +package org.jcnc.snow.vm.commands.bitwise.long64; + +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; + +/** + * The LAndCommand class implements the {@link Command} interface and represents the long64 bitwise AND (`&`) operation command. + * This class performs a long64 bitwise AND operation in the virtual machine by popping the top two values from the stack, + * computing their long64 bitwise AND operation, and then pushing the result back onto the stack. It is a basic operation command within the virtual machine. + * + *

Specific behavior:

+ *
    + *
  • Pops two operands from the virtual machine stack.
  • + *
  • Performs the long64 bitwise AND (`&`) operation.
  • + *
  • Pushes the result back onto the virtual machine stack.
  • + *
+ */ +public class LAndCommand implements Command { + /** + * Default constructor for creating an instance of {@code LAndCommand}. + * This constructor is empty as no specific initialization is required. + */ + public LAndCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * @param operandStack The virtual machine's operand stack manager, responsible for pushing and popping values. + * @param localVariableStore The local variable store, typically used to manage method-local variables. + * @param callStack The virtual machine's call stack, used for managing method calls and returns. + * @return The updated program counter-value, typically `currentPC + 1` unless a control flow instruction is executed. + * @throws IllegalStateException if there are not enough operands on the stack to perform the operation. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Ensure the stack has at least two operands + if (operandStack.size() < 2) { + throw new IllegalStateException("Not enough operands on the stack for LAND operation."); + } + + // Pop the top two operands from the stack + final long b = (long) operandStack.pop(); + final long a = (long) operandStack.pop(); + + // Perform the long64 bitwise AND operation and push the result back onto the stack + operandStack.push(a & b); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LOrCommand.java b/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LOrCommand.java new file mode 100644 index 0000000..33a9bf9 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LOrCommand.java @@ -0,0 +1,56 @@ +package org.jcnc.snow.vm.commands.bitwise.long64; + +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; + +/** + * The {@code LOrCommand} class implements the {@link Command} interface and represents the long64 bitwise OR (`|`) operation command. + * This class performs a long64 bitwise OR operation in the virtual machine by popping the top two values from the stack, + * computing their OR, and then pushing the result back onto the stack. It is a basic operation command within the virtual machine. + * + *

Operation details:

+ *
    + *
  • Pops two operands from the virtual machine stack.
  • + *
  • Performs the long64 bitwise OR (`|`) operation.
  • + *
  • Pushes the result back onto the virtual machine stack.
  • + *
+ */ +public class LOrCommand implements Command { + /** + * Default constructor for creating an instance of {@code LOrCommand}. + * This constructor is empty as no specific initialization is required. + */ + public LOrCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * @param operandStack The virtual machine's operand stack manager, responsible for performing stack operations. + * @param localVariableStore The local variable store, typically used to manage method-local variables. + * @param callStack The virtual machine's call stack, which keeps track of method invocations. + * @return The updated program counter-value, typically {@code currentPC + 1}, unless a control flow instruction is executed. + * @throws IllegalStateException if there are not enough operands on the stack to perform the operation. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Ensure the stack has at least two operands + if (operandStack.size() < 2) { + throw new IllegalStateException("Not enough operands on the stack for LOR operation."); + } + + // Pop the top two operands from the stack + final long b = (long) operandStack.pop(); + final long a = (long) operandStack.pop(); + + // Perform the long64 bitwise OR operation and push the result back onto the stack + operandStack.push(a | b); + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LXorCommand.java b/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LXorCommand.java new file mode 100644 index 0000000..2a668dd --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/bitwise/long64/LXorCommand.java @@ -0,0 +1,59 @@ +package org.jcnc.snow.vm.commands.bitwise.long64; + +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; + +/** + * The {@code LXorCommand} class implements the {@link Command} interface and represents the long64 bitwise XOR + * (`^`) operation command. + * This class performs a long64 bitwise XOR operation in the virtual machine + * by popping the top two values from the stack, + * computing their XOR, and then pushing the result back onto the stack. + * It is a basic operation command within the virtual machine. + * + *

Operation details:

+ *
    + *
  • Pops two operands from the virtual machine stack.
  • + *
  • Performs the long64 bitwise XOR (`^`) operation.
  • + *
  • Pushes the result back onto the virtual machine stack.
  • + *
+ */ +public class LXorCommand implements Command { + /** + * Default constructor for creating an instance of {@code LXorCommand}. + * This constructor is empty as no specific initialization is required. + */ + public LXorCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * @param operandStack The virtual machine's operand stack manager, responsible for performing stack operations. + * @param localVariableStore The local variable store, typically used to manage method-local variables. + * @param callStack The virtual machine's call stack, which keeps track of method invocations. + * @return The updated program counter-value, typically {@code currentPC + 1}, unless a control flow instruction is executed. + * @throws IllegalStateException if there are not enough operands on the stack to perform the operation. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Ensure the stack has at least two operands + if (operandStack.size() < 2) { + throw new IllegalStateException("Not enough operands on the stack for LXOR operation."); + } + + // Pop the top two operands from the stack + final int b = (int) operandStack.pop(); + final int a = (int) operandStack.pop(); + + // Perform the long64 bitwise XOR operation and push the result back onto the stack + operandStack.push(a ^ b); + + return currentPC + 1; + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/commands/control/all/JumpCommand.java b/src/main/java/org/jcnc/snow/vm/commands/control/all/JumpCommand.java new file mode 100644 index 0000000..63418da --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/control/all/JumpCommand.java @@ -0,0 +1,73 @@ +package org.jcnc.snow.vm.commands.control.all; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.utils.LoggingUtils; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; + +/** + * The JumpCommand class implements the {@link Command} interface and represents an unconditional jump instruction in the virtual machine. + * This class performs a jump to the specified target instruction address. + * + *

Specific behavior:

+ *
    + *
  • Parses the target instruction address and performs validation.
  • + *
  • If the target address is valid (greater than or equal to 0), it jumps to the specified address.
  • + *
  • If the target address is invalid (less than 0), it outputs an error message and halts execution.
  • + *
+ */ +public class JumpCommand implements Command { + /** + * Default constructor for creating an instance of JumpCommand. + * This constructor is empty as no specific initialization is required. + */ + public JumpCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

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

Specific behavior:

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

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

+ * + *

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

+ * + *

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

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

Specific behavior:

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

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

+ * + *

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

+ * + *

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

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

Specific behavior:

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

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

+ * + *

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

+ * + *

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

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

Specific behavior:

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

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

+ * + *

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

+ * + *

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

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

Specific behavior:

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

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

+ * + *

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

+ * + *

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

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

Specific behavior:

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

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

+ * + *

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

+ * + *

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

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

The {@code CallCommand} is used to simulate the invocation of a method or function in the virtual machine's execution flow. + * It manages the call stack by creating a new stack frame, pushing it to the stack, and modifying the program counter (PC) + * to jump to the target address.

+ * + *

Specific behavior:

+ *
    + *
  • Pops the current program counter (the return address) from the stack and stores it for later use when the method returns.
  • + *
  • Pushes a new stack frame onto the call stack with the return address and the method context (e.g., method name, local variables).
  • + *
  • Updates the program counter to the target function address, effectively transferring control to the function.
  • + *
+ * + *

This behavior allows the virtual machine to execute functions by managing a call stack that keeps track of method invocations + * and return addresses.

+ */ +public class CallCommand implements Command { + /** + * Default constructor for creating an instance of CallCommand. + * This constructor is empty as no specific initialization is required. + */ + public CallCommand() { + // Empty constructor + } + + /** + * Executes the {@code CALL} instruction, which initiates a function call in the virtual machine. + * + *

This method performs the following steps:

+ *
    + *
  • Validates and extracts the target function address from the provided instruction parameters.
  • + *
  • Creates a new stack frame that includes the return address (current PC + 1), the local variable store, + * and the method context (e.g., method name, arguments).
  • + *
  • Pushes the new stack frame onto the call stack.
  • + *
  • Sets the program counter to the target function address, causing execution to jump to that address.
  • + *
+ * + *

After executing this command, the virtual machine begins executing the function at the specified address, and + * upon return, the control will be transferred back to the instruction following the call.

+ * + * @param parts The array of instruction parameters, which should contain the target function address. + * @param currentPC The current program counter-value, which points to the instruction currently being executed. + * After the function call, this value will be updated to the target function's address. + * @param operandStack The operand stack manager, which is responsible for managing the operand stack during the execution of the command. + * @param localVariableStore The local variable store, which is used to manage the local variables for the current function being called. + * @param callStack The call stack, which is responsible for managing the method invocation hierarchy. + * The stack is modified by pushing a new frame when a function call is made. + * @return The updated program counter-value, which is set to the target function's address in the call. + * @throws IllegalArgumentException If the instruction parameters are invalid or if the function address is not provided. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Validate parts array length, expect at least 1 parameter (target address) + if (parts.length < 1) { + throw new IllegalArgumentException("Invalid instruction format. Target function address is missing."); + } + + // Extract the target function address (simulated from the parts) + int targetAddress; + + try { + targetAddress = Integer.parseInt(parts[1]); // The function address is expected as the first parameter + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid function address: " + parts[1], e); + } + + // Create a method context for the function call (name and parameters can be expanded as needed) + MethodContext methodContext = new MethodContext("main", null); // Method name is hardcoded, modify for actual use + + // Create a new stack frame and push it onto the call stack + StackFrame frame = new StackFrame(currentPC + 1, localVariableStore, methodContext); + callStack.pushFrame(frame); + + // Log the call action for debugging + System.out.println("Calling function at address: " + targetAddress); + + // Update the program counter to the target function address, which effectively jumps to the function + return targetAddress; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/function/RetCommand.java b/src/main/java/org/jcnc/snow/vm/commands/function/RetCommand.java new file mode 100644 index 0000000..6c1f082 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/function/RetCommand.java @@ -0,0 +1,99 @@ +package org.jcnc.snow.vm.commands.function; + +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.module.StackFrame; + +/** + * The {@code RetCommand} class implements the {@link Command} interface and represents the + * instruction for returning from a method in the virtual machine's execution flow. + * + *

This command performs the necessary actions to return control to the calling method + * by restoring the program counter (PC) to the saved return address from the call stack.

+ * + *

Specific behavior:

+ *
    + *
  • Pops the return address (program counter) from the call stack.
  • + *
  • Clears the local variables of the current method (stack frame) using + * {@link LocalVariableStore#clearVariables()}.
  • + *
  • Restores the program counter to the return address.
  • + *
  • Resumes execution from the instruction following the method call.
  • + *
+ * + *

This operation signifies the end of a method execution, where control is returned + * to the caller method, and execution continues from where the method was invoked.

+ * + *

Example of the process:

+ *
    + *
  1. A method is called, pushing a new stack frame onto the call stack.
  2. + *
  3. Execution proceeds in the method, using the operand stack and local variables.
  4. + *
  5. When a {@code RET} command is encountered, the return address is popped + * from the call stack, the method's local variables are cleared, and the program + * counter is updated to the return address.
  6. + *
  7. Execution continues from the point where the method was called.
  8. + *
+ */ +public class RetCommand implements Command { + /** + * Default constructor for creating an instance of RetCommand. + * This constructor is empty as no specific initialization is required. + */ + public RetCommand() { + // Empty constructor + } + + /** + * Executes the {@code RET} instruction, returning control to the caller method. + * + *

This method performs the following actions:

+ *
    + *
  • Checks if the call stack is empty (indicating no method to return from).
  • + *
  • Pops the current stack frame from the call stack, retrieving the return address.
  • + *
  • Clears the local variables in the current stack frame using + * {@link LocalVariableStore#clearVariables()}.
  • + *
  • Restores the program counter to the return address stored in the stack frame.
  • + *
+ * + *

The execution of this method results in the program counter being updated to + * the return address of the previous method in the call stack.

+ * + * @param parts The array of instruction parameters, which can include + * operation arguments (such as target addresses or function names). + * @param currentPC The current program counter-value, which represents the + * address of the instruction being executed. + * @param operandStack The operand stack manager, used to manage the operand stack + * during the execution of the command (though not directly + * involved in this command). + * @param localVariableStore The local variable store associated with the current method, + * which is cleared when returning from the method. + * @param callStack The call stack that tracks method invocations and manages + * the stack frames, which is used to retrieve and pop the + * return address during the execution of this command. + * @return The updated program counter-value, which is the return address popped from + * the call stack. This value will be used to continue execution after returning + * from the current method. + * @throws IllegalStateException If the call stack is empty, indicating there is no + * method to return from. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Check if the call stack is empty (i.e., no function was called before) + if (callStack.isEmpty()) { + throw new IllegalStateException("Call stack is empty. No function to return to."); + } + + // Clear the local variable store in the current stack frame + callStack.peekFrame().getLocalVariableStore().clearVariables(); + + // Pop the return address (the saved program counter) from the call stack + StackFrame frame = callStack.popFrame(); + + // Debug log for the return address + System.out.println("Return " + frame.getReturnAddress()); + + // Restore the program counter to the return address + return frame.getReturnAddress(); + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/all/MovCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/all/MovCommand.java new file mode 100644 index 0000000..dd0b11b --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/all/MovCommand.java @@ -0,0 +1,67 @@ +package org.jcnc.snow.vm.commands.memory.all; + +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; + +/** + * The MovCommand class implements the {@link Command} interface and represents a MOV instruction in the virtual machine. + * This class is used to transfer a value from one memory location to another within the local variable store of the current frame. + * + *

Specific behavior:

+ *
    + *
  • Retrieves a value from the specified source index in the local variable store of the current method frame.
  • + *
  • Stores the retrieved value into the specified destination index within the same local variable store.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class MovCommand implements Command { + /** + * Default constructor for creating an instance of MovCommand. + * This constructor is empty as no specific initialization is required. + */ + public MovCommand() { + // Empty constructor + } + + /** + * Executes the MOV instruction to transfer a value from one local variable to another within the same method frame. + * + *

This method performs the following operations:

+ *
    + *
  • Parses the source and destination indices from the instruction parameters.
  • + *
  • Retrieves the value from the local variable store at the source index.
  • + *
  • Stores the retrieved value into the destination index of the local variable store.
  • + *
  • Increments the program counter to point to the next instruction in the program sequence.
  • + *
+ * + *

After execution, the program counter (PC) is updated to continue with the next instruction, unless control flow is modified.

+ * + * @param parts The array of instruction parameters, which includes the source and destination indices + * of the local variables involved in the move operation. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * Typically, this is incremented after each instruction execution. + * @param operandStack The virtual machine's operand stack manager, responsible for pushing, popping, and peeking values. + * @param localVariableStore The local variable store, used to retrieve and store values between different local variables. + * This store is accessed by the current method frame. + * @param callStack The virtual machine's call stack, used to track method calls and manage method frames. It is needed to + * retrieve the correct method frame's local variable store in this command. + * @return The updated program counter-value, typically incremented by 1, unless modified by control flow instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the source and destination indices from the instruction parameters + int sourceIndex = Integer.parseInt(parts[1]); + int destinationIndex = Integer.parseInt(parts[2]); + + // Retrieve the value from the local variable store at the source index + Object value = callStack.peekFrame().getLocalVariableStore().getVariable(sourceIndex); + + // Store the retrieved value into the destination index within the local variable store + callStack.peekFrame().getLocalVariableStore().setVariable(destinationIndex, value); + + // Return the updated program counter to continue to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/byte8/BLoadCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/byte8/BLoadCommand.java new file mode 100644 index 0000000..c42e645 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/byte8/BLoadCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.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; + +/** + * The BLoadCommand class implements the {@link Command} interface and represents a load instruction in the virtual machine. + * This class is used to load a value from the local variable store of the current method frame and push it onto the virtual machine stack. + * + *

Specific behavior:

+ *
    + *
  • Retrieves a value from the specified index in the local variable store of the current frame.
  • + *
  • Pushes that value onto the virtual machine operand stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class BLoadCommand implements Command { + /** + * Default constructor for creating an instance of BLoadCommand. + * This constructor is empty as no specific initialization is required. + */ + public BLoadCommand() { + // Empty constructor + } + + /** + * Executes the load instruction to retrieve a value from the local variable store and push it onto the operand stack. + * + *

This method performs the following operations:

+ *
    + *
  • Parses the index of the local variable to load from the instruction parameters.
  • + *
  • Retrieves the corresponding value from the local variable store of the current method frame.
  • + *
  • Pushes the retrieved value onto the operand stack for subsequent operations.
  • + *
  • Increments the program counter to point to the next instruction to be executed.
  • + *
+ * + *

After execution, the program counter (PC) is updated to continue with the next instruction in the sequence, unless control flow changes.

+ * + * @param parts The array of instruction parameters, which typically includes the operation type and the index + * of the local variable to be loaded. The structure may vary based on the specific instruction. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after execution to point to the next instruction. + * @param operandStack The virtual machine's operand stack manager, responsible for pushing, popping, and peeking values. + * @param localVariableStore The local variable store, from which values are loaded based on the provided index. + * This store manages method-local variables. + * @param callStack The virtual machine's call stack, which tracks method calls and returns. It is used to access + * the correct frame's local variable store in this case. + * @return The updated program counter-value, which is typically incremented by 1 unless control flow is modified by other instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index of the local variable to be loaded + int index = Integer.parseInt(parts[1]); + + // Retrieve the value from the local variable store of the current method frame + byte value = (byte) callStack.peekFrame().getLocalVariableStore().getVariable(index); + + // Push the loaded value onto the operand stack for subsequent operations + operandStack.push(value); + + // Return the updated program counter to continue to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/byte8/BStoreCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/byte8/BStoreCommand.java new file mode 100644 index 0000000..47211d1 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/byte8/BStoreCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.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; + +/** + * The BStoreCommand class implements the {@link Command} interface and represents a store instruction in the virtual machine. + * This class is used to store the value from the top of the virtual machine stack into the local variable store, typically used to save computed results into local variables. + * + *

Specific behavior:

+ *
    + *
  • Pops a value from the virtual machine operand stack.
  • + *
  • Stores that value into the specified index location in the local variable store of the current frame on the call stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class BStoreCommand implements Command { + /** + * Default constructor for creating an instance of BStoreCommand. + * This constructor is empty as no specific initialization is required. + */ + public BStoreCommand() { + // Empty constructor + } + + /** + * Executes the store instruction. + * + *

This method retrieves the value from the operand stack, pops the value, and stores it in the local variable store + * of the current method frame, based on the specified index. The program counter (PC) is then updated to point to the next instruction.

+ * + *

The method performs the following actions:

+ *
    + *
  • Parses the index of the local variable where the value will be stored.
  • + *
  • Pops the top value from the operand stack.
  • + *
  • Stores the popped value into the specified local variable index in the current method frame's local variable store.
  • + *
  • Returns the next program counter-value to continue execution of the following instruction.
  • + *
+ * + * @param parts The array of instruction parameters, typically consisting of the operation type and related arguments, + * such as the index for the local variable. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack, used to store and manipulate values during instruction execution. + * @param localVariableStore The local variable store, used for managing method-local variables. + * @param callStack The virtual machine's call stack, which tracks the method invocation hierarchy. + * Used in conjunction with local variable store for method-local variable management. + * @return The updated program counter-value, typically the current PC value incremented by 1, unless modified by control flow instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index for the local variable where the value will be stored + int index = Integer.parseInt(parts[1]); + + // Pop the value from the operand stack + byte value = (byte) operandStack.pop(); + + // Store the value into the local variable store of the current method frame + callStack.peekFrame().getLocalVariableStore().setVariable(index, value); + + // Return the updated program counter, which moves to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/double64/DLoadCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/double64/DLoadCommand.java new file mode 100644 index 0000000..f1c7ddd --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/double64/DLoadCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.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; + +/** + * The DLoadCommand class implements the {@link Command} interface and represents a store instruction in the virtual machine. + * This class is used to store the value from the top of the virtual machine stack into the local variable store, typically used to save computed results into local variables. + * + *

Specific behavior:

+ *
    + *
  • Pops a value from the virtual machine operand stack.
  • + *
  • Stores that value into the specified index location in the local variable store of the current frame on the call stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class DLoadCommand implements Command { + /** + * Default constructor for creating an instance of DLoadCommand. + * This constructor is empty as no specific initialization is required. + */ + public DLoadCommand() { + // Empty constructor + } + + /** + * Executes the store instruction. + * + *

This method retrieves the value from the operand stack, pops the value, and stores it in the local variable store + * of the current method frame, based on the specified index. The program counter (PC) is then updated to point to the next instruction.

+ * + *

The method performs the following actions:

+ *
    + *
  • Parses the index of the local variable where the value will be stored.
  • + *
  • Pops the top value from the operand stack.
  • + *
  • Stores the popped value into the specified local variable index in the current method frame's local variable store.
  • + *
  • Returns the next program counter-value to continue execution of the following instruction.
  • + *
+ * + * @param parts The array of instruction parameters, typically consisting of the operation type and related arguments, + * such as the index for the local variable. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack, used to store and manipulate values during instruction execution. + * @param localVariableStore The local variable store, used for managing method-local variables. + * @param callStack The virtual machine's call stack, which tracks the method invocation hierarchy. + * Used in conjunction with local variable store for method-local variable management. + * @return The updated program counter-value, typically the current PC value incremented by 1, unless modified by control flow instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index for the local variable where the value will be stored + int index = Integer.parseInt(parts[1]); + + // Pop the value from the operand stack + double value = (double) operandStack.pop(); + + // Store the value into the local variable store of the current method frame + callStack.peekFrame().getLocalVariableStore().setVariable(index, value); + + // Return the updated program counter, which moves to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/double64/DStoreCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/double64/DStoreCommand.java new file mode 100644 index 0000000..7affd8f --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/double64/DStoreCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.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; + +/** + * The DStoreCommand class implements the {@link Command} interface and represents a store instruction in the virtual machine. + * This class is used to store the value from the top of the virtual machine stack into the local variable store, typically used to save computed results into local variables. + * + *

Specific behavior:

+ *
    + *
  • Pops a value from the virtual machine operand stack.
  • + *
  • Stores that value into the specified index location in the local variable store of the current frame on the call stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class DStoreCommand implements Command { + /** + * Default constructor for creating an instance of DStoreCommand. + * This constructor is empty as no specific initialization is required. + */ + public DStoreCommand() { + // Empty constructor + } + + /** + * Executes the store instruction. + * + *

This method retrieves the value from the operand stack, pops the value, and stores it in the local variable store + * of the current method frame, based on the specified index. The program counter (PC) is then updated to point to the next instruction.

+ * + *

The method performs the following actions:

+ *
    + *
  • Parses the index of the local variable where the value will be stored.
  • + *
  • Pops the top value from the operand stack.
  • + *
  • Stores the popped value into the specified local variable index in the current method frame's local variable store.
  • + *
  • Returns the next program counter-value to continue execution of the following instruction.
  • + *
+ * + * @param parts The array of instruction parameters, typically consisting of the operation type and related arguments, + * such as the index for the local variable. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack, used to store and manipulate values during instruction execution. + * @param localVariableStore The local variable store, used for managing method-local variables. + * @param callStack The virtual machine's call stack, which tracks the method invocation hierarchy. + * Used in conjunction with local variable store for method-local variable management. + * @return The updated program counter-value, typically the current PC value incremented by 1, unless modified by control flow instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index for the local variable where the value will be stored + int index = Integer.parseInt(parts[1]); + + // Pop the value from the operand stack + double value = (double) operandStack.pop(); + + // Store the value into the local variable store of the current method frame + callStack.peekFrame().getLocalVariableStore().setVariable(index, value); + + // Return the updated program counter, which moves to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/float32/FLoadCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/float32/FLoadCommand.java new file mode 100644 index 0000000..7edcdb6 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/float32/FLoadCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.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; + +/** + * The FLoadCommand class implements the {@link Command} interface and represents a load instruction in the virtual machine. + * This class is used to load a value from the local variable store of the current method frame and push it onto the virtual machine stack. + * + *

Specific behavior:

+ *
    + *
  • Retrieves a value from the specified index in the local variable store of the current frame.
  • + *
  • Pushes that value onto the virtual machine operand stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class FLoadCommand implements Command { + /** + * Default constructor for creating an instance of FLoadCommand. + * This constructor is empty as no specific initialization is required. + */ + public FLoadCommand() { + // Empty constructor + } + + /** + * Executes the load instruction to retrieve a value from the local variable store and push it onto the operand stack. + * + *

This method performs the following operations:

+ *
    + *
  • Parses the index of the local variable to load from the instruction parameters.
  • + *
  • Retrieves the corresponding value from the local variable store of the current method frame.
  • + *
  • Pushes the retrieved value onto the operand stack for subsequent operations.
  • + *
  • Increments the program counter to point to the next instruction to be executed.
  • + *
+ * + *

After execution, the program counter (PC) is updated to continue with the next instruction in the sequence, unless control flow changes.

+ * + * @param parts The array of instruction parameters, which typically includes the operation type and the index + * of the local variable to be loaded. The structure may vary based on the specific instruction. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after execution to point to the next instruction. + * @param operandStack The virtual machine's operand stack manager, responsible for pushing, popping, and peeking values. + * @param localVariableStore The local variable store, from which values are loaded based on the provided index. + * This store manages method-local variables. + * @param callStack The virtual machine's call stack, which tracks method calls and returns. It is used to access + * the correct frame's local variable store in this case. + * @return The updated program counter-value, which is typically incremented by 1 unless control flow is modified by other instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index of the local variable to be loaded + int index = Integer.parseInt(parts[1]); + + // Retrieve the value from the local variable store of the current method frame + float value = (float) callStack.peekFrame().getLocalVariableStore().getVariable(index); + + // Push the loaded value onto the operand stack for subsequent operations + operandStack.push(value); + + // Return the updated program counter to continue to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/float32/FStoreCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/float32/FStoreCommand.java new file mode 100644 index 0000000..4a1ae60 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/float32/FStoreCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.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; + +/** + * The FStoreCommand class implements the {@link Command} interface and represents a store instruction in the virtual machine. + * This class is used to store the value from the top of the virtual machine stack into the local variable store, typically used to save computed results into local variables. + * + *

Specific behavior:

+ *
    + *
  • Pops a value from the virtual machine operand stack.
  • + *
  • Stores that value into the specified index location in the local variable store of the current frame on the call stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class FStoreCommand implements Command { + /** + * Default constructor for creating an instance of FStoreCommand. + * This constructor is empty as no specific initialization is required. + */ + public FStoreCommand() { + // Empty constructor + } + + /** + * Executes the store instruction. + * + *

This method retrieves the value from the operand stack, pops the value, and stores it in the local variable store + * of the current method frame, based on the specified index. The program counter (PC) is then updated to point to the next instruction.

+ * + *

The method performs the following actions:

+ *
    + *
  • Parses the index of the local variable where the value will be stored.
  • + *
  • Pops the top value from the operand stack.
  • + *
  • Stores the popped value into the specified local variable index in the current method frame's local variable store.
  • + *
  • Returns the next program counter-value to continue execution of the following instruction.
  • + *
+ * + * @param parts The array of instruction parameters, typically consisting of the operation type and related arguments, + * such as the index for the local variable. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack, used to store and manipulate values during instruction execution. + * @param localVariableStore The local variable store, used for managing method-local variables. + * @param callStack The virtual machine's call stack, which tracks the method invocation hierarchy. + * Used in conjunction with local variable store for method-local variable management. + * @return The updated program counter-value, typically the current PC value incremented by 1, unless modified by control flow instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index for the local variable where the value will be stored + int index = Integer.parseInt(parts[1]); + + // Pop the value from the operand stack + float value = (float) operandStack.pop(); + + // Store the value into the local variable store of the current method frame + callStack.peekFrame().getLocalVariableStore().setVariable(index, value); + + // Return the updated program counter, which moves to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/int32/ILoadCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/int32/ILoadCommand.java new file mode 100644 index 0000000..02a55fa --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/int32/ILoadCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.int32; + +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; + +/** + * The ILoadCommand class implements the {@link Command} interface and represents a load instruction in the virtual machine. + * This class is used to load a value from the local variable store of the current method frame and push it onto the virtual machine stack. + * + *

Specific behavior:

+ *
    + *
  • Retrieves a value from the specified index in the local variable store of the current frame.
  • + *
  • Pushes that value onto the virtual machine operand stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class ILoadCommand implements Command { + /** + * Default constructor for creating an instance of ILoadCommand. + * This constructor is empty as no specific initialization is required. + */ + public ILoadCommand() { + // Empty constructor + } + + /** + * Executes the load instruction to retrieve a value from the local variable store and push it onto the operand stack. + * + *

This method performs the following operations:

+ *
    + *
  • Parses the index of the local variable to load from the instruction parameters.
  • + *
  • Retrieves the corresponding value from the local variable store of the current method frame.
  • + *
  • Pushes the retrieved value onto the operand stack for subsequent operations.
  • + *
  • Increments the program counter to point to the next instruction to be executed.
  • + *
+ * + *

After execution, the program counter (PC) is updated to continue with the next instruction in the sequence, unless control flow changes.

+ * + * @param parts The array of instruction parameters, which typically includes the operation type and the index + * of the local variable to be loaded. The structure may vary based on the specific instruction. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after execution to point to the next instruction. + * @param operandStack The virtual machine's operand stack manager, responsible for pushing, popping, and peeking values. + * @param localVariableStore The local variable store, from which values are loaded based on the provided index. + * This store manages method-local variables. + * @param callStack The virtual machine's call stack, which tracks method calls and returns. It is used to access + * the correct frame's local variable store in this case. + * @return The updated program counter-value, which is typically incremented by 1 unless control flow is modified by other instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index of the local variable to be loaded + int index = Integer.parseInt(parts[1]); + + // Retrieve the value from the local variable store of the current method frame + int value = (int) callStack.peekFrame().getLocalVariableStore().getVariable(index); + + // Push the loaded value onto the operand stack for subsequent operations + operandStack.push(value); + + // Return the updated program counter to continue to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/int32/IStoreCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/int32/IStoreCommand.java new file mode 100644 index 0000000..31dfb26 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/int32/IStoreCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.int32; + +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; + +/** + * The IStoreCommand class implements the {@link Command} interface and represents a store instruction in the virtual machine. + * This class is used to store the value from the top of the virtual machine stack into the local variable store, typically used to save computed results into local variables. + * + *

Specific behavior:

+ *
    + *
  • Pops a value from the virtual machine operand stack.
  • + *
  • Stores that value into the specified index location in the local variable store of the current frame on the call stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class IStoreCommand implements Command { + /** + * Default constructor for creating an instance of IStoreCommand. + * This constructor is empty as no specific initialization is required. + */ + public IStoreCommand() { + // Empty constructor + } + + /** + * Executes the store instruction. + * + *

This method retrieves the value from the operand stack, pops the value, and stores it in the local variable store + * of the current method frame, based on the specified index. The program counter (PC) is then updated to point to the next instruction.

+ * + *

The method performs the following actions:

+ *
    + *
  • Parses the index of the local variable where the value will be stored.
  • + *
  • Pops the top value from the operand stack.
  • + *
  • Stores the popped value into the specified local variable index in the current method frame's local variable store.
  • + *
  • Returns the next program counter-value to continue execution of the following instruction.
  • + *
+ * + * @param parts The array of instruction parameters, typically consisting of the operation type and related arguments, + * such as the index for the local variable. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack, used to store and manipulate values during instruction execution. + * @param localVariableStore The local variable store, used for managing method-local variables. + * @param callStack The virtual machine's call stack, which tracks the method invocation hierarchy. + * Used in conjunction with local variable store for method-local variable management. + * @return The updated program counter-value, typically the current PC value incremented by 1, unless modified by control flow instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index for the local variable where the value will be stored + int index = Integer.parseInt(parts[1]); + + // Pop the value from the operand stack + int value = (int) operandStack.pop(); + + // Store the value into the local variable store of the current method frame + callStack.peekFrame().getLocalVariableStore().setVariable(index, value); + + // Return the updated program counter, which moves to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/long64/LLoadCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/long64/LLoadCommand.java new file mode 100644 index 0000000..411d766 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/long64/LLoadCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.long64; + +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; + +/** + * The LLoadCommand class implements the {@link Command} interface and represents a load instruction in the virtual machine. + * This class is used to load a value from the local variable store of the current method frame and push it onto the virtual machine stack. + * + *

Specific behavior:

+ *
    + *
  • Retrieves a value from the specified index in the local variable store of the current frame.
  • + *
  • Pushes that value onto the virtual machine operand stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class LLoadCommand implements Command { + /** + * Default constructor for creating an instance of LLoadCommand. + * This constructor is empty as no specific initialization is required. + */ + public LLoadCommand() { + // Empty constructor + } + + /** + * Executes the load instruction to retrieve a value from the local variable store and push it onto the operand stack. + * + *

This method performs the following operations:

+ *
    + *
  • Parses the index of the local variable to load from the instruction parameters.
  • + *
  • Retrieves the corresponding value from the local variable store of the current method frame.
  • + *
  • Pushes the retrieved value onto the operand stack for subsequent operations.
  • + *
  • Increments the program counter to point to the next instruction to be executed.
  • + *
+ * + *

After execution, the program counter (PC) is updated to continue with the next instruction in the sequence, unless control flow changes.

+ * + * @param parts The array of instruction parameters, which typically includes the operation type and the index + * of the local variable to be loaded. The structure may vary based on the specific instruction. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after execution to point to the next instruction. + * @param operandStack The virtual machine's operand stack manager, responsible for pushing, popping, and peeking values. + * @param localVariableStore The local variable store, from which values are loaded based on the provided index. + * This store manages method-local variables. + * @param callStack The virtual machine's call stack, which tracks method calls and returns. It is used to access + * the correct frame's local variable store in this case. + * @return The updated program counter-value, which is typically incremented by 1 unless control flow is modified by other instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index of the local variable to be loaded + int index = Integer.parseInt(parts[1]); + + // Retrieve the value from the local variable store of the current method frame + long value = (long) callStack.peekFrame().getLocalVariableStore().getVariable(index); + + // Push the loaded value onto the operand stack for subsequent operations + operandStack.push(value); + + // Return the updated program counter to continue to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/long64/LStoreCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/long64/LStoreCommand.java new file mode 100644 index 0000000..f1b5e3f --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/long64/LStoreCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.long64; + +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; + +/** + * The LStoreCommand class implements the {@link Command} interface and represents a store instruction in the virtual machine. + * This class is used to store the value from the top of the virtual machine stack into the local variable store, typically used to save computed results into local variables. + * + *

Specific behavior:

+ *
    + *
  • Pops a value from the virtual machine operand stack.
  • + *
  • Stores that value into the specified index location in the local variable store of the current frame on the call stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class LStoreCommand implements Command { + /** + * Default constructor for creating an instance of LStoreCommand. + * This constructor is empty as no specific initialization is required. + */ + public LStoreCommand() { + // Empty constructor + } + + /** + * Executes the store instruction. + * + *

This method retrieves the value from the operand stack, pops the value, and stores it in the local variable store + * of the current method frame, based on the specified index. The program counter (PC) is then updated to point to the next instruction.

+ * + *

The method performs the following actions:

+ *
    + *
  • Parses the index of the local variable where the value will be stored.
  • + *
  • Pops the top value from the operand stack.
  • + *
  • Stores the popped value into the specified local variable index in the current method frame's local variable store.
  • + *
  • Returns the next program counter-value to continue execution of the following instruction.
  • + *
+ * + * @param parts The array of instruction parameters, typically consisting of the operation type and related arguments, + * such as the index for the local variable. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack, used to store and manipulate values during instruction execution. + * @param localVariableStore The local variable store, used for managing method-local variables. + * @param callStack The virtual machine's call stack, which tracks the method invocation hierarchy. + * Used in conjunction with local variable store for method-local variable management. + * @return The updated program counter-value, typically the current PC value incremented by 1, unless modified by control flow instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index for the local variable where the value will be stored + int index = Integer.parseInt(parts[1]); + + // Pop the value from the operand stack + long value = (long) operandStack.pop(); + + // Store the value into the local variable store of the current method frame + callStack.peekFrame().getLocalVariableStore().setVariable(index, value); + + // Return the updated program counter, which moves to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/short16/SLoadCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/short16/SLoadCommand.java new file mode 100644 index 0000000..6379837 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/short16/SLoadCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.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; + +/** + * The SLoadCommand class implements the {@link Command} interface and represents a load instruction in the virtual machine. + * This class is used to load a value from the local variable store of the current method frame and push it onto the virtual machine stack. + * + *

Specific behavior:

+ *
    + *
  • Retrieves a value from the specified index in the local variable store of the current frame.
  • + *
  • Pushes that value onto the virtual machine operand stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class SLoadCommand implements Command { + /** + * Default constructor for creating an instance of SLoadCommand. + * This constructor is empty as no specific initialization is required. + */ + public SLoadCommand() { + // Empty constructor + } + + /** + * Executes the load instruction to retrieve a value from the local variable store and push it onto the operand stack. + * + *

This method performs the following operations:

+ *
    + *
  • Parses the index of the local variable to load from the instruction parameters.
  • + *
  • Retrieves the corresponding value from the local variable store of the current method frame.
  • + *
  • Pushes the retrieved value onto the operand stack for subsequent operations.
  • + *
  • Increments the program counter to point to the next instruction to be executed.
  • + *
+ * + *

After execution, the program counter (PC) is updated to continue with the next instruction in the sequence, unless control flow changes.

+ * + * @param parts The array of instruction parameters, which typically includes the operation type and the index + * of the local variable to be loaded. The structure may vary based on the specific instruction. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after execution to point to the next instruction. + * @param operandStack The virtual machine's operand stack manager, responsible for pushing, popping, and peeking values. + * @param localVariableStore The local variable store, from which values are loaded based on the provided index. + * This store manages method-local variables. + * @param callStack The virtual machine's call stack, which tracks method calls and returns. It is used to access + * the correct frame's local variable store in this case. + * @return The updated program counter-value, which is typically incremented by 1 unless control flow is modified by other instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index of the local variable to be loaded + int index = Integer.parseInt(parts[1]); + + // Retrieve the value from the local variable store of the current method frame + short value = (short) callStack.peekFrame().getLocalVariableStore().getVariable(index); + + // Push the loaded value onto the operand stack for subsequent operations + operandStack.push(value); + + // Return the updated program counter to continue to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/memory/short16/SStoreCommand.java b/src/main/java/org/jcnc/snow/vm/commands/memory/short16/SStoreCommand.java new file mode 100644 index 0000000..fb5d79c --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/memory/short16/SStoreCommand.java @@ -0,0 +1,66 @@ +package org.jcnc.snow.vm.commands.memory.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; + +/** + * The SStoreCommand class implements the {@link Command} interface and represents a store instruction in the virtual machine. + * This class is used to store the value from the top of the virtual machine stack into the local variable store, typically used to save computed results into local variables. + * + *

Specific behavior:

+ *
    + *
  • Pops a value from the virtual machine operand stack.
  • + *
  • Stores that value into the specified index location in the local variable store of the current frame on the call stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class SStoreCommand implements Command { + /** + * Default constructor for creating an instance of SStoreCommand. + * This constructor is empty as no specific initialization is required. + */ + public SStoreCommand() { + // Empty constructor + } + + /** + * Executes the store instruction. + * + *

This method retrieves the value from the operand stack, pops the value, and stores it in the local variable store + * of the current method frame, based on the specified index. The program counter (PC) is then updated to point to the next instruction.

+ * + *

The method performs the following actions:

+ *
    + *
  • Parses the index of the local variable where the value will be stored.
  • + *
  • Pops the top value from the operand stack.
  • + *
  • Stores the popped value into the specified local variable index in the current method frame's local variable store.
  • + *
  • Returns the next program counter-value to continue execution of the following instruction.
  • + *
+ * + * @param parts The array of instruction parameters, typically consisting of the operation type and related arguments, + * such as the index for the local variable. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack, used to store and manipulate values during instruction execution. + * @param localVariableStore The local variable store, used for managing method-local variables. + * @param callStack The virtual machine's call stack, which tracks the method invocation hierarchy. + * Used in conjunction with local variable store for method-local variable management. + * @return The updated program counter-value, typically the current PC value incremented by 1, unless modified by control flow instructions. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Parse the index for the local variable where the value will be stored + int index = Integer.parseInt(parts[1]); + + // Pop the value from the operand stack + short value = (short) operandStack.pop(); + + // Store the value into the local variable store of the current method frame + callStack.peekFrame().getLocalVariableStore().setVariable(index, value); + + // Return the updated program counter, which moves to the next instruction + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/stack/all/DupCommand.java b/src/main/java/org/jcnc/snow/vm/commands/stack/all/DupCommand.java new file mode 100644 index 0000000..8d0d1f8 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/stack/all/DupCommand.java @@ -0,0 +1,67 @@ +package org.jcnc.snow.vm.commands.stack.all; + +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; + +/** + * The DupCommand class implements the {@link Command} interface and represents the DUP instruction in the virtual machine. + * This class is used to duplicate the top value of the stack, copying it and pushing it back onto the stack. + * + *

Specific behavior:

+ *
    + *
  • Duplicates the top value of the stack and pushes it back onto the stack.
  • + *
  • Returns the updated program counter value, indicating the continuation of the next instruction.
  • + *
+ */ +public class DupCommand implements Command { + /** + * Default constructor for creating an instance of DupCommand. + * This constructor is empty as no specific initialization is required. + */ + public DupCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter value, typically the current program counter value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the top value from the stack + Object topValue = operandStack.peek(); + + // Push the duplicated value back onto the stack + operandStack.push(topValue); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/stack/all/PopCommand.java b/src/main/java/org/jcnc/snow/vm/commands/stack/all/PopCommand.java new file mode 100644 index 0000000..fe00f9d --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/stack/all/PopCommand.java @@ -0,0 +1,64 @@ +package org.jcnc.snow.vm.commands.stack.all; + +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; + +/** + * The PopCommand class implements the {@link Command} interface and represents a stack POP instruction in the virtual machine. + * This class is used to pop an element from the virtual machine stack, typically removing the topmost data. + * + *

Specific behavior:

+ *
    + *
  • Pops an element from the virtual machine stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class PopCommand implements Command { + /** + * Default constructor for creating an instance of PopCommand. + * This constructor is empty as no specific initialization is required. + */ + public PopCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Pop an element from the stack + operandStack.pop(); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/stack/all/SwapCommand.java b/src/main/java/org/jcnc/snow/vm/commands/stack/all/SwapCommand.java new file mode 100644 index 0000000..1f27318 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/stack/all/SwapCommand.java @@ -0,0 +1,74 @@ +package org.jcnc.snow.vm.commands.stack.all; + +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; + +/** + * The SwapCommand class implements the {@link Command} interface and represents the SWAP instruction in the virtual machine. + * This class is used to swap the top two values on the stack, rearranging the two most recent values. + * + *

Specific behavior:

+ *
    + *
  • Swaps the two top values of the stack.
  • + *
  • Returns the updated program counter value, indicating the continuation of the next instruction.
  • + *
+ */ +public class SwapCommand implements Command { + /** + * Default constructor for creating an instance of SwapCommand. + * This constructor is empty as no specific initialization is required. + */ + public SwapCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter value, typically the current program counter value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Ensure that the stack has at least two elements to swap + if (operandStack.size() < 2) { + throw new IllegalStateException("Insufficient elements on stack for SWAP operation"); + } + + // Pop the two topmost values from the stack + Object firstValue = operandStack.pop(); + Object secondValue = operandStack.pop(); + + // Push them back in reversed order + operandStack.push(firstValue); + operandStack.push(secondValue); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/stack/byte8/BPushCommand.java b/src/main/java/org/jcnc/snow/vm/commands/stack/byte8/BPushCommand.java new file mode 100644 index 0000000..6953ff8 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/stack/byte8/BPushCommand.java @@ -0,0 +1,67 @@ +package org.jcnc.snow.vm.commands.stack.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; + +/** + * The BPushCommand class implements the {@link Command} interface and represents a stack PUSH instruction in the virtual machine. + * This class is used to push a byte8 value onto the virtual machine stack, typically for later operations that require this data. + * + *

Specific behavior:

+ *
    + *
  • Pushes the provided byte8 value onto the virtual machine stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class BPushCommand implements Command { + /** + * Default constructor for creating an instance of BPushCommand. + * This constructor is empty as no specific initialization is required. + */ + public BPushCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the byte8 value from the command parameters to be pushed onto the stack + byte value = Byte.parseByte(parts[1]); + + // Push the byte8 value onto the stack + operandStack.push(value); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/stack/double64/DPushCommand.java b/src/main/java/org/jcnc/snow/vm/commands/stack/double64/DPushCommand.java new file mode 100644 index 0000000..5245d08 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/stack/double64/DPushCommand.java @@ -0,0 +1,67 @@ +package org.jcnc.snow.vm.commands.stack.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; + +/** + * The DPushCommand class implements the {@link Command} interface and represents a stack PUSH instruction in the virtual machine. + * This class is used to push a double64 value onto the virtual machine stack, typically for subsequent operations that require this data. + * + *

Specific behavior:

+ *
    + *
  • Pushes the provided double64 value onto the virtual machine stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class DPushCommand implements Command { + /** + * Default constructor for creating an instance of DPushCommand. + * This constructor is empty as no specific initialization is required. + */ + public DPushCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the double64 value from the command parameters to be pushed onto the stack + double value = Double.parseDouble(parts[1]); + + // Push the double64 value onto the stack + operandStack.push(value); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/stack/float32/FPushCommand.java b/src/main/java/org/jcnc/snow/vm/commands/stack/float32/FPushCommand.java new file mode 100644 index 0000000..da6da33 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/stack/float32/FPushCommand.java @@ -0,0 +1,67 @@ +package org.jcnc.snow.vm.commands.stack.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; + +/** + * The FPushCommand class implements the {@link Command} interface and represents a stack PUSH instruction in the virtual machine. + * This class is used to push a float32 value onto the virtual machine stack, typically for subsequent operations that require this data. + * + *

Specific behavior:

+ *
    + *
  • Pushes the provided float32 value onto the virtual machine stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class FPushCommand implements Command { + /** + * Default constructor for creating an instance of FPushCommand. + * This constructor is empty as no specific initialization is required. + */ + public FPushCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the float32 value from the command parameters to be pushed onto the stack + float value = Float.parseFloat(parts[1]); + + // Push the float32 value onto the stack + operandStack.push(value); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/stack/int32/IPushCommand.java b/src/main/java/org/jcnc/snow/vm/commands/stack/int32/IPushCommand.java new file mode 100644 index 0000000..5515e1f --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/stack/int32/IPushCommand.java @@ -0,0 +1,67 @@ +package org.jcnc.snow.vm.commands.stack.int32; + +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; + +/** + * The IPushCommand class implements the {@link Command} interface and represents a stack PUSH instruction in the virtual machine. + * This class is used to push an int32 value onto the virtual machine stack, typically for later operations that require this data. + * + *

Specific behavior:

+ *
    + *
  • Pushes the provided int32 value onto the virtual machine stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class IPushCommand implements Command { + /** + * Default constructor for creating an instance of IPushCommand. + * This constructor is empty as no specific initialization is required. + */ + public IPushCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the int32 value from the command parameters to be pushed onto the stack + int value = Integer.parseInt(parts[1]); + + // Push the int32 value onto the stack + operandStack.push(value); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/stack/long64/LPushCommand.java b/src/main/java/org/jcnc/snow/vm/commands/stack/long64/LPushCommand.java new file mode 100644 index 0000000..d00b9c7 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/stack/long64/LPushCommand.java @@ -0,0 +1,67 @@ +package org.jcnc.snow.vm.commands.stack.long64; + +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; + +/** + * The LPushCommand class implements the {@link Command} interface and represents a stack PUSH instruction in the virtual machine. + * This class is used to push a long64 value onto the virtual machine stack, typically for later operations that require this data. + * + *

Specific behavior:

+ *
    + *
  • Pushes the provided long64 value onto the virtual machine stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class LPushCommand implements Command { + /** + * Default constructor for creating an instance of LPushCommand. + * This constructor is empty as no specific initialization is required. + */ + public LPushCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the long64 value from the command parameters to be pushed onto the stack + long value = Long.parseLong(parts[1]); + + // Push the long64 value onto the stack + operandStack.push(value); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/stack/short16/SPushCommand.java b/src/main/java/org/jcnc/snow/vm/commands/stack/short16/SPushCommand.java new file mode 100644 index 0000000..b61fbe2 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/stack/short16/SPushCommand.java @@ -0,0 +1,67 @@ +package org.jcnc.snow.vm.commands.stack.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; + +/** + * The SPushCommand class implements the {@link Command} interface and represents a stack PUSH instruction in the virtual machine. + * This class is used to push a short16 value onto the virtual machine stack, typically for later operations that require this data. + * + *

Specific behavior:

+ *
    + *
  • Pushes the provided short16 value onto the virtual machine stack.
  • + *
  • Returns the updated program counter-value, indicating the continuation of the next instruction.
  • + *
+ */ +public class SPushCommand implements Command { + /** + * Default constructor for creating an instance of SPushCommand. + * This constructor is empty as no specific initialization is required. + */ + public SPushCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Retrieve the short16 value from the command parameters to be pushed onto the stack + short value = Short.parseShort(parts[1]); + + // Push the short16 value onto the stack + operandStack.push(value); + + return currentPC + 1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/commands/vm/HaltCommand.java b/src/main/java/org/jcnc/snow/vm/commands/vm/HaltCommand.java new file mode 100644 index 0000000..19e4d5d --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/commands/vm/HaltCommand.java @@ -0,0 +1,67 @@ +package org.jcnc.snow.vm.commands.vm; + +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.utils.LoggingUtils; +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; + +/** + * The HaltCommand class implements the {@link Command} interface and represents the stop instruction in the virtual machine. + * This class is used to terminate the execution of the virtual machine. When this command is executed, the virtual machine + * outputs a message and stops executing subsequent instructions. + * + *

Specific behavior:

+ *
    + *
  • Outputs the message "Process has ended," indicating that the program execution has been terminated.
  • + *
  • Returns -1 to signal the virtual machine to stop execution.
  • + *
+ */ +public class HaltCommand implements Command { + /** + * Default constructor for creating an instance of HaltCommand. + * This constructor is empty as no specific initialization is required. + */ + public HaltCommand() { + // Empty constructor + } + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + @Override + public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + // Output the termination message + LoggingUtils.logInfo("Process has ended", "\n"); + + // Return -1 to indicate the program termination, and the virtual machine will not continue executing subsequent instructions + return -1; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/engine/VMCommandExecutor.java b/src/main/java/org/jcnc/snow/vm/engine/VMCommandExecutor.java new file mode 100644 index 0000000..3c3a830 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/engine/VMCommandExecutor.java @@ -0,0 +1,44 @@ +package org.jcnc.snow.vm.engine; + + +import org.jcnc.snow.vm.utils.LoggingUtils; + +import java.util.List; + +/** + * Virtual Machine Command Executor (VMCommandExecutor) + *

+ * This class is responsible for executing a set of instructions for the virtual machine. It calls the `execute` method of + * {@link VirtualMachineEngine} to execute the provided list of instructions. If any errors occur during execution, the + * error messages are logged using {@link LoggingUtils}. + *

+ */ +public class VMCommandExecutor { + /** + * Default constructor for creating an instance of VMCommandExecutor. + * This constructor is empty as no specific initialization is required. + */ + public VMCommandExecutor() { + // Empty constructor + } + + /** + * Executes the virtual machine instructions. + *

+ * This method takes a virtual machine instance and a list of instructions, and executes them while controlling the + * virtual machine's operation. If any exceptions occur during execution, they are caught and logged via {@link LoggingUtils}. + *

+ * + * @param virtualMachineEngine The virtual machine instance used to execute the instructions. + * @param instructions The list of instructions to be executed. + */ + public static void executeInstructions(VirtualMachineEngine virtualMachineEngine, List instructions) { + try { + // Call the virtual machine's execute method to run the instruction list + virtualMachineEngine.execute(instructions); + } catch (Exception e) { + // If an exception occurs, log the error message + LoggingUtils.logError("Error while executing instructions: " + e.getMessage()); + } + } +} diff --git a/src/main/java/org/jcnc/snow/vm/engine/VMMode.java b/src/main/java/org/jcnc/snow/vm/engine/VMMode.java new file mode 100644 index 0000000..a378ef7 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/engine/VMMode.java @@ -0,0 +1,19 @@ +package org.jcnc.snow.vm.engine; + +/** + * The VMMode enum defines the different operational modes of the virtual machine. + *

This class is used to distinguish the behavior of the virtual machine in different states, with each mode corresponding to a different operational logic.

+ */ +public enum VMMode { + /** + * Run Mode: The virtual machine executes instructions in the normal execution flow. + *

In this mode, the virtual machine processes instructions and performs related calculations.

+ */ + RUN, + + /** + * Debug Mode: The virtual machine outputs debug information during execution. + *

This mode is used for debugging the virtual machine, allowing developers to view detailed information such as the execution state, local variables, and more.

+ */ + DEBUG, +} diff --git a/src/main/java/org/jcnc/snow/vm/engine/VMOpCode.java b/src/main/java/org/jcnc/snow/vm/engine/VMOpCode.java new file mode 100644 index 0000000..dad55af --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/engine/VMOpCode.java @@ -0,0 +1,1749 @@ +package org.jcnc.snow.vm.engine; + +import org.jcnc.snow.vm.commands.arithmetic.byte8.*; +import org.jcnc.snow.vm.commands.arithmetic.conversion.I2LCommand; +import org.jcnc.snow.vm.commands.arithmetic.double64.*; +import org.jcnc.snow.vm.commands.arithmetic.float32.*; +import org.jcnc.snow.vm.commands.arithmetic.int32.*; +import org.jcnc.snow.vm.commands.arithmetic.long64.*; +import org.jcnc.snow.vm.commands.arithmetic.short16.*; +import org.jcnc.snow.vm.commands.bitwise.int32.IAndCommand; +import org.jcnc.snow.vm.commands.bitwise.int32.IOrCommand; +import org.jcnc.snow.vm.commands.bitwise.int32.IXorCommand; +import org.jcnc.snow.vm.commands.bitwise.long64.LAndCommand; +import org.jcnc.snow.vm.commands.bitwise.long64.LOrCommand; +import org.jcnc.snow.vm.commands.bitwise.long64.LXorCommand; +import org.jcnc.snow.vm.commands.control.all.JumpCommand; +import org.jcnc.snow.vm.commands.control.int32.*; +import org.jcnc.snow.vm.commands.function.CallCommand; +import org.jcnc.snow.vm.commands.function.RetCommand; +import org.jcnc.snow.vm.commands.memory.all.MovCommand; +import org.jcnc.snow.vm.commands.memory.int32.ILoadCommand; +import org.jcnc.snow.vm.commands.stack.all.DupCommand; +import org.jcnc.snow.vm.commands.stack.all.PopCommand; +import org.jcnc.snow.vm.commands.stack.all.SwapCommand; +import org.jcnc.snow.vm.commands.stack.float32.FPushCommand; +import org.jcnc.snow.vm.commands.stack.int32.IPushCommand; +import org.jcnc.snow.vm.commands.vm.HaltCommand; +import org.jcnc.snow.vm.module.LocalVariableStore; + +/** + * VMOpCode defines the compact instruction set for the virtual machine, organized into logical categories. + *

Each opcode represents a specific operation executed by the virtual machine.

+ */ +public class VMOpCode { + // 1 Arithmetic Operations (1–80) + // 1.1 int32 (1-10) + /** + * I_ADD Opcode: Represents the int32 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the addition operation on these two int32s.
  4. + *
  5. Pushes the result of the addition back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic int32 addition tasks.

+ */ + public static final int I_ADD = 1; + /** + * I_SUB Opcode: Represents the int32 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack (the first value popped is the subtrahend, and the second value popped is the minuend).
  2. + *
  3. Performs the subtraction operation by subtracting the subtrahend from the minuend (i.e., minuend - subtrahend).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic int32 subtraction tasks.

+ */ + public static final int I_SUB = 2; + /** + * I_MUL Opcode: Represents the int32 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the multiplication operation on these two int32s (i.e., firstOperand * secondOperand).
  4. + *
  5. Pushes the result of the multiplication back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic int32 multiplication tasks.

+ */ + public static final int I_MUL = 3; + /** + * I_DIV Opcode: Represents the int32 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the division operation by dividing the dividend by the divisor (i.e., dividend / divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the division back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic int32 division tasks.

+ */ + public static final int I_DIV = 4; + /** + * I_MOD Opcode: Represents the int32 modulus (remainder) operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the modulus operation by calculating the remainder of the division of the dividend by the divisor (i.e., dividend % divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the modulus operation back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic int32 modulus (remainder) tasks.

+ */ + public static final int I_MOD = 5; + /** + * I_INC Opcode: Represents the int32 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Gets the current value of the local variable at the specified index from the local variable store.
  4. + *
  5. Increments the local variable's value by the specified increment (i.e., + * localVariables[index] += increment).
  6. + *
  7. Updates the local variable store with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, typically incremented by 1, unless control flow changes.
  10. + *
+ * + *

This opcode is particularly useful for optimizing scenarios where a local variable, such as a counter or loop index, is frequently incremented.

+ */ + public static final int I_INC = 6; + + /** + * I_NEG Opcode: Represents the int32 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top int32 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate an int32 value, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ + public static final int I_NEG = 7; + // 1.2 long64 (11-20) + /** + * L_ADD Opcode: Represents the long64 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the addition operation on these two long64s.
  4. + *
  5. Pushes the result of the addition back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic long64 addition tasks.

+ */ + public static final int L_ADD = 11; + + /** + * L_SUB Opcode: Represents the long64 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack (the first value popped is the subtrahend, and the second value popped is the minuend).
  2. + *
  3. Performs the subtraction operation by subtracting the subtrahend from the minuend (i.e., minuend - subtrahend).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic long64 subtraction tasks.

+ */ + public static final int L_SUB = 12; + + /** + * L_MUL Opcode: Represents the long64 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the multiplication operation on these two long64s (i.e., firstOperand * secondOperand).
  4. + *
  5. Pushes the result of the multiplication back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic long64 multiplication tasks.

+ */ + public static final int L_MUL = 13; + + /** + * L_DIV Opcode: Represents the long64 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the division operation by dividing the dividend by the divisor (i.e., dividend / divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the division back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic long64 division tasks.

+ */ + public static final int L_DIV = 14; + + /** + * L_MOD Opcode: Represents the long64 modulus (remainder) operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the modulus operation by calculating the remainder of the division of the dividend by the divisor (i.e., dividend % divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the modulus operation back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic long64 modulus (remainder) tasks.

+ */ + public static final int L_MOD = 15; + + /** + * L_INC Opcode: Represents the long64 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Gets the current value of the local variable at the specified index from the local variable store.
  4. + *
  5. Increments the local variable's value by the specified increment (i.e., + * localVariables[index] += increment).
  6. + *
  7. Updates the local variable store with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, typically incremented by 1, unless control flow changes.
  10. + *
+ * + *

This opcode is particularly useful for optimizing scenarios where a local `long64` variable, such as a counter or loop index, is frequently incremented.

+ */ + public static final int L_INC = 16; + + + /** + * L_NEG Opcode: Represents the long64 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top long64 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate a long64 value, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ + public static final int L_NEG = 17; + + // 1.3 short16 (21-30) + /** + * S_ADD Opcode: Represents the short16 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two short16 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the addition operation on these two short16 values.
  4. + *
  5. Pushes the result of the addition back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic short16 addition tasks.

+ */ + public static final int S_ADD = 21; + + /** + * S_SUB Opcode: Represents the short16 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two short16 values from the operand stack (the first value popped is the subtrahend, and the second value popped is the minuend).
  2. + *
  3. Performs the subtraction operation by subtracting the subtrahend from the minuend (i.e., minuend - subtrahend).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic short16 subtraction tasks.

+ */ + public static final int S_SUB = 22; + + /** + * S_MUL Opcode: Represents the short16 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two short16 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the multiplication operation on these two short16 values (i.e., firstOperand * secondOperand).
  4. + *
  5. Pushes the result of the multiplication back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic short16 multiplication tasks.

+ */ + public static final int S_MUL = 23; + + /** + * S_DIV Opcode: Represents the short16 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two short16 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the division operation by dividing the dividend by the divisor (i.e., dividend / divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the division back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic short16 division tasks.

+ */ + public static final int S_DIV = 24; + + /** + * S_MOD Opcode: Represents the short16 modulus (remainder) operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two short16 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the modulus operation by calculating the remainder of the division of the dividend by the divisor (i.e., dividend % divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the modulus operation back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic short16 modulus (remainder) tasks.

+ */ + public static final int S_MOD = 25; + + /** + * S_INC Opcode: Represents the short16 increment operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two values from the operand stack: the first value is the index of the short16 local variable to be incremented, + * and the second value is the increment value to be added to the local variable.
  2. + *
  3. Increments the value of the local variable at the given index by the specified increment value (i.e., + * localVariables[index] += increment).
  4. + *
  5. Does not affect the operand stack as the increment operation directly modifies the local variable's value.
  6. + *
  7. Executes quickly as the operation is an efficient increment of a local variable.
  8. + *
+ * + *

This opcode is useful for scenarios where a local variable needs to be incremented, such as counters within loops, + * or for optimizing the modification of variables in tight loops.

+ */ + public static final int S_INC = 26; + + /** + * S_NEG Opcode: Represents the short16 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top short16 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate a short16 value, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ + public static final int S_NEG = 27; + + // 1.4 byte8 (31-40) + /** + * B_ADD Opcode: Represents the byte8 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two byte8 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the addition operation on these two byte8 values.
  4. + *
  5. Pushes the result of the addition back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic byte8 addition tasks.

+ */ + public static final int B_ADD = 31; + + /** + * B_SUB Opcode: Represents the byte8 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two byte8 values from the operand stack (the first value popped is the subtrahend, and the second value popped is the minuend).
  2. + *
  3. Performs the subtraction operation by subtracting the subtrahend from the minuend (i.e., minuend - subtrahend).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic byte8 subtraction tasks.

+ */ + public static final int B_SUB = 32; + + /** + * B_MUL Opcode: Represents the byte8 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two byte8 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the multiplication operation on these two byte8 values (i.e., firstOperand * secondOperand).
  4. + *
  5. Pushes the result of the multiplication back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic byte8 multiplication tasks.

+ */ + public static final int B_MUL = 33; + + /** + * B_DIV Opcode: Represents the byte8 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two byte8 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the division operation by dividing the dividend by the divisor (i.e., dividend / divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the division back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic byte8 division tasks.

+ */ + public static final int B_DIV = 34; + + /** + * B_MOD Opcode: Represents the byte8 modulus (remainder) operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two byte8 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the modulus operation by calculating the remainder of the division of the dividend by the divisor (i.e., dividend % divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the modulus operation back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic byte8 modulus (remainder) tasks.

+ */ + public static final int B_MOD = 35; + + /** + * B_INC Opcode: Represents the byte8 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Gets the current value of the local variable at the specified index from the local variable store.
  4. + *
  5. Increments the local variable's value by the specified increment (i.e., + * localVariables[index] += increment).
  6. + *
  7. Updates the local variable store with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, typically incremented by 1, unless control flow changes.
  10. + *
+ * + *

This opcode is particularly useful for optimizing scenarios where a local `byte8` variable, such as a counter or loop index, is frequently incremented.

+ */ + public static final int B_INC = 36; + + + /** + * B_NEG Opcode: Represents the byte8 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top byte8 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate a byte8 value, making it a fundamental operation for arithmetic logic within the virtual machine.

+ */ + public static final int B_NEG = 37; + + // 1.5 double64 (41-50) + /** + * D_ADD Opcode: Represents the double64 precision floating-point addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two double64 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the double64 precision floating-point addition operation on these two operands.
  4. + *
  5. Pushes the result of the addition back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic double precision floating-point addition tasks.

+ */ + public static final int D_ADD = 41; + + /** + * D_SUB Opcode: Represents the double64 precision floating-point subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two double values from the operand stack (the first value popped is the subtrahend, and the second value popped is the minuend).
  2. + *
  3. Performs the double precision floating-point subtraction operation by subtracting the subtrahend from the minuend (i.e., minuend - subtrahend).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic double precision floating-point subtraction tasks.

+ */ + public static final int D_SUB = 42; + + /** + * D_MUL Opcode: Represents the double64 precision floating-point multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two double64 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the double64 precision floating-point multiplication operation on these two operands (i.e., firstOperand * secondOperand).
  4. + *
  5. Pushes the result of the multiplication back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic double64 precision floating-point multiplication tasks.

+ */ + public static final int D_MUL = 43; + + /** + * D_DIV Opcode: Represents the double64 precision floating-point division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two double64 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the double64 precision floating-point division operation by dividing the dividend by the divisor (i.e., dividend / divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the division back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic double64 precision floating-point division tasks.

+ */ + public static final int D_DIV = 44; + + /** + * D_MOD Opcode: Represents the double64 precision floating-point modulus (remainder) operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two double64 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the modulus operation by calculating the remainder of the division of the dividend by the divisor (i.e., dividend % divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the modulus operation back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic double64 precision floating-point modulus (remainder) tasks.

+ */ + public static final int D_MOD = 45; + + /** + * D_INC Opcode: Represents the double64 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Gets the current value of the local variable at the specified index from the local variable store.
  4. + *
  5. Increments the local variable's value by the specified increment (i.e., + * localVariables[index] += increment).
  6. + *
  7. Updates the local variable store with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, typically incremented by 1, unless control flow changes.
  10. + *
+ * + *

This opcode is particularly useful for optimizing scenarios where a local `double64` variable, such as a counter or loop index, is frequently incremented.

+ */ + public static final int D_INC = 46; + + /** + * D_NEG Opcode: Represents the double64 precision floating-point negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top double64 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate a double64 precision floating-point value, making it a fundamental operation for double64 precision arithmetic logic within the virtual machine.

+ */ + public static final int D_NEG = 47; + + // 1.6 float32 (51-60) + /** + * F_ADD Opcode: Represents the float32 addition operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two float32 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the float32 addition operation on these two operands.
  4. + *
  5. Pushes the result of the addition back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic float32 addition tasks.

+ */ + public static final int F_ADD = 51; + /** + * F_SUB Opcode: Represents the float32 subtraction operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two float32 values from the operand stack (the first value popped is the subtrahend, and the second value popped is the minuend).
  2. + *
  3. Performs the float32 subtraction operation by subtracting the subtrahend from the minuend (i.e., minuend - subtrahend).
  4. + *
  5. Pushes the result of the subtraction back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic float32 subtraction tasks.

+ */ + public static final int F_SUB = 52; + /** + * F_MUL Opcode: Represents the float32 multiplication operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two float32 values from the operand stack (the first value popped is the second operand, and the second value popped is the first operand).
  2. + *
  3. Performs the float32 multiplication operation on these two operands (i.e., firstOperand * secondOperand).
  4. + *
  5. Pushes the result of the multiplication back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic float32 multiplication tasks.

+ */ + public static final int F_MUL = 53; + /** + * F_DIV Opcode: Represents the float32 division operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two float32 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the float32 division operation by dividing the dividend by the divisor (i.e., dividend / divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the division back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic float32 division tasks.

+ */ + public static final int F_DIV = 54; + /** + * F_MOD Opcode: Represents the float32 modulus (remainder) operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two float32 values from the operand stack (the first value popped is the divisor, and the second value popped is the dividend).
  2. + *
  3. Performs the modulus operation by calculating the remainder of the division of the dividend by the divisor (i.e., dividend % divisor).
  4. + *
  5. Checks for division by zero and throws an {@link ArithmeticException} if the divisor is zero, as this operation is undefined.
  6. + *
  7. Pushes the result of the modulus operation back onto the operand stack for later instructions to use.
  8. + *
+ * + *

This opcode is a fundamental arithmetic operation within the virtual machine's instruction set, + * primarily used to handle basic float32 modulus (remainder) tasks.

+ */ + public static final int F_MOD = 55; + /** + * F_INC Opcode: Represents the float32 increment operation for a local variable in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index of the local variable and the increment value from the instruction parameters.
  2. + *
  3. Gets the current value of the local variable at the specified index from the local variable store.
  4. + *
  5. Increments the local variable's value by the specified increment (i.e., + * localVariables[index] += increment).
  6. + *
  7. Updates the local variable store with the new incremented value.
  8. + *
  9. Returns the updated program counter (PC) value, typically incremented by 1, unless control flow changes.
  10. + *
+ * + *

This opcode is particularly useful for optimizing scenarios where a local `float32` variable, such as a counter or loop index, is frequently incremented.

+ */ + public static final int F_INC = 56; + + /** + * F_NEG Opcode: Represents the float32 negation operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top float32 value from the operand stack.
  2. + *
  3. Performs the negation of the popped value (i.e., -value).
  4. + *
  5. Pushes the negated result back onto the operand stack for later instructions to use.
  6. + *
+ * + *

This opcode is typically used to negate a float32 value, making it a fundamental operation for float32 arithmetic logic within the virtual machine.

+ */ + public static final int F_NEG = 57; + + /** + * I2L Opcode: Represents the type conversion operation from int32 to long64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top int32 value from the operand stack.
  2. + *
  3. Convert the int32 value to a long64 value.
  4. + *
  5. Push the converted long64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is commonly used to widen an int32 value to a long64 type to accommodate larger numeric ranges.

+ */ + public static final int I2L = 61; + + /** + * I2S Opcode: Represents the type conversion operation from int32 to short16 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top int32 value from the operand stack.
  2. + *
  3. Convert the int32 value to a short16 value (this may involve truncation).
  4. + *
  5. Push the converted short16 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is typically used to narrow an int32 value to a short16 type when a smaller data representation is needed.

+ */ + public static final int I2S = 62; + + /** + * I2B Opcode: Represents the type conversion operation from int32 to byte8 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top int32 value from the operand stack.
  2. + *
  3. Convert the int32 value to a byte8 value (this may involve truncation).
  4. + *
  5. Push the converted byte8 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to narrow an int32 value to a byte8 type, suitable when a smaller numeric type is required.

+ */ + public static final int I2B = 63; + + /** + * I2D Opcode: Represents the type conversion operation from int32 to double64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top int32 value from the operand stack.
  2. + *
  3. Convert the int32 value to a double64 value.
  4. + *
  5. Push the converted double64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to widen an int32 value to a double64 type, providing high-precision floating-point calculations.

+ */ + public static final int I2D = 64; + + /** + * I2F Opcode: Represents the type conversion operation from int32 to float32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top int32 value from the operand stack.
  2. + *
  3. Convert the int32 value to a float32 value.
  4. + *
  5. Push the converted float32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to convert an int32 value to a float32 type when floating-point arithmetic is required.

+ */ + public static final int I2F = 65; + + /** + * L2I Opcode: Represents the type conversion operation from long64 to int32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top long64 value from the operand stack.
  2. + *
  3. Convert the long64 value to an int32 value (this may involve truncation).
  4. + *
  5. Push the converted int32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is typically used to narrow a long64 value to an int32 type for further integer operations.

+ */ + public static final int L2I = 66; + + /** + * L2D Opcode: Represents the type conversion operation from long64 to double64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top long64 value from the operand stack.
  2. + *
  3. Convert the long64 value to a double64 value.
  4. + *
  5. Push the converted double64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to widen a long64 value to a double64 type for high-precision floating-point computations.

+ */ + public static final int L2D = 67; + + /** + * L2F Opcode: Represents the type conversion operation from long64 to float32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top long64 value from the operand stack.
  2. + *
  3. Convert the long64 value to a float32 value.
  4. + *
  5. Push the converted float32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to convert a long64 value to a float32 type, typically for floating-point arithmetic involving long values.

+ */ + public static final int L2F = 68; + + /** + * F2I Opcode: Represents the type conversion operation from float32 to int32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top float32 value from the operand stack.
  2. + *
  3. Convert the float32 value to an int32 value (this may involve truncation).
  4. + *
  5. Push the converted int32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to convert a float32 value to an int32 type for further integer-based operations or comparisons.

+ */ + public static final int F2I = 69; + + /** + * F2L Opcode: Represents the type conversion operation from float32 to long64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top float32 value from the operand stack.
  2. + *
  3. Convert the float32 value to a long64 value.
  4. + *
  5. Push the converted long64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to widen a float32 value to a long64 type, which is useful when operations require a larger numeric range.

+ */ + public static final int F2L = 70; + + /** + * F2D Opcode: Represents the type conversion operation from float32 to double64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top float32 value from the operand stack.
  2. + *
  3. Convert the float32 value to a double64 value.
  4. + *
  5. Push the converted double64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to promote a float32 value to a double64 type, thereby increasing precision for floating-point computations.

+ */ + public static final int F2D = 71; + + /** + * D2I Opcode: Represents the type conversion operation from double64 to int32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top double64 value from the operand stack.
  2. + *
  3. Convert the double64 value to an int32 value (this may involve truncation).
  4. + *
  5. Push the converted int32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to narrow a double64 value to an int32 type for further integer-based processing.

+ */ + public static final int D2I = 72; + + /** + * D2L Opcode: Represents the type conversion operation from double64 to long64 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top double64 value from the operand stack.
  2. + *
  3. Convert the double64 value to a long64 value (this may involve truncation).
  4. + *
  5. Push the converted long64 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to narrow a double64 value to a long64 type, which can then be used for integer operations.

+ */ + public static final int D2L = 73; + + /** + * D2F Opcode: Represents the type conversion operation from double64 to float32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top double64 value from the operand stack.
  2. + *
  3. Convert the double64 value to a float32 value.
  4. + *
  5. Push the converted float32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to narrow a double64 value to a float32 type when lower precision floating-point arithmetic is acceptable.

+ */ + public static final int D2F = 74; + + /** + * S2I Opcode: Represents the type conversion operation from short16 to int32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top short16 value from the operand stack.
  2. + *
  3. Convert the short16 value to an int32 value.
  4. + *
  5. Push the converted int32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to widen a short16 value to an int32 type, facilitating subsequent integer arithmetic or comparison operations.

+ */ + public static final int S2I = 75; + + /** + * B2I Opcode: Represents the type conversion operation from byte8 to int32 in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pop the top byte8 value from the operand stack.
  2. + *
  3. Convert the byte8 value to an int32 value.
  4. + *
  5. Push the converted int32 value back onto the operand stack for subsequent operations.
  6. + *
+ * + *

This opcode is used to widen a byte8 value to an int32 type to ensure compatibility with integer-based operations.

+ */ + public static final int B2I = 76; + + + + // 2. Bitwise Operations (81–90) + // 2.1 int32 (81-85) + /** + * I_AND Opcode: Represents the int32 bitwise AND operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack. These values are treated as 32-bit binary representations.
  2. + *
  3. Performs the int32 bitwise AND operation on the two popped operands. The operation compares corresponding bits of both operands: + *
      + *
    • Each bit in the result is set to 1 only if the corresponding bits in both operands are also 1.
    • + *
    • If either of the corresponding bits is 0, the resulting bit is 0.
    • + *
    + *
  4. + *
  5. Pushes the result of the int32 bitwise AND operation back onto the operand stack for further processing.
  6. + *
+ * + *

This opcode is essential for low-level bit manipulation tasks.

+ */ + public static final int I_AND = 81; + /** + * I_OR Opcode: Represents the int32 bitwise OR operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack. These values are treated as 32-bit binary representations.
  2. + *
  3. Performs the int32 bitwise OR operation on the two popped operands. The operation compares corresponding bits of both operands: + *
      + *
    • Each bit in the result is set to 1 if at least one of the corresponding bits in either operand is 1.
    • + *
    • If both corresponding bits are 0, the resulting bit is 0.
    • + *
    + *
  4. + *
  5. Pushes the result of the int32 bitwise OR operation back onto the operand stack for further processing.
  6. + *
+ * + *

This opcode is essential for low-level bit manipulation tasks.

+ */ + public static final int I_OR = 82; + + /** + * I_XOR Opcode: Represents the int32 bitwise XOR operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two int32 values from the operand stack. These values are treated as 32-bit binary representations.
  2. + *
  3. Performs the int32 bitwise XOR (exclusive OR) operation on the two operands: + *
      + *
    • If the corresponding bits are different, the result is 1.
    • + *
    • If the corresponding bits are the same, the result is 0.
    • + *
    + *
  4. + *
  5. Pushes the result of the int32 bitwise XOR operation back onto the operand stack for further processing.
  6. + *
+ * + *

This opcode is essential for low-level bit manipulation tasks.

+ */ + public static final int I_XOR = 83; + + // 2.2 Long64 (86-90) + /** + * L_AND Opcode: Represents the long64 bitwise AND operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack. These values are treated as 32-bit binary representations.
  2. + *
  3. Performs the long64 bitwise AND operation on the two popped operands. The operation compares corresponding bits of both operands: + *
      + *
    • Each bit in the result is set to 1 only if the corresponding bits in both operands are also 1.
    • + *
    • If either of the corresponding bits is 0, the resulting bit is 0.
    • + *
    + *
  4. + *
  5. Pushes the result of the long64 bitwise AND operation back onto the operand stack for further processing.
  6. + *
+ * + *

This opcode is essential for low-level bit manipulation tasks.

+ */ + public static final int L_AND = 86; + /** + * L_OR Opcode: Represents the long64 bitwise OR operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack. These values are treated as 32-bit binary representations.
  2. + *
  3. Performs the long64 bitwise OR operation on the two popped operands. The operation compares corresponding bits of both operands: + *
      + *
    • Each bit in the result is set to 1 if at least one of the corresponding bits in either operand is 1.
    • + *
    • If both corresponding bits are 0, the resulting bit is 0.
    • + *
    + *
  4. + *
  5. Pushes the result of the long64 bitwise OR operation back onto the operand stack for further processing.
  6. + *
+ * + *

This opcode is essential for low-level bit manipulation tasks.

+ */ + public static final int L_OR = 87; + + /** + * L_XOR Opcode: Represents the long64 bitwise XOR operation in the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Pops the top two long64 values from the operand stack. These values are treated as 32-bit binary representations.
  2. + *
  3. Performs the long64 bitwise XOR (exclusive OR) operation on the two operands: + *
      + *
    • If the corresponding bits are different, the result is 1.
    • + *
    • If the corresponding bits are the same, the result is 0.
    • + *
    + *
  4. + *
  5. Pushes the result of the long64 bitwise XOR operation back onto the operand stack for further processing.
  6. + *
+ * + *

This opcode is essential for low-level bit manipulation tasks.

+ */ + public static final int L_XOR = 88; + + + // 3. Control Flow Operations (91–110) + /** + * JUMP Opcode: Represents an unconditional jump to a target instruction address. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the target instruction address from the instruction parameters.
  2. + *
  3. Validates the target address to ensure it is a non-negative int32.
  4. + *
  5. If the target address is valid (greater than or equal to 0), updates the program counter (PC) to the specified target address, + * effectively skipping all intermediate instructions.
  6. + *
  7. If the target address is invalid (less than 0), logs an error message and halts execution by returning an invalid value (typically -1).
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Control flow management in virtual machine execution.
  • + *
+ */ + public static final int JUMP = 91; + /** + * I_C_E Opcode: Represents a conditional jump based on int32 equality. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the target instruction address from the instruction parameters.
  2. + *
  3. Pops two int32 values from the operand stack.
  4. + *
  5. Compares the two int32s for equality.
  6. + *
  7. If the int32s are equal, updates the program counter (PC) to the specified target address, + * effectively jumping to the target instruction.
  8. + *
  9. If the int32s are not equal, increments the program counter to proceed with the next sequential instruction.
  10. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Conditional branching in virtual machine execution based on int32 comparison.
  • + *
  • Implementing control flow structures such as if-statements and loops.
  • + *
+ */ + public static final int I_C_E = 92; + /** + * I_C_NE Opcode: Represents a conditional jump based on int32 inequality. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the target instruction address from the instruction parameters.
  2. + *
  3. Pops two int32 values from the operand stack.
  4. + *
  5. Compares the two int32s for inequality.
  6. + *
  7. If the int32s are not equal, updates the program counter (PC) to the specified target address, + * effectively jumping to the target instruction.
  8. + *
  9. If the int32s are equal, increments the program counter to proceed with the next sequential instruction.
  10. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Conditional branching in virtual machine execution based on int32 comparison.
  • + *
  • Implementing control flow structures such as conditional loops and if-else statements.
  • + *
+ */ + public static final int I_C_NE = 93; + /** + * I_C_G Opcode: Represents a conditional jump based on int32 comparison (greater than). + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the target instruction address from the instruction parameters.
  2. + *
  3. Pops two int32 values from the operand stack.
  4. + *
  5. Compares the first int32 with the second to determine if it is greater.
  6. + *
  7. If the first int32 is greater than the second, updates the program counter (PC) to the specified target address, + * effectively jumping to the target instruction.
  8. + *
  9. If the first int32 is not greater than the second, increments the program counter to proceed with the next sequential instruction.
  10. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Conditional branching in virtual machine execution based on int32 comparison.
  • + *
  • Implementing control flow structures such as greater-than conditions in loops and conditional statements.
  • + *
+ */ + public static final int I_C_G = 94; + /** + * I_C_GE Opcode: Represents a conditional jump based on int32 comparison (greater than or equal to). + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the target instruction address from the instruction parameters.
  2. + *
  3. Pops two int32 values from the operand stack.
  4. + *
  5. Compares the first int32 with the second to determine if it is greater than or equal to the second int32.
  6. + *
  7. If the first int32 is greater than or equal to the second, updates the program counter (PC) to the specified target address, + * effectively jumping to the target instruction.
  8. + *
  9. If the first int32 is less than the second, increments the program counter to proceed with the next sequential instruction.
  10. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Conditional branching in virtual machine execution based on int32 comparison.
  • + *
  • Implementing control flow structures such as loops, conditional statements, and range checks.
  • + *
+ */ + public static final int I_C_GE = 95; + /** + * I_C_L Opcode: Represents a conditional jump based on int32 comparison (less than). + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the target instruction address from the instruction parameters.
  2. + *
  3. Pops two int32 values from the operand stack.
  4. + *
  5. Compares the first int32 with the second to determine if it is less than the second int32.
  6. + *
  7. If the first int32 is less than the second, updates the program counter (PC) to the specified target address, + * effectively jumping to the target instruction.
  8. + *
  9. If the first int32 is greater than or equal to the second, increments the program counter to proceed with the next sequential instruction.
  10. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Conditional branching in virtual machine execution based on int32 comparison.
  • + *
  • Implementing control flow structures such as loops, conditional statements, and range validations.
  • + *
+ */ + public static final int I_C_L = 96; + /** + * I_C_LE Opcode: Represents a conditional jump based on int32 comparison (less than or equal). + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the target instruction address from the instruction parameters.
  2. + *
  3. Pops two int32 values from the operand stack.
  4. + *
  5. Compares the first int32 with the second to determine if it is less than or equal to the second int32.
  6. + *
  7. If the first int32 is less than or equal to the second, updates the program counter (PC) to the specified target address, + * effectively jumping to the target instruction.
  8. + *
  9. If the first int32 is greater than the second, increments the program counter to proceed with the next sequential instruction.
  10. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Conditional branching in virtual machine execution based on int32 comparison.
  • + *
  • Implementing control flow structures such as loops, conditional statements, and boundary checks.
  • + *
+ */ + public static final int I_C_LE = 97; + + // 4. Stack Operations (111–150) + // 4.1 PUSH (111-120) + /** + * I_PUSH Opcode: Represents a stack operation that pushes an int32 value onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the int32 value from the instruction parameters.
  2. + *
  3. Pushes the parsed int32 value onto the operand stack.
  4. + *
  5. Increments the program counter (PC) to proceed with the next sequential instruction.
  6. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading constant values into the operand stack for later operations.
  • + *
  • Preparing operands for arithmetic, logical, or comparison instructions.
  • + *
  • Facilitating method calls or control flow by managing stack-based data.
  • + *
+ */ + public static final int I_PUSH = 111; + /** + * L_PUSH Opcode: Represents a stack operation that pushes a long64 value onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the long64 value from the instruction parameters.
  2. + *
  3. Pushes the parsed long64 value onto the operand stack.
  4. + *
  5. Increments the program counter (PC) to proceed with the next sequential instruction.
  6. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading constant values into the operand stack for later operations.
  • + *
  • Preparing operands for arithmetic, logical, or comparison instructions.
  • + *
  • Facilitating method calls or control flow by managing stack-based data.
  • + *
+ */ + public static final int L_PUSH = 112; + /** + * S_PUSH Opcode: Represents a stack operation that pushes an short16 value onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the short16 value from the instruction parameters.
  2. + *
  3. Pushes the parsed short16 value onto the operand stack.
  4. + *
  5. Increments the program counter (PC) to proceed with the next sequential instruction.
  6. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading constant values into the operand stack for later operations.
  • + *
  • Preparing operands for arithmetic, logical, or comparison instructions.
  • + *
  • Facilitating method calls or control flow by managing stack-based data.
  • + *
+ */ + public static final int S_PUSH = 113; + /** + * I_PUSH Opcode: Represents a stack operation that pushes a byte8 value onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the byte8 value from the instruction parameters.
  2. + *
  3. Pushes the parsed byte8 value onto the operand stack.
  4. + *
  5. Increments the program counter (PC) to proceed with the next sequential instruction.
  6. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading constant values into the operand stack for later operations.
  • + *
  • Preparing operands for arithmetic, logical, or comparison instructions.
  • + *
  • Facilitating method calls or control flow by managing stack-based data.
  • + *
+ */ + public static final int B_PUSH = 114; + /** + * I_PUSH Opcode: Represents a stack operation that pushes an double64 value onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the double64 value from the instruction parameters.
  2. + *
  3. Pushes the parsed double64 value onto the operand stack.
  4. + *
  5. Increments the program counter (PC) to proceed with the next sequential instruction.
  6. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading constant values into the operand stack for later operations.
  • + *
  • Preparing operands for arithmetic, logical, or comparison instructions.
  • + *
  • Facilitating method calls or control flow by managing stack-based data.
  • + *
+ */ + public static final int D_PUSH = 115; + /** + * F_PUSH Opcode: Represents a stack operation that pushes a float32 value onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the float32 value from the instruction parameters.
  2. + *
  3. Pushes the parsed float32 value onto the operand stack.
  4. + *
  5. Increments the program counter (PC) to proceed with the next sequential instruction.
  6. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading constant values into the operand stack for later operations.
  • + *
  • Preparing operands for arithmetic, logical, or comparison instructions.
  • + *
  • Facilitating method calls or control flow by managing stack-based data.
  • + *
+ */ + public static final int F_PUSH = 116; + /** + * I_POP Opcode: Represents a stack operation that removes the top element from the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Removes (pops) the top element from the operand stack.
  2. + *
  3. Discards the popped value, as it is not stored or used further.
  4. + *
  5. Increments the program counter (PC) to proceed with the next sequential instruction.
  6. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Clearing temporary or unnecessary data from the operand stack.
  • + *
  • Managing stack cleanup after operations that leave excess data.
  • + *
  • Ensuring stack balance during function calls or control flow transitions.
  • + *
+ */ + // 4.2 POP (121-125) + public static final int POP = 121; + /** + * DUP Opcode: Represents a stack operation that duplicates the top element of the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the top element from the operand stack.
  2. + *
  3. Duplicates the top value and pushes it back onto the stack.
  4. + *
  5. Increments the program counter (PC) to proceed with the next sequential instruction.
  6. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Preserving the top element of the operand stack for later use in later operations.
  • + *
  • Duplicating values that are needed multiple times in the execution flow.
  • + *
  • Managing stack balance when performing operations that require repeated access to the same data.
  • + *
+ */ + // 4.3 DUP (126-130) + public static final int DUP = 126; + /** + * SWAP Opcode: Represents a stack operation that swaps the top two values of the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Ensures that there are at least two elements on the operand stack.
  2. + *
  3. Pops the two topmost values from the stack.
  4. + *
  5. Pushes the two values back onto the stack in reversed order.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Reversing the order of the top two elements on the stack, which may be required in certain algorithms or operations.
  • + *
  • Handling data rearrangements that require immediate swapping of operands during execution.
  • + *
  • Ensuring proper operand placement for later instructions that depend on the order of stack elements.
  • + *
+ */ + // 4.4 SWAP (131-135) + public static final int SWAP = 131; + + // 5. Memory Operations (151–) + /** + * I_STORE Opcode: Represents a load operation that retrieves an int32 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for later operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for later instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int I_STORE = 151; + /** + * L_STORE Opcode: Represents a load operation that retrieves a long64 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for later operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for later instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int L_STORE = 152; + + /** + * S_LOAD Opcode: Represents a load operation that retrieves a short16 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for later operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for later instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int S_STORE = 153; + + /** + * B_STORE Opcode: Represents a load operation that retrieves a byte8 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for later operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for later instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int B_STORE = 154; + + /** + * D_STORE Opcode: Represents a load operation that retrieves a double64 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for later operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for later instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int D_STORE = 155; + + /** + * F_STORE Opcode: Represents a load operation that retrieves a float32 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for later operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for later instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int F_STORE = 156; + + + /** + * I_LOAD Opcode: Represents a load operation that retrieves an int32 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for subsequent operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for subsequent instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int I_LOAD = 161; + /** + * L_LOAD Opcode: Represents a load operation that retrieves a long64 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for subsequent operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for subsequent instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int L_LOAD = 162; + /** + * S_LOAD Opcode: Represents a load operation that retrieves a short16 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for subsequent operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for subsequent instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int S_LOAD = 163; + /** + * B_LOAD Opcode: Represents a load operation that retrieves a byte8 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for subsequent operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for subsequent instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int B_LOAD = 164; + /** + * D_LOAD Opcode: Represents a load operation that retrieves a double64 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for subsequent operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for subsequent instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int D_LOAD = 165; + /** + * F_LOAD Opcode: Represents a load operation that retrieves a float32 value from the local variable store and pushes it onto the operand stack. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Retrieves the index for the local variable from the instruction parameters.
  2. + *
  3. Retrieves the corresponding value from the local variable store of the current method frame.
  4. + *
  5. Pushes the retrieved value onto the operand stack for subsequent operations.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Loading local variables onto the operand stack for further operations or computations.
  • + *
  • Retrieving stored values that are needed for subsequent instructions, such as arithmetic or logic operations.
  • + *
  • Preserving the necessary method-local state by pushing relevant values from the local variable store to the operand stack.
  • + *
+ */ + public static final int F_LOAD = 166; + + /** + * MOV Opcode: Represents a move operation that transfers a value from one local variable to another within the local variable store. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Parses the source and destination indices from the instruction parameters.
  2. + *
  3. Retrieves the value from the local variable store at the source index.
  4. + *
  5. Stores the retrieved value into the destination index of the local variable store.
  6. + *
  7. Increments the program counter (PC) to proceed with the next sequential instruction.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Transferring values between local variables within a method frame.
  • + *
  • Preserving computed results by moving them to designated local variable slots.
  • + *
  • Facilitating intermediate storage of values needed for later computations.
  • + *
+ */ + public static final int MOV = 171; + /** + * CALL Opcode: Represents a function or subroutine call operation that transfers control to a specified function address. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Validates and extracts the target function address from the instruction parameters.
  2. + *
  3. Creates a new stack frame containing the return address (current PC + 1), the local variable store, and the method context.
  4. + *
  5. Pushes the newly created stack frame onto the call stack to manage the function invocation hierarchy.
  6. + *
  7. Updates the program counter (PC) to the target function address, effectively transferring control to the function.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Invoking functions or subroutines within the virtual machine's execution flow.
  • + *
  • Managing method invocations by maintaining a call stack with return addresses and local variable contexts.
  • + *
  • Facilitating modular and reusable code execution by enabling jumps to specific function addresses.
  • + *
+ */ + public static final int CALL = 201; + /** + * RET Opcode: Represents a return operation that transfers control back to the calling method by restoring the saved return address. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Validates that the call stack is not empty to ensure there is a method to return to.
  2. + *
  3. Clears the local variables of the current method using {@link LocalVariableStore#clearVariables()}.
  4. + *
  5. Pops the current stack frame from the call stack to retrieve the saved return address.
  6. + *
  7. Restores the program counter (PC) to the return address, allowing execution to continue from the calling method.
  8. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Returning from a function or method to the caller in the virtual machine's execution flow.
  • + *
  • Restoring the program's control flow by using the return address saved during the function call.
  • + *
  • Cleaning up the local variables of the completed method to maintain memory consistency.
  • + *
+ */ + public static final int RET = 202; + /** + * HALT Opcode: Represents a termination operation that stops the execution of the virtual machine. + *

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

+ * + *

Execution Steps:

+ *
    + *
  1. Outputs the message "Process has ended" to indicate that the program execution has been terminated.
  2. + *
  3. Returns -1 as a signal to the virtual machine to halt execution, preventing any further instructions from being processed.
  4. + *
+ * + *

This opcode is commonly used for:

+ *
    + *
  • Terminating program execution explicitly when the program has completed its intended operations.
  • + *
  • Serving as the final instruction in a program to indicate normal completion.
  • + *
+ */ + public static final int HALT = 255; + + + // VI. Function Operations (50–59) + + /** + * Default constructor for creating an instance of VMOpCode. + * This constructor is empty as no specific initialization is required. + */ + public VMOpCode() { + // Empty constructor + } +} diff --git a/src/main/java/org/jcnc/snow/vm/engine/VirtualMachineEngine.java b/src/main/java/org/jcnc/snow/vm/engine/VirtualMachineEngine.java new file mode 100644 index 0000000..5673fde --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/engine/VirtualMachineEngine.java @@ -0,0 +1,174 @@ +package org.jcnc.snow.vm.engine; + +import org.jcnc.snow.vm.execution.CommandExecutionHandler; +import org.jcnc.snow.vm.module.*; + +import java.util.List; + +/** + * Virtual Machine Engine ({@code VirtualMachineEngine}) + *

+ * This class implements a virtual machine capable of parsing and executing a sequence of commands. + * The execution is controlled by a program counter (PC), which fetches and processes one instruction at a time + * from the provided command list. The virtual machine manages its internal state using core components + * such as the operand stack, local variable store, and call stack. + *

+ * + *

Core Components

+ *
    + *
  • Operand Stack: Manages intermediate values during execution, used for arithmetic operations, data manipulation, etc. {@link OperandStack}
  • + *
  • Local Variable Store: Maintains local variables for functions or methods, enabling scoped data handling. {@link LocalVariableStore}
  • + *
  • Call Stack: Tracks active function calls, supporting nested invocations and proper return address management. {@link CallStack}
  • + *
  • Command Handler: Delegates command execution to appropriate instruction implementations. {@link CommandExecutionHandler}
  • + *
+ * + *

+ * Each command is processed by the {@link CommandExecutionHandler}, which determines the appropriate operation + * based on the opcode and maintains the program counter to control program flow. + *

+ */ +public class VirtualMachineEngine { + private final OperandStack operandStack; + private final LocalVariableStore localVariableStore; + private final CallStack callStack; + private final CommandExecutionHandler commandExecutionHandler; + private int programCounter; + + /** + * Constructs and initializes the virtual machine engine. + *

+ * This constructor sets up the core components of the virtual machine, including the operand stack, + * call stack, local variable store, and command handler. The program counter is initialized to zero, + * indicating that execution will start from the first instruction. + *

+ * + * @param vmMode The operating mode of the virtual machine, which may affect local variable storage behavior. + */ + public VirtualMachineEngine(VMMode vmMode) { + this.operandStack = new OperandStack(); + this.callStack = new CallStack(); + this.localVariableStore = new LocalVariableStore(vmMode); + this.commandExecutionHandler = new CommandExecutionHandler(operandStack, localVariableStore, callStack); + this.programCounter = 0; + } + + CallStack getCallStack() { + return callStack; + } + + /** + * Executes a list of commands in sequence. + *

+ * This method processes each command from the provided list until either all commands are executed + * or a termination condition (such as a halt command) is met. The method relies on the + * {@link CommandExecutionHandler} to interpret and execute each instruction. + *

+ * + *

Error Handling: If an invalid command format or execution error occurs, an error message + * is printed, and the virtual machine halts execution to prevent undefined behavior.

+ * + * @param command The list of commands, where each command is formatted as "opcode operand1 operand2 ...". + * @throws IllegalArgumentException If the command list is empty or contains invalid instructions. + */ + public void execute(List command) { + + if (command == null || command.isEmpty()) { + throw new IllegalArgumentException("The command list cannot be empty or null."); + } + + ensureRootFrame(); // ← 新增 + + if (command == null || command.isEmpty()) { + throw new IllegalArgumentException("The command list cannot be empty or null."); + } + + while (programCounter >= 0 && programCounter < command.size()) { + String instruction = command.get(programCounter); + String[] parts = instruction.trim().split(" "); + + if (parts.length < 1) { + System.err.println("Invalid command format at " + programCounter + " -> Missing opcode"); + break; + } + + try { + int opCode = parseOpCode(parts[0]); + int nextPC = commandExecutionHandler.handle(opCode, parts, programCounter); + + if (nextPC == -1) break; // Halt condition + + programCounter = nextPC; + } catch (IllegalArgumentException e) { + System.err.println("Command error at " + programCounter + " -> " + e.getMessage()); + break; + } + } + } + + /** 若 callStack 为空,则构造一个根栈帧并预置空局部变量槽 */ + private void ensureRootFrame() { + if (!callStack.isEmpty()) return; + + LocalVariableStore lvs = this.localVariableStore; // 仍复用现有对象 + + /* ---------- 预分配 32 个空位 ---------- */ + for (int i = 0; i < 32; i++) { + lvs.setVariable(i, 0); // setVariable() 会自动扩容,先填 0 占位 + } + + MethodContext mc = new MethodContext("root", null); + StackFrame sf = new StackFrame(0, lvs, mc); + callStack.pushFrame(sf); + } + + + + /** + * Prints the current state of the operand stack and the call stack. + *

+ * This method provides a comprehensive snapshot of the virtual machine's execution state by invoking: + *

    + *
  • {@link OperandStack#printOperandStack()} - Displays the current elements in the operand stack, + * which holds intermediate values used during instruction execution, such as computation results, + * operands for upcoming operations, and temporary data.
  • + *
  • {@link CallStack#printCallStack()} - Displays the current function call hierarchy, + * including active stack frames, return addresses, local variables, and method contexts. + * This helps track the flow of nested function calls and identify the current execution context.
  • + *
+ */ + public void printStack() { + operandStack.printOperandStack(); + callStack.printCallStack(); + } + + + /** + * Prints the current state of the local variable store. + *

+ * This method invokes {@link LocalVariableStore#printLv()} to display all active local variables, + * which can be useful for debugging or inspecting the state of function calls. + *

+ */ + public void printLocalVariables() { + localVariableStore.printLv(); + } + + /** + * Parses the opcode from a string representation. + *

+ * This method converts the opcode string into an integer value. If the conversion fails, + * an {@link IllegalArgumentException} is thrown, indicating an invalid opcode format. + *

+ * + * @param opCodeStr The string representation of the opcode. + * @return The integer value of the opcode. + * @throws IllegalArgumentException If the opcode format is invalid or cannot be parsed. + */ + private int parseOpCode(String opCodeStr) { + try { + return Integer.parseInt(opCodeStr); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Invalid opcode -> " + opCodeStr, e); + } + } +} diff --git a/src/main/java/org/jcnc/snow/vm/execution/CommandExecutionHandler.java b/src/main/java/org/jcnc/snow/vm/execution/CommandExecutionHandler.java new file mode 100644 index 0000000..2667a87 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/execution/CommandExecutionHandler.java @@ -0,0 +1,63 @@ +package org.jcnc.snow.vm.execution; + + +import org.jcnc.snow.vm.factories.CommandFactory; +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; + +/** + * Command Execution Handler (CommandExecutionHandler) + *

+ * This class is responsible for invoking the appropriate command object based on the opcode + * and executing the command logic. It retrieves specific command instances through the {@link CommandFactory}, + * and calls the {@code execute} method of the command to handle the virtual machine's instruction execution process. + *

+ */ +public class CommandExecutionHandler { + private final OperandStack operandStack; + private final LocalVariableStore localVariableStore; + private final CallStack callStack; + + /** + * Constructor to initialize the command execution handler. + * + * @param operandStack The stack manager used to manage the virtual machine's stack data. + * @param localVariableStore The local variable table used to store the local variables used during instruction execution. + * @param callStack The call stack used to manage the method invocation hierarchy during execution. + */ + public CommandExecutionHandler(OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) { + this.operandStack = operandStack; + this.localVariableStore = localVariableStore; + this.callStack = callStack; + } + + /** + * Handles the given instruction operation. + *

+ * This method retrieves the corresponding command instance based on the passed opcode + * and executes it. If the command is invalid or an error occurs during execution, + * an error message is printed, and -1 is returned to indicate that the program should terminate or an error occurred. + *

+ * + * @param opCode The opcode representing the type of instruction to execute (e.g., PUSH, POP, ADD, etc.). + * @param parts The array of parameters for the instruction, for example, `10` in `PUSH 10` is the parameter. + * @param currentPC The current Program Counter (PC) indicating the current instruction's position. + * @return The address of the next instruction to execute. A return value of -1 indicates termination or an error. + * @throws IllegalArgumentException If the opcode is invalid, this exception will be thrown. + */ + public int handle(int opCode, String[] parts, int currentPC) { + try { + // Use CommandFactory to retrieve the specific command instance + Command command = CommandFactory.getInstruction(opCode).orElseThrow(() -> new IllegalArgumentException("Unknown instruction: " + opCode)); + + // Execute the command and return the address of the next instruction + return command.execute(parts, currentPC, operandStack, localVariableStore, callStack); + } catch (Exception e) { + // If an error occurs during execution, print the error message and return -1 to terminate + System.err.println("Command execution error (PC=" + currentPC + ") -> " + e.getMessage()); + return -1; + } + } +} diff --git a/src/main/java/org/jcnc/snow/vm/execution/CommandLoader.java b/src/main/java/org/jcnc/snow/vm/execution/CommandLoader.java new file mode 100644 index 0000000..70d6c9b --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/execution/CommandLoader.java @@ -0,0 +1,49 @@ +package org.jcnc.snow.vm.execution; + + + +import org.jcnc.snow.vm.utils.LoggingUtils; +import org.jcnc.snow.vm.io.FileIOUtils; + +import java.util.List; + +/** + * Command Loader (CommandLoader) + *

+ * This class is used to load instructions from a specified file path. It reads instruction data from the file + * using {@link FileIOUtils}, and returns a list of instructions. If the file reading fails or the instruction list is empty, + * an error log will be recorded using {@link LoggingUtils}. + *

+ */ +public class CommandLoader { + /** + * Default constructor for creating an instance of CommandLoader. + * This constructor is empty as no specific initialization is required. + */ + public CommandLoader() { + // Empty constructor + } + + /** + * Loads instructions from a file. + *

+ * This method loads instructions from the given file path and returns them as a list. If the instruction reading fails or the list is empty, + * an error log will be recorded and an empty instruction list will be returned. + *

+ * + * @param filePath The file path pointing to the file containing the instructions. + * @return A list of instructions. If reading fails, an empty list will be returned. + */ + public static List loadInstructions(String filePath) { + // Read instructions from the file + List instructions = FileIOUtils.readInstructionsFromFile(filePath); + + // If the instruction list is empty, log an error message + if (instructions.isEmpty()) { + LoggingUtils.logError("Failed to read instructions or the instruction list is empty"); + } + + // Return the instruction list + return instructions; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/factories/CommandFactory.java b/src/main/java/org/jcnc/snow/vm/factories/CommandFactory.java new file mode 100644 index 0000000..0bc47b8 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/factories/CommandFactory.java @@ -0,0 +1,222 @@ +package org.jcnc.snow.vm.factories; + +import org.jcnc.snow.vm.commands.arithmetic.conversion.*; +import org.jcnc.snow.vm.interfaces.Command; +import org.jcnc.snow.vm.commands.arithmetic.byte8.*; +import org.jcnc.snow.vm.commands.arithmetic.double64.*; +import org.jcnc.snow.vm.commands.arithmetic.float32.*; +import org.jcnc.snow.vm.commands.arithmetic.int32.*; +import org.jcnc.snow.vm.commands.arithmetic.long64.*; +import org.jcnc.snow.vm.commands.arithmetic.short16.*; +import org.jcnc.snow.vm.commands.bitwise.int32.IAndCommand; +import org.jcnc.snow.vm.commands.bitwise.int32.IOrCommand; +import org.jcnc.snow.vm.commands.bitwise.int32.IXorCommand; +import org.jcnc.snow.vm.commands.bitwise.long64.LAndCommand; +import org.jcnc.snow.vm.commands.bitwise.long64.LOrCommand; +import org.jcnc.snow.vm.commands.bitwise.long64.LXorCommand; +import org.jcnc.snow.vm.commands.control.all.JumpCommand; +import org.jcnc.snow.vm.commands.control.int32.*; +import org.jcnc.snow.vm.commands.function.CallCommand; +import org.jcnc.snow.vm.commands.function.RetCommand; +import org.jcnc.snow.vm.commands.memory.all.MovCommand; +import org.jcnc.snow.vm.commands.memory.byte8.BLoadCommand; +import org.jcnc.snow.vm.commands.memory.byte8.BStoreCommand; +import org.jcnc.snow.vm.commands.memory.double64.DLoadCommand; +import org.jcnc.snow.vm.commands.memory.double64.DStoreCommand; +import org.jcnc.snow.vm.commands.memory.float32.FLoadCommand; +import org.jcnc.snow.vm.commands.memory.float32.FStoreCommand; +import org.jcnc.snow.vm.commands.memory.int32.ILoadCommand; +import org.jcnc.snow.vm.commands.memory.int32.IStoreCommand; +import org.jcnc.snow.vm.commands.memory.long64.LLoadCommand; +import org.jcnc.snow.vm.commands.memory.long64.LStoreCommand; +import org.jcnc.snow.vm.commands.memory.short16.SLoadCommand; +import org.jcnc.snow.vm.commands.memory.short16.SStoreCommand; +import org.jcnc.snow.vm.commands.stack.all.DupCommand; +import org.jcnc.snow.vm.commands.stack.all.PopCommand; +import org.jcnc.snow.vm.commands.stack.all.SwapCommand; +import org.jcnc.snow.vm.commands.stack.byte8.BPushCommand; +import org.jcnc.snow.vm.commands.stack.double64.DPushCommand; +import org.jcnc.snow.vm.commands.stack.float32.FPushCommand; +import org.jcnc.snow.vm.commands.stack.int32.IPushCommand; +import org.jcnc.snow.vm.commands.stack.long64.LPushCommand; +import org.jcnc.snow.vm.commands.stack.short16.SPushCommand; +import org.jcnc.snow.vm.commands.vm.HaltCommand; +import org.jcnc.snow.vm.engine.VMOpCode; + +import java.util.Optional; + +/** + * The CommandFactory class is responsible + * for getting the corresponding instruction instance based on the operation code. + *

This class uses an array for fast, constant-time access to corresponding command instances.

+ */ +public class CommandFactory { + private static final Command[] COMMANDS = new Command[1000]; // Adjust, according to your VMOpCode range + + static { + // Initialize the array with corresponding commands based on opCode values + + // 1 Arithmetic Operations (1–80) + // 1.1 int32 (1-10) + COMMANDS[VMOpCode.I_ADD] = new IAddCommand(); // 1 + COMMANDS[VMOpCode.I_SUB] = new ISubCommand(); // 2 + COMMANDS[VMOpCode.I_MUL] = new IMulCommand(); // 3 + COMMANDS[VMOpCode.I_DIV] = new IDivCommand(); // 4 + COMMANDS[VMOpCode.I_MOD] = new IModCommand(); // 5 + COMMANDS[VMOpCode.I_INC] = new IIncCommand(); // 6 + COMMANDS[VMOpCode.I_NEG] = new INegCommand(); // 7 + // 1.2 long64 (11-20) + COMMANDS[VMOpCode.L_ADD] = new LAddCommand(); // 11 + COMMANDS[VMOpCode.L_SUB] = new LSubCommand(); // 12 + COMMANDS[VMOpCode.L_MUL] = new LMulCommand(); // 13 + COMMANDS[VMOpCode.L_DIV] = new LDivCommand(); // 14 + COMMANDS[VMOpCode.L_MOD] = new LModCommand(); // 15 + COMMANDS[VMOpCode.L_INC] = new LIncCommand(); // 16 + COMMANDS[VMOpCode.L_NEG] = new LNegCommand(); // 17 + // 1.3 short16 (21-30) + COMMANDS[VMOpCode.S_ADD] = new SAddCommand(); // 21 + COMMANDS[VMOpCode.S_SUB] = new SSubCommand(); // 22 + COMMANDS[VMOpCode.S_MUL] = new SMulCommand(); // 23 + COMMANDS[VMOpCode.S_DIV] = new SDivCommand(); // 24 + COMMANDS[VMOpCode.S_MOD] = new SModCommand(); // 25 + COMMANDS[VMOpCode.S_INC] = new SIncCommand(); // 26 + COMMANDS[VMOpCode.S_NEG] = new SNegCommand(); // 27 + // 1.4 byte8 (31-40) + COMMANDS[VMOpCode.B_ADD] = new BAddCommand(); // 31 + COMMANDS[VMOpCode.B_SUB] = new BSubCommand(); // 32 + COMMANDS[VMOpCode.B_MUL] = new BMulCommand(); // 33 + COMMANDS[VMOpCode.B_DIV] = new BDivCommand(); // 34 + COMMANDS[VMOpCode.B_MOD] = new BModCommand(); // 35 + COMMANDS[VMOpCode.B_INC] = new BIncCommand(); // 36 + COMMANDS[VMOpCode.B_NEG] = new BNegCommand(); // 37 + // 1.5 double64 (41-50) + COMMANDS[VMOpCode.D_ADD] = new DAddCommand(); // 41 + COMMANDS[VMOpCode.D_SUB] = new DSubCommand(); // 42 + COMMANDS[VMOpCode.D_MUL] = new DMulCommand(); // 43 + COMMANDS[VMOpCode.D_DIV] = new DDivCommand(); // 44 + COMMANDS[VMOpCode.D_MOD] = new DModCommand(); // 45 + COMMANDS[VMOpCode.D_INC] = new DIncCommand(); // 46 + COMMANDS[VMOpCode.D_NEG] = new DNegCommand(); // 47 + // 1.6 float32 (51-60) + COMMANDS[VMOpCode.F_ADD] = new FAddCommand(); // 51 + COMMANDS[VMOpCode.F_SUB] = new FSubCommand(); // 52 + COMMANDS[VMOpCode.F_MUL] = new FMulCommand(); // 53 + COMMANDS[VMOpCode.F_DIV] = new FDivCommand(); // 54 + COMMANDS[VMOpCode.F_MOD] = new FModCommand(); // 55 + COMMANDS[VMOpCode.F_INC] = new FIncCommand(); // 56 + COMMANDS[VMOpCode.F_NEG] = new FNegCommand(); // 57 + + // 1.7 Type Conversion (61-80) + COMMANDS[VMOpCode.I2L] = new I2LCommand(); // 61 int -> long + COMMANDS[VMOpCode.I2S] = new I2SCommand(); // 62 int -> short + COMMANDS[VMOpCode.I2B] = new I2BCommand(); // 63 int -> byte + COMMANDS[VMOpCode.I2D] = new I2DCommand(); // 64 int -> double + COMMANDS[VMOpCode.I2F] = new I2FCommand(); // 65 int -> float + + COMMANDS[VMOpCode.L2I] = new L2ICommand(); // 66 long -> int + COMMANDS[VMOpCode.L2D] = new L2DCommand(); // 67 long -> double + COMMANDS[VMOpCode.L2F] = new L2FCommand(); // 68 long -> float + + COMMANDS[VMOpCode.F2I] = new F2ICommand(); // 69 float -> int + COMMANDS[VMOpCode.F2L] = new F2LCommand(); // 70 float -> long + COMMANDS[VMOpCode.F2D] = new F2DCommand(); // 71 float -> double + + COMMANDS[VMOpCode.D2I] = new D2ICommand(); // 72 double -> int + COMMANDS[VMOpCode.D2L] = new D2LCommand(); // 73 double -> long + COMMANDS[VMOpCode.D2F] = new D2FCommand(); // 74 double -> float + + COMMANDS[VMOpCode.S2I] = new S2ICommand(); // 75 short -> int + + COMMANDS[VMOpCode.B2I] = new B2ICommand(); // 76 byte -> int + + // 1.8 Other (77-80) + + // 2. Bitwise Operations (81–90) + // 2.1 int32 (81-85) + COMMANDS[VMOpCode.I_AND] = new IAndCommand(); // 81 + COMMANDS[VMOpCode.I_OR] = new IOrCommand(); // 82 + COMMANDS[VMOpCode.I_XOR] = new IXorCommand(); // 83 + // 2.2 Long64 (86-90) + COMMANDS[VMOpCode.L_AND] = new LAndCommand(); // 86 + COMMANDS[VMOpCode.L_OR] = new LOrCommand(); // 87 + COMMANDS[VMOpCode.L_XOR] = new LXorCommand(); // 88 + + // 3. Control Flow Operations (91–110) + COMMANDS[VMOpCode.JUMP] = new JumpCommand(); // 91 + COMMANDS[VMOpCode.I_C_E] = new ICECommand(); // 92 + COMMANDS[VMOpCode.I_C_NE] = new ICNECommand(); // 93 + COMMANDS[VMOpCode.I_C_G] = new ICGCommand(); // 94 + COMMANDS[VMOpCode.I_C_GE] = new ICGECommand(); // 95 + COMMANDS[VMOpCode.I_C_L] = new ICLCommand(); // 96 + COMMANDS[VMOpCode.I_C_LE] = new ICLECommand(); // 97 + + // 4. Stack Operations (111–150) + // 4.1 PUSH (111-120) + COMMANDS[VMOpCode.I_PUSH] = new IPushCommand(); // 111 + COMMANDS[VMOpCode.L_PUSH] = new LPushCommand(); // 112 + COMMANDS[VMOpCode.S_PUSH] = new SPushCommand(); // 113 + COMMANDS[VMOpCode.B_PUSH] = new BPushCommand(); // 114 + COMMANDS[VMOpCode.D_PUSH] = new DPushCommand(); // 115 + COMMANDS[VMOpCode.F_PUSH] = new FPushCommand(); // 116 + // 4.2 POP (121-125) + COMMANDS[VMOpCode.POP] = new PopCommand(); // 121 + // 4.3 DUP (126-130) + COMMANDS[VMOpCode.DUP] = new DupCommand(); // 126 + // 4.4 SWAP (131-135) + COMMANDS[VMOpCode.SWAP] = new SwapCommand(); // 131 + + // 4.5 Other (136-150) + + // 5. Memory Operations (151–200) + // 5.1 STORE (151-160) + COMMANDS[VMOpCode.I_STORE] = new IStoreCommand(); // 151 + COMMANDS[VMOpCode.L_STORE] = new LStoreCommand(); // 152 + COMMANDS[VMOpCode.S_STORE] = new SStoreCommand(); // 153 + COMMANDS[VMOpCode.B_STORE] = new BStoreCommand(); // 154 + COMMANDS[VMOpCode.D_STORE] = new DStoreCommand(); // 155 + COMMANDS[VMOpCode.F_STORE] = new FStoreCommand(); // 156 + // 5.2 LOAD (161-170) + COMMANDS[VMOpCode.I_LOAD] = new ILoadCommand(); // 161 + COMMANDS[VMOpCode.L_LOAD] = new LLoadCommand(); // 162 + COMMANDS[VMOpCode.S_LOAD] = new SLoadCommand(); // 163 + COMMANDS[VMOpCode.B_LOAD] = new BLoadCommand(); // 164 + COMMANDS[VMOpCode.D_LOAD] = new DLoadCommand(); // 165 + COMMANDS[VMOpCode.F_LOAD] = new FLoadCommand(); // 166 + + // 5.3 MOV (171-176) + COMMANDS[VMOpCode.MOV] = new MovCommand(); // 171 + + // 5.4 Other (176-200) + + // 6. Function Operations (201–205) + COMMANDS[VMOpCode.CALL] = new CallCommand(); // 201 + COMMANDS[VMOpCode.RET] = new RetCommand(); // 202 + + // 7. Virtual Machine Operations(241-255) + COMMANDS[VMOpCode.HALT] = new HaltCommand(); // 255 + } + + /** + * Default constructor for creating an instance of CommandFactory. + * This constructor is empty as no specific initialization is required. + */ + public CommandFactory() { + // Empty constructor + } + + /** + * Retrieves the corresponding command instance based on the operation code. + *

This method looks up the given operation code and returns the corresponding command instance.

+ * + * @param opCode The operation code (instruction code) + * @return An Optional containing the command object. If a command exists for the operation code, it returns the command instance; otherwise, an empty Optional is returned. + */ + public static Optional getInstruction(int opCode) { + if (opCode >= 0 && opCode < COMMANDS.length) { + Command command = COMMANDS[opCode]; + return Optional.ofNullable(command); // Return the command if it's present, otherwise return empty Optional + } + // Return empty Optional if opCode is out of range + return Optional.empty(); + } +} diff --git a/src/main/java/org/jcnc/snow/vm/gui/LocalVariableStoreSwing.java b/src/main/java/org/jcnc/snow/vm/gui/LocalVariableStoreSwing.java new file mode 100644 index 0000000..d5d5f6e --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/gui/LocalVariableStoreSwing.java @@ -0,0 +1,131 @@ +package org.jcnc.snow.vm.gui; + + +import org.jcnc.snow.vm.module.LocalVariableStore; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.util.List; +import java.util.Vector; + +/** + * The LocalVariableStoreSwing class provides a graphical user interface (GUI) to display the virtual machine's local variable store. + * This class displays the local variable table in a JTable within a Swing window for users to view the current local variables and their values. + * + *

The class provides static methods to create windows, generate tables, and configure the table display, among other functionalities.

+ */ +public class LocalVariableStoreSwing { + /** + * Default constructor for creating an instance of LocalVariableStoreSwing. + * This constructor is empty as no specific initialization is required. + */ + public LocalVariableStoreSwing() { + // Empty constructor + } + + /** + * Displays the local variable table in a window. + * + *

This method opens a new Swing window containing a table that shows the content of the current local variable store.

+ * + * @param localVariableStore The current local variable store. + * @param title The title of the window. + */ + public static void display(LocalVariableStore localVariableStore, String title) { + SwingUtilities.invokeLater(() -> { + JFrame frame = createFrame(title); + JTable table = createTableFromLocalVariables(localVariableStore); + frame.add(new JScrollPane(table), BorderLayout.CENTER); + frame.setVisible(true); + }); + } + + /** + * Creates and configures a new JFrame window. + * + * @param title The title of the window. + * @return The created and configured JFrame window. + */ + private static JFrame createFrame(String title) { + JFrame frame = new JFrame(title); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.setSize(500, 400); + frame.setLocationRelativeTo(null); // Center the window on the screen + return frame; + } + + /** + * Creates a JTable based on the local variable store. + * + *

This method retrieves the local variable data from the store and converts it into a non-editable JTable.

+ * + * @param localVariableStore The current local variable store. + * @return The created JTable displaying the local variable table content. + */ + private static JTable createTableFromLocalVariables(LocalVariableStore localVariableStore) { + List variables = localVariableStore.getLocalVariables(); + + // Create column names + Vector columnNames = createColumnNames(); + + // Create table data + Vector> data = createTableData(variables); + + // Create a non-editable table model + DefaultTableModel model = new DefaultTableModel(data, columnNames) { + @Override + public boolean isCellEditable(int row, int column) { + return false; // Disable cell editing + } + }; + + JTable table = new JTable(model); // Create the table + + // Configure the table selection mode + configureTableSelection(table); + + return table; + } + + /** + * Creates the column names for the table. + * + * @return A Vector containing the column names. + */ + private static Vector createColumnNames() { + Vector columnNames = new Vector<>(); + columnNames.add("Index"); + columnNames.add("Local Variable Value"); + return columnNames; + } + + /** + * Creates the table data based on the local variable list. + * + * @param variables The list of local variables. + * @return The table data, formatted as a Vector. + */ + private static Vector> createTableData(List variables) { + Vector> data = new Vector<>(variables.size()); + for (int i = 0; i < variables.size(); i++) { + Vector row = new Vector<>(2); + row.add(String.valueOf(i)); + row.add(String.valueOf(variables.get(i))); + data.add(row); + } + return data; + } + + /** + * Configures the table's selection mode, disabling the selection of cells, rows, and columns. + * + * @param table The JTable to configure. + */ + private static void configureTableSelection(JTable table) { + table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + table.setCellSelectionEnabled(false); + table.setRowSelectionAllowed(false); + table.setColumnSelectionAllowed(false); + } +} diff --git a/src/main/java/org/jcnc/snow/vm/interfaces/Command.java b/src/main/java/org/jcnc/snow/vm/interfaces/Command.java new file mode 100644 index 0000000..afa47cb --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/interfaces/Command.java @@ -0,0 +1,53 @@ +package org.jcnc.snow.vm.interfaces; + +import org.jcnc.snow.vm.module.CallStack; +import org.jcnc.snow.vm.module.LocalVariableStore; +import org.jcnc.snow.vm.module.OperandStack; + +/** + * The Command interface defines the common execution method for virtual machine instructions. + * All virtual machine instruction classes should implement this interface to provide the specific behavior for instruction execution. + * + *

Each class that implements this interface must provide its own {@link #execute} method to execute the corresponding instruction operation.

+ * + *

The execute method in this interface receives the instruction parameters, the current program counter (PC), + * as well as the virtual machine's stack manager, local variable store, and call stack. It modifies the virtual machine's state + * (such as the stack contents, program counter, and other internal states) based on the specific functionality of the instruction.

+ * + *

This interface provides a blueprint for implementing various types of virtual machine instructions, such as arithmetic operations, + * control flow instructions (e.g., CALL, JUMP), and data manipulation instructions (e.g., PUSH, POP).

+ */ +public interface Command { + + /** + * Executes the virtual machine instruction's operation. + * + *

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

+ * + *

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

+ * + *

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

+ * + * @param parts The array of instruction parameters, which usually includes the operator and related arguments + * (such as target addresses, values, or function names). These parameters may vary based on + * the instruction being executed. + * @param currentPC The current program counter-value, indicating the address of the instruction being executed. + * This value is typically incremented after the execution of each instruction to point to the next one. + * @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack, + * such as pushing, popping, and peeking values. + * @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution. + * The store may not be used in every command but can be leveraged by instructions that require access + * to local variables. + * @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by + * instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions). + * @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the + * instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address + * corresponding to the target of the jump or the subroutine to call. + */ + int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack); +} diff --git a/src/main/java/org/jcnc/snow/vm/io/FileIOUtils.java b/src/main/java/org/jcnc/snow/vm/io/FileIOUtils.java new file mode 100644 index 0000000..fbb0693 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/io/FileIOUtils.java @@ -0,0 +1,94 @@ +package org.jcnc.snow.vm.io; + +import org.jcnc.snow.vm.utils.LoggingUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.stream.Stream; + +import static java.util.stream.Collectors.toList; + +/** + * The FileIOUtils class handles file input and output operations, primarily for reading instructions from files. + * This class provides various methods to handle file paths, read file contents, clean up unnecessary lines in files, etc. + *

+ * The primary functionality of this class is to read instructions from files and remove comments, empty lines, and other irrelevant content. + *

+ */ +public class FileIOUtils { + /** + * Default constructor for creating an instance of FileIOUtils. + * This constructor is empty as no specific initialization is required. + */ + public FileIOUtils() { + // Empty constructor + } + + /** + * Retrieves the file path from the command line arguments. + *

+ * This method checks the number of command line arguments and extracts the file path from the arguments. + *

+ * + * @param args Command line arguments + * @return The file path if the command line arguments contain a valid file path; otherwise, returns null. + */ + public static String getFilePathFromArgs(String[] args) { + if (args.length != 1) { + LoggingUtils.logError("Please provide a valid file path."); + return null; + } + return args[0]; + } + + /** + * Reads and processes instructions from the specified file path. + *

+ * This method reads each line of the file, removes comments and empty lines, and returns a list of valid instructions. + *

+ * + * @param filePath The file path + * @return A list of processed instructions from the file. If an error occurs while reading the file, returns an empty list. + */ + public static List readInstructionsFromFile(String filePath) { + try (Stream lines = Files.lines(Path.of(filePath))) { + return lines.map(FileIOUtils::cleanLine) // Remove comments from the line + .filter(FileIOUtils::isNotEmpty) // Filter out empty lines + .collect(toList()); // Collect into a list + } catch (IOException e) { + LoggingUtils.logError("Error reading file: " + e.getMessage()); + return List.of(); // Return an empty list if an error occurs + } + } + + /** + * Cleans up the content of each line by removing comments and trimming whitespace. + *

+ * This method removes comments (sections starting with "//") from the line and trims any unnecessary whitespace. + *

+ * + * @param line The original line + * @return The cleaned-up line with comments removed and whitespace trimmed. + */ + public static String cleanLine(String line) { + if (line == null || line.isEmpty()) { + return ""; // Return an empty string if the line is null or empty + } + return line.replaceAll("//.*", "").trim(); // Remove comments and trim whitespace + } + + /** + * Checks if the line is empty. + *

+ * This method checks if the line is an empty string or contains only whitespace characters. + *

+ * + * @param line The line to check + * @return True if the line is not empty or does not contain only spaces; otherwise, returns false. + */ + public static boolean isNotEmpty(String line) { + return !line.isEmpty(); // Return whether the line is not empty + } +} diff --git a/src/main/java/org/jcnc/snow/vm/io/FilePathResolver.java b/src/main/java/org/jcnc/snow/vm/io/FilePathResolver.java new file mode 100644 index 0000000..421499e --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/io/FilePathResolver.java @@ -0,0 +1,43 @@ +package org.jcnc.snow.vm.io; + +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The FilePathResolver class handles command-line arguments to retrieve a valid file path. + * This class contains a method that extracts the file path from the command-line arguments. + * If no file path is provided, an error message will be logged. + *

+ * The main functionality of this class is to obtain the file path from the command-line arguments and provide relevant error logging. + *

+ */ +public class FilePathResolver { + /** + * Default constructor for creating an instance of FilePathResolver. + * This constructor is empty as no specific initialization is required. + */ + public FilePathResolver() { + // Empty constructor + } + + /** + * Retrieves the file path. + *

+ * This method calls the method in the FileIOUtils class to obtain the file path from the command-line arguments. + * If a valid file path is not provided, an error message will be logged. + *

+ * + * @param args Command-line arguments containing the file path provided by the user + * @return The file path if a valid path is provided in the command-line arguments; otherwise, returns null. + */ + public static String getFilePath(String[] args) { + // Use the FileIOUtils class to obtain the file path + String filePath = FileIOUtils.getFilePathFromArgs(args); + + // Log an error message if no valid file path is provided + if (filePath == null) { + LoggingUtils.logError("No valid file path provided."); + } + + return filePath; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/module/CallStack.java b/src/main/java/org/jcnc/snow/vm/module/CallStack.java new file mode 100644 index 0000000..cd982d3 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/module/CallStack.java @@ -0,0 +1,96 @@ +package org.jcnc.snow.vm.module; + +import org.jcnc.snow.vm.utils.LoggingUtils; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * CallStack manages the stack frames, maintaining the function call hierarchy. + */ +public class CallStack { + private static final int MAX_STACK_DEPTH = 1024; // Stack overflow protection + private final Deque stack = new ArrayDeque<>(); + /** + * Default constructor for creating an instance of CallStack. + * This constructor is empty as no specific initialization is required. + */ + public CallStack() { + // Empty constructor + } + + /** + * Pushes a new stack frame onto the call stack. + * + * @param frame The stack frame to be pushed. + * @throws StackOverflowError If the stack exceeds the maximum allowed depth. + */ + public void pushFrame(StackFrame frame) { + if (stack.size() >= MAX_STACK_DEPTH) { + throw new StackOverflowError("Call stack overflow. Maximum depth: " + MAX_STACK_DEPTH); + } + stack.push(frame); + } + + /** + * Pops the current stack frame from the call stack. + * + * @return The popped stack frame. + */ + public StackFrame popFrame() { + if (stack.isEmpty()) { + throw new IllegalStateException("Call stack is empty, cannot pop."); + } + // Kill this StackFrame LocalVariableStore + + return stack.pop(); + } + + /** + * Retrieves the current (top) stack frame without removing it. + * + * @return The top stack frame. + */ + public StackFrame peekFrame() { + if (stack.isEmpty()) { + throw new IllegalStateException("Call stack is empty, cannot peek."); + } + return stack.peek(); + } + + /** + * Takes a snapshot of the current call stack. + * Useful for debugging during exceptions. + * + * @return A string representing the call stack snapshot. + */ + public String takeSnapshot() { + StringBuilder snapshot = new StringBuilder("--- Call Stack Snapshot ---\n"); + for (StackFrame frame : stack) { + snapshot.append("Method: ").append(frame.getMethodContext().methodName()) + .append(", Return Address: ").append(frame.getReturnAddress()) + .append(", Locals: ").append(frame.getLocalVariableStore().getLocalVariables()) + .append("\n"); + } + return snapshot.toString(); + } + + /** + * Checks if the call stack is empty. + * + * @return true if empty, false otherwise. + */ + public boolean isEmpty() { + return stack.isEmpty(); + } + + /** + * Prints the current state of the call stack. + */ + public void printCallStack() { + LoggingUtils.logInfo("--- Call Stack State ---", "\n"); + for (StackFrame frame : stack) { + frame.printFrame(); + } + } +} \ No newline at end of file diff --git a/src/main/java/org/jcnc/snow/vm/module/LocalVariableStore.java b/src/main/java/org/jcnc/snow/vm/module/LocalVariableStore.java new file mode 100644 index 0000000..d27b031 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/module/LocalVariableStore.java @@ -0,0 +1,136 @@ +package org.jcnc.snow.vm.module; + +import org.jcnc.snow.vm.gui.LocalVariableStoreSwing; +import org.jcnc.snow.vm.utils.LoggingUtils; +import org.jcnc.snow.vm.engine.VMMode; + +import java.util.ArrayList; + +/** + * The LocalVariableStore class represents the local variable store of the virtual machine. + * This class manages the local variables of the virtual machine and can behave differently based on the specified execution mode (such as debug or run mode). + * + *

The local variable table is stored using an {@link ArrayList}, which supports dynamic resizing and setting values at specific index locations.

+ * + *

The local variable store provides basic operations, including setting and getting variable values, ensuring capacity, and printing the current state.

+ */ +public class LocalVariableStore { + private final ArrayList localVariables; + private final VMMode vmMode; + + /** + * Constructor that initializes the local variable store with a specified initial capacity and execution mode. + * + * @param vmMode The current virtual machine mode (e.g., debug or run mode). + * @param initialCapacity The initial capacity determining the starting size of the local variable table. + */ + public LocalVariableStore(VMMode vmMode, int initialCapacity) { + this.localVariables = new ArrayList<>(initialCapacity); + this.vmMode = vmMode; + handleMode(); + } + + /** + * Constructor that initializes the local variable store without specifying initial capacity but with a specified execution mode. + * + * @param vmMode The current virtual machine mode (e.g., debug or run mode). + */ + public LocalVariableStore(VMMode vmMode) { + this.localVariables = new ArrayList<>(); // Default capacity of 10 + this.vmMode = vmMode; + handleMode(); + } + + /** + * Sets the local variable value at the specified index. + * + *

If the index exceeds the current size of the local variable table, the table is automatically expanded to accommodate the index.

+ * + * @param index The index position. + * @param value The value to be set for the local variable. + */ + public void setVariable(int index, Object value) { + // Ensure the local variable table has enough capacity to accommodate the specified index + ensureCapacity(index + 1); + localVariables.set(index, value); // Set the local variable value + } + + /** + * Retrieves the local variable value at the specified index. + * + * @param index The index position. + * @return The value of the local variable. + * @throws IndexOutOfBoundsException If the index is invalid, an exception is thrown. + */ + public Object getVariable(int index) { + if (index < 0 || index >= localVariables.size()) { + throw new IndexOutOfBoundsException("Invalid index: " + index + ", current size of table: " + localVariables.size()); + } + return localVariables.get(index); + } + + /** + * Expands the capacity of the local variable table to ensure it can hold at least the specified number of elements. + * + * @param minCapacity The minimum required capacity. + */ + private void ensureCapacity(int minCapacity) { + if (minCapacity > localVariables.size()) { + localVariables.ensureCapacity(minCapacity); // Expand the ArrayList capacity + while (localVariables.size() < minCapacity) { + localVariables.add(null); // Fill remaining space with null + } + } + } + + /** + * Retrieves the complete data of the local variable table. + * + * @return The ArrayList containing the local variables. + */ + public ArrayList getLocalVariables() { + return this.localVariables; + } + + /** + * Prints the current state of the local variable table. + * + *

If the local variable table is empty, a message is logged indicating that. Otherwise, each local variable's index and value are printed.

+ */ + public void printLv() { + if (localVariables.isEmpty()) { + LoggingUtils.logInfo("Local variable table is empty", ""); + return; + } + LoggingUtils.logInfo("Local Variable Table:", ""); + for (int i = 0; i < localVariables.size(); i++) { + LoggingUtils.logInfo("", String.format("%d: %s", i, localVariables.get(i))); + } + } + + /** + * Clears the local variable table, removing all local variables. + * + *

This method removes all entries from the local variable table, effectively resetting the table.

+ */ + public void clearVariables() { + localVariables.clear(); // Clears all elements in the ArrayList + } + + /** + * Executes specific operations based on the virtual machine's execution mode. + * + *

This method performs different actions depending on the current mode, such as displaying the local variable table in debug mode.

+ */ + private void handleMode() { + switch (vmMode) { + case DEBUG: + // TODO: "If you need to build a project with graalvm into a native image, you do not need to annotate nether code + LocalVariableStoreSwing.display(this, "Local Variable Table"); // Display local variable table in debug mode + break; + case RUN: + default: + break; + } + } +} diff --git a/src/main/java/org/jcnc/snow/vm/module/MethodContext.java b/src/main/java/org/jcnc/snow/vm/module/MethodContext.java new file mode 100644 index 0000000..bf72711 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/module/MethodContext.java @@ -0,0 +1,40 @@ +package org.jcnc.snow.vm.module; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents metadata about the current method invocation for debugging purposes. + *

+ * This class holds information about the method name and its arguments, which can be useful for debugging + * and tracking method invocations in the virtual machine context. If no arguments are provided, an empty list + * is used to avoid null references. + *

+ * + * @param methodName The name of the method being invoked. + * @param arguments The list of arguments passed to the method. If null, an empty list is used. + */ +public record MethodContext(String methodName, List arguments) { + + /** + * Constructs a new MethodContext with the provided method name and arguments. + * If the provided arguments are null, an empty list is used instead. + * + * @param methodName The name of the method being invoked. + * @param arguments The list of arguments passed to the method. If null, an empty list is used. + */ + public MethodContext { + arguments = arguments != null ? arguments : new ArrayList<>(); + } + + /** + * Returns a string representation of the method invocation. + * The format is: "Method: {methodName}, Args: {arguments}" + * + * @return A string representation of the method invocation, including its name and arguments. + */ + @Override + public String toString() { + return "Method: " + methodName + ", Args: " + arguments; + } +} diff --git a/src/main/java/org/jcnc/snow/vm/module/OperandStack.java b/src/main/java/org/jcnc/snow/vm/module/OperandStack.java new file mode 100644 index 0000000..347387f --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/module/OperandStack.java @@ -0,0 +1,103 @@ +package org.jcnc.snow.vm.module; + +import org.jcnc.snow.vm.utils.LoggingUtils; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.EmptyStackException; + +/** + * OperandStack class provides the stack management implementation. + *

+ * It uses Deque (ArrayDeque) to implement basic stack operations, including push, pop, checking if the stack is empty, + * getting the stack size, and printing the stack's current state. + *

+ */ +public class OperandStack { + private final Deque stack = new ArrayDeque<>(); + + /** + * Default constructor for creating an instance of OperandStack. + * This constructor is empty as no specific initialization is required. + */ + public OperandStack() { + // Empty constructor + } + + /** + * Push operation, adds an integer value to the stack. + *

+ * The push operation is implemented using Deque's push method to add the integer value to the top of the stack. + *

+ * + * @param value The value to be pushed onto the stack. + */ + public void push(Object value) { + stack.push(value); + } + + /** + * Pop operation, removes and returns the top element of the stack. + *

+ * The pop operation is implemented using Deque's pop method. If the stack is empty, an exception will be thrown. + *

+ * + * @return The top element of the stack. + * @throws IllegalStateException If the stack is empty, an exception is thrown indicating that the pop operation cannot be performed. + */ + public Object pop() { + if (stack.isEmpty()) { + throw new IllegalStateException("Stack is empty, cannot pop"); + } + return stack.pop(); + } + + + /** + * Checks if the stack is empty. + *

+ * The isEmpty method of Deque is used to check if the stack is empty. + *

+ * + * @return Returns true if the stack is empty, otherwise false. + */ + public boolean isEmpty() { + return stack.isEmpty(); + } + + /** + * Gets the current size of the stack. + *

+ * The size method of Deque is used to get the size of the stack, which is the number of elements in the stack. + *

+ * + * @return The number of elements in the stack. + */ + public int size() { + return stack.size(); + } + + /** + * Prints the current state of the stack. + *

+ * Logs the list of all elements in the stack, showing its content. Uses LoggingUtils to log the information. + *

+ */ + public void printOperandStack() { + LoggingUtils.logInfo("Operand Stack state:", stack + "\n"); + } + + /** + * Retrieves the top value of the stack without removing it. + *

This method returns the top element of the stack without modifying the stack itself.

+ * + * @return The top value of the stack. + * @throws EmptyStackException if the stack is empty. + */ + public Object peek() { + if (stack.isEmpty()) { + throw new EmptyStackException(); + } + return stack.peek(); + } +} diff --git a/src/main/java/org/jcnc/snow/vm/module/StackFrame.java b/src/main/java/org/jcnc/snow/vm/module/StackFrame.java new file mode 100644 index 0000000..d919979 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/module/StackFrame.java @@ -0,0 +1,105 @@ +package org.jcnc.snow.vm.module; + +import org.jcnc.snow.vm.utils.LoggingUtils; + +/** + * The {@code StackFrame} class represents a single frame in the call stack during program execution. + * It holds the execution context for a method invocation, including information such as the return + * address, local variables, operand stack, and method context. + * + *

This class encapsulates the state of a method call, including the local variables, operand stack, + * and metadata regarding the method being invoked. It provides a mechanism for managing method invocation + * details in a virtual machine or interpreter context.

+ */ +public class StackFrame { + + /** + * The return address indicates the position in the program to return to after the method execution completes. + */ + private final int returnAddress; + + /** + * The {@code LocalVariableStore} holds the local variables specific to the current method invocation. + */ + private final LocalVariableStore localVariableStore; + + /** + * The {@code OperandStack} stores the operand stack for the method execution, which contains temporary + * values used during the evaluation of expressions. + */ + private final OperandStack operandStack; + + /** + * The {@code MethodContext} contains metadata about the method, such as its name and the method's arguments. + */ + private final MethodContext methodContext; + + /** + * Constructs a new {@code StackFrame} with the specified return address, local variable store, and method context. + * + * @param returnAddress The address to return to after the method execution. It is the point in the program + * where control will resume once the method has completed. + * @param localVariableStore The local variable store that holds all local variables for the current method + * invocation. It provides a way to access and manipulate local variables. + * @param methodContext The method context providing metadata for the method invocation, including the method + * name, parameter types, and other relevant data. + */ + public StackFrame(int returnAddress, LocalVariableStore localVariableStore, MethodContext methodContext) { + this.returnAddress = returnAddress; + this.localVariableStore = localVariableStore; + this.operandStack = new OperandStack(); + this.methodContext = methodContext; + } + + /** + * Retrieves the return address for the current method invocation. This address indicates where control should + * return after the method completes execution. + * + * @return The return address as an integer. + */ + public int getReturnAddress() { + return returnAddress; + } + + /** + * Retrieves the local variable store associated with this method invocation. The store contains the local + * variables that are specific to the current execution context. + * + * @return The local variable store for the current method. + */ + public LocalVariableStore getLocalVariableStore() { + return localVariableStore; + } + + /** + * Retrieves the operand stack used by the current method invocation. The operand stack contains temporary values + * required for evaluating expressions and managing method execution. + * + * @return The operand stack used during the method execution. + */ + public OperandStack getOperandStack() { + return operandStack; + } + + /** + * Retrieves the method context for the current method invocation. The method context includes metadata such as + * the method's name, parameter types, and other relevant data for the method execution. + * + * @return The method context that describes the invoked method. + */ + public MethodContext getMethodContext() { + return methodContext; + } + + /** + * Prints the details of the stack frame, including the return address, method context, local variables, and + * operand stack. This method is useful for debugging and inspecting the state of a method invocation. + */ + public void printFrame() { + LoggingUtils.logInfo("----- Stack Frame -----", ""); + LoggingUtils.logInfo("Return Address:", String.valueOf(returnAddress)); + LoggingUtils.logInfo("Method Context:", methodContext.toString()); + LoggingUtils.logInfo("Local Variables:", localVariableStore.getLocalVariables().toString()); + operandStack.printOperandStack(); + } +} diff --git a/src/main/java/org/jcnc/snow/vm/utils/LoggingUtils.java b/src/main/java/org/jcnc/snow/vm/utils/LoggingUtils.java new file mode 100644 index 0000000..2367cb7 --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/utils/LoggingUtils.java @@ -0,0 +1,56 @@ +package org.jcnc.snow.vm.utils; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * The LoggingUtils class provides logging functionality, supporting different log levels for output. + * This class uses Java's built-in logging system for logging, supporting both console output and log file recording. + *

+ * This class offers two methods for logging at different levels: + * 1. Error logs: Used for recording error messages, outputting them to both the console and log file. + * 2. Information logs: Used for recording general information, outputting to the console. + *

+ */ +public class LoggingUtils { + // Logger instance using Java's built-in Logger class + private static final Logger LOGGER = Logger.getLogger(LoggingUtils.class.getName()); + + /** + * Default constructor for creating an instance of LoggingUtils. + * This constructor is empty as no specific initialization is required. + */ + public LoggingUtils() { + // Empty constructor + } + + /** + * Logs an error message, recording it to both the console and log file. + *

+ * This method is used to log error-level messages. It outputs the error message to the console and logs it to a file, + * allowing developers to review error details. + *

+ * + * @param message The error message detailing the issue. + */ + public static void logError(String message) { + // Output the error message to the console + System.err.println("Error: " + message); + // Log the error message with SEVERE level to the log file + LOGGER.log(Level.SEVERE, message); + } + + /** + * Logs an informational message. + *

+ * This method is used to log general information. It outputs the specified message to the console for developers to review. + *

+ * + * @param title The log title, used to indicate the subject or type of the log. + * @param message The information content to be logged. + */ + public static void logInfo(String title, String message) { + // Output the informational message to the console + System.out.println(title + message); + } +} diff --git a/src/main/java/org/jcnc/snow/vm/utils/VMStateLogger.java b/src/main/java/org/jcnc/snow/vm/utils/VMStateLogger.java new file mode 100644 index 0000000..67bed0f --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/utils/VMStateLogger.java @@ -0,0 +1,48 @@ +package org.jcnc.snow.vm.utils; + +import org.jcnc.snow.vm.engine.VirtualMachineEngine; + +/** + * Utility class for logging the state of a virtual machine. + *

+ * The {@code VMStateLogger} class provides methods to log and display + * the current execution state of a {@link VirtualMachineEngine}, including + * its stack, local variables, and other relevant details. + *

+ *

+ * This class serves as a wrapper around the {@link VMUtils#printVMState(VirtualMachineEngine)} + * method, simplifying the logging process. + *

+ */ +public class VMStateLogger { + + /** + * Default constructor for creating an instance of {@code VMStateLogger}. + *

+ * This constructor is intentionally left empty as no specific initialization is required. + *

+ */ + public VMStateLogger() { + // Empty constructor + } + + /** + * Prints the current state of the virtual machine. + *

+ * This method logs the current state of the provided {@link VirtualMachineEngine}, + * including the stack contents, local variables, and other relevant execution details. + * It delegates the actual state printing to the {@link VMUtils#printVMState(VirtualMachineEngine)} method. + *

+ * + * @param virtualMachineEngine The virtual machine instance whose state will be printed. + * Must not be {@code null}. + * @throws IllegalArgumentException If the provided {@code virtualMachineEngine} is {@code null}. + */ + public static void printVMState(VirtualMachineEngine virtualMachineEngine) { + if (virtualMachineEngine == null) { + throw new IllegalArgumentException("VirtualMachineEngine instance cannot be null."); + } + + VMUtils.printVMState(virtualMachineEngine); + } +} diff --git a/src/main/java/org/jcnc/snow/vm/utils/VMUtils.java b/src/main/java/org/jcnc/snow/vm/utils/VMUtils.java new file mode 100644 index 0000000..21b526d --- /dev/null +++ b/src/main/java/org/jcnc/snow/vm/utils/VMUtils.java @@ -0,0 +1,42 @@ +package org.jcnc.snow.vm.utils; + +import org.jcnc.snow.vm.engine.VirtualMachineEngine; + +/** + * Utility class for virtual machine operations. + *

+ * This class provides helper methods for managing and inspecting the state + * of a {@link VirtualMachineEngine}. It is intended for debugging and + * monitoring purposes. + *

+ *

+ * The {@code VMUtils} class is not meant to be instantiated, as all methods + * are static. + *

+ */ +public class VMUtils { + /** + * Default constructor for creating an instance of VMUtils. + * This constructor is empty as no specific initialization is required. + */ + public VMUtils() { + // Empty constructor + } + + /** + * Prints the current state of the virtual machine, including the stack and local variables. + * This method provides a snapshot of the virtual machine's current execution context, + * useful for debugging or inspection purposes. + * + * @param vm The virtual machine instance whose state will be printed. + * The vm parameter must not be null. + * @throws IllegalArgumentException If the provided vm is null. + */ + public static void printVMState(VirtualMachineEngine vm) { + if (vm == null) { + throw new IllegalArgumentException("VirtualMachineEngine instance cannot be null."); + } + vm.printStack(); + vm.printLocalVariables(); + } +} diff --git a/test b/test index 00fb23f..dd6f5ad 100644 --- a/test +++ b/test @@ -1,105 +1,14 @@ module: CommonTasks - function: add_numbers - body: - return num1 + num2 - end body + function: main parameter: - declare num1: int - declare num2: int + declare num1: int + declare num2: int return_type: int - end function -end module -module: MathUtils - function: square_number - parameter: - declare number: int - return_type: int body: - return number * number - end body - end function -end module - -module: StringUtils - function: concatenate - parameter: - declare first_str: string - declare second_str: string - return_type: string - body: - return first_str + second_str - end body - end function -end module - -module: MainModule - import: CommonTasks, MathUtils, StringUtils, BuiltinUtils - - function: test - parameter: - declare first_str: string - declare second_str: string - return_type: string - body: - return first_str + second_str - end body - end function - - function: main - parameter: - declare args: string - return_type: void - body: - declare input_number: int = BuiltinUtils.to_int(args) - - if input_number <= 0 then - input_number = 5 - end if - - loop: - initializer: - declare i: int = 0 - condition: - i < input_number - update: - i = i + 1 - body: - if i % 2 == 0 then - BuiltinUtils.print("i is even: " + BuiltinUtils.to_string(i)) - else - BuiltinUtils.print("i is odd: " + BuiltinUtils.to_string(i)) - - loop: - initializer: - declare j: int = 0 - condition: - j < i - update: - j = j + 1 - body: - if j == 1 then - BuiltinUtils.print("first inner") - else - if j % 2 == 0 then - BuiltinUtils.print("j even") - else - BuiltinUtils.print("j odd") - end if - end if - end body - end loop - end if - - declare sum: int = CommonTasks.add_numbers(i, 10) - declare squared: int = MathUtils.square_number(sum) - BuiltinUtils.print("i+10 squared = " + BuiltinUtils.to_string(squared)) - - end body - end loop - - declare final_message: string = StringUtils.concatenate("Finished with input: ", BuiltinUtils.to_string(input_number)) - BuiltinUtils.print(final_message) + num1 = 10 + num2 = 20 + return (num1 + num2) * 2 end body end function end module