Fix poset to handle circular closed dependencies (they're propegated recursively to open dependencies) and some indentation fixes

This commit is contained in:
Nathan Braswell
2018-09-19 00:43:49 -04:00
parent 3e3564ea54
commit 08b5e29b70
2 changed files with 24 additions and 25 deletions

4
k.krak
View File

@@ -231,7 +231,7 @@ fun main(argc: int, argv: **char): int {
pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(b.third, str("emit_C"))) pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(b.third, str("emit_C")))
else if (is_identifier(b.third) && is_declaration(b.third->parent) && is_top_level_item(b.third->parent)) else if (is_identifier(b.third) && is_declaration(b.third->parent) && is_top_level_item(b.third->parent))
pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(b.third->parent, str("emit_C"))) pass_poset.add_close_dep(make_pair(item, str("emit_C")), make_pair(b.third->parent, str("emit_C")))
C_str += get_c_name(b.third) C_str += idt + get_c_name(b.third)
} }
ast::_type_def(b) { error("type_def gen unimplemented"); } ast::_type_def(b) { error("type_def gen unimplemented"); }
ast::_adt_def(b) { error("no adt_def should remain at C emit"); } ast::_adt_def(b) { error("no adt_def should remain at C emit"); }
@@ -324,7 +324,7 @@ fun main(argc: int, argv: **char): int {
for (var i = 1; i < t->children.size; i++;) { for (var i = 1; i < t->children.size; i++;) {
if (i != 1) if (i != 1)
C_str += ", " C_str += ", "
emit_C(t->children[i], level+1) emit_C(t->children[i], 0)
} }
C_str += ")" C_str += ")"
} }

View File

@@ -12,20 +12,17 @@ fun poset<T>(): poset<T> {
obj poset<T> (Object) { obj poset<T> (Object) {
var open_deps: map<T, set<T>> var open_deps: map<T, set<T>>
var close_deps: map<T, set<T>> var close_deps: map<T, set<T>>
var opened: set<T> var done: set<T>
var closed: set<T>
fun construct(): *poset<T> { fun construct(): *poset<T> {
open_deps.construct() open_deps.construct()
close_deps.construct() close_deps.construct()
opened.construct() done.construct()
closed.construct()
return this return this
} }
fun copy_construct(old: *poset<T>) { fun copy_construct(old: *poset<T>) {
open_deps.copy_construct(&old->open_deps) open_deps.copy_construct(&old->open_deps)
close_deps.copy_construct(&old->close_deps) close_deps.copy_construct(&old->close_deps)
opened.copy_construct(&old->opened) done.copy_construct(&old->done)
closed.copy_construct(&old->closed)
} }
fun operator=(other: ref poset<T>) { fun operator=(other: ref poset<T>) {
destruct() destruct()
@@ -34,8 +31,7 @@ obj poset<T> (Object) {
fun destruct() { fun destruct() {
open_deps.destruct() open_deps.destruct()
close_deps.destruct() close_deps.destruct()
opened.destruct() done.destruct()
closed.destruct()
} }
fun size(): int { fun size(): int {
return open_deps.size() return open_deps.size()
@@ -44,11 +40,21 @@ obj poset<T> (Object) {
add_job(first) add_job(first)
add_job(second) add_job(second)
open_deps[first].add(second) open_deps[first].add(second)
// also add all of the closed deps of what we depend on
close_deps[second].for_each(fun(cd: T) {
add_open_dep(first, cd)
})
} }
fun add_close_dep(first: T, second: T) { fun add_close_dep(first: T, second: T) {
add_job(first) add_job(first)
add_job(second) add_job(second)
close_deps[first].add(second) close_deps[first].add(second)
// patch this one in to everything that currently depends on first
open_deps.for_each(fun(v: T, ods: set<T>) {
if ods.contains(first) {
add_open_dep(v, second)
}
})
} }
fun add_job(vertex: T) { fun add_job(vertex: T) {
if (open_deps.contains_key(vertex)) if (open_deps.contains_key(vertex))
@@ -57,26 +63,19 @@ obj poset<T> (Object) {
close_deps.set(vertex, set<T>()) close_deps.set(vertex, set<T>())
} }
fun done(job: T): bool { fun done(job: T): bool {
return closed.contains(job) return done.contains(job)
} }
fun run(f: fun(T): void) { fun run(f: fun(T): void) {
opened = set<T>() done = set<T>()
closed = set<T>() while done.size() != size() {
while closed.size() != size() {
var changed = false var changed = false
// intentionally not refs, as it can change out from under us // intentionally not refs, as it can change out from under us
open_deps.for_each(fun(v: T, ods: set<T>) { open_deps.for_each(fun(v: T, ods: set<T>) {
if !closed.contains(v) && closed.contains(ods) { if !done.contains(v) && done.contains(ods) {
if !opened.contains(v) { changed = true
changed = true f(v)
f(v) if done.contains(open_deps[v]) {
if closed.contains(open_deps[v]) { done.add(v)
opened.add(v)
}
}
if closed.contains(open_deps[v]) && closed.contains(close_deps[v]) {
changed = true
closed.add(v)
} }
} }
}) })