第一个可以运行的版本

This commit is contained in:
Luke 2025-04-28 17:45:17 +08:00
parent a7f1627df0
commit fc549217db
135 changed files with 9833 additions and 174 deletions

67
opcode
View File

@ -1,69 +1,16 @@
module: CommonTasks module: CommonTasks
function: add_numbers function: main
parameter: parameter:
declare num1: int declare num1: int
declare num2: int declare num2: int
return_type: int return_type: int
body: body:
return num1 + num2 declare sum: int = num1 + num2
end body
end function declare doubled: int = sum * 2
end module
return doubled
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
body:
loop:
initializer:
declare counter: int = 5
condition:
counter > 0
update:
counter = counter - 1
body:
BuiltinUtils.print(counter)
end body
end loop
declare input_number: int = BuiltinUtils.to_int(args)
if input_number == 0 then
input_number = 999
end if
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)
end body end body
end function end function
end module end module

View File

@ -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<VirtualRegister,Integer> map = new HashMap<>();
public Map<VirtualRegister,Integer> 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;
}
}

View File

@ -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<VirtualRegister,Integer> slotMap;
private final List<String> code = new ArrayList<>();
private String currentFnName; // 当前正在生成的函数名
public VMCodeGenerator(Map<VirtualRegister,Integer> slotMap){
this.slotMap = slotMap;
}
/** 主入口IR → 指令序列 */
public List<String> 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());
}
}

View File

@ -1,11 +1,18 @@
package org.jcnc.snow.compiler.cli; 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.core.LexerEngine;
import org.jcnc.snow.compiler.lexer.token.Token; 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.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.compiler.semantic.core.SemanticAnalyzerRunner;
import org.jcnc.snow.vm.engine.VMMode;
import org.jcnc.snow.vm.engine.VirtualMachineEngine;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -14,29 +21,59 @@ import java.nio.file.Path;
import java.util.List; import java.util.List;
public class SnowCompiler { public class SnowCompiler {
public static void main(String[] args) throws IOException { 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 <source-file>");
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. 词法分析 /* 1. 词法分析 */
LexerEngine lexerEngine = new LexerEngine(source); LexerEngine lexer = new LexerEngine(source);
List<Token> tokens = lexerEngine.getAllTokens(); List<Token> tokens = lexer.getAllTokens();
// 2. 语法分析 /* 2. 语法分析 */
ParserContext ctx = new ParserContext(tokens); ParserContext ctx = new ParserContext(tokens);
List<Node> ast = new ParserEngine(ctx).parse(); List<Node> ast = new ParserEngine(ctx).parse();
// 3. 语义分析 /* 3. 语义分析 */
SemanticAnalyzerRunner.runSemanticAnalysis(ast, true); 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 函数 */
// System.out.println(source); if ("main".equals(fn.name())) {
// TokenPrinter.print(tokens); // 打印 Token 列表 VirtualMachineEngine vm = new VirtualMachineEngine(VMMode.RUN);
// 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");
}
}
} }
} }

View File

@ -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<Node> 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<String,VirtualRegister> 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;
}
}

View File

@ -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(); }
}

View File

@ -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<IRValue> operands() { return List.of(); } // 默认无操作数
}

View File

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

View File

@ -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<IRFunction> functions = new ArrayList<>();
public void add(IRFunction fn) { functions.add(fn); }
public List<IRFunction> 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();
}
}

View File

@ -0,0 +1,6 @@
//
// file: compiler/ir/IRValue.java
package org.jcnc.snow.compiler.ir;
/** 常量、寄存器、标签的共同父接口 */
public sealed interface IRValue permits VirtualRegister, Constant, Label {}

View File

@ -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 + ":"; }
}

View File

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

View File

@ -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<IRValue> operands() { return List.of(lhs, rhs); }
@Override public String toString() { return dest + " = " + op + " " + lhs + ", " + rhs; }
}

View File

@ -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<IRInstruction> 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<IRInstruction> 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();
}
}

View File

@ -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<IRValue> operands() { return List.of(k); }
@Override public String toString() { return dest + " = CONST " + k; }
}

View File

@ -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<IRValue> operands() { return value==null? List.of() : List.of(value); }
public VirtualRegister value() { return value; }
@Override public String toString(){ return value==null? "RET" : "RET " + value; }
}

View File

@ -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<IRValue> operands() { return List.of(val); }
@Override public String toString() { return dest + " = " + op + " " + val; }
}

View File

@ -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:
* <ul>
* <li>Retrieving and validating the file path</li>
* <li>Loading the instruction set</li>
* <li>Executing the instructions</li>
* <li>Printing the virtual machine's state</li>
* </ul>
* <p>
* This class contains the main method `main(String[] args)`, which initiates the virtual machine execution flow.
* </p>
* <p>The main process:</p>
* <ol>
* <li>Retrieve and parse the file path from command-line arguments</li>
* <li>Load the instructions from the specified file path</li>
* <li>Execute the loaded instructions using the virtual machine engine</li>
* <li>Print the virtual machine's current state</li>
* </ol>
*/
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<String> 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);
}
}

