#include "work.h" #include using namespace std; size_t pt; vector tokens; // void printTokens() { // wstring_convert> cvt; // for (auto u : tokens) { // cout << token_mp[static_cast(u.type)] << " " << u.line << " " << // cvt.to_bytes(u.s) // << endl; // } // cout << endl; // } struct Def { enum Type { TEMPLATE, STRUCT, VAR }; virtual Def::Type type() const = 0; virtual ~Def() = default; }; struct DefTemplate : Def { Def::Type type() const override { return Def::TEMPLATE; } shared_ptr def_template; }; struct DefStruct : Def { Def::Type type() const override { return Def::STRUCT; } shared_ptr def_struct; }; struct DefVar : Def { Def::Type type() const override { return Def::VAR; } shared_ptr def_var; }; map> ndefs; bool preview(vector v) { if (pt + v.size() > tokens.size()) { return false; } for (size_t i = 0; i < v.size(); i++) { if (tokens[pt + i].type != v[i]) { return false; } } return true; } bool preview(TokenType t) { return preview(vector{t}); } string jump(TokenType t) { if (preview(t)) { return tokens[pt++].s; } if (pt < tokens.size()) { printf("error on line %d", tokens[pt].line); } else { puts("error on end"); } exit(1); } shared_ptr _createVal(shared_ptr t); shared_ptr createVal(); vector> createVals(); shared_ptr _createType(shared_ptr); shared_ptr createType(); vector> createTypes(); vector>> createTems(); vector>> createPars(map>* = nullptr); pair> createStruct(); pair> createVar(); shared_ptr _createVal(shared_ptr ft) { auto str = ft->str; auto s = jump(TokenType::ID); if (str->vars.find(s) == str->vars.end()) { printf("error on line %d", tokens[pt - 1].line), exit(0); } auto t = struct_replace(str->vars[s], ft); while (t->type() == ValType::FUNCTION && (preview(TokenType::LT) || preview(TokenType::LP))) { auto tt = static_pointer_cast(t); vector> types; if (preview(TokenType::LT)) { types = createTypes(); } if (tt->c1.size() != types.size()) { printf("error on line %d", tokens[pt - 1].line), exit(0); } map, shared_ptr> mp; for (size_t i = 0; i < types.size(); i++) { mp[tt->c1[i]] = types[i]; } auto vals = createVals(); bool legal = tt->c2.size() == vals.size(); if (legal) { for (size_t i = 0; i < vals.size(); i++) { if (!sameType(vals[i], function_replace(tt->c2[i], mp))) { legal = 0; break; } } } if (!legal) { printf("error on line %d", tokens[pt - 1].line), exit(0); } t = function_replace(tt->c3, mp); } if (!preview(TokenType::DOT)) { return t; } if (t->type() != ValType::STRUCT) { printf("error on line %d", tokens[pt].line), exit(0); } pt++; return _createVal(static_pointer_cast(t)); } shared_ptr createVal() { shared_ptr t; if (preview(TokenType::FN)) { pt++; auto tt = make_shared(); vector>> tems; if (preview(TokenType::LT)) { tems = createTems(); } for (const auto& pr : tems) { tt->c1.push_back(pr.second); } auto pars = createPars(); for (const auto& pr : pars) { tt->c2.push_back(pr.second); } jump(TokenType::IMPLY); tt->c3 = createType(); jump(TokenType::LB); vector defs; while (!preview(TokenType::RETURN)) { if (preview({TokenType::STRUCT, TokenType::ID})) { defs.push_back(createStruct().first); jump(TokenType::SEMI); } else { defs.push_back(createVar().first); } } pt++; auto ret = createVal(); jump(TokenType::SEMI); if (!sameType(tt->c3, ret)) { printf("error on line %d", tokens[pt - 1].line), exit(0); } for (const auto& pr : tems) { ndefs.erase(pr.first); } for (const auto& pr : pars) { ndefs.erase(pr.first); } for (const auto& s : defs) { ndefs.erase(s); } jump(TokenType::RB); t = static_pointer_cast(tt); } else { bool flag = 0; // 新实例 if (preview(TokenType::TYPEOF)) { flag = 1; } else if (preview(TokenType::ID)) { auto s = tokens[pt].s; if (ndefs.find(s) != ndefs.end() && ndefs[s]->type() == Def::STRUCT) { flag = 1; } } if (flag) { t = createType(); if (t->type() != ValType::STRUCT) { printf("error on line %d", tokens[pt - 1].line), exit(0); } auto tt = static_pointer_cast(t); auto vals = createVals(); bool legal = vals.size() == tt->str->c2.size(); if (legal) { for (size_t i = 0; i < vals.size(); i++) { if (!sameType(vals[i], struct_replace(tt->str->c2[i], tt))) { legal = 0; break; } } } if (!legal) { printf("error on line %d", tokens[pt - 1].line), exit(0); } } else { auto s = jump(TokenType::ID); if (ndefs.find(s) == ndefs.end() || ndefs[s]->type() != Def::VAR) { printf("error on line %d", tokens[pt - 1].line), exit(0); } t = static_pointer_cast(ndefs[s])->def_var; } } while (t->type() == ValType::FUNCTION && (preview(TokenType::LT) || preview(TokenType::LP))) { auto tt = static_pointer_cast(t); vector> types; if (preview(TokenType::LT)) { types = createTypes(); } if (tt->c1.size() != types.size()) { printf("error on line %d", tokens[pt - 1].line), exit(0); } map, shared_ptr> mp; for (size_t i = 0; i < types.size(); i++) { mp[tt->c1[i]] = types[i]; } auto vals = createVals(); bool legal = tt->c2.size() == vals.size(); if (legal) { for (size_t i = 0; i < vals.size(); i++) { if (!sameType(vals[i], function_replace(tt->c2[i], mp))) { legal = 0; break; } } } if (!legal) { printf("error on line %d", tokens[pt - 1].line), exit(0); } t = function_replace(tt->c3, mp); } if (!preview(TokenType::DOT)) { return t; } if (t->type() != ValType::STRUCT) { printf("error on line %d", tokens[pt].line), exit(0); } pt++; return _createVal(static_pointer_cast(t)); } vector> createVals() { vector> vals; jump(TokenType::LP); if (!preview(TokenType::RP)) { auto single = [&]() { vals.push_back(createVal()); }; for (single(); preview(TokenType::COMMA); pt++, single()) {} } jump(TokenType::RP); return vals; } shared_ptr _createType(shared_ptr t) { auto str = t->str; auto s = jump(TokenType::ID); if (str->structs.find(s) == str->structs.end()) { printf("error on line %d", tokens[pt - 1].line), exit(0); } auto tt = make_shared(); tt->str = str->structs[s], tt->mp = t->mp; vector> types; if (tt->str->c1.size() || preview(TokenType::LT)) { types = createTypes(); } if (tt->str->c1.size() != types.size()) { printf("error on line %d", tokens[pt - 1].line), exit(0); } for (size_t i = 0; i < types.size(); i++) { tt->mp[tt->str->c1[i]] = types[i]; } if (!preview(TokenType::SCOPE)) { return static_pointer_cast(tt); } pt++; return _createType(tt); } shared_ptr createType() { if (preview(TokenType::FN)) { pt++; auto t = make_shared(); jump(TokenType::LP); auto tems = createTems(); for (const auto& pr : tems) { t->c1.push_back(pr.second); } jump(TokenType::COMMA); t->c2 = createTypes(); jump(TokenType::COMMA); t->c3 = createType(); jump(TokenType::RP); for (const auto& pr : tems) { ndefs.erase(pr.first); } return t; } shared_ptr t; if (preview(TokenType::TYPEOF)) { pt++; jump(TokenType::LP); t = createVal(); jump(TokenType::RP); } else { auto s = jump(TokenType::ID); if (ndefs.find(s) == ndefs.end() || ndefs[s]->type() == Def::VAR) { printf("error on line %d", tokens[pt - 1].line), exit(0); } if (ndefs[s]->type() == Def::STRUCT) { auto tt = make_shared(); tt->str = static_pointer_cast(ndefs[s])->def_struct; vector> types; if (tt->str->c1.size() || preview(TokenType::LT)) { types = createTypes(); } if (tt->str->c1.size() != types.size()) { printf("error on line %d", tokens[pt - 1].line), exit(0); } for (size_t i = 0; i < types.size(); i++) { tt->mp[tt->str->c1[i]] = types[i]; } t = static_pointer_cast(tt); } else { t = static_pointer_cast( static_pointer_cast(ndefs[s])->def_template); } } if (!preview(TokenType::SCOPE)) { return t; } if (t->type() != ValType::STRUCT) { printf("error on line %d", tokens[pt].line), exit(0); } pt++; return _createType(static_pointer_cast(t)); } vector> createTypes() { vector> types; jump(TokenType::LT); if (!preview(TokenType::RT)) { auto single = [&]() { types.push_back(createType()); }; for (single(); preview(TokenType::COMMA); pt++, single()) {} } jump(TokenType::RT); return types; } vector>> createTems() { vector>> tems; jump(TokenType::LT); if (preview(TokenType::ID)) { auto single = [&]() { auto s = jump(TokenType::ID); if (ndefs.find(s) != ndefs.end()) { printf("error on line %d", tokens[pt - 1].line), exit(0); } auto x = make_shared(); auto d = make_shared(); d->def_template = x; ndefs[s] = static_pointer_cast(d); tems.push_back({s, x}); }; for (single(); preview(TokenType::COMMA); pt++, single()) {} } jump(TokenType::RT); return tems; } vector>> createPars(map>* vars) { vector>> pars; jump(TokenType::LP); if (!preview(TokenType::RP)) { auto single = [&]() { bool pub = 1; if (preview(TokenType::PRIVATE)) { pub = 0, pt++; } auto s = jump(TokenType::ID); if (ndefs.find(s) != ndefs.end()) { printf("error on line %d", tokens[pt - 1].line), exit(0); } jump(TokenType::COLON); auto t = createType(); auto d = make_shared(); d->def_var = t; ndefs[s] = static_pointer_cast(d); pars.push_back({s, t}); if (vars != nullptr && pub) (*vars)[s]=t; }; for (single(); preview(TokenType::COMMA); pt++, single()) {} } jump(TokenType::RP); return pars; } pair> createStruct() { jump(TokenType::STRUCT); string s; vector>> tems; vector>> pars; auto t = make_shared(); if (preview(TokenType::ID)) { s = tokens[pt++].s; if (preview(TokenType::LT)) { tems = createTems(); } pars = createPars(&t->vars); } for (const auto& pr : tems) { t->c1.push_back(pr.second); } for (const auto& pr : pars) { t->c2.push_back(pr.second); } jump(TokenType::LB); vector defs; vector> subs; while (!preview(TokenType::RB)) { bool pub = 1; if (preview(TokenType::PRIVATE)) { pub = 0, pt++; } if (preview({TokenType::STRUCT, TokenType::ID})) { auto tt = createStruct(); jump(TokenType::SEMI); subs.push_back(tt.second); defs.push_back(tt.first); if (pub) { t->structs[tt.first] = tt.second; } } else { auto tt = createVar(); defs.push_back(tt.first); if (pub) { t->vars[tt.first] = tt.second; } } } jump(TokenType::RB); for (auto str : subs) { str->fa = t; } for (const auto& pr : tems) { ndefs.erase(pr.first); } for (const auto& pr : pars) { ndefs.erase(pr.first); } for (const auto& ss : defs) { ndefs.erase(ss); } if (!s.empty()) { auto tt = make_shared(); tt->def_struct = t; ndefs[s] = static_pointer_cast(tt); } return {s, t}; } pair> createVar() { string s; shared_ptr t; if (preview(TokenType::STRUCT)) { auto pr = createStruct(); s = jump(TokenType::ID); jump(TokenType::SEMI); auto tt = make_shared(); tt->str = pr.second; t = static_pointer_cast(tt); } else { s = jump(TokenType::ID); jump(TokenType::ASSIGN); t = createVal(); jump(TokenType::SEMI); } if (ndefs.find(s) != ndefs.end()) { printf("error on line %d", tokens[pt - 1].line), exit(0); } auto d = make_shared(); d->def_var = t; ndefs[s] = static_pointer_cast(d); return {s, t}; } void work(vector _tokens) { tokens = _tokens; createVar(); }