Files
kyn/src/executor/executor.cpp

96 lines
3.2 KiB
C++
Raw Normal View History

2025-09-30 21:29:06 +10:00
#include "executor.h"
#include "../defs/defs.h"
#include "../data/data.h"
#include "../error/error.h"
#include "../vars/vars.h"
#include "../modules/println/println.h"
#include "../modules/print/print.h"
#include "../modules/math/math.h"
#include "../modules/let/let.h"
#include "../modules/exit/exit.h"
#include "../modules/if/if.h"
#include "../modules/while/while.h"
#include "../modules/compare/compare.h"
#include "../modules/input/input.h"
2025-10-01 13:43:08 +10:00
#include "../modules/function/function.h"
2025-09-30 21:29:06 +10:00
Value execute(Instruction inst) {
// Special cases that need to manage their own argument evaluation
if (inst.instruction == InstructionType::Let) {
return modules::let(inst.args);
}
if (inst.instruction == InstructionType::If) {
return modules::ifs(inst.args);
}
if (inst.instruction == InstructionType::While) {
return modules::whiles(inst.args);
}
2025-10-01 13:43:08 +10:00
if (inst.instruction == InstructionType::Function) {
return modules::fndef(inst.args);
}
2025-09-30 21:29:06 +10:00
// For all other instructions, evaluate the arguments first
size_t i = 0;
while (i < inst.args.size()) {
bool evaluated = false;
if (inst.args[i].valtype == ValueType::Processed) {
if (inst.args[i].processed) {
inst.args[i] = execute(*inst.args[i].processed);
evaluated = true;
}
} else if (inst.args[i].valtype == ValueType::Variable) {
inst.args[i] = data::getValue(inst.args[i].varName.key);
evaluated = true;
}
if (!evaluated) {
i++;
}
}
// Then, execute the instruction with the evaluated arguments
switch (inst.instruction) {
case InstructionType::Print:
return modules::print(inst.args);
break;
case InstructionType::Println:
return modules::println(inst.args);
break;
case InstructionType::Math:
return modules::math(inst.args);
break;
case InstructionType::Compare:
return modules::compare(inst.args);
break;
case InstructionType::Input:
return modules::input(inst.args);
break;
case InstructionType::Exit:
return modules::exit(inst.args);
break;
2025-10-01 13:43:08 +10:00
case InstructionType::Variable: {
if (!inst.args.empty()) {
const std::string& name = inst.args[0].real;
if (data::functions.count(name)) {
Value return_val;
for (const auto& body_inst : data::functions.at(name)) {
return_val = execute(body_inst);
}
return return_val;
}
}
2025-09-30 21:29:06 +10:00
if (inst.args.size() > 2 && inst.args[1].valtype == ValueType::Real && inst.args[1].real == "=") {
return varmod(inst.args);
} else {
error("Unknown instruction or variable");
return Value("");
}
break;
2025-10-01 13:43:08 +10:00
}
2025-09-30 21:29:06 +10:00
default:
// Note: 'If' and 'Let' are already handled.
error("Unknown instruction");
return Value("");
}
}