Add very messy code from lcw

Signed-off-by: szdytom <szdytom@qq.com>
This commit is contained in:
方而静 2023-08-27 12:41:22 +08:00
parent d14f2dcc41
commit e8f85bd3dc
Signed by: szTom
GPG Key ID: 072D999D60C6473C
2 changed files with 974 additions and 0 deletions

147
.clang-format Normal file
View File

@ -0,0 +1,147 @@
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignArrayOfStructures: Left
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Left
AlignOperands: Align
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortEnumsOnASingleLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
AttributeMacros: []
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakBeforeBinaryOperators: All
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeComma
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
BreakConstructorInitializers: BeforeComma
BreakStringLiterals: true
ColumnLimit: 99
QualifierAlignment: Left
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: Always
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: NextLine
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: false
FixNamespaceComments: true
ForEachMacros: []
IfMacros: []
IncludeBlocks: Merge
IndentAccessModifiers: false
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: false
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequires: false
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertTrailingCommas: Wrapped
InsertBraces: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PenaltyIndentedWhitespace: 0
PointerAlignment: Left
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: false
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterOverloadedOperator: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Cpp11
TabWidth: 4
UseCRLF: false
UseTab: Always

827
src/main.cpp Normal file
View File

@ -0,0 +1,827 @@
#include <bits/stdc++.h>
using namespace std;
enum class TokenType {
COMMA, // ,
SEMI, // ;
LB,
RB,
LP,
RP,
LT,
RT, // { } ( ) < >
ASSIGN, // =
DOT, // .
COLON, // :
SCOPE, // ::
IMPLY, // ->
STRUCT, // struct
FN, // Fn
RETURN, // return
TYPEOF, // typeof
PUBLIC, // public
ID
};
struct Token {
int line;
TokenType type;
wstring s;
};
size_t pt;
vector<Token> tokens;
void printTokens() {
wstring_convert<codecvt_utf8<wchar_t>> cvt;
string mp[] = {",",
";",
"{",
"}",
"(",
")",
"<",
">",
"=",
".",
":",
"::",
"->",
"struct",
"Fn",
"return",
"typeof",
"public",
"ID"};
for (auto u : tokens) {
cout << mp[static_cast<int>(u.type)] << " " << u.line << " " << cvt.to_bytes(u.s) << endl;
}
cout << endl;
}
void read() {
string ss;
for (char ch = getchar(); ch != EOF; ch = getchar()) {
ss += ch;
}
wstring_convert<codecvt_utf8<wchar_t>> cvt;
wstring s = cvt.from_bytes(ss);
size_t pt = 0;
int line = 1;
auto skipSpace = [&]() {
while (pt < s.size() && iswspace(s[pt])) {
if (s[pt] == L'\n') {
line++;
}
pt++;
}
};
for (skipSpace(); pt < s.size(); skipSpace()) {
TokenType type;
wstring t;
if (s[pt] == L',') {
type = TokenType::COMMA, pt++;
} else if (s[pt] == L';') {
type = TokenType::SEMI, pt++;
} else if (s[pt] == L'{') {
type = TokenType::LB, pt++;
} else if (s[pt] == L'}') {
type = TokenType::RB, pt++;
} else if (s[pt] == L'(') {
type = TokenType::LP, pt++;
} else if (s[pt] == L')') {
type = TokenType::RP, pt++;
} else if (s[pt] == L'<') {
type = TokenType::LT, pt++;
} else if (s[pt] == L'>') {
type = TokenType::RT, pt++;
} else if (s[pt] == L'=') {
type = TokenType::ASSIGN, pt++;
} else if (s[pt] == L'.') {
type = TokenType::DOT, pt++;
} else if (s[pt] == L':') {
if (pt + 1 < s.size() && s[pt + 1] == ':') {
type = TokenType::SCOPE, pt += 2;
} else {
type = TokenType::COLON, pt++;
}
} else if (s[pt] == L'-') {
if (pt + 1 < s.size() && s[pt + 1] == '>') {
type = TokenType::IMPLY, pt += 2;
} else {
printf("error on line %d", line), exit(1);
}
} else if ((s[pt] >= 0 && s[pt] < 128) ? (iswalpha(s[pt]) || s[pt] == L'_')
: iswprint(s[pt])) {
size_t r = pt + 1;
while (r < s.size()
&& ((s[r] >= 0 && s[r] < 128)
? (iswalpha(s[r]) || s[r] == L'_' || iswdigit(s[r]))
: iswprint(s[r]))) {
r++;
}
t = s.substr(pt, r - pt);
if (t == L"struct") {
type = TokenType::STRUCT, t.clear();
} else if (t == L"Fn") {
type = TokenType::FN, t.clear();
} else if (t == L"return") {
type = TokenType::RETURN, t.clear();
} else if (t == L"typeof") {
type = TokenType::TYPEOF, t.clear();
} else if (t == L"public") {
type = TokenType::PUBLIC, t.clear();
} else {
type = TokenType::ID;
}
pt = r;
} else {
printf("error on line %d", line), exit(1);
}
tokens.push_back({line, type, t});
}
}
struct Struct;
struct ValType;
struct TemplateType;
struct StructType;
struct FunctionType;
struct Struct {
weak_ptr<Struct> fa;
vector<shared_ptr<TemplateType>> c1;
vector<shared_ptr<ValType>> c2;
map<wstring, shared_ptr<ValType>> vars;
map<wstring, shared_ptr<Struct>> structs;
};
struct ValType {
virtual const int type() = 0;
};
struct TemplateType : ValType {
const int type() override {
return 0;
}
};
struct StructType : ValType {
const int type() override {
return 1;
}
shared_ptr<Struct> str;
map<shared_ptr<TemplateType>, shared_ptr<ValType>> mp;
};
struct FunctionType : ValType {
const int type() override {
return 2;
}
vector<shared_ptr<TemplateType>> c1;
vector<shared_ptr<ValType>> c2;
shared_ptr<ValType> c3;
};
bool sameType(shared_ptr<ValType> a, shared_ptr<ValType> b) {
static set<pair<shared_ptr<TemplateType>, shared_ptr<TemplateType>>> eq;
if (a->type() != b->type()) {
return false;
}
if (a->type() == 0) {
auto aa = static_pointer_cast<TemplateType>(a), bb = static_pointer_cast<TemplateType>(b);
return aa == bb || eq.find({aa, bb}) != eq.end();
}
if (a->type() == 1) {
auto aa = static_pointer_cast<StructType>(a);
auto bb = static_pointer_cast<StructType>(b);
if (aa->str != bb->str) {
return false;
}
assert(aa->mp.size() == bb->mp.size());
for (auto ia = aa->mp.begin(), ib = bb->mp.begin(); ia != aa->mp.end(); ia++, ib++) {
assert(ia->first == ib->first);
if (!sameType(ia->second, ib->second)) {
return false;
}
}
return true;
}
// if(a->type()==2)
{
auto aa = static_pointer_cast<FunctionType>(a);
auto bb = static_pointer_cast<FunctionType>(b);
if (aa->c1.size() != bb->c1.size() || aa->c2.size() != bb->c2.size()) {
return false;
}
for (size_t i = 0; i < aa->c1.size(); i++) {
eq.insert({aa->c1[i], bb->c1[i]});
}
bool flag = 1;
for (size_t i = 0; i < aa->c2.size(); i++) {
if (!sameType(aa->c2[i], bb->c2[i])) {
flag = 0;
break;
}
}
if (!flag && !sameType(aa->c3, bb->c3)) {
flag = 0;
}
for (size_t i = 0; i < aa->c1.size(); i++) {
eq.erase({aa->c1[i], bb->c1[i]});
}
return flag;
}
}
struct Def {
virtual const int type() = 0;
};
struct DefTemplate : Def {
const int type() override {
return 0;
}
shared_ptr<TemplateType> def_template;
};
struct DefStruct : Def {
const int type() override {
return 1;
}
shared_ptr<Struct> def_struct;
};
struct DefVar : Def {
const int type() override {
return 2;
}
shared_ptr<ValType> def_var;
};
map<wstring, shared_ptr<Def>> ndefs;
bool preview(vector<TokenType> 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<TokenType>{t});
}
wstring 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<ValType> _createVal(shared_ptr<StructType> t);
shared_ptr<ValType> createVal();
vector<shared_ptr<ValType>> createVals();
shared_ptr<ValType> _createType(shared_ptr<Struct>);
shared_ptr<ValType> createType();
vector<shared_ptr<ValType>> createTypes();
vector<pair<wstring, shared_ptr<TemplateType>>> createTems();
vector<pair<wstring, shared_ptr<ValType>>> createPars();
pair<wstring, shared_ptr<Struct>> createStruct();
pair<wstring, shared_ptr<ValType>> createVar();
shared_ptr<ValType> struct_replace(shared_ptr<ValType> vt, shared_ptr<StructType> ut) {
static map<shared_ptr<TemplateType>, shared_ptr<TemplateType>> eq;
if (vt->type() == 0) {
auto vtt = static_pointer_cast<TemplateType>(vt);
auto it1 = ut->mp.find(vtt);
auto it2 = eq.find(vtt);
assert(it1 == ut->mp.end() || it2 == eq.end());
if (it1 != ut->mp.end()) {
return it1->second;
}
if (it2 != eq.end()) {
return static_pointer_cast<ValType>(it2->second);
}
return vt;
}
if (vt->type() == 1) {
auto vtt = static_pointer_cast<StructType>(vt);
auto tt = make_shared<StructType>();
(*tt) = (*ut);
set<shared_ptr<Struct>> vis;
for (auto u = vtt->str; u.get() != nullptr; u = u->fa.lock()) {
vis.insert(u);
}
for (auto u = ut->str; u.get() != nullptr && vis.find(u) == vis.end(); u = u->fa.lock()) {
for (auto tem : u->c1) {
tt->mp.erase(tem);
}
}
for (auto pr : vtt->mp) {
tt->mp[pr.first] = struct_replace(pr.second, ut);
}
return static_pointer_cast<ValType>(tt);
}
// if(vt->type()==2)
{
auto vtt = static_pointer_cast<FunctionType>(vt);
auto tt = make_shared<FunctionType>();
for (size_t i = 0; i < vtt->c1.size(); i++) {
tt->c1.push_back(eq[vtt->c1[i]] = make_shared<TemplateType>());
}
for (auto cc : vtt->c2) {
tt->c2.push_back(struct_replace(cc, ut));
}
tt->c3 = struct_replace(vtt->c3, ut);
for (size_t i = 0; i < vtt->c1.size(); i++) {
eq.erase(vtt->c1[i]);
}
return static_pointer_cast<ValType>(tt);
}
}
shared_ptr<ValType> function_replace(
shared_ptr<ValType> t,
const map<shared_ptr<TemplateType>, shared_ptr<ValType>>& mp) {
static map<shared_ptr<TemplateType>, shared_ptr<TemplateType>> eq;
if (t->type() == 0) {
auto tt = static_pointer_cast<TemplateType>(t);
auto it1 = mp.find(tt);
auto it2 = eq.find(tt);
assert(it1 == mp.end() || it2 == eq.end());
if (it1 != mp.end()) {
return it1->second;
}
if (it2 != eq.end()) {
return static_pointer_cast<ValType>(it2->second);
}
return t;
}
if (t->type() == 1) {
auto tt = make_shared<StructType>();
(*tt) = (*static_pointer_cast<StructType>(t));
for (auto& pr : static_pointer_cast<StructType>(tt)->mp) {
pr.second = function_replace(pr.second, mp);
}
return tt;
}
// if(t->type()==2)
{
auto vt = static_pointer_cast<FunctionType>(t);
auto tt = make_shared<FunctionType>();
for (size_t i = 0; i < vt->c1.size(); i++) {
tt->c1.push_back(eq[vt->c1[i]] = make_shared<TemplateType>());
}
for (auto cc : vt->c2) {
tt->c2.push_back(function_replace(cc, mp));
}
tt->c3 = function_replace(vt->c3, mp);
for (size_t i = 0; i < vt->c1.size(); i++) {
eq.erase(vt->c1[i]);
}
return static_pointer_cast<ValType>(tt);
}
}
shared_ptr<ValType> _createVal(shared_ptr<StructType> 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() == 2 && (preview(TokenType::LT) || preview(TokenType::LP))) {
auto tt = static_pointer_cast<FunctionType>(t);
vector<shared_ptr<ValType>> 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<TemplateType>, shared_ptr<ValType>> 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() != 1) {
printf("error on line %d", tokens[pt].line), exit(0);
}
pt++;
return _createVal(static_pointer_cast<StructType>(t));
}
shared_ptr<ValType> createVal() {
shared_ptr<ValType> t;
if (preview(TokenType::FN)) {
pt++;
auto tt = make_shared<FunctionType>();
vector<pair<wstring, shared_ptr<TemplateType>>> 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<wstring> 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<ValType>(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() == 1) {
flag = 1;
}
}
if (flag) {
t = createType();
if (t->type() != 1) {
printf("error on line %d", tokens[pt - 1].line), exit(0);
}
auto tt = static_pointer_cast<StructType>(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() != 2) {
printf("error on line %d", tokens[pt - 1].line), exit(0);
}
t = static_pointer_cast<DefVar>(ndefs[s])->def_var;
}
}
while (t->type() == 2 && (preview(TokenType::LT) || preview(TokenType::LP))) {
auto tt = static_pointer_cast<FunctionType>(t);
vector<shared_ptr<ValType>> 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<TemplateType>, shared_ptr<ValType>> 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() != 1) {
printf("error on line %d", tokens[pt].line), exit(0);
}
pt++;
return _createVal(static_pointer_cast<StructType>(t));
}
vector<shared_ptr<ValType>> createVals() {
vector<shared_ptr<ValType>> 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<ValType> _createType(shared_ptr<StructType> 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<StructType>();
tt->str = str->structs[s], tt->mp = t->mp;
vector<shared_ptr<ValType>> 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<ValType>(tt);
}
pt++;
return _createType(tt);
}
shared_ptr<ValType> createType() {
if (preview(TokenType::FN)) {
pt++;
auto t = make_shared<FunctionType>();
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<ValType> 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() == 2) {
printf("error on line %d", tokens[pt - 1].line), exit(0);
}
if (ndefs[s]->type() == 1) {
auto tt = make_shared<StructType>();
tt->str = static_pointer_cast<DefStruct>(ndefs[s])->def_struct;
vector<shared_ptr<ValType>> 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<ValType>(tt);
} else {
t = static_pointer_cast<ValType>(
static_pointer_cast<DefTemplate>(ndefs[s])->def_template);
}
}
if (!preview(TokenType::SCOPE)) {
return t;
}
if (t->type() != 1) {
printf("error on line %d", tokens[pt].line), exit(0);
}
pt++;
return _createType(static_pointer_cast<StructType>(t));
}
vector<shared_ptr<ValType>> createTypes() {
vector<shared_ptr<ValType>> 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<pair<wstring, shared_ptr<TemplateType>>> createTems() {
vector<pair<wstring, shared_ptr<TemplateType>>> 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<TemplateType>();
auto d = make_shared<DefTemplate>();
d->def_template = x;
ndefs[s] = static_pointer_cast<Def>(d);
tems.push_back({s, x});
};
for (single(); preview(TokenType::COMMA); pt++, single()) {
;
}
}
jump(TokenType::RT);
return tems;
}
vector<pair<wstring, shared_ptr<ValType>>> createPars() {
vector<pair<wstring, shared_ptr<ValType>>> pars;
jump(TokenType::LP);
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);
}
jump(TokenType::COLON);
auto t = createType();
auto d = make_shared<DefVar>();
d->def_var = t;
ndefs[s] = static_pointer_cast<Def>(d);
pars.push_back({s, t});
};
for (single(); preview(TokenType::COMMA); pt++, single()) {
;
}
}
jump(TokenType::RP);
return pars;
}
pair<wstring, shared_ptr<Struct>> createStruct() {
jump(TokenType::STRUCT);
wstring s;
vector<pair<wstring, shared_ptr<TemplateType>>> tems;
vector<pair<wstring, shared_ptr<ValType>>> pars;
if (preview(TokenType::ID)) {
s = tokens[pt++].s;
if (preview(TokenType::LT)) {
tems = createTems();
}
pars = createPars();
}
auto t = make_shared<Struct>();
for (const auto& pr : tems) {
t->c1.push_back(pr.second);
}
for (const auto& pr : pars) {
t->c2.push_back(pr.second);
t->vars[pr.first] = pr.second;
}
jump(TokenType::LB);
vector<wstring> defs;
vector<shared_ptr<Struct>> subs;
while (!preview(TokenType::RB)) {
bool pub = 0;
if (preview(TokenType::PUBLIC)) {
pub = 1, 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<DefStruct>();
tt->def_struct = t;
ndefs[s] = static_pointer_cast<Def>(tt);
}
return {s, t};
}
pair<wstring, shared_ptr<ValType>> createVar() {
wstring s;
shared_ptr<ValType> t;
if (preview(TokenType::STRUCT)) {
auto pr = createStruct();
s = jump(TokenType::ID);
jump(TokenType::SEMI);
auto tt = make_shared<StructType>();
tt->str = pr.second;
t = static_pointer_cast<ValType>(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<DefVar>();
d->def_var = t;
ndefs[s] = static_pointer_cast<Def>(d);
return {s, t};
}
void work() {
createVar();
}
int main() {
freopen("test.txt", "r", stdin);
read();
printTokens();
// return 0;
work();
return 0;
}