一个月之前写的题……
http://uoj.ac/submission/293973
真的毒瘤,调了5天……
然而还是有很多缺陷
- 内存泄漏太严重,已经补救过一发了,然而还是有很多泄漏
- 把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;
}