diff --git a/src/ast.cpp b/src/ast.cpp index 403ddf7..c011bd5 100644 --- a/src/ast.cpp +++ b/src/ast.cpp @@ -4,17 +4,14 @@ namespace lily { type* ast_num::check(type_manager& mgr, std::shared_ptr env) { - std::cout << "checking number" << std::endl; return mgr.require_type("Int"); } type* ast_var::check(type_manager& mgr, std::shared_ptr env) { - std::cout << "checking variable" << std::endl; return env->get_identifier_type(name); } type* ast_app::check(type_manager& mgr, std::shared_ptr env) { - std::cout << "checking application" << std::endl; type* ltype = left->check(mgr, env); type* rtype = right->check(mgr, env); diff --git a/src/main.cpp b/src/main.cpp index a5d2385..d40831d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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; } diff --git a/src/parser.cpp b/src/parser.cpp index f0b999d..2b2dfbe 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -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 = diff --git a/src/type.cpp b/src/type.cpp index d1aea8f..240b121 100644 --- a/src/type.cpp +++ b/src/type.cpp @@ -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; } diff --git a/src/type.hpp b/src/type.hpp index 66a0133..564a720 100644 --- a/src/type.hpp +++ b/src/type.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace lily { enum reserved_types { @@ -34,7 +35,7 @@ namespace lily { }; int type_id; - std::vector> constructors; + std::map> constructors; type_data(int id) : type_id(id) {} constructor* create_constructor(const std::string& name, std::vector&& params); diff --git a/src/type_checker.cpp b/src/type_checker.cpp index b73fc1e..02fcf80 100644 --- a/src/type_checker.cpp +++ b/src/type_checker.cpp @@ -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"); diff --git a/src/type_manager.cpp b/src/type_manager.cpp index 92b9c58..a27326a 100644 --- a/src/type_manager.cpp +++ b/src/type_manager.cpp @@ -1,6 +1,8 @@ #include "type_manager.hpp" #include #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 env) { + for(auto& type_ref : types) { + type_data* data_type = dynamic_cast(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(param, current_type); + } + env->set_type(pair.first, current_type); + } + } + } } diff --git a/src/type_manager.hpp b/src/type_manager.hpp index 71e406e..253525f 100644 --- a/src/type_manager.hpp +++ b/src/type_manager.hpp @@ -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 env); }; }