#include "defs.h" #include "../error/error.h" #include #include #include #include #include "../datatypes/lists.h" 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 if (in == "return") return InstructionType::Return; else if (in == "concat") return InstructionType::Concat; else return InstructionType::Variable; } Instruction::Instruction(std::vector 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 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(std::move(instval))) {} Value::Value() : valtype(ValueType::Real) {} Value::Value(InstructionGroup instgroup) : valtype(ValueType::InstructionGroup), instructionGroup(instgroup) {}; Value::Value(std::vector listval) : valtype(ValueType::List), list(std::move(listval)) {} Value::Value(const Value& other) : valtype(other.valtype), real(other.real), varName(other.varName), instructionGroup(other.instructionGroup), list(other.list) { if (other.processed) { processed = std::make_unique(*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; list = other.list; if (other.processed) { processed = std::make_unique(*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; case ValueType::List: { out += "List, items: ["; for (const auto& item : list) { out += item.toString() + ", "; } out += "])"; 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 split(std::string line) { std::vector splitvals; std::string buf; bool instring = false; int brackets = 0; char bracket_type = 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 == '[') { if (brackets == 0) { bracket_type = chr; if (!buf.empty()) { splitvals.push_back(Value(buf)); buf = ""; } } else { buf += chr; } brackets++; } else if (chr == ')' || chr == ']') { brackets--; if (brackets == 0) { if (!buf.empty()) { if (bracket_type == '(') { splitvals.push_back(Value(Instruction(split(buf)))); } else { splitvals.push_back(Value(parse_list_content(buf))); } buf = ""; } } else { buf += chr; } } 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;