Initial commit
This commit is contained in:
205
src/defs/defs.cpp
Normal file
205
src/defs/defs.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
#include "defs.h"
|
||||
#include "../error/error.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
InstructionType strToInstructionType(std::string in) {
|
||||
if (in == "println") return InstructionType::Println;
|
||||
else if (in == "print") return InstructionType::Print;
|
||||
else if (in == "math") return InstructionType::Math;
|
||||
else if (in == "let") return InstructionType::Let;
|
||||
else if (in == "exit") return InstructionType::Exit;
|
||||
else if (in == "if") return InstructionType::If;
|
||||
else if (in == "while") return InstructionType::While;
|
||||
else if (in == "compare") return InstructionType::Compare;
|
||||
else if (in == "input") return InstructionType::Input;
|
||||
else return InstructionType::Variable;
|
||||
}
|
||||
|
||||
Instruction::Instruction(std::vector<std::string> toks) {
|
||||
if (!toks.empty()) {
|
||||
// Get type of instruction from first token
|
||||
instruction = strToInstructionType(toks[0]);
|
||||
if (instruction == InstructionType::Variable) {
|
||||
for (std::string tok : toks) {
|
||||
args.push_back(Value(tok));
|
||||
}
|
||||
} else {
|
||||
// The rest are the args, convert them to values first
|
||||
for (size_t i = 1; i < toks.size(); i++) {
|
||||
args.push_back(Value(toks[i]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error("Empty tokens!");
|
||||
}
|
||||
}
|
||||
|
||||
Instruction::Instruction(std::vector<Value> toks) {
|
||||
if (!toks.empty()) {
|
||||
// Check type of value in first token, then compute token
|
||||
if (toks[0].valtype == ValueType::Real) {
|
||||
instruction = strToInstructionType(toks[0].real);
|
||||
} else {
|
||||
error("Instruction should be a real");
|
||||
}
|
||||
if (instruction == InstructionType::Variable) {
|
||||
for (const auto& tok : toks) {
|
||||
args.push_back(tok);
|
||||
}
|
||||
} else {
|
||||
// The rest are the args
|
||||
for (size_t i = 1; i < toks.size(); i++) {
|
||||
args.push_back(toks[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error("Empty tokens!");
|
||||
}
|
||||
}
|
||||
|
||||
Value::Value(std::string stringval) : valtype(ValueType::Real), real(stringval) {}
|
||||
|
||||
Value::Value(Instruction instval) : valtype(ValueType::Processed), processed(std::make_unique<Instruction>(std::move(instval))) {}
|
||||
|
||||
Value::Value() : valtype(ValueType::Real) {}
|
||||
|
||||
Value::Value(InstructionGroup instgroup) : valtype(ValueType::InstructionGroup), instructionGroup(instgroup) {};
|
||||
|
||||
Value::Value(const Value& other) : valtype(other.valtype), real(other.real), varName(other.varName), instructionGroup(other.instructionGroup) {
|
||||
if (other.processed) {
|
||||
processed = std::make_unique<Instruction>(*other.processed);
|
||||
}
|
||||
}
|
||||
|
||||
Value::Value(Varname varname) : valtype(ValueType::Variable), varName(varname) {}
|
||||
|
||||
Varname::Varname(std::string in) : key(in.substr(1)) {}
|
||||
Varname::Varname() : key("") {}
|
||||
|
||||
Value& Value::operator=(const Value& other) {
|
||||
if (this != &other) {
|
||||
valtype = other.valtype;
|
||||
real = other.real;
|
||||
varName = other.varName;
|
||||
instructionGroup = other.instructionGroup;
|
||||
if (other.processed) {
|
||||
processed = std::make_unique<Instruction>(*other.processed);
|
||||
} else {
|
||||
processed.reset();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string Value::toString() const {
|
||||
std::string out = "Value(type: ";
|
||||
switch (valtype) {
|
||||
case ValueType::Real:
|
||||
out += "Real, value: " + real + ")";
|
||||
break;
|
||||
case ValueType::Processed:
|
||||
out += "Processed, value: ";
|
||||
if (processed) {
|
||||
out += processed->toString();
|
||||
} else {
|
||||
out += "null";
|
||||
}
|
||||
out += ")";
|
||||
break;
|
||||
case ValueType::InstructionGroup:
|
||||
out += "InstructionGroup, contains " + std::to_string(instructionGroup.size()) + " instructions)";
|
||||
break;
|
||||
default:
|
||||
out += "FIXME)";
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string Instruction::toString() const {
|
||||
std::string out = "Instruction(type: ";
|
||||
switch (instruction) {
|
||||
case InstructionType::None:
|
||||
out += "None";
|
||||
break;
|
||||
case InstructionType::Println:
|
||||
out += "Println";
|
||||
break;
|
||||
case InstructionType::Math:
|
||||
out += "Math";
|
||||
break;
|
||||
case InstructionType::Let:
|
||||
out += "Let";
|
||||
break;
|
||||
case InstructionType::If:
|
||||
out += "If";
|
||||
break;
|
||||
case InstructionType::Compare:
|
||||
out += "Compare";
|
||||
break;
|
||||
case InstructionType::Input:
|
||||
out += "Input";
|
||||
break;
|
||||
default:
|
||||
out += "FIXME";
|
||||
break;
|
||||
}
|
||||
out += ", args: [";
|
||||
for (const auto& val : args) {
|
||||
out += val.toString() + ", ";
|
||||
}
|
||||
out += "])";
|
||||
return out;
|
||||
}
|
||||
|
||||
std::vector<Value> split(std::string line) {
|
||||
std::vector<Value> splitvals;
|
||||
std::string buf;
|
||||
bool instring = false;
|
||||
int brackets = 0;
|
||||
for (char chr : line) {
|
||||
if (chr == ' ' && !instring && brackets == 0 && !buf.empty()) {
|
||||
if (buf[0] == '$') {
|
||||
splitvals.push_back(Value(Varname(buf)));
|
||||
} else {
|
||||
splitvals.push_back(Value(buf));
|
||||
}
|
||||
buf = "";
|
||||
} else if (chr == '(' || chr == '[') {
|
||||
brackets += 1;
|
||||
if (brackets == 1) {
|
||||
if (!buf.empty()) {
|
||||
splitvals.push_back(Value(buf));
|
||||
buf = "";
|
||||
}
|
||||
} else {
|
||||
buf += chr;
|
||||
}
|
||||
} else if (chr == ')' || chr == ']') {
|
||||
brackets -= 1;
|
||||
if (brackets == 0) {
|
||||
if (!buf.empty()) {
|
||||
splitvals.push_back(Value(Instruction(split(buf))));
|
||||
buf = "";
|
||||
}
|
||||
}
|
||||
} else if (chr == '"') {
|
||||
instring = !instring;
|
||||
} else {
|
||||
buf += chr;
|
||||
}
|
||||
}
|
||||
if (!buf.empty()) {
|
||||
if (buf[0] == '$') {
|
||||
splitvals.push_back(Value(Varname(buf)));
|
||||
} else {
|
||||
splitvals.push_back(Value(buf));
|
||||
}
|
||||
}
|
||||
return splitvals;
|
||||
}
|
||||
|
||||
bool inReplMode = false;
|
||||
Reference in New Issue
Block a user