From 0258f583878db395091281fa4797f6dce969e586 Mon Sep 17 00:00:00 2001 From: lcw Date: Tue, 29 Aug 2023 19:52:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8B=86=E5=88=86=EF=BC=88?= =?UTF-8?q?=E7=BB=AD=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/element.h | 58 +++++ include/read.h | 8 + include/scan.h | 10 + include/token.h | 56 +++++ include/work.h | 10 + src/element.cpp | 58 +++++ src/read.cpp | 10 + src/scan.cpp | 78 ++++++ src/token.cpp | 0 src/work.cpp | 601 ++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 889 insertions(+) create mode 100644 include/element.h create mode 100644 include/read.h create mode 100644 include/scan.h create mode 100644 include/token.h create mode 100644 include/work.h create mode 100644 src/element.cpp create mode 100644 src/read.cpp create mode 100644 src/scan.cpp create mode 100644 src/token.cpp create mode 100644 src/work.cpp diff --git a/include/element.h b/include/element.h new file mode 100644 index 0000000..11a5427 --- /dev/null +++ b/include/element.h @@ -0,0 +1,58 @@ +#ifndef ACPA_ELEMENT_H +#define ACPA_ELEMENT_H + +#include +#include +#include +#include + +using std::map; +using std::vector; +using std::string; +using std::weak_ptr; +using std::shared_ptr; + +struct Struct; +struct ValType; +struct TemplateType; +struct StructType; +struct FunctionType; + +struct Struct { + weak_ptr fa; + vector> c1; + vector> c2; + map> vars; + map> 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 str; + map, shared_ptr> mp; +}; + +struct FunctionType : ValType { + const int type() override { + return 2; + } + vector> c1; + vector> c2; + shared_ptr c3; +}; + +bool sameType(shared_ptr, shared_ptr); + +#endif \ No newline at end of file diff --git a/include/read.h b/include/read.h new file mode 100644 index 0000000..da41de7 --- /dev/null +++ b/include/read.h @@ -0,0 +1,8 @@ +#ifndef ACPA_READ_H +#define ACPA_READ_H + +#include + +std::string read(); + +#endif \ No newline at end of file diff --git a/include/scan.h b/include/scan.h new file mode 100644 index 0000000..bb5d959 --- /dev/null +++ b/include/scan.h @@ -0,0 +1,10 @@ +#ifndef ACPA_SCAN_H +#define ACPA_SCAN_H + +#include "token.h" +#include +#include + +std::vector scan(std::string); + +#endif \ No newline at end of file diff --git a/include/token.h b/include/token.h new file mode 100644 index 0000000..0481395 --- /dev/null +++ b/include/token.h @@ -0,0 +1,56 @@ +#ifndef ACPA_TOKEN_H +#define ACPA_TOKEN_H + +#include +#include + +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, // identifier + EXCEED +}; + +std::string token_mp[] = {",", + ";", + "{", + "}", + "(", + ")", + "<", + ">", + "=", + ".", + ":", + "::", + "->", + "struct", + "Fn", + "return", + "typeof", + "public", + "ID"}; + +struct Token { + int line; + TokenType type; + std::string s; +}; + +#endif \ No newline at end of file diff --git a/include/work.h b/include/work.h new file mode 100644 index 0000000..7ded275 --- /dev/null +++ b/include/work.h @@ -0,0 +1,10 @@ +#ifndef ACPA_WORK_H +#define ACPA_WORK_H + +#include "token.h" +#include "element.h" +#include + +void work(std::vector); + +#endif \ No newline at end of file diff --git a/src/element.cpp b/src/element.cpp new file mode 100644 index 0000000..8ca8c37 --- /dev/null +++ b/src/element.cpp @@ -0,0 +1,58 @@ +#include "element.h" +#include +#include + +using namespace std; + +bool sameType(shared_ptr a, shared_ptr b) { + static set, shared_ptr>> eq; + if (a->type() != b->type()) { + return false; + } + if (a->type() == 0) { + auto aa = static_pointer_cast(a), + bb = static_pointer_cast(b); + return aa == bb || eq.find({aa, bb}) != eq.end(); + } + if (a->type() == 1) { + auto aa = static_pointer_cast(a); + auto bb = static_pointer_cast(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(a); + auto bb = static_pointer_cast(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; + } +} \ No newline at end of file diff --git a/src/read.cpp b/src/read.cpp new file mode 100644 index 0000000..bb258ca --- /dev/null +++ b/src/read.cpp @@ -0,0 +1,10 @@ +#include "read.h" + +using namespace std; + +string read() +{ + string s; + for(char ch=getchar();ch!=EOF;ch=getchar()) s+=ch; + return s; +} \ No newline at end of file diff --git a/src/scan.cpp b/src/scan.cpp new file mode 100644 index 0000000..978d2af --- /dev/null +++ b/src/scan.cpp @@ -0,0 +1,78 @@ +#include "scan.h" + +using namespace std; + +vector scan(string s) { + size_t pt = 0; + int line = 1; + vector tokens; + auto skipSpace = [&]() { + while (pt < s.size() && isspace(s[pt])) { + if (s[pt] == '\n') { + line++; + } + pt++; + } + }; + for (skipSpace(); pt < s.size(); skipSpace()) { + TokenType type; + string t; + if (s[pt] == ',') { + type = TokenType::COMMA, pt++; + } else if (s[pt] == ';') { + type = TokenType::SEMI, pt++; + } else if (s[pt] == '{') { + type = TokenType::LB, pt++; + } else if (s[pt] == '}') { + type = TokenType::RB, pt++; + } else if (s[pt] == '(') { + type = TokenType::LP, pt++; + } else if (s[pt] == ')') { + type = TokenType::RP, pt++; + } else if (s[pt] == '<') { + type = TokenType::LT, pt++; + } else if (s[pt] == '>') { + type = TokenType::RT, pt++; + } else if (s[pt] == '=') { + type = TokenType::ASSIGN, pt++; + } else if (s[pt] == '.') { + type = TokenType::DOT, pt++; + } else if (s[pt] == ':') { + if (pt + 1 < s.size() && s[pt + 1] == ':') { + type = TokenType::SCOPE, pt += 2; + } else { + type = TokenType::COLON, pt++; + } + } else if (s[pt] == '-') { + if (pt + 1 < s.size() && s[pt + 1] == '>') { + type = TokenType::IMPLY, pt += 2; + } else { + printf("error on line %d", line), exit(1); + } + } else if (isalpha(s[pt]) || s[pt] == '_') { + size_t r = pt + 1; + while (r < s.size() && (isalpha(s[r]) || s[r] == '_' || isdigit(s[r]))) { + r++; + } + t = s.substr(pt, r - pt); + if (t == "struct") { + type = TokenType::STRUCT, t.clear(); + } else if (t == "Fn") { + type = TokenType::FN, t.clear(); + } else if (t == "return") { + type = TokenType::RETURN, t.clear(); + } else if (t == "typeof") { + type = TokenType::TYPEOF, t.clear(); + } else if (t == "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}); + } + return tokens; +} \ No newline at end of file diff --git a/src/token.cpp b/src/token.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/work.cpp b/src/work.cpp new file mode 100644 index 0000000..51a7ad8 --- /dev/null +++ b/src/work.cpp @@ -0,0 +1,601 @@ +#include "work.h" +#include +#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 { + virtual const int type() = 0; +}; + +struct DefTemplate : Def { + const int type() override { + return 0; + } + shared_ptr def_template; +}; + +struct DefStruct : Def { + const int type() override { + return 1; + } + shared_ptr def_struct; +}; + +struct DefVar : Def { + const int type() override { + return 2; + } + 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(); +pair> createStruct(); +pair> createVar(); + +shared_ptr struct_replace(shared_ptr vt, shared_ptr ut) { + static map, shared_ptr> eq; + if (vt->type() == 0) { + auto vtt = static_pointer_cast(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(it2->second); + } + return vt; + } + if (vt->type() == 1) { + auto vtt = static_pointer_cast(vt); + auto tt = make_shared(); + (*tt) = (*ut); + set> 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(tt); + } + // if(vt->type()==2) + { + auto vtt = static_pointer_cast(vt); + auto tt = make_shared(); + for (size_t i = 0; i < vtt->c1.size(); i++) { + tt->c1.push_back(eq[vtt->c1[i]] = make_shared()); + } + 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(tt); + } +} + +shared_ptr function_replace( + shared_ptr t, + const map, shared_ptr>& mp) { + static map, shared_ptr> eq; + if (t->type() == 0) { + auto tt = static_pointer_cast(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(it2->second); + } + return t; + } + if (t->type() == 1) { + auto tt = make_shared(); + (*tt) = (*static_pointer_cast(t)); + for (auto& pr : static_pointer_cast(tt)->mp) { + pr.second = function_replace(pr.second, mp); + } + return tt; + } + // if(t->type()==2) + { + auto vt = static_pointer_cast(t); + auto tt = make_shared(); + for (size_t i = 0; i < vt->c1.size(); i++) { + tt->c1.push_back(eq[vt->c1[i]] = make_shared()); + } + 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(tt); + } +} + +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() == 2 && (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() != 1) { + 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() == 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(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(ndefs[s])->def_var; + } + } + while (t->type() == 2 && (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() != 1) { + 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() == 2) { + printf("error on line %d", tokens[pt - 1].line), exit(0); + } + if (ndefs[s]->type() == 1) { + 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() != 1) { + 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() { + vector>> 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(); + d->def_var = t; + ndefs[s] = static_pointer_cast(d); + pars.push_back({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; + + if (preview(TokenType::ID)) { + s = tokens[pt++].s; + if (preview(TokenType::LT)) { + tems = createTems(); + } + pars = createPars(); + } + auto t = make_shared(); + 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 defs; + vector> 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(); + 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(); +} \ No newline at end of file