From d2011640f72a354c40d35c6dbcc0ce23d940cd5f Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Sun, 4 Nov 2018 19:03:55 -0500 Subject: [PATCH] templated structs starting to work, if grammer freeup --- k.krak | 81 +++++++++++++++++++++++++++++++++++------------ krakenGrammer.kgm | 2 +- 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/k.krak b/k.krak index 424c44b..6fa3036 100644 --- a/k.krak +++ b/k.krak @@ -266,7 +266,9 @@ fun main(argc: int, argv: **char): int { to_ret += scope->children[i] ast::_compiler_intrinsic(b) if (!is_type && b.first == name) to_ret += scope->children[i] - ast::_template(b) if (!is_type && b.first == name) + ast::_template(b) if (((!is_type && is_function(scope->children[i]->children[0])) + || ( is_type && is_type_def(scope->children[i]->children[0])) + || ( is_type && is_adt_def( scope->children[i]->children[0]))) && b.first == name) to_ret += scope->children[i] ast::_identifier(b) if (!is_type && b.first == name) to_ret += scope->children[i] @@ -578,7 +580,10 @@ fun main(argc: int, argv: **char): int { type::_template_placeholder() error("template_placeholder in resolve_type") type::_ptr(p) resolve_type(p) type::_ref(p) resolve_type(p) - type::_obj(o) pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(get_ast_binding(o), str("emit_C"))) + type::_obj(o) { + resolve(o) + pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(get_ast_binding(o), str("emit_C"))) + } type::_fun(t) { t.first.first.for_each(resolve_type) resolve_type(t.first.second) @@ -592,7 +597,6 @@ fun main(argc: int, argv: **char): int { if (is_template(bound_to)) { if (!instantiated_map.contains_key(bound_to)) instantiated_map[bound_to] = set, *tree>>() - var binding_type = get_type(t) // grab inst types out of binding, or regen again from unify? Cache from first unify? var inst_map = map<*binding, *binding>() @@ -605,8 +609,16 @@ fun main(argc: int, argv: **char): int { inst_map = bound_to->data._template.second.associate(fun(k: str, v: *binding): pair<*binding, *binding> return make_pair(v, binding_p(type::_unknown()));) } - // unify in both cases - we need it in the explicit case to make sure our explicit types propegate back - unify(binding_type, inst_temp_type(get_type(bound_to->children[0]), inst_map)) + + // but not in the case where this is a templated type instead of a function - that doesn't make any sense + var binding_type = null>() + if is_function(bound_to->children[0]) { + // unify in both cases - we need it in the explicit case to make sure our explicit types propegate back + binding_type = get_type(t) + unify(binding_type, inst_temp_type(get_type(bound_to->children[0]), inst_map)) + } else { + binding_type = binding_p(type::_obj(t)) + } // shouldn't cache by binding, but by all insted var already_inst = instantiated_map[bound_to].filter(fun(p: pair<*binding, *tree>): bool return equality(binding_type->bound_to, p.first->bound_to, false);) @@ -621,6 +633,10 @@ fun main(argc: int, argv: **char): int { set_single_ast_binding(t, already_inst.single().second) } else { println("Copying tree to instantiate template!") + println("using inst map:") + inst_map.for_each(fun(k: *binding, v: *binding) { + println("\t" + to_string(k->bound_to) + " -> " + to_string(v->bound_to)) + }) var inst_copy = bound_to->children[0]->clone(fun(a: ref ast): ast { match (a) { ast::_identifier(b) return ast::_identifier(make_pair(b.first, inst_temp_type(b.second, inst_map))) @@ -659,8 +675,9 @@ fun main(argc: int, argv: **char): int { pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(bound_to->parent, str("emit_C"))) } // bound_to might have changed from binding - - resolve_type(get_type(t)) + if !is_type_def(get_ast_binding(t)) { + resolve_type(get_type(t)) + } } ast::_identifier(p) resolve_type(get_type(t)) ast::_function(p) resolve_type(get_type(t)) @@ -930,7 +947,8 @@ fun parse_type_helper(syntax: *tree, declared_template_types: ref map>()) { - return binding_p(type::_obj(make_ast_binding(ident_str + ""))) + var inst_with = get_nodes("type", template_inst).map(fun(s: *tree): *binding { return parse_type(s, declared_template_types); }) + return binding_p(type::_obj(make_ast_binding(ident_str, inst_with))) } else { if (declared_template_types.contains_key(ident_str)) return declared_template_types[ident_str] @@ -1024,30 +1042,53 @@ fun syntax_to_ast(file_name: str, syntax: *tree, import_paths: ref vecdata.name == "typed_parameter") return _identifier(concat(get_node("identifier", syntax)), parse_type(get_node("type", syntax), declared_template_types)) else if (syntax->data.name == "type_def") { - var n = _type_def(concat(get_node("identifier", syntax)), - get_nodes("declaration_statement", syntax).map(fun(x: *tree): *tree return syntax_to_ast_helper(x, declared_template_types);)) + var template = get_node("template_dec", syntax) - if (template == null>()) { - return n + var new_template_type_map = map>() + var with_added_declared_template_types = declared_template_types + if (template != null>()) { + get_nodes("template_param", template).for_each(fun(p: *tree) { + var key = concat(p) + var value = binding_p(type::_template_placeholder()) + new_template_type_map[key] = value + with_added_declared_template_types[key] = value + }) + } + + var n = _type_def(concat(get_node("identifier", syntax)), + get_nodes("declaration_statement", syntax).map(fun(x: *tree): *tree return syntax_to_ast_helper(x, with_added_declared_template_types);)) + + if (new_template_type_map.size() > 0) { + return _template(n->data._type_def, new_template_type_map, vec(n)) } else { - /*return _template(n->data._type_def, from_vector(get_nodes("template_param", template).map(concat)), vec(n))*/ - error("implement me") + return n } } else if (syntax->data.name == "adt_def") { + + var template = get_node("template_dec", syntax) + var new_template_type_map = map>() + var with_added_declared_template_types = declared_template_types + if (template != null>()) { + get_nodes("template_param", template).for_each(fun(p: *tree) { + var key = concat(p) + var value = binding_p(type::_template_placeholder()) + new_template_type_map[key] = value + with_added_declared_template_types[key] = value + }) + } + var n = _adt_def(concat(get_node("identifier", syntax)), get_nodes("adt_option", syntax).map(fun(s: *tree): *tree { var option_type = get_node("type", s) if (option_type != null>()) - return _identifier(concat(get_node("identifier", s)), parse_type(option_type, declared_template_types)) + return _identifier(concat(get_node("identifier", s)), parse_type(option_type, with_added_declared_template_types)) else return _identifier(concat(get_node("identifier", s)), binding_p(type::_void())) })) - var template = get_node("template_dec", syntax) - if (template == null>()) { - return n + if (new_template_type_map.size() > 0) { + return _template(n->data._adt_def, new_template_type_map, vec(n)) } else { - /*return _template(n->data._adt_def, from_vector(get_nodes("template_param", template).map(concat)), vec(n))*/ - error("implement me") + return n } } else if (syntax->data.name == "statement") return syntax_to_ast_helper(syntax->children[0], declared_template_types) diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 2b47d21..a4681de 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -95,7 +95,7 @@ adt_def = adt_nonterm WS identifier WS "{" WS adt_option_list WS "}" | adt_nonte adt_option_list = adt_option | adt_option WS "," WS adt_option_list ; adt_option = identifier | identifier WS dec_type ; -if_statement = "if" WS boolean_expression WS statement | "if" WS "\(" WS boolean_expression WS "\)" WS statement WS "else" WS statement ; +if_statement = "if" WS boolean_expression WS statement | "if" WS boolean_expression WS statement WS "else" WS statement ; match_statement = "match" WS "\(" WS boolean_expression WS "\)" WS "{" WS case_statement_list WS "}" ; case_statement_list = case_statement WS case_statement_list | case_statement ;