【集训队互测2015】未来程序·改

一个月之前写的题……

http://uoj.ac/submission/293973

真的毒瘤,调了5天……

然而还是有很多缺陷

  1. 内存泄漏太严重,已经补救过一发了,然而还是有很多泄漏
  2. 把cincout当作了关键字,实际上当作变量更好写,重载后也符合正常观念,但是重写这部分的时候写挂了,所以回档了

最后竟然被没有关键字引导的大括号卡RE了那么久

跑的又慢,代码又长,真的是垃圾代码

// ...
// By Daklqw
// 出题人 orz

// MemoryPool 重构版本
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
namespace Mirai {
#define LOCAL_TEST
// Constant Variables
// Array Size
const int ProgramMaxLength = 50010;
// Base Type
const int TypeMask = 0xF;
const int Symbol_t = 0x1;
const int Variable_t = 0x2;
const int Function_t = 0x3;
const int Keyword_t = 0x4;
// Symbol
const int SymbolMask = 0xFF0;
const int lsBracket_s = 0x010; 	// (
const int rsBracket_s = 0x020; 	// )
const int lmBracket_s = 0x030; 	// [
const int rmBracket_s = 0x040; 	// ]
const int Not_s = 0x050; 		// !
const int Positive_s = 0x060; 	// + (sum)
const int Negative_s = 0x070; 	// - (sum)
const int Multi_s = 0x080; 		// *
const int Divide_s = 0x090; 	// /
const int Module_s = 0x0A0; 	// %
const int Plus_s = 0x0B0; 		// +
const int Minus_s = 0x0C0; 		// -
const int lEq_s = 0x0D0;		// <= 
const int rEq_s = 0x0E0; 		// >=
const int Less_s = 0x0F0; 		// <
const int Greater_s = 0x100; 	// >
const int Eq_s = 0x110; 		// ==
const int nEq_s = 0x120; 		// !=
const int Xor_s = 0x130; 		// ^
const int And_s = 0x140; 		// &&
const int Or_s = 0x150; 		// ||
const int valueEq_s = 0x160; 	// (variable) = (statement)
const int lStream_s = 0x170; 	// ostream << (statememt)
const int rStream_s = 0x180; 	// istream >> (variable)
const int endOfAStatement_s = 0x190; // ;
const int llBracket_s = 0x200;  // {
const int rlBracket_s = 0x210;  // }
const int Split_s = 0x220;      // ,
const int Fill_s = 0xEE0; 		// Take Place
// Variable
const int VariableMask = 0xF000;
const int CommonType_v = 0x1000; // int x;
const int ArrayType_v = 0x2000; // int x[10];
const int Constant_v = 0x3000; // 10
// Function
const int FunctionMask = 0xF0000;
const int CustomType_f = 0x10000;
const int BuiltinType_f = 0x20000;
// Keyword
const int KeywordMask = 0xF00000;
const int Int_k = 0x100000;
const int Cin_k = 0x200000;
const int Cout_k = 0x300000;
const int If_k = 0x400000;
const int While_k = 0x500000;
const int For_k = 0x600000;
const int Return_k = 0x700000;
const int Else_k = 0x800000;

// Char Type
const int CharMask = 0xFF;
const int Digit_ct = 0x1;
const int Space_ct = 0x2;
const int Alpha_ct = 0x3;
const int Upper_ct = 0x10;
const int Lower_ct = 0x20;
const int Symbol_ct = 0x4;

// Flags
void * FlagFalse = (void*) 0x12345;
void * FlagTrue = (void*) 0x54321;
const int EndlFlag = 0x23333;

// Without const Warning

// Debug Control
int EnableDebug;

// Utils
class _Char_Checker_base {
public:
	inline bool isDigit(char x) { return '0' <= x && x <= '9'; }
	inline bool isSpace(char x) { return x == ' ' || x == '\n' || x == '\r' || x == '\t'; }
	inline bool isAlpha(char x) { return ('A' <= x && x <= 'Z') || ('a' <= x && x <= 'z'); }
	inline bool isUpper(char x) { return 'A' <= x && x <= 'Z'; }
	inline bool isLower(char x) { return 'a' <= x && x <= 'z'; }
	inline bool isSymbol(char x) { return !isDigit(x) && !isSpace(x) && !isAlpha(x); }
	inline int getType(char x) {
		if (isDigit(x)) return Digit_ct;
		if (isSpace(x)) return Space_ct;
		if (isAlpha(x)) return (isLower(x) ? Lower_ct : Upper_ct) | Alpha_ct;
		return Symbol_ct;
	}
private:

} Char_Checker;

class _StringUtil_base {
public:
	inline unsigned length(const char * x) { return strlen(x); }
	inline void cleanReturn(char * x) { char * cur = x + length(x) - 1; if (*cur == '\n') *cur = 0; }
	inline int strcmp(const char * a, const char * b, int lengthlimit = -1) {
		if (~lengthlimit) return strncmp(a, b, lengthlimit);
		return strcmp(a, b);
	}
	inline int parseInt(const char * buf) {
		int x = 0;
		while (*buf) x = ((x << 2) + x << 1) + (*buf++ & 15);
		return x;
	}
	inline int parseInt(const string & buf) {
		return parseInt(buf.c_str());
	}
	inline string substr(const string & x, const int l, const int r) {
		return x.substr(l, r - l);
	}
	inline string int_to_string(int x) { return std::to_string(x); }
	inline string toReturnFlag(const string & x) {
		string res = x;
		int cnt = 0;
		for (int i = 0; i != res.length(); ++i) {
			cnt += res[i] == '@';
			if (cnt == 3) return substr(x, 0, i + 1) + "returnFlag";
		}
		return string("");
	}
	inline string getVariableName(const string & x) {
		int at = 0;
		for (int i = 0; i != x.length(); ++i)
			if (x[i] == '@')
				at = i;
		return substr(x, at + 1, x.length());
	}
	inline string upFloor(const string & x) {
		int cnt = 0;
		for (int i = x.length() - 1; i; --i) {
			cnt += x[i] == '@';
			if (cnt == 2) 
				return substr(x, 0, i + 1) + getVariableName(x);
		}
		return getVariableName(x);
	}
	inline int nxtChr(const string & x, const char ch) {
		int cur = 0, res = -1;
		while (cur != x.length()) {
			if (x[cur] == ch) return cur;
			++cur;
		}
		return -1;
	}
} StringUtil;

class _NameManager_base {
public:
	_NameManager_base() { bak = 0; }
	inline int getID(string x) {
		map<string, int>::iterator it = name.find(x);
		if (it != name.end()) return it -> second;
		Q.push_back(x);
		return name[x] = ++bak;
	}
	inline string getIDs(string x) { return StringUtil.int_to_string(getID(x)); }
	inline string getNameByID(int x) { return Q[x - 1]; }
private:
	map<string, int> name;
	vector<string> Q;
	int bak;
} NameManager;

class _SymbolLevelManager_base {
public:
	inline bool isKeyword(int symbol) { return !!(symbol & KeywordMask); }
	inline bool isBracket(int symbol) { 
		switch (symbol & SymbolMask) {
			case lsBracket_s: case rsBracket_s:
			case lmBracket_s: case rmBracket_s:
			case llBracket_s: case rlBracket_s:
				return true;
			default:
				return false;
		}
	}
	inline bool isControlKeyword(int symbol) {
		switch (symbol & KeywordMask) {
			case For_k: case If_k: case While_k:
				return true;
			default:
				return false;
		}
	}
	inline int getLevel(int symbol) {
		int res = 0;
		switch (symbol & SymbolMask) {
			case lsBracket_s : res = 11; break;
			case rsBracket_s : res = 11; break;
			case lmBracket_s : res = 11; break;
			case rmBracket_s : res = 11; break;
			case Not_s : res = 10; break;
			case Positive_s : res = 10; break;
			case Negative_s : res = 10; break;
			case Multi_s : res = 9; break;
			case Divide_s : res = 9; break;
			case Module_s : res = 9; break;
			case Plus_s : res = 8; break;
			case Minus_s : res = 8; break;
			case lEq_s : res = 7; break;
			case rEq_s : res = 7; break;
			case Less_s : res = 7; break;
			case Greater_s : res = 7; break;
			case Eq_s : res = 6; break;
			case nEq_s : res = 6; break;
			case Xor_s : res = 5; break;
			case And_s : res = 4; break;
			case Or_s : res = 3; break;
			case valueEq_s : res = 2; break;
			case lStream_s : res = 1; break;
			case rStream_s : res = 1; break;
			default : res = -1; break;
		}
		return res;
	}
private:

} SymbolLevelManager;

// Base Type
class _StatementType_base {
public:
	string val; // int typ;
	// _StatementType_base(const string & _val, const int _typ) { val = _val; typ = _typ; }
	_StatementType_base(const string & _val) { val = _val; }
} ;
class _SymbolTranslater_base {
public:
	_SymbolTranslater_base() {
		S["("] = lsBracket_s;
		S[")"] = rsBracket_s;
		S["["] = lmBracket_s;
		S["]"] = rmBracket_s;
		S["!"] = Not_s;
		S["+"] = Plus_s;
		S["-"] = Minus_s;
		S["*"] = Multi_s;
		S["/"] = Divide_s;
		S["%"] = Module_s;
		S["<="] = lEq_s;
		S[">="] = rEq_s;
		S["<"] = Less_s;
		S[">"] = Greater_s;
		S["=="] = Eq_s;
		S["!="] = nEq_s;
		S["^"] = Xor_s;
		S["&&"] = And_s;
		S["||"] = Or_s;
		S["="] = valueEq_s;
		S["<<"] = lStream_s;
		S[">>"] = rStream_s;
		S[";"] = endOfAStatement_s;
		S["{"] = llBracket_s;
		S["}"] = rlBracket_s;
		S[","] = Split_s;

		S["int"] = Int_k;
		S["cin"] = Cin_k;
		S["cout"] = Cout_k;
		S["if"] = If_k;
		S["while"] = While_k;
		S["for"] = For_k;
		S["return"] = Return_k;
		S["else"] = Else_k;
	}
	int trans(string s) { return S[s]; }
private:
	map<string, int> S;
} SymbolTranslater;

// Data Object
class _StatementAutomaton_base {
public:
	inline bool haveNxt(int now, int tar) { return arr[now][tar]; }
	_StatementAutomaton_base() {
		const char buf1[] = "_$QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";
		for (int i = 0; i != 64; ++i)
			for (int j = 0; j != 64; ++j)
				arr[buf1[i]][buf1[j]] = true;
		arr['=']['='] = true;
		arr['<']['='] = true;
		arr['>']['='] = true;
		arr['!']['='] = true;
		arr['&']['&'] = true;
		arr['|']['|'] = true;
		arr['<']['<'] = true;
		arr['>']['>'] = true;
		arr['/']['/'] = true; // Just For Fun
		arr['+']['+'] = true; // Just For Fun
		arr['-']['-'] = true; // Just For Fun
		arr['-']['>'] = true; // Just For Fun Need to limit symbol length
	}
private:
	bool arr[256][256];
} StatementAutomaton;

class _StatementAutomatonNode_base {
public:
	inline int nxt(int target) { if (StatementAutomaton.haveNxt(now, target)) return now = target; return -1; }
	void setNode(int index) { now = index; }
	_StatementAutomatonNode_base(int index) { now = index; }
	_StatementAutomatonNode_base() {} 
private:
	int now;
} ;

class _ProgramBuffer_base {
public:
	void setBuf(const char * src) { memcpy(buf, src, StringUtil.length(src) + 1); cur = buf; }
	inline char nextChar() { return *cur++; }
	inline void backspace() { --cur; }
	inline void seek(int index) { cur = buf + index; }
	inline int indexNow() { return cur - buf; }
	inline bool haveNext() {
		const char * tcur = cur;
		while (*tcur) { if (!Char_Checker.isSpace(*tcur)) return true; ++tcur; }
		return false;
	}
	inline _StatementType_base nextStatement() {
		int ch;
		while (Char_Checker.isSpace(ch = nextChar())) ;
		string res;
		res.append(1, ch);
		_StatementAutomatonNode_base node(ch);
		while (true) {
			ch = nextChar();
			if (!~node.nxt(ch)) { backspace(); break; }
			res.append(1, ch);
		}
		return _StatementType_base(res);
	}
	void init() {
		while (true) {
			fgets(linev, ProgramMaxLength, stdin);
			if (StringUtil.strcmp(linev, "using namespace std;", StringUtil.length("using namespace std;")) == 0) break;
		}
		fread(buf, 1, ProgramMaxLength, stdin);
		cur = buf;
	}
private:
	char buf[ProgramMaxLength], linev[ProgramMaxLength];
	const char * cur;
} ProgramBuffer;

class _ReadinBuffer_base {
public:
	int	nextInt() { return sums[cur++]; }
	void init() {
		int cnt, t; scanf("%d", &cnt);
		for (int i = 1; i <= cnt; ++i) { scanf("%d", &t); sums.push_back(t); }
	}
private:
	vector<int> sums;
	int cur = 0;
} ReadinBuffer;

class _StatementLine_base {
public:
	void append(const _StatementType_base & x) { line.push_back(x); }
	inline int size() { return line.size(); }
	inline _StatementType_base operator [] (const int index) const  { return line[index]; }
	void init() {
		// Get Match
		const int tz = size();
		for (int i = 0; i != tz; ++i) {
			const char ct = line[i].val[0];
			if (Char_Checker.isSymbol(ct) && SymbolLevelManager.isBracket(SymbolTranslater.trans(line[i].val))) {
				if (ct == '(' || ct == '[' || ct == '{') st[++top] = i;
				else match[st[top--]] = i;
			}
			match[i] = i;
		}
	}
	inline int getMatch(int pos) { return match[pos]; }
	inline int findNxt(int now, int typ, int end = -1) {
		int r = -1; if (!~end) end = size();
		for (int i = now; i <= end; ++i)
			if (SymbolTranslater.trans((this -> operator[] (i)).val) == typ) {
				r = i;
				break;
			}
		return r;
	}
	inline int findEnd(int now, int end = -1) {
		return findNxt(now, endOfAStatement_s, end);
	}
	inline int getStatementEnd(int now, int end = -1) {
		// cout << "getStatementEnd " << now << " " << end << endl;
		int rr = -1;
		string tbuf = (this -> operator[] (now)).val;
		int typ = SymbolTranslater.trans(tbuf);
		if (typ == If_k || typ == For_k || typ == While_k) {
			int rr = this -> getMatch(now + 1);
			return getStatementEnd(rr + 1, end);
		} else if (typ == llBracket_s) // now + 1 ??? 
			rr = this -> getMatch(now);
		else
			rr = this -> findEnd(now, end); 
		return rr;
	}
private:
	vector<_StatementType_base> line;
	int st[ProgramMaxLength], top;
	int match[ProgramMaxLength];
} StatementLine;

// Objects
class _Object_base {
public:
	void setToken(const string & _token) { token = _token; }
	string getToken() { return token; }
	virtual _Object_base * getValue() = 0;
	_Object_base() { is_Reference = false; }
	bool isReference() { return is_Reference; }
	void setReference(bool v = false) { is_Reference = v; }
protected:
	string token;
	bool is_Reference;
} ;

// Object Object
int FunctionCallDep;
class _Function_base : public _Object_base {
public:
	virtual _Object_base * getValue() ;
	void setRange(int _b, int _e) { begin = _b; end = _e; }
	inline void argAppend(const string & x) { arg_list.push_back(x); }
	inline string getArg(const int index) { return arg_list[index]; }
	inline int getArgCount() { return arg_list.size(); }
private:
	vector<string> arg_list;
	int begin, end;
} ;

class _Variable_base : public _Object_base {
public:
	int value;
	_Variable_base() { value = 0; setReference(); }
	virtual _Object_base * getValue() { return this; }
	inline void setValue(int v) { value = v; }
} ;

class _Array_base : public _Object_base {
public:
	_Array_base(int arrsize) { arrsz = arrsize; arr = new _Object_base* [arrsize]; setReference(); }
	// ~_Array_base() { delete [] arr; } // 玄学
	virtual _Object_base * getValue() { return this; } // Warning
	virtual _Object_base * getValue(int index) { if (index < 0) cerr << "ERR! " << index << endl; return arr[index]; }
	inline void setValue(int index, _Object_base * src) { arr[index] = src; }
	static _Object_base * makeVariableTree(vector<int>::iterator il, vector<int>::iterator ir) {
		if (il == ir) {
			_Variable_base * res = new _Variable_base();
			res -> value = 0;
			res -> setReference(true);
			return static_cast<_Object_base*> (res);
		} else {
			_Array_base * res = new _Array_base(*il);
			for (int i = 0; i != *il; ++i)
				res -> setValue(i, makeVariableTree(il + 1, ir));
			res -> setReference(true);
			return static_cast<_Object_base*> (res);
		}
	}
	static void clearVariableTree(_Object_base * now, vector<int>::iterator il, vector<int>::iterator ir) {
		if (il == ir) static_cast<_Variable_base*> (now) -> value = 0;
		else for (int i = 0; i != *il; ++i)
			clearVariableTree(static_cast<_Array_base*> (now) -> getValue(i), il + 1, ir); 
	}
	int arrsz;
	_Object_base ** arr;
private:
} ;


class _MemoryPool_base {
public:
	inline _Object_base * call(const string & token) {
		// cout << "Call " << token << endl;
		return functions[token] -> getValue();
	}
	inline _Object_base * getVariable(const string & token) {
		if (variables.find(token) == variables.end()) return NULL;
		return variables[token];
	}
	inline _Object_base * getFunction(const string & token) {
		if (functions.find(token) == functions.end()) return NULL;
		return functions[token];
	}
	inline void setFunction(const string & token, _Object_base * src) {
		// cout << "MemoryPool@ SetFunction " << token << endl;
		functions[token] = src;
	}
	inline void setVariable(const string & token, _Object_base * src) {
		// cout << "MemoryPool@ SetVariable " << token << endl; // << " " << src -> isReference() << endl;
		/*
		if (!src -> isReference()) {
			cerr << "Error! " << endl;
			for (int i = 1; i <= 1000000000; ++i) ;
		}
		*/
		variables[token] = src;
	}
	inline _Object_base* findVariable(const string & token, int lines = -1) {
		string tk = token;
		map<string, _Object_base*>::iterator it;
		if (EnableDebug) cout << "findVariable " << token << endl;
		while (true) {
			it = variables.find(tk);
			if (it != variables.end()) return it -> second;
			tk = StringUtil.upFloor(tk);
			// if (EnableDebug) {
				if (!~StringUtil.nxtChr(tk, '@')) {
					cout << "Find Variable Failed" << endl;
					cout << "The Variable Name : " << NameManager.getNameByID(StringUtil.parseInt(StringUtil.getVariableName(token))) << endl;
					if (~lines) {
						cout << "Passege:" << endl;
						const int RAN = 5;
						int begin = max(0, lines - RAN), end = min(lines + RAN, StatementLine.size() - 1);
						for (int i = begin; i <= end; ++i) cout << i << " "; cout << endl;
						for (int i = begin; i <= end; ++i) cout << StatementLine[i].val << " "; cout << endl;
					}
					exit(998244353);
				}
		}
	}
private:
	map<string, _Object_base*> variables, functions;
} MemoryPool;

class _MemoryManager_base {
public:
	void append(_Variable_base * src) { vl.push_back(src); }
	void append(_Object_base * src) { vl.push_back(static_cast<_Variable_base*> (src)); }
	~_MemoryManager_base() {
		if (EnableDebug) {
			cout << "Call Destruction" << endl;
			cout << "Variable list" << endl;
			for (vector<_Variable_base*>::iterator it = vl.begin(); it != vl.end(); ++it) cout << *it << " "; cout << endl;
			for (vector<_Variable_base*>::iterator it = vl.begin(); it != vl.end(); ++it) cout << (*it) -> isReference() << " "; cout << endl;
		}
		for (vector<_Variable_base*>::iterator it = vl.begin(); it != vl.end(); ++it) {
			if (!(*it) -> isReference()) {
				if (EnableDebug) cout << "Erase " << *it << endl;
				delete *it;
				if (EnableDebug) cout << "Erase OK " << endl;
			} else {
				if (EnableDebug) cout << "Erase " << *it << " Failed : Have Reference" << endl;
			}
		}
	}
private:
	vector<_Variable_base*> vl;
} ;
struct Node_t {
	Node_t * pre, * nxt;
	_Object_base * val;
	Node_t() { pre = nxt = NULL; val = NULL; typ = 0; }
	int typ; // 0 Variable 1 Symbol
} ;

class _Expression_base {
public:

