第一个可以运行的版本
This commit is contained in:
parent
a7f1627df0
commit
fc549217db
67
opcode
67
opcode
@ -1,69 +1,16 @@
|
||||
module: CommonTasks
|
||||
function: add_numbers
|
||||
parameter:
|
||||
declare num1: int
|
||||
declare num2: int
|
||||
return_type: int
|
||||
body:
|
||||
return num1 + num2
|
||||
end body
|
||||
end function
|
||||
end module
|
||||
|
||||
module: MathUtils
|
||||
function: square_number
|
||||
parameter:
|
||||
declare number: int
|
||||
return_type: int
|
||||
body:
|
||||
return number * number
|
||||
end body
|
||||
end function
|
||||
end module
|
||||
|
||||
module: StringUtils
|
||||
function: concatenate
|
||||
parameter:
|
||||
declare first_str: string
|
||||
declare second_str: string
|
||||
return_type: string
|
||||
body:
|
||||
return first_str + second_str
|
||||
end body
|
||||
end function
|
||||
end module
|
||||
|
||||
module: MainModule
|
||||
import: CommonTasks, MathUtils, StringUtils, BuiltinUtils
|
||||
|
||||
function: main
|
||||
parameter:
|
||||
args: string
|
||||
return_type: void
|
||||
declare num1: int
|
||||
declare num2: int
|
||||
return_type: int
|
||||
|
||||
body:
|
||||
loop:
|
||||
initializer:
|
||||
declare counter: int = 5
|
||||
condition:
|
||||
counter > 0
|
||||
update:
|
||||
counter = counter - 1
|
||||
body:
|
||||
BuiltinUtils.print(counter)
|
||||
end body
|
||||
end loop
|
||||
declare sum: int = num1 + num2
|
||||
|
||||
declare input_number: int = BuiltinUtils.to_int(args)
|
||||
if input_number == 0 then
|
||||
input_number = 999
|
||||
end if
|
||||
declare doubled: int = sum * 2
|
||||
|
||||
declare sum_result: int = CommonTasks.add_numbers(input_number, 20)
|
||||
|
||||
declare squared_result: int = MathUtils.square_number(sum_result)
|
||||
|
||||
declare final_message: string = StringUtils.concatenate("Result:",BuiltinUtils.to_string(squared_result))
|
||||
BuiltinUtils.print(final_message)
|
||||
return doubled
|
||||
end body
|
||||
end function
|
||||
end module
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,18 @@
|
||||
package org.jcnc.snow.compiler.cli;
|
||||
|
||||
import org.jcnc.snow.compiler.backend.RegisterAllocator;
|
||||
import org.jcnc.snow.compiler.backend.VMCodeGenerator;
|
||||
import org.jcnc.snow.compiler.ir.BasicIRBuilder;
|
||||
import org.jcnc.snow.compiler.ir.IRProgram;
|
||||
import org.jcnc.snow.compiler.ir.instr.IRFunction;
|
||||
import org.jcnc.snow.compiler.lexer.core.LexerEngine;
|
||||
import org.jcnc.snow.compiler.lexer.token.Token;
|
||||
import org.jcnc.snow.compiler.parser.core.ParserEngine;
|
||||
import org.jcnc.snow.compiler.parser.context.ParserContext;
|
||||
import org.jcnc.snow.compiler.parser.ast.base.Node;
|
||||
import org.jcnc.snow.compiler.parser.context.ParserContext;
|
||||
import org.jcnc.snow.compiler.parser.core.ParserEngine;
|
||||
import org.jcnc.snow.compiler.semantic.core.SemanticAnalyzerRunner;
|
||||
import org.jcnc.snow.vm.engine.VMMode;
|
||||
import org.jcnc.snow.vm.engine.VirtualMachineEngine;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -14,29 +21,59 @@ import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
|
||||
public class SnowCompiler {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
// 读取源文件
|
||||
String source = Files.readString(Path.of(args[0]), StandardCharsets.UTF_8);
|
||||
|
||||
/* ───── 读取源码 ───── */
|
||||
if (args.length == 0 || args[0].isBlank()) {
|
||||
System.err.println("Usage: SnowCompiler <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. 词法分析
|
||||
LexerEngine lexerEngine = new LexerEngine(source);
|
||||
List<Token> tokens = lexerEngine.getAllTokens();
|
||||
/* 1. 词法分析 */
|
||||
LexerEngine lexer = new LexerEngine(source);
|
||||
List<Token> tokens = lexer.getAllTokens();
|
||||
|
||||
// 2. 语法分析
|
||||
/* 2. 语法分析 */
|
||||
ParserContext ctx = new ParserContext(tokens);
|
||||
List<Node> ast = new ParserEngine(ctx).parse();
|
||||
List<Node> ast = new ParserEngine(ctx).parse();
|
||||
|
||||
// 3. 语义分析
|
||||
SemanticAnalyzerRunner.runSemanticAnalysis(ast,true);
|
||||
/* 3. 语义分析 */
|
||||
SemanticAnalyzerRunner.runSemanticAnalysis(ast, true);
|
||||
|
||||
/* 4. AST → IRProgram */
|
||||
IRProgram program = new BasicIRBuilder().buildProgram(ast);
|
||||
System.out.println("=== IR ===");
|
||||
System.out.println(program);
|
||||
|
||||
/* 5. 后端:寄存器分配 & 代码生成 + VM 执行 */
|
||||
for (IRFunction fn : program.functions()) {
|
||||
var alloc = new RegisterAllocator();
|
||||
var slotM = alloc.allocate(fn);
|
||||
|
||||
var gen = new VMCodeGenerator(slotM);
|
||||
var code = gen.generate(fn);
|
||||
|
||||
System.out.println("== VM code for " + fn.name() + " ==");
|
||||
code.forEach(System.out::println);
|
||||
|
||||
|
||||
/* 只执行 main 函数 */
|
||||
if ("main".equals(fn.name())) {
|
||||
VirtualMachineEngine vm = new VirtualMachineEngine(VMMode.RUN);
|
||||
|
||||
// 打印
|
||||
// System.out.println(source);
|
||||
// TokenPrinter.print(tokens); // 打印 Token 列表
|
||||
// ASTPrinter.print(ast); // 打印 AST
|
||||
// ASTPrinter.printJson(ast); // 打印JSON AST
|
||||
vm.execute(code); // 运行指令
|
||||
vm.printStack(); // 打印 Operand-/Call-Stack
|
||||
vm.printLocalVariables(); // 打印局部变量槽
|
||||
|
||||
System.out.println("Process has ended");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
142
src/main/java/org/jcnc/snow/compiler/ir/BasicIRBuilder.java
Normal file
142
src/main/java/org/jcnc/snow/compiler/ir/BasicIRBuilder.java
Normal 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;
|
||||
}
|
||||
}
|
||||
6
src/main/java/org/jcnc/snow/compiler/ir/Constant.java
Normal file
6
src/main/java/org/jcnc/snow/compiler/ir/Constant.java
Normal 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(); }
|
||||
}
|
||||
12
src/main/java/org/jcnc/snow/compiler/ir/IRInstruction.java
Normal file
12
src/main/java/org/jcnc/snow/compiler/ir/IRInstruction.java
Normal 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(); } // 默认无操作数
|
||||
}
|
||||
17
src/main/java/org/jcnc/snow/compiler/ir/IROp.java
Normal file
17
src/main/java/org/jcnc/snow/compiler/ir/IROp.java
Normal 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
|
||||
}
|
||||
24
src/main/java/org/jcnc/snow/compiler/ir/IRProgram.java
Normal file
24
src/main/java/org/jcnc/snow/compiler/ir/IRProgram.java
Normal 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();
|
||||
}
|
||||
}
|
||||
6
src/main/java/org/jcnc/snow/compiler/ir/IRValue.java
Normal file
6
src/main/java/org/jcnc/snow/compiler/ir/IRValue.java
Normal file
@ -0,0 +1,6 @@
|
||||
// ──────────────────────────────────────────
|
||||
// file: compiler/ir/IRValue.java
|
||||
package org.jcnc.snow.compiler.ir;
|
||||
|
||||
/** 常量、寄存器、标签的共同父接口 */
|
||||
public sealed interface IRValue permits VirtualRegister, Constant, Label {}
|
||||
6
src/main/java/org/jcnc/snow/compiler/ir/Label.java
Normal file
6
src/main/java/org/jcnc/snow/compiler/ir/Label.java
Normal 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 + ":"; }
|
||||
}
|
||||
@ -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; }
|
||||
}
|
||||
@ -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; }
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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; }
|
||||
}
|
||||
@ -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; }
|
||||
}
|
||||
@ -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; }
|
||||
}
|
||||
64
src/main/java/org/jcnc/snow/vm/VMInitializer.java
Normal file
64
src/main/java/org/jcnc/snow/vm/VMInitializer.java
Normal 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);
|
||||
}
|
||||
}
|
||||
49
src/main/java/org/jcnc/snow/vm/VMLauncher.java
Normal file
49
src/main/java/org/jcnc/snow/vm/VMLauncher.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user