Add parsed type data structure, type application and arity.
This commit is contained in:
parent
682e0d3e1c
commit
379a64f379
|
@ -21,7 +21,9 @@ llvm_map_components_to_libnames(LLVM_LIBS core x86asmparser x86codegen)
|
||||||
|
|
||||||
# Create compiler executable
|
# Create compiler executable
|
||||||
add_executable(compiler
|
add_executable(compiler
|
||||||
ast.cpp ast.hpp definition.cpp
|
definition.cpp definition.hpp
|
||||||
|
parsed_type.cpp parsed_type.hpp
|
||||||
|
ast.cpp ast.hpp
|
||||||
llvm_context.cpp llvm_context.hpp
|
llvm_context.cpp llvm_context.hpp
|
||||||
type_env.cpp type_env.hpp
|
type_env.cpp type_env.hpp
|
||||||
env.cpp env.hpp
|
env.cpp env.hpp
|
||||||
|
|
35
11/parsed_type.cpp
Normal file
35
11/parsed_type.cpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#include "parsed_type.hpp"
|
||||||
|
#include "type.hpp"
|
||||||
|
#include "type_env.hpp"
|
||||||
|
|
||||||
|
type_ptr parsed_type_app::to_type(
|
||||||
|
const std::set<std::string>& vars,
|
||||||
|
const type_env& e) const {
|
||||||
|
auto parent_type = e.lookup_type(name);
|
||||||
|
if(parent_type == nullptr) throw 0;
|
||||||
|
type_base* base_type;
|
||||||
|
if(!(base_type = dynamic_cast<type_base*>(parent_type.get()))) throw 0;
|
||||||
|
|
||||||
|
type_app* new_app = new type_app(std::move(parent_type));
|
||||||
|
type_ptr to_return(new_app);
|
||||||
|
for(auto& arg : arguments) {
|
||||||
|
new_app->arguments.push_back(arg->to_type(vars, e));
|
||||||
|
}
|
||||||
|
return to_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
type_ptr parsed_type_var::to_type(
|
||||||
|
const std::set<std::string>& vars,
|
||||||
|
const type_env& e) const {
|
||||||
|
if(vars.find(var) != vars.end()) throw 0;
|
||||||
|
return type_ptr(new type_var(var));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type_ptr parsed_type_arr::to_type(
|
||||||
|
const std::set<std::string>& vars,
|
||||||
|
const type_env& env) const {
|
||||||
|
auto new_left = left->to_type(vars, env);
|
||||||
|
auto new_right = right->to_type(vars, env);
|
||||||
|
return type_ptr(new type_arr(std::move(new_left), std::move(new_right)));
|
||||||
|
}
|
43
11/parsed_type.hpp
Normal file
43
11/parsed_type.hpp
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
#pragma once
|
||||||
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include "type_env.hpp"
|
||||||
|
|
||||||
|
struct parsed_type {
|
||||||
|
virtual type_ptr to_type(
|
||||||
|
const std::set<std::string>& vars,
|
||||||
|
const type_env& env) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
using parsed_type_ptr = std::unique_ptr<parsed_type>;
|
||||||
|
|
||||||
|
struct parsed_type_app : parsed_type {
|
||||||
|
std::string name;
|
||||||
|
std::vector<parsed_type_ptr> arguments;
|
||||||
|
|
||||||
|
parsed_type_app(
|
||||||
|
std::string n,
|
||||||
|
std::vector<parsed_type_ptr> as)
|
||||||
|
: name(std::move(n)), arguments(std::move(as)) {}
|
||||||
|
|
||||||
|
type_ptr to_type(const std::set<std::string>& vars, const type_env& env) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct parsed_type_var : parsed_type {
|
||||||
|
std::string var;
|
||||||
|
|
||||||
|
parsed_type_var(std::string v) : var(std::move(v)) {}
|
||||||
|
|
||||||
|
type_ptr to_type(const std::set<std::string>& vars, const type_env& env) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct parsed_type_arr : parsed_type {
|
||||||
|
parsed_type_ptr left;
|
||||||
|
parsed_type_ptr right;
|
||||||
|
|
||||||
|
parsed_type_arr(parsed_type_ptr l, parsed_type_ptr r)
|
||||||
|
: left(std::move(l)), right(std::move(r)) {}
|
||||||
|
|
||||||
|
type_ptr to_type(const std::set<std::string>& vars, const type_env& env) const;
|
||||||
|
};
|
48
11/type.cpp
48
11/type.cpp
|
@ -2,6 +2,7 @@
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
|
|
||||||
void type_scheme::print(const type_mgr& mgr, std::ostream& to) const {
|
void type_scheme::print(const type_mgr& mgr, std::ostream& to) const {
|
||||||
|
@ -27,6 +28,20 @@ type_ptr substitute(const type_mgr& mgr, const std::map<std::string, type_ptr>&
|
||||||
auto right_result = substitute(mgr, subst, arr->right);
|
auto right_result = substitute(mgr, subst, arr->right);
|
||||||
if(left_result == arr->left && right_result == arr->right) return t;
|
if(left_result == arr->left && right_result == arr->right) return t;
|
||||||
return type_ptr(new type_arr(left_result, right_result));
|
return type_ptr(new type_arr(left_result, right_result));
|
||||||
|
} else if(type_app* app = dynamic_cast<type_app*>(t.get())) {
|
||||||
|
auto constructor_result = substitute(mgr, subst, app->constructor);
|
||||||
|
bool arg_changed = false;
|
||||||
|
std::vector<type_ptr> new_args;
|
||||||
|
for(auto& arg : app->arguments) {
|
||||||
|
auto arg_result = substitute(mgr, subst, arg);
|
||||||
|
arg_changed |= arg_result != arg;
|
||||||
|
new_args.push_back(std::move(arg_result));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(constructor_result == app->constructor && !arg_changed) return t;
|
||||||
|
type_app* new_app = new type_app(std::move(constructor_result));
|
||||||
|
std::swap(new_app->arguments, new_args);
|
||||||
|
return type_ptr(new_app);
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -60,6 +75,15 @@ void type_arr::print(const type_mgr& mgr, std::ostream& to) const {
|
||||||
to << ")";
|
to << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void type_app::print(const type_mgr& mgr, std::ostream& to) const {
|
||||||
|
constructor->print(mgr, to);
|
||||||
|
to << "* ";
|
||||||
|
for(auto& arg : arguments) {
|
||||||
|
to << " ";
|
||||||
|
arg->print(mgr, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string type_mgr::new_type_name() {
|
std::string type_mgr::new_type_name() {
|
||||||
int temp = last_id++;
|
int temp = last_id++;
|
||||||
std::string str = "";
|
std::string str = "";
|
||||||
|
@ -99,12 +123,10 @@ type_ptr type_mgr::resolve(type_ptr t, type_var*& var) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_mgr::unify(type_ptr l, type_ptr r) {
|
void type_mgr::unify(type_ptr l, type_ptr r) {
|
||||||
type_var* lvar;
|
type_var *lvar, *rvar;
|
||||||
type_var* rvar;
|
type_arr *larr, *rarr;
|
||||||
type_arr* larr;
|
type_base *lid, *rid;
|
||||||
type_arr* rarr;
|
type_app *lapp, *rapp;
|
||||||
type_base* lid;
|
|
||||||
type_base* rid;
|
|
||||||
|
|
||||||
l = resolve(l, lvar);
|
l = resolve(l, lvar);
|
||||||
r = resolve(r, rvar);
|
r = resolve(r, rvar);
|
||||||
|
@ -123,6 +145,17 @@ void type_mgr::unify(type_ptr l, type_ptr r) {
|
||||||
} else if((lid = dynamic_cast<type_base*>(l.get())) &&
|
} else if((lid = dynamic_cast<type_base*>(l.get())) &&
|
||||||
(rid = dynamic_cast<type_base*>(r.get()))) {
|
(rid = dynamic_cast<type_base*>(r.get()))) {
|
||||||
if(lid->name == rid->name) return;
|
if(lid->name == rid->name) return;
|
||||||
|
} else if((lapp = dynamic_cast<type_app*>(l.get())) &&
|
||||||
|
(rapp = dynamic_cast<type_app*>(r.get()))) {
|
||||||
|
unify(lapp->constructor, rapp->constructor);
|
||||||
|
auto left_it = lapp->arguments.begin();
|
||||||
|
auto right_it = rapp->arguments.begin();
|
||||||
|
while(left_it != lapp->arguments.end() &&
|
||||||
|
right_it != rapp->arguments.end()) {
|
||||||
|
unify(*left_it, *right_it);
|
||||||
|
left_it++, right_it++;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw unification_error(l, r);
|
throw unification_error(l, r);
|
||||||
|
@ -144,5 +177,8 @@ void type_mgr::find_free(const type_ptr& t, std::set<std::string>& into) const {
|
||||||
} else if(type_arr* arr = dynamic_cast<type_arr*>(resolved.get())) {
|
} else if(type_arr* arr = dynamic_cast<type_arr*>(resolved.get())) {
|
||||||
find_free(arr->left, into);
|
find_free(arr->left, into);
|
||||||
find_free(arr->right, into);
|
find_free(arr->right, into);
|
||||||
|
} else if(type_app* app = dynamic_cast<type_app*>(resolved.get())) {
|
||||||
|
find_free(app->constructor, into);
|
||||||
|
for(auto& arg : app->arguments) find_free(arg, into);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
15
11/type.hpp
15
11/type.hpp
|
@ -38,9 +38,10 @@ struct type_var : public type {
|
||||||
|
|
||||||
struct type_base : public type {
|
struct type_base : public type {
|
||||||
std::string name;
|
std::string name;
|
||||||
|
int32_t arity;
|
||||||
|
|
||||||
type_base(std::string n)
|
type_base(std::string n, int32_t a = 0)
|
||||||
: name(std::move(n)) {}
|
: name(std::move(n)), arity(a) {}
|
||||||
|
|
||||||
void print(const type_mgr& mgr, std::ostream& to) const;
|
void print(const type_mgr& mgr, std::ostream& to) const;
|
||||||
};
|
};
|
||||||
|
@ -66,6 +67,16 @@ struct type_arr : public type {
|
||||||
void print(const type_mgr& mgr, std::ostream& to) const;
|
void print(const type_mgr& mgr, std::ostream& to) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct type_app : public type {
|
||||||
|
type_ptr constructor;
|
||||||
|
std::vector<type_ptr> arguments;
|
||||||
|
|
||||||
|
type_app(type_ptr c)
|
||||||
|
: constructor(std::move(c)) {}
|
||||||
|
|
||||||
|
void print(const type_mgr& mgr, std::ostream& to) const;
|
||||||
|
};
|
||||||
|
|
||||||
struct type_mgr {
|
struct type_mgr {
|
||||||
int last_id = 0;
|
int last_id = 0;
|
||||||
std::map<std::string, type_ptr> types;
|
std::map<std::string, type_ptr> types;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user