Refactoring datatypes start (unstable)
This commit is contained in:
@@ -1,53 +0,0 @@
|
|||||||
#include "lists.h"
|
|
||||||
|
|
||||||
// Helper to trim whitespace from the start and end of a string
|
|
||||||
std::string trim(const std::string& str) {
|
|
||||||
size_t first = str.find_first_not_of(" \t\n\r");
|
|
||||||
if (std::string::npos == first) {
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
size_t last = str.find_last_not_of(" \t\n\r");
|
|
||||||
return str.substr(first, (last - first + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Value> parse_list_content(const std::string& content) {
|
|
||||||
std::vector<Value> items;
|
|
||||||
std::string current_item;
|
|
||||||
bool in_string = false;
|
|
||||||
int nested_level = 0;
|
|
||||||
|
|
||||||
for (char c : content) {
|
|
||||||
if (c == '"') {
|
|
||||||
in_string = !in_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == ',' && !in_string && nested_level == 0) {
|
|
||||||
// End of an item
|
|
||||||
std::string trimmed = trim(current_item);
|
|
||||||
if (!trimmed.empty()) {
|
|
||||||
if (trimmed.front() == '"' && trimmed.back() == '"') {
|
|
||||||
items.push_back(Value(trimmed.substr(1, trimmed.length() - 2)));
|
|
||||||
} else {
|
|
||||||
items.push_back(Value(trimmed));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current_item.clear();
|
|
||||||
} else {
|
|
||||||
if (c == '[' || c == '(') nested_level++;
|
|
||||||
if (c == ']' || c == ')') nested_level--;
|
|
||||||
current_item += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Last item
|
|
||||||
std::string trimmed = trim(current_item);
|
|
||||||
if (!trimmed.empty()) {
|
|
||||||
if (trimmed.front() == '"' && trimmed.back() == '"') {
|
|
||||||
items.push_back(Value(trimmed.substr(1, trimmed.length() - 2)));
|
|
||||||
} else {
|
|
||||||
items.push_back(Value(trimmed));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include "../defs/defs.h"
|
|
||||||
|
|
||||||
std::vector<Value> parse_list_content(const std::string& content);
|
|
||||||
std::string trim(const std::string& str);
|
|
||||||
112
src/datatypes/lists/lists.cpp
Normal file
112
src/datatypes/lists/lists.cpp
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
#include "lists.h"
|
||||||
|
#include "../../error/error.h"
|
||||||
|
#include "../../modules/math/math.h"
|
||||||
|
#include "../../data/data.h"
|
||||||
|
#include "../../utils/trim/trim.h"
|
||||||
|
#include "../../utils/evaluate/evaluate.h"
|
||||||
|
|
||||||
|
Value handleListOp(std::vector<Value> args) {
|
||||||
|
// listName idx = value
|
||||||
|
if (args.size() == 4 && args[2].valtype == ValueType::Real && args[2].real == "=") {
|
||||||
|
std::string var_name;
|
||||||
|
if (args[0].valtype == ValueType::Variable) {
|
||||||
|
var_name = args[0].varName.key;
|
||||||
|
} else if (args[0].valtype == ValueType::Real) {
|
||||||
|
var_name = args[0].real;
|
||||||
|
} else {
|
||||||
|
error("Invalid target for indexed assignment");
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Value subject = data::getValue(var_name);
|
||||||
|
Value index_val = evaluate(args[1]);
|
||||||
|
Value new_val = evaluate(args[3]);
|
||||||
|
|
||||||
|
handleListSet(var_name, subject, index_val, new_val);
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Value handleListGet(const Value& subject, const std::vector<Value>& args) {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
error("Invalid number of arguments for list access");
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
Value accessor = args[0];
|
||||||
|
if (accessor.valtype != ValueType::Real) {
|
||||||
|
error("List accessor must be a real value");
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
if (accessor.real == "size") {
|
||||||
|
return Value(std::to_string(subject.list.size()));
|
||||||
|
}
|
||||||
|
if (mathstuff::strisdigit(accessor.real)) {
|
||||||
|
int index = std::stoi(accessor.real);
|
||||||
|
if (index < 0 || (size_t)index >= subject.list.size()) {
|
||||||
|
error("List index out of bounds");
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
return subject.list.at(index);
|
||||||
|
}
|
||||||
|
error("Invalid list accessor");
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleListSet(std::string var_name, Value& subject, const Value& index_val, const Value& new_val) {
|
||||||
|
if (index_val.valtype != ValueType::Real || !mathstuff::strisdigit(index_val.real)) {
|
||||||
|
error("Index must be an integer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int index = std::stoi(index_val.real);
|
||||||
|
|
||||||
|
if (index < 0 || (size_t)index >= subject.list.size()) {
|
||||||
|
error("List index out of bounds");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subject.list[index] = new_val;
|
||||||
|
data::modifyValue(var_name, subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Value> parseListContent(const std::string& content) {
|
||||||
|
std::vector<Value> items;
|
||||||
|
std::string current_item;
|
||||||
|
bool in_string = false;
|
||||||
|
int nested_level = 0;
|
||||||
|
|
||||||
|
for (char c : content) {
|
||||||
|
if (c == '"') {
|
||||||
|
in_string = !in_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == ',' && !in_string && nested_level == 0) {
|
||||||
|
// End of an item
|
||||||
|
std::string trimmed = trim(current_item);
|
||||||
|
if (!trimmed.empty()) {
|
||||||
|
if (trimmed.front() == '"' && trimmed.back() == '"') {
|
||||||
|
items.push_back(Value(trimmed.substr(1, trimmed.length() - 2)));
|
||||||
|
} else {
|
||||||
|
items.push_back(Value(trimmed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
current_item.clear();
|
||||||
|
} else {
|
||||||
|
if (c == '[' || c == '(') nested_level++;
|
||||||
|
if (c == ']' || c == ')') nested_level--;
|
||||||
|
current_item += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last item
|
||||||
|
std::string trimmed = trim(current_item);
|
||||||
|
if (!trimmed.empty()) {
|
||||||
|
if (trimmed.front() == '"' && trimmed.back() == '"') {
|
||||||
|
items.push_back(Value(trimmed.substr(1, trimmed.length() - 2)));
|
||||||
|
} else {
|
||||||
|
items.push_back(Value(trimmed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
10
src/datatypes/lists/lists.h
Normal file
10
src/datatypes/lists/lists.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "../../defs/defs.h"
|
||||||
|
|
||||||
|
Value handleListOp(std::vector<Value> args);
|
||||||
|
std::vector<Value> parseListContent(const std::string& content);
|
||||||
|
Value handleListGet(const Value& subject, const std::vector<Value>& args);
|
||||||
|
void handleListSet(std::string var_name, Value& subject, const Value& index_val, const Value& new_val);
|
||||||
71
src/datatypes/strings/strings.cpp
Normal file
71
src/datatypes/strings/strings.cpp
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#include "strings.h"
|
||||||
|
#include "../../error/error.h"
|
||||||
|
#include "../../modules/math/math.h"
|
||||||
|
#include "../../data/data.h"
|
||||||
|
#include "../../utils/evaluate/evaluate.h"
|
||||||
|
|
||||||
|
Value handleStringOp(std::vector<Value> args) {
|
||||||
|
if (args.size() == 4 && args[2].valtype == ValueType::Real && args[2].real == "=") {
|
||||||
|
std::string var_name;
|
||||||
|
if (args[0].valtype == ValueType::Variable) {
|
||||||
|
var_name = args[0].varName.key;
|
||||||
|
} else if (args[0].valtype == ValueType::Real) {
|
||||||
|
var_name = args[0].real;
|
||||||
|
} else {
|
||||||
|
error("Invalid target for indexed assignment");
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Value subject = data::getValue(var_name);
|
||||||
|
Value index_val = evaluate(args[1]);
|
||||||
|
Value new_val = evaluate(args[3]);
|
||||||
|
|
||||||
|
handleStringSet(var_name, subject, index_val, new_val);
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Value handleStringGet(const Value& subject, const std::vector<Value>& args) {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
error("Invalid number of arguments for string access");
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
Value accessor = args[0];
|
||||||
|
if (accessor.valtype != ValueType::Real) {
|
||||||
|
error("String accessor must be a real value");
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
if (accessor.real == "size") {
|
||||||
|
return Value(std::to_string(subject.real.length()));
|
||||||
|
}
|
||||||
|
if (mathstuff::strisdigit(accessor.real)) {
|
||||||
|
int index = std::stoi(accessor.real);
|
||||||
|
if (index < 0 || (size_t)index >= subject.real.length()) {
|
||||||
|
error("String index out of bounds");
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
return Value(std::string(1, subject.real.at(index)));
|
||||||
|
}
|
||||||
|
error("Invalid string accessor");
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleStringSet(std::string var_name, Value& subject, const Value& index_val, const Value& new_val) {
|
||||||
|
if (index_val.valtype != ValueType::Real || !mathstuff::strisdigit(index_val.real)) {
|
||||||
|
error("Index must be an integer");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int index = std::stoi(index_val.real);
|
||||||
|
|
||||||
|
if (new_val.valtype != ValueType::Real || new_val.real.length() != 1) {
|
||||||
|
error("Can only assign a single character to a string index");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index < 0 || (size_t)index >= subject.real.length()) {
|
||||||
|
error("String index out of bounds");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subject.real[index] = new_val.real[0];
|
||||||
|
data::modifyValue(var_name, subject);
|
||||||
|
}
|
||||||
8
src/datatypes/strings/strings.h
Normal file
8
src/datatypes/strings/strings.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../defs/defs.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
Value handleStringOp(std::vector<Value> args);
|
||||||
|
Value handleStringGet(const Value& subject, const std::vector<Value>& args);
|
||||||
|
void handleStringSet(std::string var_name, Value& subject, const Value& index_val, const Value& new_val);
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "../datatypes/lists.h"
|
#include "../datatypes/lists/lists.h"
|
||||||
|
|
||||||
InstructionType strToInstructionType(std::string in) {
|
InstructionType strToInstructionType(std::string in) {
|
||||||
if (in == "println") return InstructionType::Println;
|
if (in == "println") return InstructionType::Println;
|
||||||
@@ -45,8 +45,10 @@ Instruction::Instruction(std::vector<Value> toks) {
|
|||||||
// Check type of value in first token, then compute token
|
// Check type of value in first token, then compute token
|
||||||
if (toks[0].valtype == ValueType::Real) {
|
if (toks[0].valtype == ValueType::Real) {
|
||||||
instruction = strToInstructionType(toks[0].real);
|
instruction = strToInstructionType(toks[0].real);
|
||||||
|
} else if (toks[0].valtype == ValueType::Variable) {
|
||||||
|
instruction = InstructionType::Variable;
|
||||||
} else {
|
} else {
|
||||||
error("Instruction should be a real");
|
error("Instruction should be a real or variable value");
|
||||||
}
|
}
|
||||||
if (instruction == InstructionType::Variable) {
|
if (instruction == InstructionType::Variable) {
|
||||||
for (const auto& tok : toks) {
|
for (const auto& tok : toks) {
|
||||||
@@ -202,7 +204,7 @@ std::vector<Value> split(std::string line) {
|
|||||||
if (bracket_type == '(') {
|
if (bracket_type == '(') {
|
||||||
splitvals.push_back(Value(Instruction(split(buf))));
|
splitvals.push_back(Value(Instruction(split(buf))));
|
||||||
} else {
|
} else {
|
||||||
splitvals.push_back(Value(parse_list_content(buf)));
|
splitvals.push_back(Value(parseListContent(buf)));
|
||||||
}
|
}
|
||||||
buf = "";
|
buf = "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
#include "../defs/defs.h"
|
#include "../defs/defs.h"
|
||||||
#include "../data/data.h"
|
#include "../data/data.h"
|
||||||
#include "../error/error.h"
|
#include "../error/error.h"
|
||||||
#include "../vars/vars.h"
|
#include "../datatypes/lists/lists.h"
|
||||||
|
#include "../datatypes/strings/strings.h"
|
||||||
#include "../modules/println/println.h"
|
#include "../modules/println/println.h"
|
||||||
#include "../modules/print/print.h"
|
#include "../modules/print/print.h"
|
||||||
#include "../modules/math/math.h"
|
#include "../modules/math/math.h"
|
||||||
@@ -13,10 +14,12 @@
|
|||||||
#include "../modules/compare/compare.h"
|
#include "../modules/compare/compare.h"
|
||||||
#include "../modules/input/input.h"
|
#include "../modules/input/input.h"
|
||||||
#include "../modules/function/function.h"
|
#include "../modules/function/function.h"
|
||||||
#include "../modules/concat/concat.h"
|
|
||||||
|
// Forward declaration for mutual recursion
|
||||||
|
Value evaluate(Value val);
|
||||||
|
|
||||||
Value execute(Instruction inst) {
|
Value execute(Instruction inst) {
|
||||||
// Special cases that need to manage their own argument evaluation
|
// Special cases that don't evaluate their arguments first
|
||||||
if (inst.instruction == InstructionType::Let) {
|
if (inst.instruction == InstructionType::Let) {
|
||||||
return modules::let(inst.args);
|
return modules::let(inst.args);
|
||||||
}
|
}
|
||||||
@@ -29,67 +32,63 @@ Value execute(Instruction inst) {
|
|||||||
if (inst.instruction == InstructionType::Function) {
|
if (inst.instruction == InstructionType::Function) {
|
||||||
return modules::fndef(inst.args);
|
return modules::fndef(inst.args);
|
||||||
}
|
}
|
||||||
|
if (inst.instruction == InstructionType::Variable) {
|
||||||
// For all other instructions, evaluate the arguments first
|
auto& args = inst.args;
|
||||||
size_t i = 0;
|
if (args.empty()) {
|
||||||
while (i < inst.args.size()) {
|
return data::getValue(args[0].varName.key);
|
||||||
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) {
|
// Special reassignment
|
||||||
i++;
|
if (args[1].real != "=") {
|
||||||
|
switch (args[0].valtype) {
|
||||||
|
case ValueType::List:
|
||||||
|
handleListOp(args);
|
||||||
|
break;
|
||||||
|
case ValueType::Real:
|
||||||
|
handleStringOp(args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error("Working on it!");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then, execute the instruction with the evaluated arguments
|
// Simple reassignment: myVar = 20
|
||||||
switch (inst.instruction) {
|
if (args.size() == 3 && args[1].valtype == ValueType::Real && args[1].real == "=") {
|
||||||
case InstructionType::Print:
|
if (args[0].valtype != ValueType::Real) {
|
||||||
return modules::print(inst.args);
|
error("The target of an assignment must be a variable name.");
|
||||||
break;
|
return Value();
|
||||||
case InstructionType::Println:
|
}
|
||||||
return modules::println(inst.args);
|
std::string var_name = args[0].real;
|
||||||
break;
|
Value new_val = evaluate(args[2]);
|
||||||
case InstructionType::Math:
|
data::modifyValue(var_name, new_val);
|
||||||
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;
|
|
||||||
case InstructionType::Concat:
|
|
||||||
return modules::concat(inst.args);
|
|
||||||
break;
|
|
||||||
case InstructionType::Variable: {
|
|
||||||
if (!inst.args.empty()) {
|
|
||||||
const std::string& name = inst.args[0].real;
|
|
||||||
if (data::functions.count(name)) {
|
|
||||||
const auto& func = data::functions.at(name);
|
|
||||||
|
|
||||||
if (func.arg_names.size() != inst.args.size() - 1) {
|
|
||||||
error("Function " + name + " expects " + std::to_string(func.arg_names.size()) + " arguments, but got " + std::to_string(inst.args.size() - 1));
|
|
||||||
return Value();
|
return Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
data::pushScope();
|
// GET operations and function calls
|
||||||
|
Value subject = evaluate(args[0]);
|
||||||
|
std::vector<Value> op_args(args.begin() + 1, args.end());
|
||||||
|
|
||||||
for (size_t i = 0; i < func.arg_names.size(); ++i) {
|
if (!op_args.empty()) {
|
||||||
Value arg_val = inst.args[i+1];
|
if (subject.valtype == ValueType::List) {
|
||||||
data::scopes.back()[func.arg_names[i]] = arg_val;
|
return handleListGet(subject, op_args);
|
||||||
|
} else if (subject.valtype == ValueType::Real) {
|
||||||
|
return handleStringGet(subject, op_args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Function call
|
||||||
|
if (args[0].valtype == ValueType::Real && data::functions.count(args[0].real)) {
|
||||||
|
const auto& func = data::functions.at(args[0].real);
|
||||||
|
if (func.arg_names.size() != args.size() - 1) {
|
||||||
|
error("Function " + args[0].real + " expects " + std::to_string(func.arg_names.size()) + " arguments, but got " + std::to_string(args.size() - 1));
|
||||||
|
return Value();
|
||||||
|
}
|
||||||
|
data::pushScope();
|
||||||
|
for (size_t i = 0; i < func.arg_names.size(); ++i) {
|
||||||
|
Value arg_val = evaluate(args[i+1]);
|
||||||
|
data::scopes.back()[func.arg_names[i]] = arg_val;
|
||||||
|
}
|
||||||
Value return_val;
|
Value return_val;
|
||||||
for (const auto& body_inst : func.body) {
|
for (const auto& body_inst : func.body) {
|
||||||
return_val = execute(body_inst);
|
return_val = execute(body_inst);
|
||||||
@@ -97,21 +96,34 @@ Value execute(Instruction inst) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data::popScope();
|
data::popScope();
|
||||||
|
|
||||||
return_val.is_return = false;
|
return_val.is_return = false;
|
||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we get here, it's just a variable by itself, so return its value.
|
||||||
|
return subject;
|
||||||
}
|
}
|
||||||
if (inst.args.size() > 2 && inst.args[1].valtype == ValueType::Real && inst.args[1].real == "=") {
|
|
||||||
return varmod(inst.args);
|
// For all other instructions, evaluate the arguments first
|
||||||
} else {
|
for(auto& arg : inst.args) {
|
||||||
error("Unknown instruction or variable");
|
arg = evaluate(arg);
|
||||||
return Value("");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Then, execute the instruction with the evaluated arguments
|
||||||
|
switch (inst.instruction) {
|
||||||
|
case InstructionType::Print:
|
||||||
|
return modules::print(inst.args);
|
||||||
|
case InstructionType::Println:
|
||||||
|
return modules::println(inst.args);
|
||||||
|
case InstructionType::Math:
|
||||||
|
return modules::math(inst.args);
|
||||||
|
case InstructionType::Compare:
|
||||||
|
return modules::compare(inst.args);
|
||||||
|
case InstructionType::Input:
|
||||||
|
return modules::input(inst.args);
|
||||||
|
case InstructionType::Exit:
|
||||||
|
return modules::exit(inst.args);
|
||||||
case InstructionType::Return: {
|
case InstructionType::Return: {
|
||||||
if (inst.args.empty()) {
|
if (inst.args.empty()) {
|
||||||
Value val;
|
Value val;
|
||||||
@@ -123,7 +135,6 @@ Value execute(Instruction inst) {
|
|||||||
return return_val;
|
return return_val;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
// Note: 'If' and 'Let' are already handled.
|
|
||||||
error("Unknown instruction");
|
error("Unknown instruction");
|
||||||
return Value("");
|
return Value("");
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/utils/evaluate/evaluate.cpp
Normal file
15
src/utils/evaluate/evaluate.cpp
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include "evaluate.h"
|
||||||
|
#include "../../defs/defs.h"
|
||||||
|
#include "../../executor/executor.h"
|
||||||
|
#include "../../data/data.h"
|
||||||
|
|
||||||
|
Value evaluate(Value val) {
|
||||||
|
if (val.valtype == ValueType::Processed) {
|
||||||
|
if (val.processed) {
|
||||||
|
return execute(*val.processed);
|
||||||
|
}
|
||||||
|
} else if (val.valtype == ValueType::Variable) {
|
||||||
|
return data::getValue(val.varName.key);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
5
src/utils/evaluate/evaluate.h
Normal file
5
src/utils/evaluate/evaluate.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../defs/defs.h"
|
||||||
|
|
||||||
|
Value evaluate(Value val);
|
||||||
12
src/utils/trim/trim.cpp
Normal file
12
src/utils/trim/trim.cpp
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#include "trim.h"
|
||||||
|
|
||||||
|
// Helper to trim whitespace from the start and end of a string
|
||||||
|
std::string trim(const std::string& str) {
|
||||||
|
size_t first = str.find_first_not_of(" \t\n\r");
|
||||||
|
if (std::string::npos == first) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
size_t last = str.find_last_not_of(" \t\n\r");
|
||||||
|
return str.substr(first, (last - first + 1));
|
||||||
|
}
|
||||||
|
|
||||||
5
src/utils/trim/trim.h
Normal file
5
src/utils/trim/trim.h
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
std::string trim(const std::string& str);
|
||||||
Reference in New Issue
Block a user