cplusplus2x.Examples/C++20/MasterX/src/apps/ats/code_func.cpp
Source: cplusplus2x.Examples/C++20/MasterX/src/apps/ats/code_func.cpp
#include "code.hpp"
namespace interp {
bool saveLineSource(const std::string &text) {
std::fstream file;
file.open(text, std::ios::out);
if (!file.is_open())
return false;
for (unsigned int i = 0; i < lines.size(); ++i) {
file << lines[i].index << " " << lines[i].text << "\r\n";
}
file.close();
return true;
}
std::string eatComment(std::string src) {
std::string text;
for (unsigned int i = 0; i < src.length(); ++i) {
if (src[i] == ';')
return text;
else
text += src[i];
}
return text;
}
bool openLineSource(const std::string &text) {
std::fstream file;
file.open(text, std::ios::in);
if (!file.is_open())
return false;
if (!lines.empty()) {
lines.erase(lines.begin(), lines.end());
}
while (!file.eof() && file) {
std::string in, orig;
std::getline(file, orig);
in = eatComment(orig);
if (in.length() == 0)
continue;
std::vector<lex::Token> tokens;
std::istringstream stream(in);
lex::Scanner scan(stream);
while (scan.valid()) {
lex::Token token;
scan >> token;
if (token.getTokenType() != lex::TOKEN_EOF)
tokens.push_back(token);
}
inputText(tokens, in);
}
file.close();
return true;
}
void insertText(std::vector<lex::Token> &tokens, const TextLine &in) {
for (unsigned int i = 0; i < lines.size(); ++i) {
if (lines[i].index == in.index) {
if (checkInstruction(tokens, in)) {
lines[i].text = in.text;
return;
} else
return;
}
}
if (checkInstruction(tokens, in)) {
lines.push_back(in);
std::sort(lines.begin(), lines.end());
}
}
void inputText(std::vector<lex::Token> &tokens, std::string input_line) {
if (tokens.size() >= 2 && input_line.length() > 0) {
lex::Token_type num = tokens[0].getTokenType();
if (num != lex::TOKEN_DIGIT) {
stream << "Requires line number before code.\r\n";
return;
}
int value = atoi(tokens[0].getToken().c_str());
std::string codetext;
codetext = input_line.substr(input_line.find(tokens[0].getToken()) + tokens[0].getToken().length() + 1, input_line.length());
TextLine in(value, codetext);
insertText(tokens, in);
} else {
stream << "Error invalid input.\r\n";
return;
}
}
// should have used recursive functions
// will do for translating
bool checkInstruction(std::vector<lex::Token> &tokens, const TextLine &text) {
if (tokens.size() <= 1) {
stream << "Error: Statement requires instruction.\r\n";
return false;
}
static unsigned int inc_offset = 0;
if (tokens.size() >= 2) {
icode::opc op = icode::strtoInc(tokens[1].getToken());
if (op == icode::opc::NOTINC) {
if (tokens[1].getTokenType() != lex::TOKEN_CHAR) {
stream << "Syntax Error: After line number requires either Label or instruction.\r\n";
return false;
}
inc_offset = 1;
op = icode::strtoInc(tokens[1 + inc_offset].getToken());
if (op == icode::opc::NOTINC) {
stream << "Syntax Error: After Label requires Instruction.\r\n";
return false;
}
} else {
// check operands
if (tokens.size() >= 3 + inc_offset) {
if (tokens[2 + inc_offset].getToken() == "#") {
if (tokens.size() >= 4 + inc_offset) {
if (tokens[3 + inc_offset].getTokenType() == lex::TOKEN_DIGIT) {
} else if (tokens[3 + inc_offset].getTokenType() != lex::TOKEN_DIGIT && tokens[3 + inc_offset].getTokenType() != lex::TOKEN_HEX) {
stream << "Syntax Error: requires either digit or $.\r\n";
return false;
} else if (tokens[3 + inc_offset].getTokenType() != lex::TOKEN_HEX) {
stream << "Syntax Error: $ is followed by a Hex value\r\n";
return false;
}
if (tokens.size() >= 5 + inc_offset && tokens[4 + inc_offset].getToken() == ",") {
if (tokens.size() >= 6 + inc_offset && tokens[5 + inc_offset].getTokenType() == lex::TOKEN_CHAR) {
// check if register
}
} else if (tokens.size() >= 5 + inc_offset && tokens[4 + inc_offset].getToken() != ",") {
stream << "Syntax Error: Expecting comma instead I found: " << tokens[4].getToken() << "\r\n";
return false;
}
} else {
stream << "Syntax Error: Missing value after #\r\n";
return false;
}
}
} else {
return true; // check if inc requires no operand
}
}
}
return true;
}
bool procLine(const TextLine &text, Code &code) {
std::istringstream input(text.text);
lex::Scanner scan(input);
std::vector<lex::Token> tokens;
while (scan.valid()) {
lex::Token token;
scan >> token;
if (token.getTokenType() != lex::TOKEN_EOF)
tokens.push_back(token);
}
// for now output each token
stream << "Code Line: [" << text.index << "] - [" << text.text << "] = {\r\n";
for (unsigned int i = 0; i < tokens.size(); ++i) {
stream << tokens[i] << "\r\n";
}
stream << "}\r\n\r\n";
return true;
}
} // namespace interp