	void setFlag(string token, void * flag) {
		// cout << "FLAG " << token << " " << StringUtil.toReturnFlag(token) << " " << flag << endl;
		MemoryPool.setVariable(StringUtil.toReturnFlag(token), static_cast<_Object_base*> (flag));
	}

	bool isFlagTrue(string token) {
		// cout << "WHAT " << token << " " << StringUtil.toReturnFlag(token) << " " << static_cast<void*> (MemoryPool.getVariable(token)) << endl;
		token = StringUtil.toReturnFlag(token);
		return static_cast<void*> (MemoryPool.getVariable(token)) == FlagTrue;
	}

	_Object_base * getVariableBlock(string token, int begin, int end) {
		_Object_base * var = MemoryPool.findVariable(token + NameManager.getIDs(StatementLine[begin].val), begin);
		int now = begin + 1;
		// EnableDebug = true;
		// {
		_MemoryManager_base mm;
		while (now <= end) {
			int rr = StatementLine.getMatch(now);
			_Variable_base * at = static_cast<_Variable_base*> (calc(token, now + 1, rr - 1));
			var = static_cast<_Object_base*> (static_cast<_Array_base*> (var) -> getValue(at -> value));
			mm.append(at);
			now = rr + 1;
		}
		// }
		// EnableDebug = false;
		return var;
	}
	_Object_base * runStatement(string token, int rightk, int rr) {
		// cout << "runStatement " << token << " " << rightk << " " << rr << endl;
		int tarr = rightk + 1;
		int typ = SymbolTranslater.trans(StatementLine[tarr].val);
		if (!SymbolLevelManager.isControlKeyword(typ))
			if (SymbolTranslater.trans(StatementLine[rr].val) != endOfAStatement_s) ++tarr;
		// if (typ == llBracket_s) ++tarr;
		// cout << "TEST TARR " << tarr << endl;
		return run(token, tarr, rr - 1);
	}

