改善了一些实现

Co-authored-by: lcw <ez_lcw@foxmail.com>
This commit is contained in:
方而静 2023-08-30 09:02:34 +08:00
parent e5caca5350
commit 3d1ffa838f
Signed by: szTom
GPG Key ID: 072D999D60C6473C
6 changed files with 206 additions and 185 deletions

1
.gitignore vendored
View File

@ -37,6 +37,7 @@
build/
CMakeList.txt
acpa
.stackdump
# --> Editors
# Vim

View File

@ -2,11 +2,15 @@
#define ACPA_ELEMENT_H
#include <map>
#include <set>
#include <utility>
#include <memory>
#include <string>
#include <vector>
using std::map;
using std::set;
using std::pair;
using std::shared_ptr;
using std::string;
using std::vector;
@ -27,27 +31,46 @@ struct Struct {
};
struct ValType {
virtual int type() const = 0;
enum Type {
TEMPLATE,
STRUCT,
FUNCTION
};
virtual ValType::Type type() const = 0;
virtual shared_ptr<ValType> struct_replace(shared_ptr<StructType>, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>>&) = 0;
virtual shared_ptr<ValType> function_replace(const map<shared_ptr<TemplateType>, shared_ptr<ValType>>&, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>>&) = 0;
virtual bool sameType(shared_ptr<ValType>, set<pair<shared_ptr<TemplateType>, shared_ptr<TemplateType>>>&) = 0;
virtual ~ValType() = default;
};
struct TemplateType : ValType {
int type() const override;
ValType::Type type() const override;
shared_ptr<ValType> struct_replace(shared_ptr<StructType>, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>>&) override;
shared_ptr<ValType> function_replace(const map<shared_ptr<TemplateType>, shared_ptr<ValType>>&, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>>&) override;
bool sameType(shared_ptr<ValType>, set<pair<shared_ptr<TemplateType>, shared_ptr<TemplateType>>>&) override;
};
struct StructType : ValType {
int type() const override;
ValType::Type type() const override;
shared_ptr<ValType> struct_replace(shared_ptr<StructType>, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>>&) override;
shared_ptr<ValType> function_replace(const map<shared_ptr<TemplateType>, shared_ptr<ValType>>&, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>>&) override;
bool sameType(shared_ptr<ValType>, set<pair<shared_ptr<TemplateType>, shared_ptr<TemplateType>>>&) override;
shared_ptr<Struct> str;
map<shared_ptr<TemplateType>, shared_ptr<ValType>> mp;
};
struct FunctionType : ValType {
int type() const override;
ValType::Type type() const override;
shared_ptr<ValType> struct_replace(shared_ptr<StructType>, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>>&) override;
shared_ptr<ValType> function_replace(const map<shared_ptr<TemplateType>, shared_ptr<ValType>>&, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>>&) override;
bool sameType(shared_ptr<ValType>, set<pair<shared_ptr<TemplateType>, shared_ptr<TemplateType>>>&) override;
vector<shared_ptr<TemplateType>> c1;
vector<shared_ptr<ValType>> c2;
shared_ptr<ValType> c3;
};
shared_ptr<ValType> struct_replace(shared_ptr<ValType>, shared_ptr<StructType>);
shared_ptr<ValType> function_replace(shared_ptr<ValType>, const map<shared_ptr<TemplateType>, shared_ptr<ValType>>&);
bool sameType(shared_ptr<ValType>, shared_ptr<ValType>);
#endif

View File