View File

@ -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.
*
* <p>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}).</p>
*/
public class VMLauncher {
/**
* Default constructor for creating an instance of {@code VMLauncher}.
* <p>This constructor is empty as no specific initialization is required
* for the {@code VMLauncher} class.</p>
*/
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.
*
* <p>The sequence of operations in this method is as follows:</p>
* <ol>
* <li>Retrieve and validate the file path from the command-line arguments.</li>
* <li>Load the instruction set from the specified file.</li>
* <li>Execute the instructions using the virtual machine engine.</li>
* <li>Output the current state of the virtual machine.</li>
* </ol>
*
* @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);
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link BAddCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two byte8 values from the operand stack.</li>
* <li>Performs the addition of the two values (i.e., <code>a + b</code>).</li>
* <li>Pushes the sum back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to add two byte8 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two byte8 values from the operand stack, adds them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link BDivCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two byte8 values from the operand stack.</li>
* <li>Performs the division operation (i.e., <code>a / b</code>).</li>
* <li>Checks for division by zero to prevent errors.</li>
* <li>Pushes the result of the division back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to divide one byte8 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link BIncCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Extracts the index of the local variable and the increment value from the instruction parameters.</li>
* <li>Retrieves the current value of the local variable at the given index.</li>
* <li>Increments the value of the local variable by the specified increment value (i.e., <code>localVariables[index] += increment</code>).</li>
* <li>Updates the local variable with the new incremented value.</li>
* <li>Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.</li>
* </ol>
*
* <p>This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link BModCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two byte8 values from the operand stack.</li>
* <li>Performs the modulus operation to calculate the remainder (i.e., <code>a % b</code>).</li>
* <li>Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>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.</p>
*/
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.
*
* <p>This method retrieves the two byte8 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link BMulCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two byte8 values from the operand stack.</li>
* <li>Performs the multiplication of the two values (i.e., <code>a * b</code>).</li>
* <li>Pushes the result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to multiply two byte8 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two byte8 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link BNegCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top byte8 value from the operand stack.</li>
* <li>Performs the negation of the popped value (i.e., <code>-value</code>).</li>
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an byte8 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the byte8 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link BSubCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two byte8 values from the operand stack.</li>
* <li>Performs the subtraction of the second popped value from the first (i.e., <code>a - b</code>).</li>
* <li>Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to subtract one byte8 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link B2ICommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top byte8 value from the operand stack.</li>
* <li>Convert the byte8 value to an int32 value.</li>
* <li>Push the converted int32 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to widen a byte8 value to an int32 type to ensure compatibility with integer-based operations.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link D2FCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top double64 value from the operand stack.</li>
* <li>Convert the double64 value to a float32 value.</li>
* <li>Push the converted float32 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to narrow a double64 value to a float32 type when lower precision floating-point arithmetic is acceptable.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link D2ICommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top double64 value from the operand stack.</li>
* <li>Convert the double64 value to an int32 value (this may involve truncation).</li>
* <li>Push the converted int32 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to narrow a double64 value to an int32 type for further integer-based operations.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link D2LCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top double64 value from the operand stack.</li>
* <li>Convert the double64 value to a long64 value (this may involve truncation).</li>
* <li>Push the converted long64 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to narrow a double64 value to a long64 type, which can then be used for integer operations.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link F2DCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top float32 value from the operand stack.</li>
* <li>Convert the float32 value to a double64 value.</li>
* <li>Push the converted double64 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to promote a float32 value to a double64 type, thereby increasing precision for floating-point computations.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link F2ICommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top float32 value from the operand stack.</li>
* <li>Convert the float32 value to an int32 value (this may involve truncation).</li>
* <li>Push the converted int32 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to convert a float32 value to an int32 type for further integer operations or comparisons.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link F2LCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top float32 value from the operand stack.</li>
* <li>Convert the float32 value to a long64 value.</li>
* <li>Push the converted long64 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to widen a float32 value to a long64 type for operations requiring a larger numeric range.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link I2BCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top int32 value from the operand stack.</li>
* <li>Convert the int32 value to a byte8 value (this may involve truncation).</li>
* <li>Push the converted byte8 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to narrow an int32 value to a byte8 type when a smaller numeric representation is required.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link I2DCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top int32 value from the operand stack.</li>
* <li>Convert the int32 value to a double64 value.</li>
* <li>Push the converted double64 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to widen an int32 value to a double64 type, providing high-precision floating-point calculations.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link I2FCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top int32 value from the operand stack.</li>
* <li>Convert the int32 value to a float32 value.</li>
* <li>Push the converted float32 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to convert an int32 value to a float32 type when floating-point arithmetic is required.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link I2LCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top int32 value from the operand stack.</li>
* <li>Convert the int32 value to a long64 value.</li>
* <li>Push the converted long64 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is commonly used to widen an int32 value to a long64 type to accommodate larger numeric ranges.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link I2SCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top int32 value from the operand stack.</li>
* <li>Convert the int32 value to a short16 value (this may involve truncation).</li>
* <li>Push the converted short16 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is typically used to narrow an int32 value to a short16 type when a smaller data representation is required.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link L2DCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top long64 value from the operand stack.</li>
* <li>Convert the long64 value to a double64 value.</li>
* <li>Push the converted double64 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to widen a long64 value to a double64 type for high-precision floating-point computations.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link L2FCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top long64 value from the operand stack.</li>
* <li>Convert the long64 value to a float32 value.</li>
* <li>Push the converted float32 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to convert a long64 value to a float32 type, typically for floating-point arithmetic involving long values.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link L2ICommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top long64 value from the operand stack.</li>
* <li>Convert the long64 value to an int32 value (this may involve truncation).</li>
* <li>Push the converted int32 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is typically used to narrow a long64 value to an int32 type for further integer operations.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link S2ICommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pop the top short16 value from the operand stack.</li>
* <li>Convert the short16 value to an int32 value.</li>
* <li>Push the converted int32 value back onto the operand stack for subsequent operations.</li>
* </ol>
*
* <p>This opcode is used to widen a short16 value to an int32 type, facilitating subsequent integer arithmetic or comparison operations.</p>
*/
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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link DAddCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two double64 values from the operand stack.</li>
* <li>Performs the addition of the two values (i.e., <code>a + b</code>).</li>
* <li>Pushes the sum back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to add two double64 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two double64 values from the operand stack, adds them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link DDivCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two double64 values from the operand stack.</li>
* <li>Performs the division operation (i.e., <code>a / b</code>).</li>
* <li>Checks for division by zero to prevent errors.</li>
* <li>Pushes the result of the division back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to divide one double64 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link DIncCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Extracts the index of the local variable and the increment value from the instruction parameters.</li>
* <li>Retrieves the current value of the local variable at the given index.</li>
* <li>Increments the value of the local variable by the specified increment value (i.e., <code>localVariables[index] += increment</code>).</li>
* <li>Updates the local variable with the new incremented value.</li>
* <li>Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.</li>
* </ol>
*
* <p>This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link DModCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two double64 values from the operand stack.</li>
* <li>Performs the modulus operation to calculate the remainder (i.e., <code>a % b</code>).</li>
* <li>Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>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.</p>
*/
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.
*
* <p>This method retrieves the two double64 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link DMulCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two double64 values from the operand stack.</li>
* <li>Performs the multiplication of the two values (i.e., <code>a * b</code>).</li>
* <li>Pushes the result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to multiply two double64 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two double64 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link DNegCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top double64 value from the operand stack.</li>
* <li>Performs the negation of the popped value (i.e., <code>-value</code>).</li>
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an double64 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the double64 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link DSubCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two double64 values from the operand stack.</li>
* <li>Performs the subtraction of the second popped value from the first (i.e., <code>a - b</code>).</li>
* <li>Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to subtract one double64 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link FAddCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two float32 values from the operand stack.</li>
* <li>Performs the addition of the two values (i.e., <code>a + b</code>).</li>
* <li>Pushes the sum back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to add two float32 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two float32 values from the operand stack, adds them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link FDivCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two float32 values from the operand stack.</li>
* <li>Performs the division operation (i.e., <code>a / b</code>).</li>
* <li>Checks for division by zero to prevent errors.</li>
* <li>Pushes the result of the division back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to divide one float32 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link FIncCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Extracts the index of the local variable and the increment value from the instruction parameters.</li>
* <li>Retrieves the current value of the local variable at the given index.</li>
* <li>Increments the value of the local variable by the specified increment value (i.e., <code>localVariables[index] += increment</code>).</li>
* <li>Updates the local variable with the new incremented value.</li>
* <li>Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.</li>
* </ol>
*
* <p>This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link FModCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two float32 values from the operand stack.</li>
* <li>Performs the modulus operation to calculate the remainder (i.e., <code>a % b</code>).</li>
* <li>Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>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.</p>
*/
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.
*
* <p>This method retrieves the two float32 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link FMulCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two float32 values from the operand stack.</li>
* <li>Performs the multiplication of the two values (i.e., <code>a * b</code>).</li>
* <li>Pushes the result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to multiply two float32 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two float32 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link FNegCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top float32 value from the operand stack.</li>
* <li>Performs the negation of the popped value (i.e., <code>-value</code>).</li>
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an float32 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the float32 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link FSubCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two float32 values from the operand stack.</li>
* <li>Performs the subtraction of the second popped value from the first (i.e., <code>a - b</code>).</li>
* <li>Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to subtract one float32 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link IAddCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two int32 values from the operand stack.</li>
* <li>Performs the addition of the two values (i.e., <code>a + b</code>).</li>
* <li>Pushes the sum back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to add two int32 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two int32 values from the operand stack, adds them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link IDivCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two int32 values from the operand stack.</li>
* <li>Performs the division operation (i.e., <code>a / b</code>).</li>
* <li>Checks for division by zero to prevent errors.</li>
* <li>Pushes the result of the division back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to divide one int32 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link IIncCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Extracts the index of the local variable and the increment value from the instruction parameters.</li>
* <li>Retrieves the current value of the local variable at the given index.</li>
* <li>Increments the value of the local variable by the specified increment value (i.e., <code>localVariables[index] += increment</code>).</li>
* <li>Updates the local variable with the new incremented value.</li>
* <li>Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.</li>
* </ol>
*
* <p>This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link IModCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two int32 values from the operand stack.</li>
* <li>Performs the modulus operation to calculate the remainder (i.e., <code>a % b</code>).</li>
* <li>Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>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.</p>
*/
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.
*
* <p>This method retrieves the two int32 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link IMulCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two int32 values from the operand stack.</li>
* <li>Performs the multiplication of the two values (i.e., <code>a * b</code>).</li>
* <li>Pushes the result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to multiply two int32 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two int32 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link INegCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top int32 value from the operand stack.</li>
* <li>Performs the negation of the popped value (i.e., <code>-value</code>).</li>
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an int32 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
public 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.
*
* <p>This method retrieves the int32 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link ISubCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two int32 values from the operand stack.</li>
* <li>Performs the subtraction of the second popped value from the first (i.e., <code>a - b</code>).</li>
* <li>Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to subtract one int32 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link LAddCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two long64 values from the operand stack.</li>
* <li>Performs the addition of the two values (i.e., <code>a + b</code>).</li>
* <li>Pushes the sum back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to add two long64 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two long64 values from the operand stack, adds them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link LDivCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two long64 values from the operand stack.</li>
* <li>Performs the division operation (i.e., <code>a / b</code>).</li>
* <li>Checks for division by zero to prevent errors.</li>
* <li>Pushes the result of the division back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to divide one long64 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link LIncCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Extracts the index of the local variable and the increment value from the instruction parameters.</li>
* <li>Retrieves the current value of the local variable at the given index.</li>
* <li>Increments the value of the local variable by the specified increment value (i.e., <code>localVariables[index] += increment</code>).</li>
* <li>Updates the local variable with the new incremented value.</li>
* <li>Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.</li>
* </ol>
*
* <p>This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link LModCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two long64 values from the operand stack.</li>
* <li>Performs the modulus operation to calculate the remainder (i.e., <code>a % b</code>).</li>
* <li>Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>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.</p>
*/
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.
*
* <p>This method retrieves the two long64 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link LMulCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two long64 values from the operand stack.</li>
* <li>Performs the multiplication of the two values (i.e., <code>a * b</code>).</li>
* <li>Pushes the result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to multiply two long64 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two long64 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link LNegCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top long64 value from the operand stack.</li>
* <li>Performs the negation of the popped value (i.e., <code>-value</code>).</li>
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an long64 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the long64 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link LSubCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two long64 values from the operand stack.</li>
* <li>Performs the subtraction of the second popped value from the first (i.e., <code>a - b</code>).</li>
* <li>Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to subtract one long64 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link SAddCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two short16 values from the operand stack.</li>
* <li>Performs the addition of the two values (i.e., <code>a + b</code>).</li>
* <li>Pushes the sum back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to add two short16 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two short16 values from the operand stack, adds them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link SDivCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two short16 values from the operand stack.</li>
* <li>Performs the division operation (i.e., <code>a / b</code>).</li>
* <li>Checks for division by zero to prevent errors.</li>
* <li>Pushes the result of the division back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to divide one short16 value by another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link SIncCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Extracts the index of the local variable and the increment value from the instruction parameters.</li>
* <li>Retrieves the current value of the local variable at the given index.</li>
* <li>Increments the value of the local variable by the specified increment value (i.e., <code>localVariables[index] += increment</code>).</li>
* <li>Updates the local variable with the new incremented value.</li>
* <li>Returns the updated program counter (PC) value, which typically increments by 1 unless control flow is modified.</li>
* </ol>
*
* <p>This opcode is useful for optimizing the modification of local variables, especially in tight loops or when managing counters.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link SModCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two short16 values from the operand stack.</li>
* <li>Performs the modulus operation to calculate the remainder (i.e., <code>a % b</code>).</li>
* <li>Pushes the result of the modulus operation back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>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.</p>
*/
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.
*
* <p>This method retrieves the two short16 values from the operand stack, performs the modulus operation, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link SMulCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two short16 values from the operand stack.</li>
* <li>Performs the multiplication of the two values (i.e., <code>a * b</code>).</li>
* <li>Pushes the result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to multiply two short16 values together, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the two short16 values from the operand stack, multiplies them together, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link SNegCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top short16 value from the operand stack.</li>
* <li>Performs the negation of the popped value (i.e., <code>-value</code>).</li>
* <li>Pushes the negated result back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to negate an short16 value, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>This method retrieves the short16 value from the operand stack, negates it, and pushes the result back onto the operand stack.</p>
*
* @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;
}
}

