Type check constructors.

This commit is contained in:
Danila Fedorin 2019-06-09 20:24:44 -07:00
parent 0b544a2515
commit 0b80ce711d
8 changed files with 31 additions and 7 deletions

View File

@ -4,17 +4,14 @@
namespace lily {
type* ast_num::check(type_manager& mgr, std::shared_ptr<type_env> env) {
std::cout << "checking number" << std::endl;
return mgr.require_type("Int");
}
type* ast_var::check(type_manager& mgr, std::shared_ptr<type_env> env) {
std::cout << "checking variable" << std::endl;
return env->get_identifier_type(name);
}
type* ast_app::check(type_manager& mgr, std::shared_ptr<type_env> env) {
std::cout << "checking application" << std::endl;
type* ltype = left->check(mgr, env);
type* rtype = right->check(mgr, env);

View File

@ -9,7 +9,8 @@ int main() {
"data Color = { Red, Black }\n"
"data IntList = { Nil, Cons(Int, IntList) }\n"
"defn other x y = { 3 }\n"
"defn add x y = { x + add x x }");
"defn add x y = { x + y }\n"
"defn ones = { Cons 1 ones }");
} catch(lily::error& e) {
std::cout << e.message << std::endl;
}

View File

@ -279,6 +279,9 @@ namespace lily {
base_env->set_type(pair.first, current_type);
}
// We also want to gather all the constructor calls.
type_mgr.register_constructors(base_env);
// Now that we have collected the functions, check their bodies.
for(auto& pair : functions) {
type* body_type =

View File

@ -10,7 +10,7 @@ namespace lily {
new_constructor->params = std::move(params);
constructor* raw_ptr = new_constructor.get();
constructors.push_back(std::move(new_constructor));
constructors[name] = std::move(new_constructor);
return raw_ptr;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <string>
#include <vector>
#include <map>
namespace lily {
enum reserved_types {
@ -34,7 +35,7 @@ namespace lily {
};
int type_id;
std::vector<std::unique_ptr<constructor>> constructors;
std::map<std::string, std::unique_ptr<constructor>> constructors;
type_data(int id) : type_id(id) {}
constructor* create_constructor(const std::string& name, std::vector<type*>&& params);

View File

@ -7,7 +7,6 @@ namespace lily {
}
type* type_env::get_identifier_type(const std::string& name) {
std::cout << "looking up " << name << std::endl;
if(!identifier_types.count(name)) {
if(parent) return parent->get_identifier_type(name);
throw error("unknown variable");

View File

@ -1,6 +1,8 @@
#include "type_manager.hpp"
#include <memory>
#include "error.hpp"
#include "type.hpp"
#include "type_checker.hpp"
namespace lily {
type_manager::type_manager() {
@ -38,4 +40,21 @@ namespace lily {
if(!type_names.count(name)) throw error("invalid type name");
return type_names.find(name)->second;
}
void type_manager::register_constructors(std::shared_ptr<type_env> env) {
for(auto& type_ref : types) {
type_data* data_type = dynamic_cast<type_data*>(type_ref.get());
if(!data_type) continue;
for(auto& pair : data_type->constructors) {
size_t param_count = pair.second->params.size();
type* current_type = data_type;
for(int i = 0; i < param_count; i++) {
type* param = pair.second->params[param_count - i - 1];
current_type = create_type<type_func>(param, current_type);
}
env->set_type(pair.first, current_type);
}
}
}
}

View File

@ -5,6 +5,8 @@
#include "type.hpp"
namespace lily {
class type_env;
class type_manager {
private:
int next_id;
@ -25,5 +27,7 @@ namespace lily {
}
type* require_type(const std::string& name) const;
void register_constructors(std::shared_ptr<type_env> env);
};
}