Write up type code

This commit is contained in:
Danila Fedorin 2019-08-25 16:42:23 -07:00
parent 11716f21e7
commit d4e46d5597
2 changed files with 69 additions and 11 deletions

View File

@ -3,18 +3,17 @@
#include <algorithm> #include <algorithm>
std::string type_mgr::new_type_name() { std::string type_mgr::new_type_name() {
std::ostringstream oss;
int temp = last_id++; int temp = last_id++;
std::string str = "";
do { while(temp != -1) {
oss << (char) ('a' + (temp % 26)); str += (char) ('a' + (temp % 26));
temp /= 26; temp = temp / 26 - 1;
} while(temp); }
std::string str = oss.str();
std::reverse(str.begin(), str.end()); std::reverse(str.begin(), str.end());
return str; return str;
}; }
type_ptr type_mgr::new_type() { type_ptr type_mgr::new_type() {
return type_ptr(new type_var(new_type_name())); return type_ptr(new type_var(new_type_name()));
@ -23,3 +22,57 @@ type_ptr type_mgr::new_type() {
type_ptr type_mgr::new_arrow_type() { type_ptr type_mgr::new_arrow_type() {
return type_ptr(new type_arr(new_type(), new_type())); return type_ptr(new type_arr(new_type(), new_type()));
} }
type_ptr type_mgr::resolve(type_ptr t, type_var*& var) {
type_var* cast;
var = nullptr;
while((cast = dynamic_cast<type_var*>(t.get()))) {
auto it = types.find(cast->name);
if(it == types.end()) {
var = cast;
break;
}
t = it->second;
}
return t;
}
void type_mgr::unify(type_ptr l, type_ptr r) {
type_var* lvar;
type_var* rvar;
type_arr* larr;
type_arr* rarr;
type_base* lid;
type_base* rid;
l = resolve(l, lvar);
r = resolve(r, rvar);
if(lvar) {
bind(lvar->name, r);
return;
} else if(rvar) {
bind(rvar->name, l);
return;
} else if((larr = dynamic_cast<type_arr*>(l.get())) &&
(rarr = dynamic_cast<type_arr*>(r.get()))) {
unify(larr->left, rarr->left);
unify(larr->right, rarr->right);
return;
} else if((lid = dynamic_cast<type_base*>(l.get())) &&
(rid = dynamic_cast<type_base*>(r.get()))) {
if(lid->name == rid->name) return;
}
throw 0;
}
void type_mgr::bind(std::string s, type_ptr t) {
type_var* other = dynamic_cast<type_var*>(t.get());
if(other && other->name == s) return;
types[s] = t;
}

View File

@ -15,11 +15,11 @@ struct type_var : public type {
: name(std::move(n)) {} : name(std::move(n)) {}
}; };
struct type_id : public type { struct type_base : public type {
int id; std::string name;
type_id(int i) type_base(std::string n)
: id(i) {} : name(std::move(n)) {}
}; };
struct type_arr : public type { struct type_arr : public type {
@ -32,8 +32,13 @@ struct type_arr : public type {
struct type_mgr { struct type_mgr {
int last_id = 0; int last_id = 0;
std::map<std::string, type_ptr> types;
std::string new_type_name(); std::string new_type_name();
type_ptr new_type(); type_ptr new_type();
type_ptr new_arrow_type(); type_ptr new_arrow_type();
void unify(type_ptr l, type_ptr r);
type_ptr resolve(type_ptr t, type_var*& var);
void bind(std::string s, type_ptr t);
}; };