#ifndef MASC__H_ #define MASC__H_ #include<iostream> #include<fstream> #include<map> #include<vector> #include<string> #include<list> #include<cstdio> #include "garbage.h" namespace masc { const double version = 2.01; char *mysprintf(char *src, const char *sptr, ...); int myprintf(const char *src, ...); struct symb { std::string val,name; int type; symb() { val = name = ""; type = 0; } }; class BackEnd; class Parser; class Symbol_Table { public: void Set(int type, std::string val, std::string name); symb &Get(std::string name); void DebugPrint() const; symb &operator[]( std::string str ) { return vars[str]; } symb &operator() ( size_t pos ); symb operator--(); std::list<symb>::iterator operator*() { return st.begin(); } void operator+=(const symb &s); std::list<symb> st; symb Pop(); void PopAll(); void Push(symb &s); protected: std::map<std::string, symb> vars; friend class BackEnd; friend class Parser; }; class MFile { public: std::string cur_line; MFile(std::string s) { file = 0; Open(s); } ~MFile() { if(opened == true) file->close(); delete file; } void Open(std::string s) { if(file && file->is_open()) file->close(); if(file) delete file; file = new std::fstream; file->open(s.c_str(),std::ios::in); if(!file->is_open()) { opened = false; return; } opened = true; file_name = s; curline = 0; } bool GetLine() { if(file->eof()) { file->close(); return true; } std::getline(*file,cur_line); ++curline; return false; } protected: std::fstream *file; bool opened; std::string file_name; int curline; }; struct Token { unsigned char type; std::string token; int line_num; std::string source_file; }; enum { IDENTIFIER = 1, DIGIT, STRING, CODELABEL }; class Parser : public MFile { public: friend class BackEnd; Parser(std::string s); void Begin(); void Parse(std::string str); void DebugTokens(); Token &operator[](size_t pos) { if(pos < tok_vec.size()) return tok_vec[pos]; else return cur; } bool LexAnayalize(); void StartParse(std::string str); inline bool pBounds(size_t pos) { if(pos < tok_vec.size()) { current_line = tok_vec[pos].line_num; current_file = tok_vec[pos].source_file; return true; } return false; } void ErrorMsg(const char *str, ...); private: Token cur; int err,current_line; std::string current_file; std::vector<Token> tok_vec; std::vector<std::string> insert_vec; }; struct Instruct { unsigned char op_code; std::string op1; std::string op2; Instruct(unsigned char op_code, std::string op1, std::string op2) { this->op_code = op_code; this->op1 = op1; this->op2 = op2; } Instruct() { op_code = 0; op1 = op2 = ""; } }; struct External_Callback { int (*f) (Symbol_Table &t); std::string name,other_name; bool isdef,imp; External_Callback() { name = ""; isdef = false; imp = false; } }; enum TOK_TYPE { TOK_INSERT, TOK_MAIN, TOK_USES, TOK_MAS, TOK_VAR, TOK_BEGIN, TOK_END, TOK_MOV, TOK_ADD,TOK_SUB,TOK_MUL,TOK_DIV,TOK_OR, TOK_XOR,TOK_AND,TOK_NOT,TOK_PUSH,TOK_POP,TOK_INC,TOK_DEC,TOK_CMP,TOK_JMP,TOK_JNE,TOK_JE,TOK_JL,TOK_JG,TOK_JLE,TOK_JGE,TOK_RET, TOK_EXIT,TOK_CALL,TOK_SCAT,TOK_PRINT, TOK_PROC,TOK_IMPLEMENT,TOK_EXTERN,VAR_INTEGER, VAR_STRING, VAR_FLOAT }; static const char *tok_array[] = {"insert", "master","uses","mas","var","begin","end","mov","add","sub","mul","div","or","xor","and","not", "push", "pop","inc","dec","cmp","jmp","jne","je","jl","jg","jle","jge","ret","exit","call","scat","print","proc","implement","extern","var&","var$","var#", 0, 0 }; enum PROC_RETURN { PROC_CONT, PROC_JMP, PROC_RET }; struct Code_Label { std::string label_name; std::string proc; size_t pos; Code_Label(std::string label_name, std::string proc, size_t pos) { this->label_name = label_name; this->pos = pos; this->proc = proc; } Code_Label() { label_name = ""; pos = 0; proc = ""; } }; class BackEnd { Parser *p; std::vector<std::vector<Instruct> > ins; std::string prog_name,current_obj; std::vector<std::string> uses; std::list<std::pair<size_t,size_t> > code; public: Symbol_Table symbols; BackEnd(Parser *p) { this->p = p; memset(reg,0,sizeof(reg)); back = this; } ~BackEnd() { if(p) delete p; } void Convert(); void Execute(bool anaylize); inline void Debug() { std::cout << "Program Name: " << prog_name << '\n'; p->DebugTokens(); symbols.DebugPrint(); DebugInc(); } inline bool Bounds(size_t pos) { if(pos < p->tok_vec.size()) return true; return false; } size_t Find(std::string what); void AddExternal(std::string name, int (*f)(Symbol_Table &t)); void DebugHTML(std::string src,bool sout); std::string GetName() { return prog_name; } void CallProcedure(std::string proc_name); static class BackEnd *back; protected: void AddIncBlock(std::string block_name, size_t start); void DebugInc(); PROC_RETURN ProcInc(size_t block, size_t &inc); bool IsVar(std::string &name); std::string byteToString(unsigned char type); std::string tokenTypeToString(TOK_TYPE t); size_t i , cur_pos; bool reg[4];// flag registers std::string prev_op1,prev_op2; std::map<std::string, External_Callback> callb; std::map<std::string,Code_Label> labels; std::map<std::string,std::string> obj; friend class Parser; }; inline int IdentToValue(std::string s); inline BackEnd *GetBend() { return BackEnd::back; } } #endif