@ -1,19 +1,158 @@
#include "element.h"
#include <assert.h>
#include <set>
using namespace std;
int TemplateType::type() const {
return 0;
ValType::Type TemplateType::type() const {
return ValType::TEMPLATE;
}
int StructType::type() const {
return 1;
ValType::Type StructType::type() const {
return ValType::STRUCT;
}
int FunctionType::type() const {
return 2;
ValType::Type FunctionType::type() const {
return ValType::FUNCTION;
}
shared_ptr<ValType> TemplateType::struct_replace(shared_ptr<StructType> ut, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>> &eq) {
auto vt = shared_ptr<TemplateType>(this);
auto it1 = ut->mp.find(vt);
auto it2 = eq.find(vt);
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 static_pointer_cast<ValType>(vt);
}
shared_ptr<ValType> StructType::struct_replace(shared_ptr<StructType> ut, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>> &eq) {
auto tt = make_shared<StructType>();
(*tt) = (*ut);
set<shared_ptr<Struct>> vis;
for (auto u = 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 : mp) {
tt->mp[pr.first] = pr.second->struct_replace(ut, eq);
}
return static_pointer_cast<ValType>(tt);
}
shared_ptr<ValType> FunctionType::struct_replace(shared_ptr<StructType> ut, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>> &eq) {
auto tt = make_shared<FunctionType>();
for (size_t i = 0; i < c1.size(); i++) {
tt->c1.push_back(eq[c1[i]] = make_shared<TemplateType>());
}
for (auto cc : c2) {
tt->c2.push_back(cc->struct_replace(ut, eq));
}
tt->c3 = c3->struct_replace(ut, eq);
for (size_t i = 0; i < c1.size(); i++) {
eq.erase(c1[i]);
}
return static_pointer_cast<ValType>(tt);
}
shared_ptr<ValType> struct_replace(shared_ptr<ValType> vt, shared_ptr<StructType> ut) {
static map<shared_ptr<TemplateType>, shared_ptr<TemplateType>> eq;
return vt->struct_replace(ut,eq);
}
shared_ptr<ValType> TemplateType::function_replace(const map<shared_ptr<TemplateType>, shared_ptr<ValType>> &mp, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>> &eq) {
auto tt = shared_ptr<TemplateType>(this);
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 static_pointer_cast<ValType>(tt);
}
shared_ptr<ValType> StructType::function_replace(const map<shared_ptr<TemplateType>, shared_ptr<ValType>> &mp, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>> &eq) {
auto tt = make_shared<StructType>();
(*tt) = (*this);
for (auto& pr : tt->mp) {
pr.second = pr.second->function_replace(mp, eq);
}
return tt;
}
shared_ptr<ValType> FunctionType::function_replace(const map<shared_ptr<TemplateType>, shared_ptr<ValType>> &mp, map<shared_ptr<TemplateType>, shared_ptr<TemplateType>> &eq) {
auto tt = make_shared<FunctionType>();
for (size_t i = 0; i < c1.size(); i++) {
tt->c1.push_back(eq[c1[i]] = make_shared<TemplateType>());
}
for (auto cc : c2) {
tt->c2.push_back(cc->function_replace(mp, eq));
}
tt->c3 = c3->function_replace(mp, eq);
for (size_t i = 0; i < c1.size(); i++) {
eq.erase(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;
return t->function_replace(mp, eq);
}
bool TemplateType::sameType(shared_ptr<ValType> b, set<pair<shared_ptr<TemplateType>, shared_ptr<TemplateType>>> &eq) {
auto aa = shared_ptr<TemplateType>(this), bb = static_pointer_cast<TemplateType>(b);
return aa == bb || eq.find({aa, bb}) != eq.end();
}
bool StructType::sameType(shared_ptr<ValType> b, set<pair<shared_ptr<TemplateType>, shared_ptr<TemplateType>>> &eq) {
auto bb = static_pointer_cast<StructType>(b);
if (str != bb->str) {
return false;
}
assert(mp.size() == bb->mp.size());
for (auto ia = mp.begin(), ib = bb->mp.begin(); ia != mp.end(); ia++, ib++) {
assert(ia->first == ib->first);
if (!ia->second->sameType(ib->second, eq)) {
return false;
}
}
return true;
}
bool FunctionType::sameType(shared_ptr<ValType> b, set<pair<shared_ptr<TemplateType>, shared_ptr<TemplateType>>> &eq) {
auto bb = static_pointer_cast<FunctionType>(b);
if (c1.size() != bb->c1.size() || c2.size() != bb->c2.size()) {
return false;
}
for (size_t i = 0; i < c1.size(); i++) {
eq.insert({c1[i], bb->c1[i]});
}
bool flag = 1;
for (size_t i = 0; i < c2.size(); i++) {
if (!c2[i]->sameType(bb->c2[i], eq)) {
flag = 0;
break;
}
}
if (!flag && !c3->sameType(bb->c3, eq)) {
flag = 0;
}
for (size_t i = 0; i < c1.size(); i++) {
eq.erase({c1[i], bb->c1[i]});
}
return flag;
}
bool sameType(shared_ptr<ValType> a, shared_ptr<ValType> b) {
@ -21,50 +160,5 @@ bool sameType(shared_ptr<ValType> a, shared_ptr<ValType> b) {
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;
}
return a->sameType(b, eq);
}

View File

@ -1,6 +1,5 @@
#include "work.h"
#include <assert.h>
#include <set>
using namespace std;
@ -18,27 +17,32 @@ vector<Token> tokens;
// }
struct Def {
virtual int type() const = 0;
enum Type {
TEMPLATE,
STRUCT,
VAR
};
virtual Def::Type type() const = 0;
virtual ~Def() = default;
};
struct DefTemplate : Def {
int type() const override {
return 0;
Def::Type type() const override {
return Def::TEMPLATE;
}
shared_ptr<TemplateType> def_template;
};
struct DefStruct : Def {
int type() const override {
return 1;
Def::Type type() const override {
return Def::STRUCT;
}
shared_ptr<Struct> def_struct;
};
struct DefVar : Def {
int type() const override {
return 2;
Def::Type type() const override {
return Def::VAR;
}
shared_ptr<ValType> def_var;
};
@ -82,101 +86,6 @@ 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);
@ -184,7 +93,8 @@ shared_ptr<ValType> _createVal(shared_ptr<StructType> ft) {
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))) {
while (t->type() == ValType::FUNCTION
&& (preview(TokenType::LT) || preview(TokenType::LP))) {
auto tt = static_pointer_cast<FunctionType>(t);
vector<shared_ptr<ValType>> types;
if (preview(TokenType::LT)) {
@ -215,7 +125,7 @@ shared_ptr<ValType> _createVal(shared_ptr<StructType> ft) {
if (!preview(TokenType::DOT)) {
return t;
}
if (t->type() != 1) {
if (t->type() != ValType::STRUCT) {
printf("error on line %d", tokens[pt].line), exit(0);
}
pt++;
@ -275,14 +185,14 @@ shared_ptr<ValType> createVal() {
flag = 1;
} else if (preview(TokenType::ID)) {
auto s = tokens[pt].s;
if (ndefs.find(s) != ndefs.end() && ndefs[s]->type() == 1) {
if (ndefs.find(s) != ndefs.end() && ndefs[s]->type() == Def::STRUCT) {
flag = 1;
}
}
if (flag) {
t = createType();
if (t->type() != 1) {
if (t->type() != ValType::STRUCT) {
printf("error on line %d", tokens[pt - 1].line), exit(0);
}
auto tt = static_pointer_cast<StructType>(t);
@ -302,13 +212,14 @@ shared_ptr<ValType> createVal() {
}
} else {
auto s = jump(TokenType::ID);
if (ndefs.find(s) == ndefs.end() || ndefs[s]->type() != 2) {
if (ndefs.find(s) == ndefs.end() || ndefs[s]->type() != Def::VAR) {
printf("error on line %d", tokens[pt - 1].line), exit(0);
}
t = static_pointer_cast<DefVar>(ndefs[s])->def_var;
}
}
while (t->type() == 2 && (preview(TokenType::LT) || preview(TokenType::LP))) {
while (t->type() == ValType::FUNCTION
&& (preview(TokenType::LT) || preview(TokenType::LP))) {
auto tt = static_pointer_cast<FunctionType>(t);
vector<shared_ptr<ValType>> types;
if (preview(TokenType::LT)) {
@ -339,7 +250,7 @@ shared_ptr<ValType> createVal() {
if (!preview(TokenType::DOT)) {
return t;
}
if (t->type() != 1) {
if (t->type() != ValType::STRUCT) {
printf("error on line %d", tokens[pt].line), exit(0);
}
pt++;
@ -351,9 +262,7 @@ vector<shared_ptr<ValType>> createVals() {
jump(TokenType::LP);
if (!preview(TokenType::RP)) {
auto single = [&]() { vals.push_back(createVal()); };
for (single(); preview(TokenType::COMMA); pt++, single()) {
;
}
for (single(); preview(TokenType::COMMA); pt++, single()) {}
}
jump(TokenType::RP);
return vals;
@ -411,10 +320,10 @@ shared_ptr<ValType> createType() {
jump(TokenType::RP);
} else {
auto s = jump(TokenType::ID);
if (ndefs.find(s) == ndefs.end() || ndefs[s]->type() == 2) {
if (ndefs.find(s) == ndefs.end() || ndefs[s]->type() == Def::VAR) {
printf("error on line %d", tokens[pt - 1].line), exit(0);
}
if (ndefs[s]->type() == 1) {
if (ndefs[s]->type() == Def::STRUCT) {
auto tt = make_shared<StructType>();
tt->str = static_pointer_cast<DefStruct>(ndefs[s])->def_struct;
vector<shared_ptr<ValType>> types;
@ -436,7 +345,7 @@ shared_ptr<ValType> createType() {
if (!preview(TokenType::SCOPE)) {
return t;
}
if (t->type() != 1) {
if (t->type() != ValType::STRUCT) {
printf("error on line %d", tokens[pt].line), exit(0);
}
pt++;
@ -448,9 +357,7 @@ vector<shared_ptr<ValType>> createTypes() {
jump(TokenType::LT);
if (!preview(TokenType::RT)) {
auto single = [&]() { types.push_back(createType()); };
for (single(); preview(TokenType::COMMA); pt++, single()) {
;
}
for (single(); preview(TokenType::COMMA); pt++, single()) {}
}
jump(TokenType::RT);
return types;
@ -471,9 +378,7 @@ vector<pair<string, shared_ptr<TemplateType>>> createTems() {
ndefs[s] = static_pointer_cast<Def>(d);
tems.push_back({s, x});
};
for (single(); preview(TokenType::COMMA); pt++, single()) {
;
}
for (single(); preview(TokenType::COMMA); pt++, single()) {}
}
jump(TokenType::RT);
return tems;
@ -495,9 +400,7 @@ vector<pair<string, shared_ptr<ValType>>> createPars() {
ndefs[s] = static_pointer_cast<Def>(d);
pars.push_back({s, t});
};
for (single(); preview(TokenType::COMMA); pt++, single()) {
;
}
for (single(); preview(TokenType::COMMA); pt++, single()) {}
}
jump(TokenType::RP);
return pars;

View File

@ -677,7 +677,7 @@ public:
// align multiline help message
auto stream_width = stream.width();
auto name_padding = std::string(name_stream.str().size(), ' ');
auto pos = 0;
std::size_t pos = 0;
auto prev = 0;
auto first_line = true;
auto hspace = " "; // minimal space between name and help message

View File

@ -2,7 +2,7 @@ set_project("acpa")
app_version = "0.1a0"
set_version(app_version)
set_basename("acpa")
set_languages("c++17")
set_languages("c++20")
set_targetdir(".")
set_policy("build.warning", true)
@ -14,7 +14,7 @@ target("build")
add_files("src/**.cpp")
add_includedirs("include/")
add_includedirs("third-party/")
add_defines("APP_VERSION=" .. app_version)
-- add_defines("APP_VERSION=" .. app_version)
if is_mode("release") then
set_strip("all")
set_optimize("faster")