2016-01-06 02:46:42 -05:00
|
|
|
import mem:*
|
|
|
|
|
import string:*
|
|
|
|
|
import vector:*
|
2016-02-29 04:53:03 -05:00
|
|
|
import set:*
|
2016-01-21 03:18:02 -05:00
|
|
|
import ast_nodes:*
|
2016-02-29 04:53:03 -05:00
|
|
|
import io:*
|
2016-01-05 21:40:00 -05:00
|
|
|
|
|
|
|
|
// 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,
|
2016-01-21 03:18:02 -05:00
|
|
|
object,
|
2016-01-05 21:40:00 -05:00
|
|
|
template,
|
|
|
|
|
template_type,
|
|
|
|
|
void_return,
|
|
|
|
|
boolean,
|
|
|
|
|
character,
|
|
|
|
|
integer,
|
|
|
|
|
floating,
|
|
|
|
|
double_precision,
|
|
|
|
|
function
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-06 02:46:42 -05:00
|
|
|
fun type_ptr(): *type {
|
|
|
|
|
return new<type>()->construct()
|
|
|
|
|
}
|
2016-02-29 04:53:03 -05:00
|
|
|
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)
|
2016-01-21 03:18:02 -05:00
|
|
|
}
|
2016-03-01 14:54:58 -05:00
|
|
|
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)
|
2016-01-05 21:40:00 -05:00
|
|
|
}
|
2016-03-01 14:54:58 -05:00
|
|
|
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)
|
2016-01-05 21:40:00 -05:00
|
|
|
}
|
|
|
|
|
|
2016-02-29 04:53:03 -05:00
|
|
|
fun type_ptr(traits: set<string>): *type {
|
2016-02-01 05:35:08 -05:00
|
|
|
return new<type>()->construct(traits)
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-05 21:40:00 -05:00
|
|
|
obj type (Object) {
|
|
|
|
|
var base: base_type
|
2016-01-06 02:46:42 -05:00
|
|
|
var parameter_types: vector<*type>
|
|
|
|
|
var return_type: *type
|
2016-01-10 18:26:31 -05:00
|
|
|
var indirection: int
|
2016-01-21 03:18:02 -05:00
|
|
|
var type_def: *ast_node
|
2016-02-29 04:53:03 -05:00
|
|
|
var traits: set<string>
|
2016-03-01 14:54:58 -05:00
|
|
|
var is_ref: bool
|
2016-01-05 21:40:00 -05:00
|
|
|
fun construct(): *type {
|
|
|
|
|
base.copy_construct(&base_type::none())
|
2016-01-06 02:46:42 -05:00
|
|
|
parameter_types.construct()
|
2016-01-10 18:26:31 -05:00
|
|
|
indirection = 0
|
2016-01-14 12:57:16 -05:00
|
|
|
return_type = null<type>()
|
2016-01-21 03:18:02 -05:00
|
|
|
type_def = null<ast_node>()
|
2016-02-01 05:35:08 -05:00
|
|
|
traits.construct()
|
2016-03-01 14:54:58 -05:00
|
|
|
is_ref = false
|
2016-02-01 05:35:08 -05:00
|
|
|
return this
|
|
|
|
|
}
|
2016-02-29 04:53:03 -05:00
|
|
|
fun construct(traits_in: set<string>): *type {
|
2016-02-01 05:35:08 -05:00
|
|
|
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)
|
2016-03-01 14:54:58 -05:00
|
|
|
is_ref = false
|
2016-01-05 21:40:00 -05:00
|
|
|
return this
|
|
|
|
|
}
|
2016-03-01 14:54:58 -05:00
|
|
|
fun construct(base_in: base_type, indirection_in: int, is_ref_in: bool): *type {
|
2016-01-05 21:40:00 -05:00
|
|
|
base.copy_construct(&base_in)
|
2016-01-06 02:46:42 -05:00
|
|
|
parameter_types.construct()
|
2016-01-10 18:26:31 -05:00
|
|
|
indirection = indirection_in
|
2016-01-14 12:57:16 -05:00
|
|
|
return_type = null<type>()
|
2016-01-21 03:18:02 -05:00
|
|
|
type_def = null<ast_node>()
|
2016-02-01 05:35:08 -05:00
|
|
|
traits.construct()
|
2016-03-01 14:54:58 -05:00
|
|
|
is_ref = is_ref_in
|
2016-01-21 03:18:02 -05:00
|
|
|
return this
|
|
|
|
|
}
|
2016-02-29 04:53:03 -05:00
|
|
|
fun construct(type_def_in: *ast_node, traits_in: set<string>): *type {
|
2016-01-21 03:18:02 -05:00
|
|
|
base.copy_construct(&base_type::object())
|
|
|
|
|
parameter_types.construct()
|
|
|
|
|
indirection = 0
|
|
|
|
|
return_type = null<type>()
|
|
|
|
|
type_def = type_def_in
|
2016-02-29 04:53:03 -05:00
|
|
|
traits.copy_construct(&traits_in)
|
2016-03-01 14:54:58 -05:00
|
|
|
is_ref = false
|
2016-01-06 02:46:42 -05:00
|
|
|
return this
|
|
|
|
|
}
|
2016-03-01 14:54:58 -05:00
|
|
|
fun construct(parameter_types_in: vector<*type>, return_type_in: *type, indirection_in: int, is_ref_in: bool): *type {
|
2016-01-06 02:46:42 -05:00
|
|
|
base.copy_construct(&base_type::function())
|
2016-01-14 12:57:16 -05:00
|
|
|
parameter_types.copy_construct(¶meter_types_in)
|
2016-01-06 02:46:42 -05:00
|
|
|
return_type = return_type_in
|
2016-01-10 18:26:31 -05:00
|
|
|
indirection = indirection_in
|
2016-01-21 03:18:02 -05:00
|
|
|
type_def = null<ast_node>()
|
2016-02-01 05:35:08 -05:00
|
|
|
traits.construct()
|
2016-03-01 14:54:58 -05:00
|
|
|
is_ref = is_ref_in
|
2016-01-05 21:40:00 -05:00
|
|
|
return this
|
|
|
|
|
}
|
|
|
|
|
fun copy_construct(old: *type) {
|
2016-01-06 02:46:42 -05:00
|
|
|
base.copy_construct(&old->base)
|
|
|
|
|
parameter_types.copy_construct(&old->parameter_types)
|
|
|
|
|
return_type = old->return_type
|
2016-01-10 18:26:31 -05:00
|
|
|
indirection = old->indirection
|
2016-01-21 03:18:02 -05:00
|
|
|
type_def = old->type_def
|
2016-02-01 05:35:08 -05:00
|
|
|
traits.copy_construct(&old->traits)
|
2016-03-01 14:54:58 -05:00
|
|
|
is_ref = old->is_ref
|
2016-01-05 21:40:00 -05:00
|
|
|
}
|
|
|
|
|
fun operator=(other: ref type) {
|
|
|
|
|
destruct()
|
|
|
|
|
copy_construct(&other)
|
|
|
|
|
}
|
|
|
|
|
fun destruct() {
|
|
|
|
|
base.destruct()
|
2016-01-06 02:46:42 -05:00
|
|
|
parameter_types.destruct()
|
2016-02-01 05:35:08 -05:00
|
|
|
traits.destruct()
|
2016-01-06 02:46:42 -05:00
|
|
|
}
|
2016-03-01 14:54:58 -05:00
|
|
|
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 {
|
2016-02-03 21:57:06 -05:00
|
|
|
if (parameter_types.size != other.parameter_types.size)
|
2016-01-14 12:57:16 -05:00
|
|
|
return false
|
2016-02-03 21:57:06 -05:00
|
|
|
for (var i = 0; i < parameter_types.size; i++;)
|
|
|
|
|
if (!deref_equality(parameter_types[i], other.parameter_types[i]))
|
|
|
|
|
return false
|
2016-03-01 14:54:58 -05:00
|
|
|
if (care_about_ref && (is_ref != other.is_ref))
|
|
|
|
|
return false
|
2016-02-03 21:57:06 -05:00
|
|
|
return base == other.base && deref_equality(return_type, other.return_type) &&
|
|
|
|
|
indirection == other.indirection && deref_equality(type_def, other.type_def) && traits == other.traits
|
2016-01-14 12:57:16 -05:00
|
|
|
}
|
2016-01-06 02:46:42 -05:00
|
|
|
fun to_string(): string {
|
2016-02-01 05:35:08 -05:00
|
|
|
var all_string = string("traits:[")
|
2016-02-29 04:53:03 -05:00
|
|
|
traits.for_each(fun(t: string) all_string += t;)
|
2016-02-01 05:35:08 -05:00
|
|
|
all_string += "] "
|
2016-03-01 14:54:58 -05:00
|
|
|
if (is_ref)
|
|
|
|
|
all_string += " ref "
|
2016-02-01 05:35:08 -05:00
|
|
|
for (var i = 0; i < indirection; i++;) all_string += "*"
|
2016-01-06 02:46:42 -05:00
|
|
|
match (base) {
|
2016-02-01 05:35:08 -05:00
|
|
|
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")
|
2016-01-06 02:46:42 -05:00
|
|
|
base_type::function() {
|
2016-02-01 05:35:08 -05:00
|
|
|
var temp = all_string + string("fun(")
|
2016-01-18 18:04:34 -05:00
|
|
|
parameter_types.for_each(fun(parameter_type: *type) temp += parameter_type->to_string() + ", ";)
|
|
|
|
|
return temp + ")" + return_type->to_string()
|
2016-01-06 02:46:42 -05:00
|
|
|
}
|
|
|
|
|
}
|
2016-01-10 18:26:31 -05:00
|
|
|
return string("impossible type, indirection:") + indirection
|
2016-01-05 21:40:00 -05:00
|
|
|
}
|
2016-02-05 16:43:14 -05:00
|
|
|
fun rank(): int {
|
|
|
|
|
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
|
|
|
|
|
}
|
2016-03-01 14:54:58 -05:00
|
|
|
fun clone(): *type return clone_with_indirection(indirection, is_ref);
|
|
|
|
|
fun clone_without_ref(): *type return clone_with_indirection(indirection, false);
|
2016-01-30 22:04:37 -05:00
|
|
|
fun clone_with_increased_indirection(): *type return clone_with_indirection(indirection+1);
|
2016-03-01 14:54:58 -05:00
|
|
|
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);
|
2016-03-01 14:54:58 -05:00
|
|
|
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
|
2016-03-01 14:54:58 -05:00
|
|
|
to_ret->is_ref = is_ref_in
|
2016-01-24 01:02:56 -05:00
|
|
|
return to_ret
|
|
|
|
|
}
|
2016-01-29 22:46:09 -05:00
|
|
|
fun is_object(): bool {
|
|
|
|
|
match (base) {
|
|
|
|
|
base_type::object() return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
2016-02-25 14:24:55 -05:00
|
|
|
fun is_function(): bool {
|
|
|
|
|
match (base) {
|
|
|
|
|
base_type::function() return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
2016-02-27 21:07:22 -05:00
|
|
|
fun is_void(): bool {
|
|
|
|
|
match (base) {
|
|
|
|
|
base_type::void_return() return true
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
2016-01-05 21:40:00 -05:00
|
|
|
}
|
|
|
|
|
|