View File

@ -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.
* <p>This opcode is implemented by the {@link SSubCommand} class, which defines its specific execution logic.</p>
*
* <p>Execution Steps:</p>
* <ol>
* <li>Pops the top two short16 values from the operand stack.</li>
* <li>Performs the subtraction of the second popped value from the first (i.e., <code>a - b</code>).</li>
* <li>Pushes the result of the subtraction back onto the operand stack for subsequent instructions to use.</li>
* </ol>
*
* <p>This opcode is typically used to subtract one short16 value from another, making it a fundamental operation for arithmetic logic within the virtual machine.</p>
*/
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.
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two operands from the virtual machine stack.</li>
* <li>Performs the int32 bitwise AND (`&`) operation.</li>
* <li>Pushes the result back onto the virtual machine stack.</li>
* </ul>
*/
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;
}
}

View File

@ -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.
*
* <p><b>Operation details:</b></p>
* <ul>
* <li>Pops two operands from the virtual machine stack.</li>
* <li>Performs the int32 bitwise OR (`|`) operation.</li>
* <li>Pushes the result back onto the virtual machine stack.</li>
* </ul>
*/
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;
}
}

View File

@ -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.
*
* <p><b>Operation details:</b></p>
* <ul>
* <li>Pops two operands from the virtual machine stack.</li>
* <li>Performs the int32 bitwise XOR (`^`) operation.</li>
* <li>Pushes the result back onto the virtual machine stack.</li>
* </ul>
*/
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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two operands from the virtual machine stack.</li>
* <li>Performs the long64 bitwise AND (`&`) operation.</li>
* <li>Pushes the result back onto the virtual machine stack.</li>
* </ul>
*/
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;
}
}

