2018-10-08 00:28:42 -04:00
|
|
|
import vec:*
|
|
|
|
|
import str:*
|
|
|
|
|
// for decent to string
|
|
|
|
|
// should be fixed by UFCS or decent scoping on template types
|
|
|
|
|
import ast:*
|
|
|
|
|
import type2:*
|
|
|
|
|
|
2019-01-06 01:06:15 -05:00
|
|
|
adt binding_epoch {
|
|
|
|
|
pre_ref,
|
|
|
|
|
post_ref,
|
|
|
|
|
all
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-08 00:28:42 -04:00
|
|
|
var bindings: *vec<*void>
|
|
|
|
|
|
|
|
|
|
fun binding<T>(): *binding<T> {
|
2019-01-06 01:06:15 -05:00
|
|
|
return binding(null<T>(), binding_epoch::all())
|
2018-10-08 00:28:42 -04:00
|
|
|
}
|
2019-01-06 01:06:15 -05:00
|
|
|
fun binding_p<T>(it: T, epoch: binding_epoch): *binding<T> {
|
2018-10-08 00:28:42 -04:00
|
|
|
var p = new<T>()
|
|
|
|
|
p->copy_construct(&it)
|
2019-01-06 01:06:15 -05:00
|
|
|
return binding(p, epoch)
|
2018-10-08 00:28:42 -04:00
|
|
|
}
|
2019-01-06 01:06:15 -05:00
|
|
|
fun binding<T>(it: *T, epoch: binding_epoch): *binding<T> {
|
|
|
|
|
var to_ret = new<binding<T>>()->construct(it, epoch)
|
2018-10-08 00:28:42 -04:00
|
|
|
if (bindings == null<vec<*void>>())
|
|
|
|
|
bindings = new<vec<*void>>()->construct()
|
|
|
|
|
bindings->add( (to_ret) cast *void )
|
|
|
|
|
return to_ret
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
obj binding<T> (Object) {
|
2019-01-06 01:06:15 -05:00
|
|
|
var bound_to_pre_ref: *T
|
|
|
|
|
var bound_to_post_ref: *T
|
2018-10-08 00:28:42 -04:00
|
|
|
fun construct(): *binding<T> {
|
2019-01-06 01:06:15 -05:00
|
|
|
bound_to_pre_ref = null<T>()
|
|
|
|
|
bound_to_post_ref = null<T>()
|
2018-10-08 00:28:42 -04:00
|
|
|
return this
|
|
|
|
|
}
|
2019-01-06 01:06:15 -05:00
|
|
|
fun construct(it: *T, epoch: binding_epoch): *binding<T> {
|
|
|
|
|
set_single(it, epoch)
|
2018-10-08 00:28:42 -04:00
|
|
|
return this
|
|
|
|
|
}
|
|
|
|
|
fun copy_construct(old: *binding<T>): void {
|
2019-01-06 01:06:15 -05:00
|
|
|
bound_to_pre_ref = old->bound_to_pre_ref
|
|
|
|
|
bound_to_post_ref = old->bound_to_post_ref
|
2018-10-08 00:28:42 -04:00
|
|
|
}
|
|
|
|
|
fun destruct() {
|
2019-01-06 01:06:15 -05:00
|
|
|
bound_to_pre_ref = null<T>()
|
|
|
|
|
bound_to_post_ref = null<T>()
|
2018-10-08 00:28:42 -04:00
|
|
|
}
|
2019-01-06 01:06:15 -05:00
|
|
|
fun bound(epoch: binding_epoch): bool {
|
|
|
|
|
return bound_to_pre_ref != null<T>() || bound_to_post_ref != null<T>()
|
2018-10-08 00:28:42 -04:00
|
|
|
}
|
2019-01-06 01:06:15 -05:00
|
|
|
fun set(to: T, epoch: binding_epoch) {
|
2018-10-08 00:28:42 -04:00
|
|
|
var p = new<T>()
|
|
|
|
|
p->copy_construct(&to)
|
2019-01-06 01:06:15 -05:00
|
|
|
set(p, epoch)
|
2018-10-08 00:28:42 -04:00
|
|
|
}
|
2019-01-06 01:06:15 -05:00
|
|
|
fun set(to: *T, epoch: binding_epoch) {
|
|
|
|
|
var pre_ref_from = bound_to_pre_ref
|
|
|
|
|
var post_ref_from = bound_to_post_ref
|
|
|
|
|
if epoch == binding_epoch::pre_ref() || epoch == binding_epoch::all() {
|
|
|
|
|
bound_to_pre_ref = to
|
|
|
|
|
// don't set null, that will set all unbound ones
|
|
|
|
|
if pre_ref_from != null<T>() {
|
|
|
|
|
for (var i = 0; i < bindings->size; i++;)
|
|
|
|
|
if ( ((bindings->get(i)) cast *binding<T>)->bound_to_pre_ref == pre_ref_from)
|
|
|
|
|
((bindings->get(i)) cast *binding<T>)->bound_to_pre_ref = to
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if epoch == binding_epoch::post_ref() || epoch == binding_epoch::all() {
|
|
|
|
|
bound_to_post_ref = to
|
|
|
|
|
// don't set null, that will set all unbound ones
|
|
|
|
|
if post_ref_from != null<T>() {
|
|
|
|
|
for (var i = 0; i < bindings->size; i++;)
|
|
|
|
|
if ( ((bindings->get(i)) cast *binding<T>)->bound_to_post_ref == post_ref_from)
|
|
|
|
|
((bindings->get(i)) cast *binding<T>)->bound_to_post_ref = to
|
|
|
|
|
}
|
2018-10-08 00:28:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
2019-01-06 01:06:15 -05:00
|
|
|
fun set_single(to: *T, epoch: binding_epoch) {
|
|
|
|
|
match (epoch) {
|
|
|
|
|
binding_epoch::pre_ref() { bound_to_pre_ref = to; }
|
|
|
|
|
binding_epoch::post_ref() { bound_to_post_ref = to; }
|
|
|
|
|
binding_epoch::all() { bound_to_pre_ref = to; bound_to_post_ref = to; }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fun bound(): bool {
|
|
|
|
|
return bound_to_pre_ref != null<T>() || bound_to_post_ref != null<T>()
|
|
|
|
|
}
|
|
|
|
|
fun get_bound_to(epoch: binding_epoch): *T {
|
|
|
|
|
match (epoch) {
|
|
|
|
|
binding_epoch::pre_ref() { return bound_to_pre_ref; }
|
|
|
|
|
binding_epoch::post_ref() if bound_to_post_ref != null<T>() { return bound_to_post_ref; } else { return bound_to_pre_ref; }
|
|
|
|
|
binding_epoch::all() { error("trying to get_bound_to for all, which doesn't make any sense"); }
|
|
|
|
|
}
|
2018-10-09 23:00:57 -04:00
|
|
|
}
|
2018-10-08 00:28:42 -04:00
|
|
|
fun to_string(): str {
|
|
|
|
|
/*return "binding(" + to_string(bound_to) + ")"*/
|
2019-01-06 01:06:15 -05:00
|
|
|
return "binding(pre_ref:" + deref_to_string(bound_to_pre_ref) + "/post_ref:" + deref_to_string(bound_to_post_ref) + ")"
|
2018-10-08 00:28:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|