拆分源代码到多个文件 (#5)
fixes #3 Co-authored-by: lcw <ez_lcw@foxmail.com> Co-authored-by: szdytom <szdytom@qq.com> Reviewed-on: #5
This commit is contained in:
parent
35b8c3bdcc
commit
e5caca5350
53
include/element.h
Normal file
53
include/element.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef ACPA_ELEMENT_H
|
||||||
|
#define ACPA_ELEMENT_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using std::map;
|
||||||
|
using std::shared_ptr;
|
||||||
|
using std::string;
|
||||||
|
using std::vector;
|
||||||
|
using std::weak_ptr;
|
||||||
|
|
||||||
|
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<string, shared_ptr<ValType>> vars;
|
||||||
|
map<string, shared_ptr<Struct>> structs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ValType {
|
||||||
|
virtual int type() const = 0;
|
||||||
|
virtual ~ValType() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TemplateType : ValType {
|
||||||
|
int type() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StructType : ValType {
|
||||||
|
int type() const override;
|
||||||
|
shared_ptr<Struct> str;
|
||||||
|
map<shared_ptr<TemplateType>, shared_ptr<ValType>> mp;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FunctionType : ValType {
|
||||||
|
int type() const override;
|
||||||
|
vector<shared_ptr<TemplateType>> c1;
|
||||||
|
vector<shared_ptr<ValType>> c2;
|
||||||
|
shared_ptr<ValType> c3;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool sameType(shared_ptr<ValType>, shared_ptr<ValType>);
|
||||||
|
|
||||||
|
#endif
|
8
include/read.h
Normal file
8
include/read.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef ACPA_READ_H
|
||||||
|
#define ACPA_READ_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
std::string read();
|
||||||
|
|
||||||
|
#endif
|
10
include/scan.h
Normal file
10
include/scan.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef ACPA_SCAN_H
|
||||||
|
#define ACPA_SCAN_H
|
||||||
|
|
||||||
|
#include "token.h"
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
std::vector<Token> scan(std::string);
|
||||||
|
|
||||||
|
#endif
|
38
include/token.h
Normal file
38
include/token.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef ACPA_TOKEN_H
|
||||||
|
#define ACPA_TOKEN_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
extern std::string token_mp[];
|
||||||
|
|
||||||
|
struct Token {
|
||||||
|
int line;
|
||||||
|
TokenType type;
|
||||||
|
std::string s;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
10
include/work.h
Normal file
10
include/work.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef ACPA_WORK_H
|
||||||
|
#define ACPA_WORK_H
|
||||||
|
|
||||||
|
#include "element.h"
|
||||||
|
#include "token.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
void work(std::vector<Token>);
|
||||||
|
|
||||||
|
#endif
|
70
src/element.cpp
Normal file
70
src/element.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include "element.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int TemplateType::type() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StructType::type() const {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FunctionType::type() const {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
837
src/main.cpp
837
src/main.cpp
@ -1,832 +1,15 @@
|
|||||||
|
#include "element.h"
|
||||||
|
#include "read.h"
|
||||||
|
#include "scan.h"
|
||||||
|
#include "token.h"
|
||||||
|
#include "work.h"
|
||||||
#include <argparse/argparse.hpp>
|
#include <argparse/argparse.hpp>
|
||||||
#include <bits/stdc++.h>
|
|
||||||
using namespace std;
|
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, // identifier
|
|
||||||
EXCEED
|
|
||||||
};
|
|
||||||
|
|
||||||
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(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
#define AS_STR(x) #x
|
|
||||||
argparse::ArgumentParser program("acpa",
|
argparse::ArgumentParser program("acpa",
|
||||||
AS_STR(APP_VERSION),
|
"0.1a0",
|
||||||
argparse::default_arguments::help,
|
argparse::default_arguments::help,
|
||||||
false);
|
false);
|
||||||
|
|
||||||
@ -845,9 +28,7 @@ int main(int argc, char* argv[]) {
|
|||||||
auto input_file = program.get<std::string>("input_file");
|
auto input_file = program.get<std::string>("input_file");
|
||||||
freopen(input_file.c_str(), "r", stdin);
|
freopen(input_file.c_str(), "r", stdin);
|
||||||
|
|
||||||
read();
|
work(scan(read()));
|
||||||
printTokens();
|
|
||||||
work();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
src/read.cpp
Normal file
11
src/read.cpp
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#include "read.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
string read() {
|
||||||
|
string s;
|
||||||
|
for (char ch = getchar(); ch != EOF; ch = getchar()) {
|
||||||
|
s += ch;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
78
src/scan.cpp
Normal file
78
src/scan.cpp
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#include "scan.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
vector<Token> scan(string s) {
|
||||||
|
size_t pt = 0;
|
||||||
|
int line = 1;
|
||||||
|
vector<Token> 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;
|
||||||
|
}
|
22
src/token.cpp
Normal file
22
src/token.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
std::string token_mp[] = {",",
|
||||||
|
";",
|
||||||
|
"{",
|
||||||
|
"}",
|
||||||
|
"(",
|
||||||
|
")",
|
||||||
|
"<",
|
||||||
|
">",
|
||||||
|
"=",
|
||||||
|
".",
|
||||||
|
":",
|
||||||
|
"::",
|
||||||
|
"->",
|
||||||
|
"struct",
|
||||||
|
"Fn",
|
||||||
|
"return",
|
||||||
|
"typeof",
|
||||||
|
"public",
|
||||||
|
"ID"};
|
603
src/work.cpp
Normal file
603
src/work.cpp
Normal file
@ -0,0 +1,603 @@
|
|||||||
|
#include "work.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
size_t pt;
|
||||||
|
vector<Token> tokens;
|
||||||
|
|
||||||
|
// void printTokens() {
|
||||||
|
// wstring_convert<codecvt_utf8<wchar_t>> cvt;
|
||||||
|
// for (auto u : tokens) {
|
||||||
|
// cout << token_mp[static_cast<int>(u.type)] << " " << u.line << " " <<
|
||||||
|
// cvt.to_bytes(u.s)
|
||||||
|
// << endl;
|
||||||
|
// }
|
||||||
|
// cout << endl;
|
||||||
|
// }
|
||||||
|
|
||||||
|
struct Def {
|
||||||
|
virtual int type() const = 0;
|
||||||
|
virtual ~Def() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DefTemplate : Def {
|
||||||
|
int type() const override {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
shared_ptr<TemplateType> def_template;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DefStruct : Def {
|
||||||
|
int type() const override {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
shared_ptr<Struct> def_struct;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DefVar : Def {
|
||||||
|
int type() const override {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
shared_ptr<ValType> def_var;
|
||||||
|
};
|
||||||
|
|
||||||
|
map<string, 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});
|
||||||
|
}
|
||||||
|
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<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<string, shared_ptr<TemplateType>>> createTems();
|
||||||
|
vector<pair<string, shared_ptr<ValType>>> createPars();
|
||||||
|
pair<string, shared_ptr<Struct>> createStruct();
|
||||||
|
pair<string, 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<string, 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<string> 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<string, shared_ptr<TemplateType>>> createTems() {
|
||||||
|
vector<pair<string, 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<string, shared_ptr<ValType>>> createPars() {
|
||||||
|
vector<pair<string, 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<string, shared_ptr<Struct>> createStruct() {
|
||||||
|
jump(TokenType::STRUCT);
|
||||||
|
string s;
|
||||||
|
vector<pair<string, shared_ptr<TemplateType>>> tems;
|
||||||
|
vector<pair<string, 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<string> 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<string, shared_ptr<ValType>> createVar() {
|
||||||
|
string 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(vector<Token> _tokens) {
|
||||||
|
tokens = _tokens;
|
||||||
|
createVar();
|
||||||
|
}
|
@ -12,7 +12,7 @@ target("build")
|
|||||||
set_default(true)
|
set_default(true)
|
||||||
set_warnings("allextra")
|
set_warnings("allextra")
|
||||||
add_files("src/**.cpp")
|
add_files("src/**.cpp")
|
||||||
-- add_includedirs("include/")
|
add_includedirs("include/")
|
||||||
add_includedirs("third-party/")
|
add_includedirs("third-party/")
|
||||||
add_defines("APP_VERSION=" .. app_version)
|
add_defines("APP_VERSION=" .. app_version)
|
||||||
if is_mode("release") then
|
if is_mode("release") then
|
||||||
|
Loading…
x
Reference in New Issue
Block a user