Files
kraken/stdlib/type.krak

132 lines
4.7 KiB
Plaintext

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<type>()->construct()
}
fun type_ptr(definition: *ast_node): *type {
return new<type>()->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<type>()->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<type>()->construct(parameters, return_type, indirection)
}
obj type (Object) {
var base: base_type
var parameter_types: vector<*type>
var return_type: *type
var indirection: int
var type_def: *ast_node
fun construct(): *type {
base.copy_construct(&base_type::none())
parameter_types.construct()
indirection = 0
return_type = null<type>()
type_def = null<ast_node>()
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>()
type_def = null<ast_node>()
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>()
type_def = type_def_in
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(&parameter_types_in)
return_type = return_type_in
indirection = indirection_in
type_def = null<ast_node>()
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
}
fun operator=(other: ref type) {
destruct()
copy_construct(&other)
}
fun destruct() {
base.destruct()
parameter_types.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
}
fun to_string(): string {
var indirection_str = string()
for (var i = 0; i < indirection; i++;) indirection_str += "*"
match (base) {
base_type::none() return indirection_str + string("none")
base_type::object() return indirection_str + type_def->type_def.name
base_type::template() return indirection_str + string("template")
base_type::template_type() return indirection_str + string("template_type")
base_type::void_return() return indirection_str + string("void_return")
base_type::boolean() return indirection_str + string("boolean")
base_type::character() return indirection_str + string("character")
base_type::integer() return indirection_str + string("integer")
base_type::floating() return indirection_str + string("floating")
base_type::double_precision() return indirection_str + string("double_precision")
base_type::function() {
var temp = indirection_str + 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_indirection(ind: int): *type {
var to_ret = new<type>()
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
}
}