	_Object_base * run(string tokenpre, int begin, int end) {
		if (EnableDebug) {
			cout << "RUN AT (" << begin << ", " << end << ")  TOKEN = \"" << tokenpre << "\"" << endl;
			for (int i = begin; i <= end; ++i) cout << i << " "; cout << endl;
			for (int i = begin; i <= end; ++i) cout << StatementLine[i].val << " "; cout << endl;
		}
		// Run Statement
		// 不带括号
		_MemoryManager_base mm;
		int now = begin;
		while (now <= end) {
			// cout << "Main " << now << " " << end << endl;
			int statement_type = SymbolTranslater.trans(StatementLine[now].val);
			if (SymbolLevelManager.isKeyword(statement_type)) {
				switch (statement_type) {
					case Return_k: {
						int r = StatementLine.findEnd(now);
						// cout << "TEST " << r << endl;
						//	token.subString(0, StringUtil.find(token, "@", 3) + 1)
						setFlag(tokenpre, FlagTrue);
						_Object_base * ret = calc(tokenpre, now + 1, r - 1);
						_Variable_base * res = new _Variable_base;
						res -> value = static_cast<_Variable_base*> (ret) -> value;
						mm.append(ret);
						return static_cast<_Object_base*> (res);
					}
					case If_k: {
						int rightk = StatementLine.getMatch(now + 1), rr = StatementLine.getStatementEnd(rightk + 1);
						_Object_base * ret = calc(tokenpre, now + 2, rightk - 1);
						mm.append(ret);
						bool haveElse = false; int er = 0;
						// cout << "DEBUG " << rightk << " " << rr << " ";
						if (rr < end) {
							if (SymbolTranslater.trans(StatementLine[rr + 1].val) == Else_k) {
								haveElse = true;
								er = StatementLine.getStatementEnd(rr + 2);
							}
						}
						// cout << "Get Value " << static_cast<_Variable_base*> (ret) -> value << endl;
						if (static_cast<_Variable_base*> (ret) -> value != 0) {
							// cout << "CASE1 " << endl;
							_Object_base * res;
							res = runStatement(tokenpre + "if@", rightk, rr);
							if (isFlagTrue(tokenpre)) return res;
							mm.append(res);
						} else if (haveElse) {
							// cout << "CASE2 " << rr << endl;
							_Object_base * res;
							res = runStatement(tokenpre + "if@", rr + 1, er);
							if (isFlagTrue(tokenpre)) return res;
							mm.append(res);
						}
						if (haveElse) now = er + 1; else now = rr + 1;
						break;
					}
					case For_k: {
						int rightk = StatementLine.getMatch(now + 1), rr = StatementLine.getStatementEnd(rightk + 1),
							f1 = StatementLine.getStatementEnd(now + 2), f2 = StatementLine.getStatementEnd(f1 + 1);
						// cout << "DEBUG " << rr << " " << StatementLine[rightk + 1].val << endl;
						_Object_base * ret = run(tokenpre, now + 2, f1);
						mm.append(ret);
						while (true) {
							if (f1 + 1 <= f2 - 1) {
								ret = calc(tokenpre, f1 + 1, f2 - 1);
								mm.append(ret);
								if (static_cast<_Variable_base*> (ret) -> value == 0) break;
							}
							_Object_base * res;
							res = runStatement(tokenpre + "for@", rightk, rr);
							if (isFlagTrue(tokenpre)) return res;
							mm.append(res);
							ret = calc(tokenpre, f2 + 1, rightk - 1);
							mm.append(ret);
						}
						now = rr + 1;
						break;
					}
					case While_k: {
						int rightk = StatementLine.getMatch(now + 1), rr = StatementLine.getStatementEnd(rightk + 1);
						while (true) {
							_Object_base * ret = calc(tokenpre, now + 2, rightk - 1);
							mm.append(ret);
							if (static_cast<_Variable_base*> (ret) -> value == 0) break;
							_Object_base * res;
							res = runStatement(tokenpre + "while@", rightk, rr);
							if (isFlagTrue(tokenpre)) return res;
							mm.append(res);
						}
						now = rr + 1;
						break;
					}
					case Int_k: {
						// cout << StatementLine[now + 2].val << endl;
						// cout << SymbolTranslater.trans(StatementLine[now + 2].val) << endl;
						if (SymbolTranslater.trans(StatementLine[now + 2].val) == lsBracket_s) {
							// Function
							int r = StatementLine.getMatch(now + 2), rr = StatementLine.getMatch(r + 1);
							// cout << "DEBUG " << r << " " << rr << endl;
							_Function_base * f = new _Function_base;
							string tokent = "Global@" + NameManager.getIDs(StatementLine[now + 1].val);
							f -> setToken(tokent);
							f -> setRange(r + 2, rr - 1);
							MemoryPool.setFunction(tokent, static_cast<_Object_base*> (f));
							for (int i = now + 4; i < r; i += 3) f -> argAppend(StatementLine[i].val);
							now = rr + 1;
						} else {
							// Variable and Array
							int tnow = now, end = StatementLine.findEnd(now);
							// cout << now << " " << end << endl;
							while (tnow < end) {
								int nt = StatementLine.findNxt(tnow + 1, Split_s, end);
								// cout << "now " << tnow << " Nxt " << nt << endl;
								if (!~nt) nt = end;
								int vl = tnow + 1, vr = nt - 1;
								// cout << "Var " << vl << " " << vr << endl;
								if (vl == vr) {
									string tokent = tokenpre + NameManager.getIDs(StatementLine[vl].val);
									_Object_base * tx;
									if ((tx = MemoryPool.getVariable(tokent)) != NULL)
										static_cast<_Variable_base*> (tx) -> value = 0;
									else {
										_Variable_base * v = new _Variable_base;
										v -> setReference(true);
										v -> value = 0;
										v -> setToken(tokent);
										MemoryPool.setVariable(tokent, static_cast<_Object_base*> (v));
									}
								} else {
									vector<int> ranArr;
									for (int i = vl + 2; i <= vr; i += 3) ranArr.push_back(StringUtil.parseInt(StatementLine[i].val));
									string tokent = tokenpre + NameManager.getIDs(StatementLine[vl].val);
									_Object_base * tx;
									if ((tx = MemoryPool.getVariable(tokent)) != NULL)
										_Array_base::clearVariableTree(tx, ranArr.begin(), ranArr.end());
									else {
										_Array_base * v = static_cast<_Array_base*> (_Array_base::makeVariableTree(ranArr.begin(), ranArr.end()));
										v -> setToken(tokent);
										MemoryPool.setVariable(tokent, static_cast<_Object_base*> (v));
									}
								}
								tnow = nt;
							}
							now = end + 1;
						}
						break;
					}
					case Cin_k: {
						int r = StatementLine.findEnd(now); int tnow = now + 1;
						// cout << "Cin " << r << endl;
						while (true) {
							if (SymbolTranslater.trans(StatementLine[tnow].val) == endOfAStatement_s) break;
							int rr = StatementLine.findNxt(tnow + 1, rStream_s, r);
							// cout << "Find " << tnow << " " << rr << endl;
							if (!~rr) rr = r;
							_Object_base * var = getVariableBlock(tokenpre, tnow + 1, rr - 1);
							int tv = ReadinBuffer.nextInt();
							static_cast<_Variable_base*> (var) -> setValue(tv);
							// cout << "Cin " << var -> getToken() << " " << static_cast<_Variable_base*> (var) -> value << endl;
							tnow = rr;
						}
						now = r + 1;
						// cout << "JUMP " << endl;
						break;
					}
					case Cout_k: {
						int r = StatementLine.findEnd(now); int tnow = now + 1;
						// cout << "Cout " << r << endl;
						while (true) {
							if (SymbolTranslater.trans(StatementLine[tnow].val) == endOfAStatement_s) break;
							int rr = StatementLine.findNxt(tnow + 1, lStream_s, r);
							if (!~rr) rr = r;
							// cout << "Find " << tnow << " " << rr << endl;
							_Object_base * rev = calc(tokenpre, tnow + 1, rr - 1);
							if (static_cast<_Variable_base*> (rev) -> value == EndlFlag) putchar(10);
							else printf("%d", static_cast<_Variable_base*> (rev) -> value);
							mm.append(rev);
							tnow = rr;
						}
						now = r + 1;
						break;
					}
				}
			} else if (statement_type == llBracket_s) {
				int rr = StatementLine.getMatch(now);
				_Object_base * res;
				res = run(tokenpre + "bkt@", now + 1, rr - 1);
				if (isFlagTrue(tokenpre)) return res;
				mm.append(res);
				now = rr + 1;
			} else {
				int r = StatementLine.findEnd(now);
				_Object_base * res = calc(tokenpre, now, r - 1);
				mm.append(res);
				now = r + 1;
			}
		}
		_Variable_base * result = new _Variable_base;
		result -> value = 0;
		// cout << "RUNOK " << endl;
		return static_cast<_Object_base*> (result);
	}

