Type check constructors.
This commit is contained in:
parent
0b544a2515
commit
0b80ce711d
|
@ -4,17 +4,14 @@
|
||||||
|
|
||||||
namespace lily {
|
namespace lily {
|
||||||
type* ast_num::check(type_manager& mgr, std::shared_ptr<type_env> env) {
|
type* ast_num::check(type_manager& mgr, std::shared_ptr<type_env> env) {
|
||||||
std::cout << "checking number" << std::endl;
|
|
||||||
return mgr.require_type("Int");
|
return mgr.require_type("Int");
|
||||||
}
|
}
|
||||||
|
|
||||||
type* ast_var::check(type_manager& mgr, std::shared_ptr<type_env> env) {
|
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);
|
return env->get_identifier_type(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
type* ast_app::check(type_manager& mgr, std::shared_ptr<type_env> env) {
|
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* ltype = left->check(mgr, env);
|
||||||
type* rtype = right->check(mgr, env);
|
type* rtype = right->check(mgr, env);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ int main() {
|
||||||
"data Color = { Red, Black }\n"
|
"data Color = { Red, Black }\n"
|
||||||
"data IntList = { Nil, Cons(Int, IntList) }\n"
|
"data IntList = { Nil, Cons(Int, IntList) }\n"
|
||||||
"defn other x y = { 3 }\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) {
|
} catch(lily::error& e) {
|
||||||
std::cout << e.message << std::endl;
|
std::cout << e.message << std::endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,6 +279,9 @@ namespace lily {
|
||||||
base_env->set_type(pair.first, current_type);
|
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.
|
// Now that we have collected the functions, check their bodies.
|
||||||
for(auto& pair : functions) {
|
for(auto& pair : functions) {
|
||||||
type* body_type =
|
type* body_type =
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace lily {
|
||||||
new_constructor->params = std::move(params);
|
new_constructor->params = std::move(params);
|
||||||
|
|
||||||
constructor* raw_ptr = new_constructor.get();
|
constructor* raw_ptr = new_constructor.get();
|
||||||
constructors.push_back(std::move(new_constructor));
|
constructors[name] = std::move(new_constructor);
|
||||||
return raw_ptr;
|
return raw_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace lily {
|
namespace lily {
|
||||||
enum reserved_types {
|
enum reserved_types {
|
||||||
|
@ -34,7 +35,7 @@ namespace lily {
|
||||||
};
|
};
|
||||||
|
|
||||||
int type_id;
|
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) {}
|
type_data(int id) : type_id(id) {}
|
||||||
constructor* create_constructor(const std::string& name, std::vector<type*>&& params);
|
constructor* create_constructor(const std::string& name, std::vector<type*>&& params);
|
||||||
|
|
|
@ -7,7 +7,6 @@ namespace lily {
|
||||||
}
|
}
|
||||||
|
|
||||||
type* type_env::get_identifier_type(const std::string& name) {
|
type* type_env::get_identifier_type(const std::string& name) {
|
||||||
std::cout << "looking up " << name << std::endl;
|
|
||||||
if(!identifier_types.count(name)) {
|
if(!identifier_types.count(name)) {
|
||||||
if(parent) return parent->get_identifier_type(name);
|
if(parent) return parent->get_identifier_type(name);
|
||||||
throw error("unknown variable");
|
throw error("unknown variable");
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "type_manager.hpp"
|
#include "type_manager.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
|
#include "type.hpp"
|
||||||
|
#include "type_checker.hpp"
|
||||||
|
|
||||||
namespace lily {
|
namespace lily {
|
||||||
type_manager::type_manager() {
|
type_manager::type_manager() {
|
||||||
|
@ -38,4 +40,21 @@ namespace lily {
|
||||||
if(!type_names.count(name)) throw error("invalid type name");
|
if(!type_names.count(name)) throw error("invalid type name");
|
||||||
return type_names.find(name)->second;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "type.hpp"
|
#include "type.hpp"
|
||||||
|
|
||||||
namespace lily {
|
namespace lily {
|
||||||
|
class type_env;
|
||||||
|
|
||||||
class type_manager {
|
class type_manager {
|
||||||
private:
|
private:
|
||||||
int next_id;
|
int next_id;
|
||||||
|
@ -25,5 +27,7 @@ namespace lily {
|
||||||
}
|
}
|
||||||
|
|
||||||
type* require_type(const std::string& name) const;
|
type* require_type(const std::string& name) const;
|
||||||
|
|
||||||
|
void register_constructors(std::shared_ptr<type_env> env);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user