import mem:* import string:* import vector:* import ast_nodes:* // 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) adt base_type { none, object, template, template_type, void_return, boolean, character, integer, floating, double_precision, function } fun type_ptr(): *type { return new()->construct() } fun type_ptr(definition: *ast_node): *type { return new()->construct(definition) } fun type_ptr(base: base_type): *type return type_ptr(base, 0); fun type_ptr(base: base_type, indirection: int): *type { return new()->construct(base, indirection) } fun type_ptr(parameters: vector<*type>, return_type: *type): *type return type_ptr(parameters, return_type, 0); fun type_ptr(parameters: vector<*type>, return_type: *type, indirection: int): *type { return new()->construct(parameters, return_type, indirection) } fun type_ptr(traits: vector): *type { return new()->construct(traits) } obj type (Object) { var base: base_type var parameter_types: vector<*type> var return_type: *type var indirection: int var type_def: *ast_node var traits: vector fun construct(): *type { base.copy_construct(&base_type::none()) parameter_types.construct() indirection = 0 return_type = null() type_def = null() traits.construct() return this } fun construct(traits_in: vector): *type { base.copy_construct(&base_type::template_type()) parameter_types.construct() indirection = 0 return_type = null() type_def = null() traits.copy_construct(&traits_in) return this } fun construct(base_in: base_type, indirection_in: int): *type { base.copy_construct(&base_in) parameter_types.construct() indirection = indirection_in return_type = null() type_def = null() traits.construct() return this } fun construct(type_def_in: *ast_node): *type { base.copy_construct(&base_type::object()) parameter_types.construct() indirection = 0 return_type = null() type_def = type_def_in traits.construct() return this } fun construct(parameter_types_in: vector<*type>, return_type_in: *type, indirection_in: int): *type { base.copy_construct(&base_type::function()) parameter_types.copy_construct(¶meter_types_in) return_type = return_type_in indirection = indirection_in type_def = null() traits.construct() return this } fun copy_construct(old: *type) { base.copy_construct(&old->base) parameter_types.copy_construct(&old->parameter_types) return_type = old->return_type indirection = old->indirection type_def = old->type_def traits.copy_construct(&old->traits) } fun operator=(other: ref type) { destruct() copy_construct(&other) } fun destruct() { base.destruct() parameter_types.destruct() traits.destruct() } fun operator!=(other: ref type):bool return !(*this == other); fun operator==(other: ref type):bool { if ( (return_type && other.return_type && *return_type != *other.return_type) || (return_type && !other.return_type) || (!return_type && other.return_type) ) return false return base == other.base && parameter_types == other.parameter_types && indirection == other.indirection && type_def == other.type_def && traits == other.traits } fun to_string(): string { var all_string = string("traits:[") for (var i = 0; i < traits.size; i++;) all_string += traits[i] all_string += "] " for (var i = 0; i < indirection; i++;) all_string += "*" match (base) { base_type::none() return all_string + string("none") base_type::object() return all_string + type_def->type_def.name base_type::template() return all_string + string("template") base_type::template_type() return all_string + string("template_type") base_type::void_return() return all_string + string("void_return") base_type::boolean() return all_string + string("boolean") base_type::character() return all_string + string("character") base_type::integer() return all_string + string("integer") base_type::floating() return all_string + string("floating") base_type::double_precision() return all_string + string("double_precision") base_type::function() { var temp = all_string + string("fun(") parameter_types.for_each(fun(parameter_type: *type) temp += parameter_type->to_string() + ", ";) return temp + ")" + return_type->to_string() } } return string("impossible type, indirection:") + indirection } fun clone_with_increased_indirection(): *type return clone_with_indirection(indirection+1); fun clone_with_increased_indirection(more: int): *type return clone_with_indirection(indirection+more); fun clone_with_decreased_indirection(): *type return clone_with_indirection(indirection-1); fun clone_with_indirection(ind: int): *type { var to_ret = new() to_ret->copy_construct(this) to_ret->indirection = ind return to_ret } fun is_object(): bool { match (base) { base_type::object() return true } return false } }