	pair<_Object_base*, int> nextVariable(string tokenpre, int begin, int end) {
		if (EnableDebug) cout << "nextVariable AT (" << begin << ", " << end << ")  TOKEN = \"" << tokenpre << "\"" << endl;
		int typ = -1;
		if (SymbolTranslater.trans(StatementLine[begin].val) == lsBracket_s) { // 括号表达式
			int rr = StatementLine.getMatch(begin);
			return make_pair(calc(tokenpre, begin + 1, rr - 1), rr);
		} else if (begin + 1 <= end && SymbolLevelManager.isBracket(typ = SymbolTranslater.trans(StatementLine[begin + 1].val))) {
			_MemoryManager_base mm;
			// cout << "WAHT " << endl;
			if (typ == lsBracket_s) { // Function
				// Get Nxt ,
				int tp = 1, rr;
				vector<int> sp_list;
				// cout << "Call FUNCTION VAR_LIST " << endl;
				for (int i = begin + 2; i <= end; ++i) {
					int typ = SymbolTranslater.trans(StatementLine[i].val);
					if (typ == llBracket_s || typ == lmBracket_s || typ == lsBracket_s) ++tp;
					if (typ == rlBracket_s || typ == rmBracket_s || typ == rsBracket_s) --tp;
					// cout << "DEBUG " << i << " " << typ << " " << StatementLine[i].val << " " << tp << endl;
					if (typ == Split_s && tp == 1) sp_list.push_back(i);
					if (tp == 0) { rr = i; break; }
				}
				// cout << "GET : ";
				// for (int i = 0; i != sp_list.size(); ++i) cout << sp_list[i] << " "; cout << endl;
				_Function_base * func = static_cast<_Function_base*> (MemoryPool.getFunction("Global@" + NameManager.getIDs(StatementLine[begin].val)));
				string tokenprecall = func -> getToken() + "@st" + StringUtil.int_to_string(FunctionCallDep + 1) + "@";
				// cout << "Test Token " << func -> getToken() << endl;
				int ll = begin + 2;
				if (func -> getArgCount()) for (int i = 0; i <= sp_list.size(); ++i) {
					int tr;
					if (i != sp_list.size()) tr = sp_list[i] - 1; else tr = rr - 1;
					string tokenlike = tokenprecall + NameManager.getIDs(func -> getArg(i));
					_Variable_base * tmp = new _Variable_base;
					tmp -> value = static_cast<_Variable_base*> (calc(tokenpre, ll, tr)) -> value;
					_Object_base * tx;
					if ((tx = MemoryPool.getVariable(tokenlike)) != NULL) {
						static_cast<_Variable_base*> (tx) -> value = tmp -> value;
						mm.append(tmp);
					} else {
						tmp -> setReference(true);
						MemoryPool.setVariable(tokenlike, static_cast<_Object_base*> (tmp));
						// cout << "Arg " << i << " " << func -> getArg(i) << endl;
					}
					if (i != sp_list.size()) ll = sp_list[i] + 1;
				}
				// cout << "Ready for call" << endl;
				// cout << "Test Token " << func -> getToken() << endl;
				// _Object_base * res = func -> getValue();
				_Object_base * res = MemoryPool.call(func -> getToken());
				// cout << "nextVariable RETURNED with " << static_cast<_Variable_base*> (res) -> value << " " << rr << endl;
				return make_pair(res, rr);
			} else { // Array
				// cout << "Array_T " << endl;
				int now = begin;
				while (now < end) {
					// cout << "FIND " << now << " " << end << endl;
					if (SymbolTranslater.trans(StatementLine[now + 1].val) != lmBracket_s) break;
					now = StatementLine.getMatch(now + 1);
				}
				return make_pair(getVariableBlock(tokenpre, begin, now), now);
			}
		} else {
			string t = StatementLine[begin].val;
			if (Char_Checker.isDigit(t[0])) {
				_Variable_base * res = new _Variable_base;
				res -> value = StringUtil.parseInt(t);
				return make_pair(static_cast<_Object_base*> (res), begin);
			}
			return make_pair(MemoryPool.findVariable(tokenpre + NameManager.getIDs(t), begin), begin);
		}
	}

