#include #include #include #include #include #include #include using namespace std; vector zas; // zasobnik int linenumber; // pointer na #radku v kodu map lab; // navesti: jmeno -> #radku map functions; // jmeno fce -> #radku stack fzas; // zasobnik volani fci class instr { public: virtual void Execute() = 0; }; class add : public instr { void Execute() { int b = zas.back(); zas.pop_back(); int a = zas.back(); zas.pop_back(); zas.push_back(a+b); } }; class sub : public instr { void Execute() { int b = zas.back(); zas.pop_back(); int a = zas.back(); zas.pop_back(); zas.push_back(a-b); } }; class mul : public instr { void Execute() { int b = zas.back(); zas.pop_back(); int a = zas.back(); zas.pop_back(); zas.push_back(a*b); } }; class div2 : public instr { void Execute() { int b = zas.back(); zas.pop_back(); int a = zas.back(); zas.pop_back(); zas.push_back(a+b); } }; class mod : public instr { void Execute() { int b = zas.back(); zas.pop_back(); int a = zas.back(); zas.pop_back(); zas.push_back(a%b); } }; class read : public instr { public: void Execute() { int x; cin >> x; zas.push_back(x); } }; class go2 : public instr { string nazev; public: go2(string navesti) : nazev(navesti) {} void Execute() { linenumber = lab[nazev] - 1; } }; class jz : public instr { string nazev; public: jz(string navesti) : nazev(navesti) {} void Execute() { int x = zas.back(); zas.pop_back(); if (x == 0) { linenumber = lab[nazev] - 1; } } }; class call : public instr { string nazev; public: call(string navesti) : nazev(navesti) {} void Execute() { fzas.push(linenumber); linenumber = functions[nazev]; } }; class ret : public instr { public: ret() {} void Execute() { if (!fzas.empty()) { linenumber = fzas.top(); fzas.pop(); } } }; class dup : public instr { int n; public: dup(int n_) : n(n_) {} void Execute() { zas.push_back(zas[zas.size()-1+n]); } }; class push : public instr { int n; public: push(int n_) : n(n_) {} void Execute() { zas.push_back(n); } }; class pop : public instr { public: pop() {} void Execute() { int x = zas.back(); zas.pop_back(); //cout << "popped " << x << endl; } }; class print : public instr { public: void Execute() { int x = zas.back(); zas.pop_back(); cout << x << endl; //system("pause"); } }; class blop : public instr { public: void Execute() {} }; int main() { fstream infile; infile.open("sum.txt", ios::in); // parse linenumber = 0; int mainln = -1; vector prog; // seznam instrukci programu string cur_fun(""); do { string line, nazev, ins; getline(infile, line); // navesti bool isLab = false; for (int i=0; i> nazev >> ins; nazev.erase(nazev.size()-1, 1); isLab = true; lab.insert(make_pair(nazev+cur_fun, linenumber)); } } if (!isLab) { ins = line; } // jednoslovne prikazy if (!ins.compare("read")) { prog.push_back(new read()); } else if (!ins.compare("print")) { prog.push_back(new print()); } else if (!ins.compare("add")) { prog.push_back(new add()); } else if (!ins.compare("sub")) { prog.push_back(new sub()); } else if (!ins.compare("mul")) { prog.push_back(new mul()); } else if (!ins.compare("div")) { prog.push_back(new div2()); } else if (!ins.compare("mod")) { prog.push_back(new mod()); } else if (!ins.compare("pop")) { prog.push_back(new pop()); } else if (!ins.compare("return")) { prog.push_back(new ret()); // viceslovne prikazy } else { stringstream ss(ins); ss >> ins >> nazev; if (!ins.compare("goto")) { prog.push_back(new go2(nazev+cur_fun)); } else if (!ins.compare("jz")) { prog.push_back(new jz(nazev+cur_fun)); } else if (!ins.compare("push")) { stringstream ss2(nazev); int n; ss2 >> n; prog.push_back(new push(n)); } else if (!ins.compare("dup")) { stringstream ss2(line); int n; ss2 >> nazev; if (isLab) { ss2 >> nazev; } ss2 >> n; prog.push_back(new dup(n)); } else if (!ins.compare("function")) { stringstream ss2(line); ss2 >> nazev >> nazev; functions.insert(make_pair(nazev, linenumber)); if (!nazev.compare("main")) {mainln = linenumber;} cur_fun = nazev; prog.push_back(new blop()); } else if (!ins.compare("call")) { stringstream ss2(line); ss2 >> nazev; if (isLab) { ss2 >> nazev; } ss2 >> nazev; prog.push_back(new call(nazev)); } else { prog.push_back(new blop()); // prazdny radek } } linenumber++; } while (!infile.eof()); // execution for (linenumber= (mainln<0) ? 0 : mainln; linenumberExecute(); } system("pause"); return 0; }