Skip to content

Commit

Permalink
refactor: Interpreter.cpp refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
mrunix00 committed Mar 18, 2024
1 parent df8f7f8 commit 5c276d1
Showing 1 changed file with 91 additions and 92 deletions.
183 changes: 91 additions & 92 deletions src/bytecode/vm/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,99 +3,98 @@
#include <iostream>

void Bytecode::Interpreter::execute(const Program &program) {
while (true) {
const auto currentLine = vm.call_stack.stackTop->current_line;
const auto currentSegment = vm.call_stack.stackTop->segment;
if (currentSegment == 0 &&
currentLine == program.segments[0]->instructions.size()) {
break;
}
const auto currentInstruction = program.segments[currentSegment]
->instructions[currentLine];
if (currentLine == program.segments[currentSegment]->instructions.size()) {
const auto &stackTop = vm.call_stack.stackTop;
for (; stackTop->segment != 0 ||
stackTop->current_line !=
program.segments[0]->instructions.size();
stackTop->current_line++) {
const auto currentSegment =
program.segments[stackTop->segment];
const auto currentInstruction =
currentSegment->instructions[stackTop->current_line];
if (stackTop->current_line == currentSegment->instructions.size()) {
vm.call_stack.popStackFrame();
} else {
switch (currentInstruction->type) {
case InstructionType::Add:
vm.program_stack.push(
vm.program_stack.pop().asNumber() +
vm.program_stack.pop().asNumber());
break;
case InstructionType::Subtract: {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
vm.program_stack.push(object1.asNumber() - object2.asNumber());
} break;
case InstructionType::Multiply:
vm.program_stack.push(
vm.program_stack.pop().asNumber() *
vm.program_stack.pop().asNumber());
break;
case InstructionType::Divide: {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
vm.program_stack.push(object1.asNumber() / object2.asNumber());
} break;
case InstructionType::Equals: {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
vm.program_stack.push(object1.asNumber() == object2.asNumber());
} break;
case InstructionType::LessThan: {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
vm.program_stack.push(object1.asNumber() < object2.asNumber());
} break;
case InstructionType::GreaterThan: {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
vm.program_stack.push(object1.asNumber() > object2.asNumber());
} break;
case InstructionType::Not:
vm.program_stack.push(!vm.program_stack.pop().asBoolean());
break;
case InstructionType::LoadLiteral:
vm.program_stack.push(currentInstruction->literal);
break;
case InstructionType::LoadLocal:
vm.program_stack.push(vm.call_stack.getLocal(
currentInstruction->reg));
break;
case InstructionType::LoadGlobal:
vm.program_stack.push(vm.getGlobal(
currentInstruction->reg));
break;
case InstructionType::StoreGlobal:
vm.setGlobal(currentInstruction->reg, vm.program_stack.pop());
break;
case InstructionType::CondJumpIfNot:
if (const auto cond = vm.program_stack.pop();
!cond.asBoolean())
vm.call_stack.stackTop->current_line = currentInstruction->param - 1;
break;
case InstructionType::Jump:
vm.call_stack.stackTop->current_line = currentInstruction->param - 1;
break;
case InstructionType::Call:
vm.call_stack.newStackFrame(
currentInstruction->reg,
currentInstruction->param,
&vm.program_stack);
break;
case InstructionType::CallLambda: {
const auto lambda = vm.program_stack.pop();
vm.call_stack.newStackFrame(
lambda.asLambda(),
currentInstruction->param,
&vm.program_stack);
} break;
case InstructionType::SendToStdout:
std::cout << vm.program_stack.pop().toString();
break;
default:
throw;
}
continue;
}
switch (currentInstruction->type) {
case InstructionType::Add:
vm.program_stack.push(
vm.program_stack.pop().asNumber() +
vm.program_stack.pop().asNumber());
break;
case InstructionType::Subtract: {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
vm.program_stack.push(object1.asNumber() - object2.asNumber());
} break;
case InstructionType::Multiply:
vm.program_stack.push(
vm.program_stack.pop().asNumber() *
vm.program_stack.pop().asNumber());
break;
case InstructionType::Divide: {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
vm.program_stack.push(object1.asNumber() / object2.asNumber());
} break;
case InstructionType::Equals: {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
vm.program_stack.push(object1.asNumber() == object2.asNumber());
} break;
case InstructionType::LessThan: {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
vm.program_stack.push(object1.asNumber() < object2.asNumber());
} break;
case InstructionType::GreaterThan: {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
vm.program_stack.push(object1.asNumber() > object2.asNumber());
} break;
case InstructionType::Not:
vm.program_stack.push(!vm.program_stack.pop().asBoolean());
break;
case InstructionType::LoadLiteral:
vm.program_stack.push(currentInstruction->literal);
break;
case InstructionType::LoadLocal:
vm.program_stack.push(vm.call_stack.getLocal(
currentInstruction->reg));
break;
case InstructionType::LoadGlobal:
vm.program_stack.push(vm.getGlobal(
currentInstruction->reg));
break;
case InstructionType::StoreGlobal:
vm.setGlobal(currentInstruction->reg, vm.program_stack.pop());
break;
case InstructionType::CondJumpIfNot:
if (const auto cond = vm.program_stack.pop();
!cond.asBoolean())
stackTop->current_line = currentInstruction->param - 1;
break;
case InstructionType::Jump:
stackTop->current_line = currentInstruction->param - 1;
break;
case InstructionType::Call:
vm.call_stack.newStackFrame(
currentInstruction->reg,
currentInstruction->param,
&vm.program_stack);
break;
case InstructionType::CallLambda: {
const auto lambda = vm.program_stack.pop();
vm.call_stack.newStackFrame(
lambda.asLambda(),
currentInstruction->param,
&vm.program_stack);
} break;
case InstructionType::SendToStdout:
std::cout << vm.program_stack.pop().toString();
break;
default:
throw;
}
vm.call_stack.stackTop->current_line++;
}
}

0 comments on commit 5c276d1

Please sign in to comment.