Files
kraken/stdlib/type.krak

244 lines
8.9 KiB
Plaintext
Raw Normal View History

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)
adt base_type {
none,
object,
adt,
no_type_adt_option,
template,
template_type,
void_return,
boolean,
character,
integer,
floating,
double_precision,
function
}
fun type_ptr(): *type {
return new<type>()->construct()
}
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, false);
fun type_ptr(base: base_type, indirection: int): *type return type_ptr(base, indirection, false)
fun type_ptr(base: base_type, indirection: int, is_ref: bool): *type {
return new<type>()->construct(base, indirection, is_ref)
}
fun type_ptr(parameters: vector<*type>, return_type: *type): *type return type_ptr(parameters, return_type, 0, false);
fun type_ptr(parameters: vector<*type>, return_type: *type, indirection: int): *type return type_ptr(parameters, return_type, indirection, false)
fun type_ptr(parameters: vector<*type>, return_type: *type, indirection: int, is_ref: bool): *type {
return new<type>()->construct(parameters, return_type, indirection, is_ref)
}
fun type_ptr(traits: set<string>): *type {
return new<type>()->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: set<string>
var is_ref: bool
fun construct(): *type {
base.copy_construct(&base_type::none())
parameter_types.construct()
indirection = 0
return_type = null<type>()
type_def = null<ast_node>()
traits.construct()
is_ref = false
return this
}
fun construct(traits_in: set<string>): *type {
base.copy_construct(&base_type::template_type())
parameter_types.construct()
indirection = 0
return_type = null<type>()
type_def = null<ast_node>()
traits.copy_construct(&traits_in)
is_ref = false
return this
}
fun construct(base_in: base_type, indirection_in: int, is_ref_in: bool): *type {
base.copy_construct(&base_in)
parameter_types.construct()
indirection = indirection_in
return_type = null<type>()
type_def = null<ast_node>()
traits.construct()
is_ref = is_ref_in
return this
}
fun construct(type_def_in: *ast_node, traits_in: set<string>): *type {
if (is_type_def(type_def_in))
base.copy_construct(&base_type::object())
else
base.copy_construct(&base_type::adt())
parameter_types.construct()
indirection = 0
return_type = null<type>()
type_def = type_def_in
traits.copy_construct(&traits_in)
is_ref = false
return this
}
fun construct(parameter_types_in: vector<*type>, return_type_in: *type, indirection_in: int, is_ref_in: bool): *type {
base.copy_construct(&base_type::function())
parameter_types.copy_construct(&parameter_types_in)
return_type = return_type_in
indirection = indirection_in
type_def = null<ast_node>()
traits.construct()
is_ref = is_ref_in
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)
is_ref = old->is_ref
}
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 !equality(other, true);
fun operator==(other: ref type):bool return equality(other, true);
fun equality(other: *type, care_about_ref: bool):bool return equality(*other, care_about_ref);
fun equality(other: ref type, care_about_ref: bool):bool {
if (parameter_types.size != other.parameter_types.size)
return false
for (var i = 0; i < parameter_types.size; i++;)
if (!deref_equality(parameter_types[i], other.parameter_types[i]))
return false
if (care_about_ref && (is_ref != other.is_ref))
return false
return base == other.base && deref_equality(return_type, other.return_type) &&
indirection == other.indirection && deref_equality(type_def, other.type_def) && traits == other.traits
}
fun to_string(): string return to_string(true);
fun to_string(include_traits: bool): string {
var trait_string = string()
if (include_traits) {
trait_string = string(":[")
traits.for_each(fun(t: string) trait_string += t;)
trait_string += "] "
}
2016-03-24 21:32:28 -04:00
var indr_string = string("")
if (is_ref)
2016-03-24 21:32:28 -04:00
indr_string += " ref "
for (var i = 0; i < indirection; i++;) indr_string += "*"
match (base) {
2016-03-24 21:32:28 -04:00
base_type::none() return indr_string + string("none") + trait_string
base_type::object() return indr_string + type_def->type_def.name + trait_string
base_type::adt() return indr_string + type_def->adt_def.name + trait_string
base_type::no_type_adt_option() return indr_string + "no_type_adt_option" + trait_string
base_type::template() return indr_string + string("template") + trait_string
base_type::template_type() return indr_string + string("template_type") + trait_string
base_type::void_return() return indr_string + string("void_return") + trait_string
base_type::boolean() return indr_string + string("boolean") + trait_string
base_type::character() return indr_string + string("character") + trait_string
base_type::integer() return indr_string + string("integer") + trait_string
base_type::floating() return indr_string + string("floating") + trait_string
base_type::double_precision() return indr_string + string("double_precision") + trait_string
base_type::function() {
2016-03-24 21:32:28 -04:00
var temp = indr_string + string("fun(")
parameter_types.for_each(fun(parameter_type: *type) temp += parameter_type->to_string() + ", ";)
2016-03-24 21:32:28 -04:00
return temp + ")" + return_type->to_string() + trait_string
}
}
return string("impossible type, indirection:") + indirection
}
fun rank(): int {
if (indirection > 0)
return 5
match (base) {
base_type::character() return 1
base_type::integer() return 2
base_type::floating() return 3
base_type::double_precision() return 4
}
return 0
}
fun clone(): *type return clone_with_indirection(indirection, is_ref);
fun clone_without_ref(): *type return clone_with_indirection(indirection, false);
fun clone_with_ref(): *type return clone_with_indirection(indirection, true);
2016-01-30 22:04:37 -05:00
fun clone_with_increased_indirection(): *type return clone_with_indirection(indirection+1);
fun clone_with_increased_indirection(more: int, is_ref_in: bool): *type return clone_with_indirection(indirection+more, is_ref_in);
2016-01-30 22:04:37 -05:00
fun clone_with_decreased_indirection(): *type return clone_with_indirection(indirection-1);
fun clone_with_indirection(ind: int): *type return clone_with_indirection(ind, false)
fun clone_with_indirection(ind: int, is_ref_in: bool): *type {
2016-01-24 01:02:56 -05:00
var to_ret = new<type>()
to_ret->copy_construct(this)
to_ret->indirection = ind
to_ret->is_ref = is_ref_in
2016-01-24 01:02:56 -05:00
return to_ret
}
fun is_object(): bool {
match (base) {
base_type::object() return true
}
return false
}
fun is_adt(): bool {
match (base) {
base_type::adt() return true
}
return false
}
fun is_function(): bool {
match (base) {
base_type::function() return true
}
return false
}
fun is_void(): bool {
match (base) {
base_type::void_return() return true
}
return false
}
fun is_empty_adt_option(): bool {
match (base) {
base_type::no_type_adt_option() return true
}
return false
}
fun is_none(): bool {
match (base) {
base_type::none() return true
}
return false
}
fun is_template_type(): bool {
match (base) {
base_type::template_type() return true
}
return false
}
}