	_Object_base * calc(string tokenpre, int begin, int end) {
		if (EnableDebug) {
			cout << "CALC AT (" << begin << ", " << end << ")  TOKEN = \"" << tokenpre << "\"" << endl;
			for (int i = begin; i <= end; ++i) cout << i << " "; cout << endl;
			for (int i = begin; i <= end; ++i) cout << StatementLine[i].val << " "; cout << endl;
		}
		// Calculate Expression
		// 不带分号
		vector<Node_t*> optli[12];
		// 采用链表计算
		// 单目优先处理 形式:... S S V S V ...
		// 双目 形式 ... S V S V S ...
		_MemoryManager_base mm;
		Node_t * now = NULL, * fir = NULL, * bak = NULL;
		int tnow = begin;
		int ltyp = Fill_s;
		while (tnow <= end) {
			// cout << "DEBUG " << tnow << endl;
			Node_t * x = new Node_t;
			int typ = SymbolTranslater.trans(StatementLine[tnow].val) & SymbolMask;
			// cout << "ORI " << typ << " " << SymbolLevelManager.isBracket(typ) << endl;
			if (SymbolLevelManager.isBracket(typ)) typ = 0;
			// cout << StatementLine[tnow].val << " " << typ << " " << tnow << " " << ltyp << endl;
			x -> typ = typ;
			x -> pre = now;
			if (now != NULL) now -> nxt = x;
			now = x;
			if (ltyp && x -> typ) { // 单目, 往下读一个变量
				// cout << "CALC CASE 1" << endl;
				// TODO 如果(!!a)会怎么样
				// _Object_base * var = nextVariable(tokenpre, tnow + 1, end);
				vector<int> singlelist;
				int tn = tnow;
				while (true) {
					int typ = SymbolTranslater.trans(StatementLine[tn].val);
					if (typ != Not_s && typ != Plus_s && typ != Minus_s) { tnow = tn; break; }
					singlelist.push_back(typ);
					++tn;
				}
				pair<_Object_base*, int> res = nextVariable(tokenpre, tnow, end);
				mm.append(res.first);
				_Variable_base * tv = new _Variable_base;
				tv -> value = static_cast<_Variable_base*> (res.first) -> value;
				mm.append(tv);
				_Object_base * var = static_cast<_Object_base*> (tv);
				int & tx = tv -> value;
				for (int i = singlelist.size() - 1; ~i; --i) {
					switch (singlelist[i]) {
						case Not_s:
							tx = !tx;
							break;
						case Plus_s:
							break;
						case Minus_s:
							tx = -tx;
							break;
					}
				}
				x -> typ = 0;
				x -> val = var;
				// cout << "TEST " << res.second << endl;
				tnow = res.second + 1;
			} else if (!x -> typ) { // 变量,先取值
				// cout << "CALC CASE 2" << endl;
				// cout << "23333" << endl;
				pair<_Object_base*, int> res = nextVariable(tokenpre, tnow, end);
				// cout << "23333" << endl;
				_Object_base * var = res.first;
				mm.append(var);
				x -> typ = 0;
				x -> val = var;
				// cout << "TEST " << res.second << endl;
				tnow = res.second + 1;
			} else ++tnow;
			ltyp = x -> typ;
			if (x -> typ) {
				optli[SymbolLevelManager.getLevel(typ)].push_back(x);
				x -> typ = typ;
			}
			if (fir == NULL) fir = x;
			bak = x;
		}
		if (EnableDebug) {
			cout << "Build list OK" << endl;
			Node_t * tl = fir; while (tl != NULL) { if (tl -> typ == 0) cout << static_cast<_Variable_base*> (tl -> val) -> value << " -> "; else cout << tl -> typ << " -> "; tl = tl -> nxt; } cout << endl; tl = fir; while (tl != NULL) { if (tl -> typ == 0) cout << tl -> val << " -> "; else cout << tl -> typ << " -> "; tl = tl -> nxt; } cout << endl; tl = fir; while (tl != NULL) { if (tl -> typ == 0) cout << tl -> val -> isReference() << " -> "; else cout << tl -> typ << " -> "; tl = tl -> nxt; } cout << endl;
		}
		for (int i = 11; i; --i) {
			vector<Node_t*>::iterator itb, ite;
			if (i == 2) reverse(optli[i].begin(), optli[i].end());
			itb = optli[i].begin(), ite = optli[i].end();
			for (; itb != ite; ++itb) {
				// 消符号两边
				_Variable_base * lhs = static_cast<_Variable_base*> ((*itb) -> pre -> val),
							   * rhs = static_cast<_Variable_base*> ((*itb) -> nxt -> val);
				_Variable_base * result = new _Variable_base;
				mm.append(result); // 可能会诡异
				switch ((*itb) -> typ) {
					case Multi_s : result -> value = lhs -> value * rhs -> value; break;
					case Divide_s : result -> value = lhs -> value / rhs -> value; break;
					case Module_s : result -> value = lhs -> value % rhs -> value; break;
					case Plus_s : result -> value = lhs -> value + rhs -> value; break;
					case Minus_s : result -> value = lhs -> value - rhs -> value; break;
					case lEq_s : result -> value = lhs -> value <= rhs -> value; break;
					case rEq_s : result -> value = lhs -> value >= rhs -> value; break;
					case Less_s : result -> value = lhs -> value < rhs -> value; break;
					case Greater_s : result -> value = lhs -> value > rhs -> value; break;
					case Eq_s : result -> value = lhs -> value == rhs -> value; break;
					case nEq_s : result -> value = lhs -> value != rhs -> value; break;
					case Xor_s : result -> value = lhs -> value ^ rhs -> value; break;
					case And_s : result -> value = lhs -> value && rhs -> value; break;
					case Or_s : result -> value = lhs -> value || rhs -> value; break;
					case valueEq_s : lhs -> value = rhs -> value; break;
				}
				if (EnableDebug) {
					cout << "Calc " << lhs -> value << " " << rhs -> value << " " << result -> value << " " << (*itb) -> typ << endl;
				}
				Node_t * remain = (*itb) -> pre;
				if ((*itb) -> typ != valueEq_s) // lhs -> value = result -> value;
				/* else */ (*itb) -> pre -> val = result;
				// 留下LHS,赋值什么的都不怕
				remain -> nxt = (*itb) -> nxt -> nxt;
				if ((*itb) -> nxt -> nxt != NULL) (*itb) -> nxt -> nxt -> pre = remain;
				delete (*itb) -> nxt; delete (*itb);
			}
			// 注意销毁链表
		}
		// cout << "???" << endl;
		_Object_base * res;
		if (fir != NULL) {
			if (!fir -> val -> isReference()) {
				_Variable_base * ret = new _Variable_base;
				ret -> value = static_cast<_Variable_base*> (fir -> val) -> value;
				res = ret;
			} else res = fir -> val;
			delete fir;
		} else {
			_Variable_base * ttt = new _Variable_base;
			ttt -> value = 0;
			res = static_cast<_Object_base*> (ttt);
		}
		if (EnableDebug) {
			cout << "Returned With " << static_cast<_Variable_base*> (res) -> value << endl;
		}
		return res;
	}
} Expression;

_Object_base * _Function_base::getValue() {
	// Set Argument into Global@FunctionID@XX
	// Function Variables : Global@FuntionID@st${count}@XX
	++FunctionCallDep;
	// Return Flag : Global@sum@stX@RetXX
	string tokenpre = token + "@st" + StringUtil.int_to_string(FunctionCallDep) + "@MainProc@";
	string flaglike = StringUtil.toReturnFlag(tokenpre);
	Expression.setFlag(tokenpre, FlagFalse);
	_Object_base * res = Expression.run(tokenpre, begin, end);
	--FunctionCallDep;
	return res;
}

// Builtin Functions
class __builtin_putchar_base : public _Function_base {
public:
	virtual _Object_base * getValue() {
		_Object_base * res = MemoryPool.findVariable(
				this -> getToken() + "@st" + StringUtil.int_to_string(FunctionCallDep + 1) + "@" + NameManager.getIDs("__putch")
													);
		putchar(static_cast<_Variable_base*> (res) -> value);
		return res;
	}
	__builtin_putchar_base() {
		this -> setToken("Global@" + NameManager.getIDs("putchar"));
		this -> argAppend("__putch");
	}
} ;

class __builtin_start_debug : public _Function_base {
public:
	virtual _Object_base * getValue() { EnableDebug = true; _Variable_base * res = new _Variable_base; res -> value = 0; return static_cast<_Object_base*> (res); }
	__builtin_start_debug() {
		this -> setToken("Global@" + NameManager.getIDs("__builtin_start_debug"));
	}
} ;

class __builtin_stop_debug : public _Function_base {
public:
	virtual _Object_base * getValue() { EnableDebug = false; _Variable_base * res = new _Variable_base; res -> value = 0; return static_cast<_Object_base*> (res); }
	__builtin_stop_debug() {
		this -> setToken("Global@" + NameManager.getIDs("__builtin_stop_debug"));
	}
} ;

class Main {
public:
	Main() {
		// Input Buff Stream
		ReadinBuffer.init();
		ProgramBuffer.init();
		while (ProgramBuffer.haveNext()) StatementLine.append(ProgramBuffer.nextStatement());
		StatementLine.init();
		// Set Global Variables
		_Variable_base * endlt = new _Variable_base;
		endlt -> value = EndlFlag;
		endlt -> setReference(true);
		MemoryPool.setVariable("Global@" + NameManager.getIDs("endl"), endlt);
		__builtin_putchar_base * putchar_t = new __builtin_putchar_base;
		MemoryPool.setFunction("Global@" + NameManager.getIDs("putchar"), static_cast<_Object_base*> (putchar_t));
		__builtin_start_debug * start_debug = new __builtin_start_debug;
		MemoryPool.setFunction("Global@" + NameManager.getIDs("__builtin_start_debug"), static_cast<_Object_base*> (start_debug));
		__builtin_stop_debug * stop_debug = new __builtin_stop_debug;
		MemoryPool.setFunction("Global@" + NameManager.getIDs("__builtin_stop_debug"), static_cast<_Object_base*> (stop_debug));
	}
	
	void run() {
		Expression.run(string("Global@"), 0, StatementLine.size() - 1);
		MemoryPool.call("Global@" + NameManager.getIDs("main"));
	}
} ;

}

int main() {
	Mirai::Main runner;
	runner.run();
	return 0;
}
posted @ 2018-11-20 20:13  daklqw  阅读(904)  评论(1编辑  收藏  举报