View File

@ -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.
*
* <p><b>Operation details:</b></p>
* <ul>
* <li>Pops two operands from the virtual machine stack.</li>
* <li>Performs the long64 bitwise OR (`|`) operation.</li>
* <li>Pushes the result back onto the virtual machine stack.</li>
* </ul>
*/
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;
}
}

View File

@ -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.
*
* <p><b>Operation details:</b></p>
* <ul>
* <li>Pops two operands from the virtual machine stack.</li>
* <li>Performs the long64 bitwise XOR (`^`) operation.</li>
* <li>Pushes the result back onto the virtual machine stack.</li>
* </ul>
*/
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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Parses the target instruction address and performs validation.</li>
* <li>If the target address is valid (greater than or equal to 0), it jumps to the specified address.</li>
* <li>If the target address is invalid (less than 0), it outputs an error message and halts execution.</li>
* </ul>
*/
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.
*
* <p>This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's
* specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction
* to be executed.</p>
*
* <p>The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow
* of execution by updating the program counter.</p>
*
* <p>The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching,
* function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame,
* while a `POP` instruction will remove an item from the operand stack.</p>
*
* @param parts The array of instruction parameters, which usually includes the operator and related arguments
* (such as target addresses, values, or function names). These parameters may vary based on
* the instruction being executed.
* @param currentPC The current program counter-value, indicating the address of the instruction being executed.
* This value is typically incremented after the execution of each instruction to point to the next one.
* @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack,
* such as pushing, popping, and peeking values.
* @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution.
* The store may not be used in every command but can be leveraged by instructions that require access
* to local variables.
* @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by
* instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions).
* @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the
* instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address
* corresponding to the target of the jump or the subroutine to call.
*/
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) {
// Parse the target 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
}
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two integers from the virtual machine stack.</li>
* <li>If the two integers are equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's
* specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction
* to be executed.</p>
*
* <p>The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow
* of execution by updating the program counter.</p>
*
* <p>The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching,
* function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame,
* while a `POP` instruction will remove an item from the operand stack.</p>
*
* @param parts The array of instruction parameters, which usually includes the operator and related arguments
* (such as target addresses, values, or function names). These parameters may vary based on
* the instruction being executed.
* @param currentPC The current program counter-value, indicating the address of the instruction being executed.
* This value is typically incremented after the execution of each instruction to point to the next one.
* @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack,
* such as pushing, popping, and peeking values.
* @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution.
* The store may not be used in every command but can be leveraged by instructions that require access
* to local variables.
* @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by
* instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions).
* @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the
* instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address
* corresponding to the target of the jump or the subroutine to call.
*/
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) {
// Parse the target command address
int target = Integer.parseInt(parts[1]);
// Pop the two operands from the stack
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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two integers from the virtual machine stack.</li>
* <li>If the first integer is greater than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's
* specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction
* to be executed.</p>
*
* <p>The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow
* of execution by updating the program counter.</p>
*
* <p>The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching,
* function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame,
* while a `POP` instruction will remove an item from the operand stack.</p>
*
* @param parts The array of instruction parameters, which usually includes the operator and related arguments
* (such as target addresses, values, or function names). These parameters may vary based on
* the instruction being executed.
* @param currentPC The current program counter-value, indicating the address of the instruction being executed.
* This value is typically incremented after the execution of each instruction to point to the next one.
* @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack,
* such as pushing, popping, and peeking values.
* @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution.
* The store may not be used in every command but can be leveraged by instructions that require access
* to local variables.
* @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by
* instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions).
* @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the
* instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address
* corresponding to the target of the jump or the subroutine to call.
*/
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) {
// Parse the target command address
int target = Integer.parseInt(parts[1]);
// Pop the two operands from the stack
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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two integers from the virtual machine stack.</li>
* <li>If the first integer is greater than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's
* specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction
* to be executed.</p>
*
* <p>The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow
* of execution by updating the program counter.</p>
*
* <p>The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching,
* function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame,
* while a `POP` instruction will remove an item from the operand stack.</p>
*
* @param parts The array of instruction parameters, which usually includes the operator and related arguments
* (such as target addresses, values, or function names). These parameters may vary based on
* the instruction being executed.
* @param currentPC The current program counter-value, indicating the address of the instruction being executed.
* This value is typically incremented after the execution of each instruction to point to the next one.
* @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack,
* such as pushing, popping, and peeking values.
* @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution.
* The store may not be used in every command but can be leveraged by instructions that require access
* to local variables.
* @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by
* instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions).
* @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the
* instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address
* corresponding to the target of the jump or the subroutine to call.
*/
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) {
// Parse the target command address
int target = Integer.parseInt(parts[1]);
// Pop the two operands from the stack
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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two integers from the virtual machine stack.</li>
* <li>If the first integer is less than the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's
* specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction
* to be executed.</p>
*
* <p>The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow
* of execution by updating the program counter.</p>
*
* <p>The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching,
* function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame,
* while a `POP` instruction will remove an item from the operand stack.</p>
*
* @param parts The array of instruction parameters, which usually includes the operator and related arguments
* (such as target addresses, values, or function names). These parameters may vary based on
* the instruction being executed.
* @param currentPC The current program counter-value, indicating the address of the instruction being executed.
* This value is typically incremented after the execution of each instruction to point to the next one.
* @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack,
* such as pushing, popping, and peeking values.
* @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution.
* The store may not be used in every command but can be leveraged by instructions that require access
* to local variables.
* @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by
* instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions).
* @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the
* instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address
* corresponding to the target of the jump or the subroutine to call.
*/
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) {
// Parse the target command address
int target = Integer.parseInt(parts[1]);
// Pop the two operands from the stack
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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two integers from the virtual machine stack.</li>
* <li>If the first integer is less than or equal to the second, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's
* specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction
* to be executed.</p>
*
* <p>The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow
* of execution by updating the program counter.</p>
*
* <p>The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching,
* function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame,
* while a `POP` instruction will remove an item from the operand stack.</p>
*
* @param parts The array of instruction parameters, which usually includes the operator and related arguments
* (such as target addresses, values, or function names). These parameters may vary based on
* the instruction being executed.
* @param currentPC The current program counter-value, indicating the address of the instruction being executed.
* This value is typically incremented after the execution of each instruction to point to the next one.
* @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack,
* such as pushing, popping, and peeking values.
* @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution.
* The store may not be used in every command but can be leveraged by instructions that require access
* to local variables.
* @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by
* instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions).
* @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the
* instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address
* corresponding to the target of the jump or the subroutine to call.
*/
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) {
// Parse the target command address
int target = Integer.parseInt(parts[1]);
// Pop the two operands from the stack
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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops two integers from the virtual machine stack.</li>
* <li>If the two integers are not equal, jumps to the target command.</li>
* <li>Otherwise, the program continues with the next command.</li>
* </ul>
*/
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.
*
* <p>This method retrieves the necessary data from the virtual machine stack and local variable store based on the instruction's
* specific implementation, performs the operation, and updates the program counter (PC) to reflect the next instruction
* to be executed.</p>
*
* <p>The parameters provided allow the command to manipulate the operand stack, modify the local variables, and control the flow
* of execution by updating the program counter.</p>
*
* <p>The exact behavior of this method will depend on the specific instruction being executed (e.g., arithmetic, branching,
* function calls, etc.). For example, a `CALL` instruction will modify the call stack by pushing a new frame,
* while a `POP` instruction will remove an item from the operand stack.</p>
*
* @param parts The array of instruction parameters, which usually includes the operator and related arguments
* (such as target addresses, values, or function names). These parameters may vary based on
* the instruction being executed.
* @param currentPC The current program counter-value, indicating the address of the instruction being executed.
* This value is typically incremented after the execution of each instruction to point to the next one.
* @param operandStack The virtual machine's operand stack manager, responsible for performing operations on the operand stack,
* such as pushing, popping, and peeking values.
* @param localVariableStore The local variable store, typically used to manage method-local variables during instruction execution.
* The store may not be used in every command but can be leveraged by instructions that require access
* to local variables.
* @param callStack The virtual machine's call stack, which keeps track of the method invocation hierarchy. It is used by
* instructions that involve method calls or returns (such as `CALL` and `RETURN` instructions).
* @return The updated program counter-value, typically the current program counter-value incremented by 1, unless the
* instruction modifies control flow (such as a `JUMP` or `CALL`), in which case it may return a new address
* corresponding to the target of the jump or the subroutine to call.
*/
@Override
public int execute(String[] parts, int currentPC, OperandStack operandStack, LocalVariableStore localVariableStore, CallStack callStack) {
// Parse the target command address
int target = Integer.parseInt(parts[1]);
// Pop the two operands from the stack
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;
}
}

