Skip to content

Commit

Permalink
refactor: move instructions code to execute(VM&) method
Browse files Browse the repository at this point in the history
  • Loading branch information
mrunix00 committed Apr 19, 2024
1 parent bb3a2f5 commit 7d1a899
Show file tree
Hide file tree
Showing 30 changed files with 193 additions and 198 deletions.
2 changes: 0 additions & 2 deletions src/bytecode/compiler/Program.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,5 @@ namespace Bytecode {
size_t declare_lambda(Segment *);
size_t find_global(const std::string &);
size_t find_function(const std::string &);

bool operator==(const Program &program) const;
};
}// namespace Bytecode
10 changes: 10 additions & 0 deletions src/bytecode/instructions/Add.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
#pragma once

#include "bytecode/instructions/Instruction.h"
#include "exceptions/SyntaxError.h"

namespace Bytecode {
class Add final : public Instruction {
public:
Add() { type = InstructionType::Add; }
void execute(Bytecode::VM &vm) override {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
if (object1.type != ObjectType::Number ||
object2.type != ObjectType::Number) {
throw SyntaxError("Invalid argument type for function \"+\", Expected number, got string");
}
vm.program_stack.push(object1.asNumber() + object2.asNumber());
}
[[nodiscard]] std::string toString() const override { return "Add"; }
};
}// namespace Bytecode
12 changes: 11 additions & 1 deletion src/bytecode/instructions/AddRI.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
#pragma once

#include "Instruction.h"
#include "exceptions/SyntaxError.h"

