#include<iostream>
#include<fstream>
#include<sstream>
#include<vector>
#include<string>
#include<map>
#include<stack>
using namespace std;

vector<int> zas;		// zasobnik
int linenumber;			// pointer na #radku v kodu
map<string,int> lab;	// navesti: jmeno -> #radku
map<string,int> functions;	// jmeno fce -> #radku
stack<int> 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<instr *> prog;	// seznam instrukci programu
	string cur_fun("");
	do {
		string line, nazev, ins;
		getline(infile, line);

		// navesti
		bool isLab = false;
		for (int i=0; i<line.size(); i++) {
			if (line[i] == ':') {
				stringstream ss(line);
				ss >> 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; linenumber<prog.size(); linenumber++) {
		prog[linenumber]->Execute();
	}

	system("pause");
	return 0;
}