View File

@ -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.
*
* <p>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.</p>
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops the current program counter (the return address) from the stack and stores it for later use when the method returns.</li>
* <li>Pushes a new stack frame onto the call stack with the return address and the method context (e.g., method name, local variables).</li>
* <li>Updates the program counter to the target function address, effectively transferring control to the function.</li>
* </ul>
*
* <p>This behavior allows the virtual machine to execute functions by managing a call stack that keeps track of method invocations
* and return addresses.</p>
*/
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.
*
* <p>This method performs the following steps:</p>
* <ul>
* <li>Validates and extracts the target function address from the provided instruction parameters.</li>
* <li>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).</li>
* <li>Pushes the new stack frame onto the call stack.</li>
* <li>Sets the program counter to the target function address, causing execution to jump to that address.</li>
* </ul>
*
* <p>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.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>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.</p>
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops the return address (program counter) from the call stack.</li>
* <li>Clears the local variables of the current method (stack frame) using
* {@link LocalVariableStore#clearVariables()}.</li>
* <li>Restores the program counter to the return address.</li>
* <li>Resumes execution from the instruction following the method call.</li>
* </ul>
*
* <p>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.</p>
*
* <p>Example of the process:</p>
* <ol>
* <li>A method is called, pushing a new stack frame onto the call stack.</li>
* <li>Execution proceeds in the method, using the operand stack and local variables.</li>
* <li>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.</li>
* <li>Execution continues from the point where the method was called.</li>
* </ol>
*/
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.
*
* <p>This method performs the following actions:</p>
* <ul>
* <li>Checks if the call stack is empty (indicating no method to return from).</li>
* <li>Pops the current stack frame from the call stack, retrieving the return address.</li>
* <li>Clears the local variables in the current stack frame using
* {@link LocalVariableStore#clearVariables()}.</li>
* <li>Restores the program counter to the return address stored in the stack frame.</li>
* </ul>
*
* <p>The execution of this method results in the program counter being updated to
* the return address of the previous method in the call stack.</p>
*
* @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();
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Retrieves a value from the specified source index in the local variable store of the current method frame.</li>
* <li>Stores the retrieved value into the specified destination index within the same local variable store.</li>
* <li>Returns the updated program counter-value, indicating the continuation of the next instruction.</li>
* </ul>
*/
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.
*
* <p>This method performs the following operations:</p>
* <ul>
* <li>Parses the source and destination indices from the instruction parameters.</li>
* <li>Retrieves the value from the local variable store at the source index.</li>
* <li>Stores the retrieved value into the destination index of the local variable store.</li>
* <li>Increments the program counter to point to the next instruction in the program sequence.</li>
* </ul>
*
* <p>After execution, the program counter (PC) is updated to continue with the next instruction, unless control flow is modified.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Retrieves a value from the specified index in the local variable store of the current frame.</li>
* <li>Pushes that value onto the virtual machine operand stack.</li>
* <li>Returns the updated program counter-value, indicating the continuation of the next instruction.</li>
* </ul>
*/
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.
*
* <p>This method performs the following operations:</p>
* <ul>
* <li>Parses the index of the local variable to load from the instruction parameters.</li>
* <li>Retrieves the corresponding value from the local variable store of the current method frame.</li>
* <li>Pushes the retrieved value onto the operand stack for subsequent operations.</li>
* <li>Increments the program counter to point to the next instruction to be executed.</li>
* </ul>
*
* <p>After execution, the program counter (PC) is updated to continue with the next instruction in the sequence, unless control flow changes.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops a value from the virtual machine operand stack.</li>
* <li>Stores that value into the specified index location in the local variable store of the current frame on the call stack.</li>
* <li>Returns the updated program counter-value, indicating the continuation of the next instruction.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>The method performs the following actions:</p>
* <ul>
* <li>Parses the index of the local variable where the value will be stored.</li>
* <li>Pops the top value from the operand stack.</li>
* <li>Stores the popped value into the specified local variable index in the current method frame's local variable store.</li>
* <li>Returns the next program counter-value to continue execution of the following instruction.</li>
* </ul>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops a value from the virtual machine operand stack.</li>
* <li>Stores that value into the specified index location in the local variable store of the current frame on the call stack.</li>
* <li>Returns the updated program counter-value, indicating the continuation of the next instruction.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>The method performs the following actions:</p>
* <ul>
* <li>Parses the index of the local variable where the value will be stored.</li>
* <li>Pops the top value from the operand stack.</li>
* <li>Stores the popped value into the specified local variable index in the current method frame's local variable store.</li>
* <li>Returns the next program counter-value to continue execution of the following instruction.</li>
* </ul>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops a value from the virtual machine operand stack.</li>
* <li>Stores that value into the specified index location in the local variable store of the current frame on the call stack.</li>
* <li>Returns the updated program counter-value, indicating the continuation of the next instruction.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>The method performs the following actions:</p>
* <ul>
* <li>Parses the index of the local variable where the value will be stored.</li>
* <li>Pops the top value from the operand stack.</li>
* <li>Stores the popped value into the specified local variable index in the current method frame's local variable store.</li>
* <li>Returns the next program counter-value to continue execution of the following instruction.</li>
* </ul>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Retrieves a value from the specified index in the local variable store of the current frame.</li>
* <li>Pushes that value onto the virtual machine operand stack.</li>
* <li>Returns the updated program counter-value, indicating the continuation of the next instruction.</li>
* </ul>
*/
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.
*
* <p>This method performs the following operations:</p>
* <ul>
* <li>Parses the index of the local variable to load from the instruction parameters.</li>
* <li>Retrieves the corresponding value from the local variable store of the current method frame.</li>
* <li>Pushes the retrieved value onto the operand stack for subsequent operations.</li>
* <li>Increments the program counter to point to the next instruction to be executed.</li>
* </ul>
*
* <p>After execution, the program counter (PC) is updated to continue with the next instruction in the sequence, unless control flow changes.</p>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Pops a value from the virtual machine operand stack.</li>
* <li>Stores that value into the specified index location in the local variable store of the current frame on the call stack.</li>
* <li>Returns the updated program counter-value, indicating the continuation of the next instruction.</li>
* </ul>
*/
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.
*
* <p>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.</p>
*
* <p>The method performs the following actions:</p>
* <ul>
* <li>Parses the index of the local variable where the value will be stored.</li>
* <li>Pops the top value from the operand stack.</li>
* <li>Stores the popped value into the specified local variable index in the current method frame's local variable store.</li>
* <li>Returns the next program counter-value to continue execution of the following instruction.</li>
* </ul>
*
* @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;
}
}

View File

@ -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.
*
* <p>Specific behavior:</p>
* <ul>
* <li>Retrieves a value from the specified index in the local variable store of the current frame.</li>
* <li>Pushes that value onto the virtual machine operand stack.</li>
* <li>Returns the updated program counter-value, indicating the continuation of the next instruction.</li>
* </ul>
*/
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.
*
* <p>This method performs the following operations:</p>
* <ul>
* <li>Parses the index of the local variable to load from the instruction parameters.</li>
* <li>Retrieves the corresponding value from the local variable store of the current method frame.</li>
* <li>Pushes the retrieved value onto the operand stack for subsequent operations.</li>
* <li>Increments the program counter to point to the next instruction to be executed.</li>
* </ul>
*
* <p>After execution, the program counter (PC) is updated to continue with the next instruction in the sequence, unless control flow changes.</p>
*
* @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;
}
}

Some files were not shown because too many files have changed in this diff Show More