← index
ats.web/source/code_func.cpp
Source: ats.web/source/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 << "\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.\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 if(tokens.size()==1 && input_line.length()>0) {
            int index_n = atoi(tokens[0].getToken().c_str());
            for(int i = 0; i < lines.size(); ++i) {
                if(lines[i].index == index_n) {
                    lines.erase(lines.begin()+i);
                    return;
                }
            }
        } 
        else {
            stream << "Error invalid input.\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.\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.\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.\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 $.\n";
                                return false;
                                
                            } else if(tokens[3+inc_offset].getTokenType() != lex::TOKEN_HEX) {
                                stream << "Syntax Error: $ is followed by a Hex value\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() << "\n";
                                return false;
                            }
                            
                        } else {
                            stream << "Syntax Error: Missing value after #\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
        std::cout << "Code Line: ["<<text.index <<"] - [" << text.text << "] = {\n";
        for(unsigned int i = 0; i < tokens.size(); ++i) {
            std::cout << tokens[i] << "\n";
        }
        std::cout << "}\n\n";
        return true;
    }
}