namespace Bytecode {
class AddRI final : public Instruction {
public:
AddRI(uint32_t rg, double number) {
AddRI(size_t rg, double number) {
type = InstructionType::AddRI;
params = {rg, StackObject(number)};
}
void execute(Bytecode::VM &vm) override {
const auto object1 =params.ri_params.intermediate;
const auto object2 = vm.call_stack.getLocal(params.ri_params.reg);
if (object1.type != ObjectType::Number ||
object2.type != ObjectType::Number) {
throw SyntaxError("Invalid argument type for function \"+\", Expected number, got string");
}
vm.program_stack.push(object1.asNumber() + object2.asNumber());
}
[[nodiscard]] std::string toString() const override {
return "AddRI $r" + std::to_string(params.ri_params.reg) +
", " + params.ri_params.intermediate.toString();
Expand Down
10 changes: 10 additions & 0 deletions src/bytecode/instructions/And.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
#pragma once

#include "Instruction.h"
#include "exceptions/SyntaxError.h"

namespace Bytecode {
class And final : public Instruction {
public:
And() {type = InstructionType::And;}
void execute(Bytecode::VM &vm) override {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
if (object1.type != ObjectType::Boolean ||
object2.type != ObjectType::Boolean) {
throw SyntaxError("Invalid argument type for function \"and\", Expected boolean, got string");
}
vm.program_stack.push(object1.asBoolean() && object2.asBoolean());
}
[[nodiscard]] std::string toString() const override {
return "And";
}
Expand Down
6 changes: 6 additions & 0 deletions src/bytecode/instructions/Call.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ namespace Bytecode {
params.ri_params = {.reg = segment, .intermediate = StackObject(args)};
type = InstructionType::Call;
}
void execute(Bytecode::VM &vm) override {
vm.call_stack.newStackFrame(
params.ri_params.reg,
params.ri_params.intermediate.asLambda(),
&vm.program_stack);
}
[[nodiscard]] std::string toString() const override {
return "Call :" + std::to_string(params.ri_params.reg) +
", " + params.ri_params.intermediate.toString();
Expand Down
7 changes: 7 additions & 0 deletions src/bytecode/instructions/CallLambda.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ namespace Bytecode {
params.r_param = {args};
type = InstructionType::CallLambda;
}
void execute(Bytecode::VM &vm) override {
const auto lambda = vm.program_stack.pop();
vm.call_stack.newStackFrame(
lambda.asLambda(),
params.r_param.reg,
&vm.program_stack);
}
[[nodiscard]] std::string toString() const override {
return "CallLambda " + std::to_string(params.r_param.reg);
}
Expand Down
5 changes: 5 additions & 0 deletions src/bytecode/instructions/CondJumpIfNot.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ namespace Bytecode {
params.r_param = {line};
type = InstructionType::CondJumpIfNot;
}
void execute(Bytecode::VM &vm) override {
if (const auto cond = vm.program_stack.pop();
!cond.asBoolean())
vm.call_stack.stackTop->current_line = params.r_param.reg - 1;
}
[[nodiscard]] std::string toString() const override {
return "CondJumpIfNot " + std::to_string(params.r_param.reg);
}
Expand Down
3 changes: 3 additions & 0 deletions src/bytecode/instructions/Decrement.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ namespace Bytecode {
class Decrement final : public Instruction {
public:
Decrement() { type = InstructionType::Decrement; };
void execute(Bytecode::VM &vm) override {
vm.program_stack.push(vm.program_stack.pop().asNumber() - 1);
}
[[nodiscard]] std::string toString() const override { return "Decrement"; }
};
}// namespace Bytecode
4 changes: 4 additions & 0 deletions src/bytecode/instructions/DecrementR.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ namespace Bytecode {
params.r_param = {reg};
type = InstructionType::DecrementR;
}
void execute(Bytecode::VM &vm) override {
double number = vm.call_stack.getLocal(params.r_param.reg).asNumber();
vm.program_stack.push(number - 1);
}
[[nodiscard]] std::string toString() const override {
return "DecrementR $r" + std::to_string(params.r_param.reg);
}
Expand Down
13 changes: 13 additions & 0 deletions src/bytecode/instructions/Divide.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
#pragma once

#include "bytecode/instructions/Instruction.h"
#include "exceptions/SyntaxError.h"

namespace Bytecode {
class Divide final : public Instruction {
public:
Divide() { type = InstructionType::Divide; };
void execute(Bytecode::VM &vm) override {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
if (object1.type != ObjectType::Number ||
object2.type != ObjectType::Number) {
throw SyntaxError("Invalid argument type for function \"/\", Expected number, got string");
}
if (object2.asNumber() == 0) {
throw SyntaxError("Division by zero", 0, 0);
}
vm.program_stack.push(object1.asNumber() / object2.asNumber());
}
[[nodiscard]] std::string toString() const override { return "Divide"; }
};
}// namespace Bytecode
10 changes: 10 additions & 0 deletions src/bytecode/instructions/Equals.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
#pragma once

#include "bytecode/instructions/Instruction.h"
#include "exceptions/SyntaxError.h"

namespace Bytecode {
class Equals final : public Instruction {
public:
Equals() { type = InstructionType::Equals; };
void execute(Bytecode::VM &vm) override {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
if (object1.type != ObjectType::Number ||
object2.type != ObjectType::Number) {
throw SyntaxError("Invalid argument type for function \"=\", Expected number, got string");
}
vm.program_stack.push(object1.asNumber() == object2.asNumber());
}
[[nodiscard]] std::string toString() const override { return "Equals"; }
};
}// namespace Bytecode
10 changes: 10 additions & 0 deletions src/bytecode/instructions/GreaterThan.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
#pragma once

#include "bytecode/instructions/Instruction.h"
#include "exceptions/SyntaxError.h"

namespace Bytecode {
class GreaterThan final : public Instruction {
public:
GreaterThan() { type = InstructionType::GreaterThan; };
void execute(Bytecode::VM &vm) override {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
if (object1.type != ObjectType::Number ||
object2.type != ObjectType::Number) {
throw SyntaxError("Invalid argument type for function \">\", Expected number, got string");
}
vm.program_stack.push(object1.asNumber() > object2.asNumber());
}
[[nodiscard]] std::string toString() const override { return "GreaterThan"; }
};
}// namespace Bytecode
3 changes: 3 additions & 0 deletions src/bytecode/instructions/Increment.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ namespace Bytecode {
class Increment final : public Instruction {
public:
Increment() { type = InstructionType::Increment; };
void execute(Bytecode::VM &vm) override {
vm.program_stack.push(vm.program_stack.pop().asNumber() + 1);
}
[[nodiscard]] std::string toString() const override { return "Increment"; }
};
}// namespace Bytecode
1 change: 1 addition & 0 deletions src/bytecode/instructions/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ namespace Bytecode {
} params{.none = nullptr};
Instruction() : type(InstructionType::Unknown){};
virtual ~Instruction() = default;
virtual void execute(VM &vm) = 0;
[[nodiscard]] virtual std::string toString() const = 0;
};
}// namespace Bytecode
3 changes: 3 additions & 0 deletions src/bytecode/instructions/Jump.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ namespace Bytecode {
params.r_param.reg = line;
type = InstructionType::Jump;
}
void execute(Bytecode::VM &vm) override {
vm.call_stack.stackTop->current_line = params.r_param.reg - 1;
}
[[nodiscard]] std::string toString() const override {
return "Jump " + std::to_string(params.r_param.reg);
}
Expand Down
10 changes: 10 additions & 0 deletions src/bytecode/instructions/LessThan.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
#pragma once

#include "bytecode/instructions/Instruction.h"
#include "exceptions/SyntaxError.h"

namespace Bytecode {
class LessThan final : public Instruction {
public:
LessThan() { type = InstructionType::LessThan; };
void execute(Bytecode::VM &vm) override {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
if (object1.type != ObjectType::Number ||
object2.type != ObjectType::Number) {
throw SyntaxError("Invalid argument type for function \"<\", Expected number, got string");
}
vm.program_stack.push(object1.asNumber() < object2.asNumber());
}
[[nodiscard]] std::string toString() const override { return "LessThan"; }
};
}// namespace Bytecode
9 changes: 9 additions & 0 deletions src/bytecode/instructions/LessThanRI.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ namespace Bytecode {
params.ri_params = {.reg = rg, .intermediate = StackObject(number)};
type = InstructionType::LessThanRI;
}
void execute(Bytecode::VM &vm) override {
const auto object2 =params.ri_params.intermediate;
const auto object1 = vm.call_stack.getLocal(params.ri_params.reg);
if (object1.type != ObjectType::Number ||
object2.type != ObjectType::Number) {
throw SyntaxError("Invalid argument type for function \"<\", Expected number, got string");
}
vm.program_stack.push(object1.asNumber() < object2.asNumber());
}
[[nodiscard]] std::string toString() const override {
return "LessThanRI $r" + std::to_string(params.ri_params.reg) +
", " + params.ri_params.intermediate.toString();
Expand Down
4 changes: 3 additions & 1 deletion src/bytecode/instructions/LoadGlobal.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ namespace Bytecode {
params.r_param = {reg};
type = InstructionType::LoadGlobal;
}

void execute(Bytecode::VM &vm) override {
vm.program_stack.push(vm.getGlobal(params.r_param.reg));
}
[[nodiscard]] std::string toString() const override {
return "LoadGlobal $g" + std::to_string(params.r_param.reg);
}
Expand Down
4 changes: 4 additions & 0 deletions src/bytecode/instructions/LoadLiteral.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ namespace Bytecode {
type = InstructionType::LoadLiteral;
}

void execute(Bytecode::VM &vm) override {
vm.program_stack.push(params.i_param.intermediate);
}

[[nodiscard]] std::string toString() const override {
if (params.i_param.intermediate.type == ObjectType::String) {
std::string str = params.i_param.intermediate.toString();
Expand Down
4 changes: 3 additions & 1 deletion src/bytecode/instructions/LoadLocal.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ namespace Bytecode {
type = InstructionType::LoadLocal;
params.r_param = {reg};
}

void execute(Bytecode::VM &vm) override {
vm.program_stack.push(vm.call_stack.getLocal(params.r_param.reg));
}
[[nodiscard]] std::string toString() const override {
return "LoadLocal $r" + std::to_string(params.r_param.reg);
}
Expand Down
10 changes: 10 additions & 0 deletions src/bytecode/instructions/Multiply.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
#pragma once

#include "bytecode/instructions/Instruction.h"
#include "exceptions/SyntaxError.h"

namespace Bytecode {
class Multiply final : public Instruction {
public:
Multiply() { type = InstructionType::Multiply; };
void execute(VM &vm) override {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
if (object1.type != ObjectType::Number ||
object2.type != ObjectType::Number) {
throw SyntaxError("Invalid argument type for function \"*\", Expected number, got string");
}
vm.program_stack.push(object1.asNumber() * object2.asNumber());
}
[[nodiscard]] std::string toString() const override { return "Multiply"; }
};
}// namespace Bytecode
7 changes: 7 additions & 0 deletions src/bytecode/instructions/Not.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ namespace Bytecode {
class Not final : public Instruction {
public:
Not() { type = InstructionType::Not; }
void execute(Bytecode::VM &vm) override {
const auto object = vm.program_stack.pop();
if (object.type != ObjectType::Boolean)
vm.program_stack.push(false);
else
vm.program_stack.push(!object.asBoolean());
}
[[nodiscard]] std::string toString() const override { return "Not"; }
};
}// namespace Bytecode
10 changes: 10 additions & 0 deletions src/bytecode/instructions/Or.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
#pragma once

#include "Instruction.h"
#include "exceptions/SyntaxError.h"

namespace Bytecode {
class Or final : public Instruction {
public:
Or() {type = InstructionType::Or;}
void execute(Bytecode::VM &vm) override {
const auto object2 = vm.program_stack.pop();
const auto object1 = vm.program_stack.pop();
if (object1.type != ObjectType::Boolean ||
object2.type != ObjectType::Boolean) {
throw SyntaxError("Invalid argument type for function \"or\", Expected boolean, got string");
}
vm.program_stack.push(object1.asBoolean() || object2.asBoolean());
}
[[nodiscard]] std::string toString() const override {
return "Or";
}
Expand Down
10 changes: 10 additions & 0 deletions src/bytecode/instructions/ReadFromStdin.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ namespace Bytecode {
explicit ReadFromStdin() {
type = InstructionType::ReadFromStdin;
}
void execute(Bytecode::VM &vm) override {
std::string input;
std::getline(std::cin, input);
char *p;
double number = std::strtod(input.c_str(), &p);
if (*p)
vm.program_stack.push(input);
else
vm.program_stack.push(number);
}
[[nodiscard]] std::string toString() const override { return "ReadFromStdin"; }
};
}// namespace Bytecode
3 changes: 3 additions & 0 deletions src/bytecode/instructions/Return.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ namespace Bytecode {
class Return final : public Instruction {
public:
Return() { type = InstructionType::Return; }
void execute(Bytecode::VM &vm) override {
vm.call_stack.popStackFrame();
}
[[nodiscard]] std::string toString() const override { return "Return"; }
};
}// namespace Bytecode
Loading

0 comments on commit 7d1a899

Please sign in to comment.