Implemented traits, so test_traitsTest passes now and fixed small bug that allowed test_functionsValues to pass as well. 42 now
This commit is contained in:
@@ -77,6 +77,11 @@ obj ast_transformation (Object) {
|
||||
})
|
||||
return translation_unit
|
||||
}
|
||||
fun transform_traits(traits_node: *tree<symbol>): set<string> {
|
||||
if (!traits_node)
|
||||
return set<string>()
|
||||
return from_vector(get_nodes("scoped_identifier", traits_node).map(fun(s: *tree<symbol>): string return concat_symbol_tree(s);))
|
||||
}
|
||||
fun first_pass_type_def(child: *tree<symbol>, scope: *ast_node, instantiate_template: bool): *ast_node {
|
||||
var name = concat_symbol_tree(get_node("identifier", child))
|
||||
var template_dec = get_node("template_dec", child)
|
||||
@@ -86,7 +91,7 @@ obj ast_transformation (Object) {
|
||||
// XXX add traits
|
||||
get_nodes("template_param", template_dec).for_each(fun(template_param: *tree<symbol>) {
|
||||
template_types.add(concat_symbol_tree(get_node("identifier", template_param)))
|
||||
template_type_replacements.set(template_types.last(), type_ptr(vector<string>()))
|
||||
template_type_replacements.set(template_types.last(), type_ptr(transform_traits(get_node("traits", template_param))))
|
||||
})
|
||||
var template = ast_template_ptr(name, child, template_types, template_type_replacements, false)
|
||||
add_to_scope("~enclosing_scope", scope, template)
|
||||
@@ -94,7 +99,7 @@ obj ast_transformation (Object) {
|
||||
return template
|
||||
} else {
|
||||
var type_def_node = ast_type_def_ptr(name)
|
||||
type_def_node->type_def.self_type = type_ptr(type_def_node)
|
||||
type_def_node->type_def.self_type = type_ptr(type_def_node, transform_traits(get_node("traits", child)))
|
||||
ast_to_syntax.set(type_def_node, child)
|
||||
add_to_scope("~enclosing_scope", scope, type_def_node)
|
||||
add_to_scope(name, type_def_node, scope)
|
||||
@@ -147,10 +152,9 @@ obj ast_transformation (Object) {
|
||||
if (do_raw_template && template_dec) {
|
||||
var template_types = vector<string>()
|
||||
var template_type_replacements = map<string, *type>()
|
||||
// XXX add traits
|
||||
get_nodes("template_param", template_dec).for_each(fun(template_param: *tree<symbol>) {
|
||||
template_types.add(concat_symbol_tree(get_node("identifier", template_param)))
|
||||
template_type_replacements.set(template_types.last(), type_ptr(vector<string>()))
|
||||
template_type_replacements.set(template_types.last(), type_ptr(transform_traits(get_node("traits", template_param))))
|
||||
})
|
||||
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
|
||||
println("MAP DONE")
|
||||
@@ -243,6 +247,8 @@ obj ast_transformation (Object) {
|
||||
var real_types = get_nodes("type", template_inst).map(fun(t: *tree<symbol>): *type return transform_type(t, scope, template_replacements);)
|
||||
var real_types_deref = real_types.map(fun(t:*type):type return *t;)
|
||||
var results = scope_lookup(name, scope)
|
||||
|
||||
var fitting_types = vector<pair<*ast_node, int>>()
|
||||
for (var i = 0; i < results.size; i++;) {
|
||||
if (!is_template(results[i]) || results[i]->template.is_function)
|
||||
continue
|
||||
@@ -251,26 +257,36 @@ obj ast_transformation (Object) {
|
||||
var template_type_replacements = results[i]->template.template_type_replacements
|
||||
if (template_types.size != real_types.size)
|
||||
continue
|
||||
// check if already instantiated
|
||||
var inst_type = null<ast_node>()
|
||||
if (results[i]->template.instantiated_map.contains_key(real_types_deref)) {
|
||||
println("USING CACHED TEMPLATE OBJECT")
|
||||
inst_type = results[i]->template.instantiated_map[real_types_deref]
|
||||
} else {
|
||||
|
||||
var num_satisfied_traits = 0
|
||||
var satisfied_traits = true
|
||||
template_type_replacements.for_each(fun(key: string, value: *type) num_satisfied_traits += value->traits.size();)
|
||||
println("FOR FIND OR INSTATINTATE PREEEE")
|
||||
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
|
||||
println("MAP DONE")
|
||||
for (var j = 0; j < template_types.size; j++;) {
|
||||
satisfied_traits = satisfied_traits && real_types[j]->traits.contains(template_type_replacements[template_types[j]]->traits) &&
|
||||
(real_types[j]->indirection == 0 || template_type_replacements[template_types[j]]->traits.size() == 0)
|
||||
template_type_replacements[template_types[j]] = real_types[j]
|
||||
println("Just made")
|
||||
println(template_types[j])
|
||||
println("equal to")
|
||||
println(real_types[j]->to_string())
|
||||
}
|
||||
if (!satisfied_traits) {
|
||||
println(name + " did not satisfy traits!")
|
||||
continue
|
||||
}
|
||||
println("FOR FIND OR INSTATINTATE")
|
||||
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
|
||||
println("MAP DONE")
|
||||
|
||||
var inst_type = null<ast_node>()
|
||||
// check if already instantiated
|
||||
if (results[i]->template.instantiated_map.contains_key(real_types_deref)) {
|
||||
println("USING CACHED TEMPLATE OBJECT")
|
||||
inst_type = results[i]->template.instantiated_map[real_types_deref]
|
||||
} else {
|
||||
inst_type = first_pass_type_def(results[i]->template.syntax_node, results[i], true)
|
||||
// add to instantiated_map so we only instantiate with a paticular set of types once
|
||||
// put in map first for recursive purposes
|
||||
@@ -279,9 +295,14 @@ obj ast_transformation (Object) {
|
||||
second_pass_type_def(results[i]->template.syntax_node, inst_type, results[i], template_type_replacements)
|
||||
fourth_pass_worklist.push(inst_type)
|
||||
}
|
||||
return inst_type->type_def.self_type->clone_with_indirection(indirection)
|
||||
fitting_types.add(make_pair(inst_type, num_satisfied_traits))
|
||||
}
|
||||
if (fitting_types.size == 0) {
|
||||
println("no working templated object found")
|
||||
error("FREAK OUT AUTOMATON")
|
||||
return null<type>()
|
||||
}
|
||||
return fitting_types.max(fun(a: pair<*ast_node, int>, b: pair<*ast_node, int>): bool return a.second < b.second;).first->type_def.self_type->clone_with_indirection(indirection)
|
||||
}
|
||||
var type_syntax_str = concat_symbol_tree(real_node)
|
||||
println(type_syntax_str + " *************************")
|
||||
@@ -723,12 +744,14 @@ obj ast_transformation (Object) {
|
||||
real_types_deref = real_types.map(fun(t:*type):type return *t;)
|
||||
had_real_types = true
|
||||
}
|
||||
var fitting_functions = vector<pair<*ast_node, int>>()
|
||||
for (var i = 0; i < results.size; i++;) {
|
||||
if (is_template(results[i]) && results[i]->template.is_function) {
|
||||
println(string() + i + " is a template!")
|
||||
var template_types = results[i]->template.template_types
|
||||
var template_type_replacements = results[i]->template.template_type_replacements
|
||||
if (!had_real_types) {
|
||||
var unify_template_type_replacements = template_type_replacements
|
||||
// reset the vars, cuz we might be iterating through multiple of them
|
||||
real_types = vector<*type>()
|
||||
real_types_deref = vector<type>()
|
||||
@@ -737,24 +760,32 @@ obj ast_transformation (Object) {
|
||||
if (param_types.size != typed_params.size)
|
||||
continue
|
||||
for (var j = 0; j < typed_params.size; j++;)
|
||||
unify_type(typed_params[j], param_types[j], &template_type_replacements, template_replacements)
|
||||
unify_type(typed_params[j], param_types[j], &unify_template_type_replacements, template_replacements)
|
||||
for (var j = 0; j < typed_params.size; j++;) {
|
||||
var t = template_type_replacements[template_types[j]];
|
||||
var t = unify_template_type_replacements[template_types[j]];
|
||||
real_types.add(t)
|
||||
real_types_deref.add(*t)
|
||||
}
|
||||
} else if (template_types.size != real_types.size)
|
||||
continue
|
||||
var num_satisfied_traits = 0
|
||||
var satisfied_traits = true
|
||||
template_type_replacements.for_each(fun(key: string, value: *type) num_satisfied_traits += value->traits.size();)
|
||||
// check if already instantiated
|
||||
var inst_func = null<ast_node>()
|
||||
if (results[i]->template.instantiated_map.contains_key(real_types_deref)) {
|
||||
println("USING CACHED TEMPLATE FUNCITON")
|
||||
inst_func = results[i]->template.instantiated_map[real_types_deref]
|
||||
} else {
|
||||
println(string("FOR TEMPLATE FUNCTION ") + name)
|
||||
println("FOR FIND OR INSTATINTATE PREEEE")
|
||||
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
|
||||
println("MAP DONE")
|
||||
for (var j = 0; j < template_types.size; j++;) {
|
||||
print("NEW TRAITS IN ALREADY: ")
|
||||
template_type_replacements[template_types[j]]->traits.for_each(fun (t: string) print(t + " ");)
|
||||
println()
|
||||
print("NEW TRAITS PASSED IN: ")
|
||||
real_types[j]->traits.for_each(fun (t: string) print(t + " ");)
|
||||
println()
|
||||
satisfied_traits = satisfied_traits && real_types[j]->traits.contains(template_type_replacements[template_types[j]]->traits) &&
|
||||
(real_types[j]->indirection == 0 || template_type_replacements[template_types[j]]->traits.size() == 0)
|
||||
template_type_replacements[template_types[j]] = real_types[j]
|
||||
println("Just made")
|
||||
println(template_types[j])
|
||||
@@ -772,6 +803,15 @@ obj ast_transformation (Object) {
|
||||
template_type_replacements.for_each(fun(key: string, value: *type) println(string("MAP: ") + key + " : " + value->to_string());)
|
||||
println("MAP DONE")
|
||||
|
||||
if (!satisfied_traits) {
|
||||
println("Did not satisfy traits!")
|
||||
continue
|
||||
}
|
||||
|
||||
if (results[i]->template.instantiated_map.contains_key(real_types_deref)) {
|
||||
println("USING CACHED TEMPLATE FUNCITON")
|
||||
inst_func = results[i]->template.instantiated_map[real_types_deref]
|
||||
} else {
|
||||
inst_func = second_pass_function(results[i]->template.syntax_node, results[i], template_type_replacements, false)
|
||||
// add to instantiated_map so we only instantiate with a paticular set of types once
|
||||
// put in map first for recursive purposes
|
||||
@@ -780,16 +820,18 @@ obj ast_transformation (Object) {
|
||||
// and fully instantiate it
|
||||
inst_func->function.body_statement = transform_statement(get_node("statement", results[i]->template.syntax_node), inst_func, template_type_replacements)
|
||||
}
|
||||
|
||||
if (function_satisfies_params(inst_func, param_types))
|
||||
return inst_func
|
||||
fitting_functions.add(make_pair(inst_func, num_satisfied_traits))
|
||||
else
|
||||
println(string("this paticular ") + name + " did not satisfy params")
|
||||
}
|
||||
}
|
||||
if (fitting_functions.size == 0) {
|
||||
println("no working templated method found")
|
||||
return null<ast_node>()
|
||||
}
|
||||
return fitting_functions.max(fun(a: pair<*ast_node, int>, b: pair<*ast_node, int>): bool return a.second < b.second;).first
|
||||
}
|
||||
}
|
||||
fun has_method(object: *ast_node, name: *char, parameter_types: vector<*type>): bool return has_method(object, string(name), parameter_types);
|
||||
fun has_method(object: *ast_node, name: string, parameter_types: vector<*type>): bool {
|
||||
@@ -825,7 +867,7 @@ fun get_builtin_function(name: string, param_types: vector<*type>): *ast_node {
|
||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_decreased_indirection()), vector<*ast_node>())
|
||||
if (name == "&")
|
||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_increased_indirection()), vector<*ast_node>())
|
||||
if (name == "\*")
|
||||
if (name == "\*" && param_types.size == 1)
|
||||
return ast_function_ptr(name, type_ptr(param_types, param_types[0]->clone_with_decreased_indirection()), vector<*ast_node>())
|
||||
if (param_types.size > 1 && param_types[1]->rank() > param_types[0]->rank())
|
||||
return ast_function_ptr(name, type_ptr(param_types, param_types[1]), vector<*ast_node>())
|
||||
|
||||
@@ -98,7 +98,7 @@ obj importer (Object) {
|
||||
remove_node(symbol("\"\\(\"", true), parse_tree)
|
||||
remove_node(symbol("\"\\)\"", true), parse_tree)
|
||||
remove_node(symbol("\"var\"", true), parse_tree)
|
||||
remove_node(symbol("\"fun\"", true), parse_tree)
|
||||
// remove_node(symbol("\"fun\"", true), parse_tree)
|
||||
remove_node(symbol("\"template\"", true), parse_tree)
|
||||
remove_node(symbol("\"return\"", true), parse_tree)
|
||||
remove_node(symbol("\"defer\"", true), parse_tree)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import mem:*
|
||||
import string:*
|
||||
import vector:*
|
||||
import set:*
|
||||
import ast_nodes:*
|
||||
import io:*
|
||||
|
||||
// hmm, like the ast_node, this is another candadate for being fully an ADT
|
||||
// one issue is that there are properties shared between most of the options (indirection, say)
|
||||
@@ -22,8 +24,9 @@ adt base_type {
|
||||
fun type_ptr(): *type {
|
||||
return new<type>()->construct()
|
||||
}
|
||||
fun type_ptr(definition: *ast_node): *type {
|
||||
return new<type>()->construct(definition)
|
||||
fun type_ptr(definition: *ast_node): *type return type_ptr(definition, set<string>());
|
||||
fun type_ptr(definition: *ast_node, traits: set<string>): *type {
|
||||
return new<type>()->construct(definition, traits)
|
||||
}
|
||||
fun type_ptr(base: base_type): *type return type_ptr(base, 0);
|
||||
fun type_ptr(base: base_type, indirection: int): *type {
|
||||
@@ -34,7 +37,7 @@ fun type_ptr(parameters: vector<*type>, return_type: *type, indirection: int): *
|
||||
return new<type>()->construct(parameters, return_type, indirection)
|
||||
}
|
||||
|
||||
fun type_ptr(traits: vector<string>): *type {
|
||||
fun type_ptr(traits: set<string>): *type {
|
||||
return new<type>()->construct(traits)
|
||||
}
|
||||
|
||||
@@ -44,7 +47,7 @@ obj type (Object) {
|
||||
var return_type: *type
|
||||
var indirection: int
|
||||
var type_def: *ast_node
|
||||
var traits: vector<string>
|
||||
var traits: set<string>
|
||||
fun construct(): *type {
|
||||
base.copy_construct(&base_type::none())
|
||||
parameter_types.construct()
|
||||
@@ -54,7 +57,7 @@ obj type (Object) {
|
||||
traits.construct()
|
||||
return this
|
||||
}
|
||||
fun construct(traits_in: vector<string>): *type {
|
||||
fun construct(traits_in: set<string>): *type {
|
||||
base.copy_construct(&base_type::template_type())
|
||||
parameter_types.construct()
|
||||
indirection = 0
|
||||
@@ -72,13 +75,13 @@ obj type (Object) {
|
||||
traits.construct()
|
||||
return this
|
||||
}
|
||||
fun construct(type_def_in: *ast_node): *type {
|
||||
fun construct(type_def_in: *ast_node, traits_in: set<string>): *type {
|
||||
base.copy_construct(&base_type::object())
|
||||
parameter_types.construct()
|
||||
indirection = 0
|
||||
return_type = null<type>()
|
||||
type_def = type_def_in
|
||||
traits.construct()
|
||||
traits.copy_construct(&traits_in)
|
||||
return this
|
||||
}
|
||||
fun construct(parameter_types_in: vector<*type>, return_type_in: *type, indirection_in: int): *type {
|
||||
@@ -119,7 +122,7 @@ obj type (Object) {
|
||||
}
|
||||
fun to_string(): string {
|
||||
var all_string = string("traits:[")
|
||||
for (var i = 0; i < traits.size; i++;) all_string += traits[i]
|
||||
traits.for_each(fun(t: string) all_string += t;)
|
||||
all_string += "] "
|
||||
for (var i = 0; i < indirection; i++;) all_string += "*"
|
||||
match (base) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import io:*
|
||||
import simple_print:*
|
||||
|
||||
fun test(): void {
|
||||
println(9)
|
||||
|
||||
@@ -22,11 +22,6 @@ fun OneTwoFunc<T(SecondTrait)>(obj: T): void {
|
||||
fun OneTwoFunc<T(FirstTrait, SecondTrait)>(obj: T): void {
|
||||
println("Both Traits");
|
||||
}
|
||||
/*
|
||||
template <AlreadySpecilized> |void| OneTwoFunc(|AlreadySpecilized| obj) {
|
||||
println("Already Specilized");
|
||||
}
|
||||
*/
|
||||
//This should work for objects too!
|
||||
//To test, we cycle the mapping of traits
|
||||
|
||||
@@ -34,13 +29,6 @@ obj OneTwoObj<T> (FirstTrait) {};
|
||||
obj OneTwoObj<T(FirstTrait)> (SecondTrait) {};
|
||||
obj OneTwoObj<T(SecondTrait)> (FirstTrait, SecondTrait) {};
|
||||
obj OneTwoObj<T(FirstTrait, SecondTrait)> {};
|
||||
/*
|
||||
*obj template<AlreadySpecilized> OneTwoObj {
|
||||
* void proveSpecilized() {
|
||||
* println("I'm specilized!");
|
||||
* }
|
||||
*};
|
||||
*/
|
||||
|
||||
fun main(): int {
|
||||
var a: NoTraits;
|
||||
@@ -54,7 +42,6 @@ fun main(): int {
|
||||
OneTwoFunc<Trait1>(b);
|
||||
OneTwoFunc<Trait2>(c);
|
||||
OneTwoFunc<TwoTrait>(d);
|
||||
// OneTwoFunc<AlreadySpecilized>(e);
|
||||
OneTwoFunc<*TwoTrait>(f);
|
||||
println();
|
||||
|
||||
@@ -62,7 +49,6 @@ fun main(): int {
|
||||
OneTwoFunc(b);
|
||||
OneTwoFunc(c);
|
||||
OneTwoFunc(d);
|
||||
// OneTwoFunc(e);
|
||||
OneTwoFunc(f);
|
||||
println();
|
||||
|
||||
@@ -70,7 +56,6 @@ fun main(): int {
|
||||
var beta: OneTwoObj<Trait1>;
|
||||
var gamma: OneTwoObj<Trait2>;
|
||||
var delta: OneTwoObj<TwoTrait>;
|
||||
// |OneTwoObj<AlreadySpecilized>| epsilon;
|
||||
var zeta: OneTwoObj<*TwoTrait>;
|
||||
|
||||
OneTwoFunc<OneTwoObj<NoTraits>>(alpha);
|
||||
|
||||
Reference in New Issue
Block a user