diff --git a/k.krak b/k.krak index a425a39..c651b37 100644 --- a/k.krak +++ b/k.krak @@ -85,10 +85,10 @@ fun main(argc: int, argv: **char): int { var pass_poset = poset, str>>() var name_ast_map = map>() - var passes = map): bool>() + var passes = map): void>() // resolves a single import - passes[str("import_resolver")] = fun(import_binding: *tree): bool { + passes[str("import")] = fun(import_binding: *tree) { var file_path = binding_str(import_binding) println("Running import resolver for " + file_path) if (!name_ast_map.contains_key(file_path)) { @@ -99,41 +99,51 @@ fun main(argc: int, argv: **char): int { } set_bindings(import_binding, name_ast_map[file_path]) - return true - } - - // ensures that all imports reachable from this one are resolved - passes[str("import_checker")] = fun(import_binding: *tree): bool { - var all_resolved = true - var file_path = binding_str(import_binding) - println("Running import checker for " + file_path) name_ast_map[file_path]->children.for_each(fun(n: *tree) { match (n->data) { ast::_import(b) { if (!bound(b.first)) { - all_resolved = false - pass_poset.add_relationship(make_pair(import_binding, str("import_checker")), make_pair(b.first, str("import_resolver"))) - println(to_string(b.first->data) + " is not bound!") - } else { - println(to_string(b.first->data) + " is bound!") + pass_poset.add_close_dep(make_pair(import_binding, str("import")), make_pair(b.first, str("import"))) } } } }) + } - return all_resolved + // emit C + var C_str = str() + passes[str("emit_C")] = fun(import_binding: *tree) { + if !pass_poset.done(make_pair(import_binding, str("import"))) { + pass_poset.add_open_dep(make_pair(import_binding, str("emit_C")), make_pair(import_binding, str("import"))) + return + } + + var file_path = binding_str(import_binding) + println("Running emit C for " + file_path) + var emit_C: fun(*tree, int): void = fun(t: *tree, level: int) { + match (t->data) { + ast::_identifier(b) { + C_str += b.first + } + ast::_import(b) { + pass_poset.add_close_dep(make_pair(import_binding, str("emit_C")), make_pair(b.first, str("emit_C"))) + } + } + + t->children.for_each(fun(c: *tree) { + emit_C(c, level+1) + }) + } + emit_C(name_ast_map[file_path], 0) } var top_binding = make_binding(kraken_file_name) - pass_poset.add_relationship(make_pair(top_binding, str("import_checker")), make_pair(top_binding, str("import_resolver"))) + pass_poset.add_job(make_pair(top_binding, str("emit_C"))) - while (pass_poset.size() != 0) { - var file_pass = pass_poset.top() - printlnerr("doing pass " + file_pass.second + " on " + to_string(file_pass.first->data)) - var done = passes[file_pass.second](file_pass.first) - if (done) - pass_poset.remove(file_pass) - } + pass_poset.run(fun(file_pass: pair<*tree, str>) { + printlnerr("doing pass new style " + file_pass.second + " on " + to_string(file_pass.first->data)) + passes[file_pass.second](file_pass.first) + }) println() println() @@ -145,9 +155,8 @@ fun main(argc: int, argv: **char): int { }) var kraken_c_output_name = kraken_file_name + ".c" - var c_code = str("//don't you wish this was real kraken\n") var c_flags = str("") - write_file(kraken_c_output_name, c_code) + write_file(kraken_c_output_name, C_str) if (compile_c) { var compile_string = "cc -g " + opt_str + " -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Wno-incompatible-pointer-types -std=c99 " + c_flags + " " + kraken_c_output_name + " -o " + executable_name @@ -326,7 +335,11 @@ fun syntax_to_ast(file_name: str, syntax: *tree, import_paths: ref vecchildren.map(syntax_to_ast_helper)) })) } else if (syntax->data.name == "declaration_statement") { - var children = vec(_identifier(concat(get_node("identifier", syntax)), parse_type(get_node("type", syntax)))) + var t = type(base_type::_unknown(), 0, false) + var type_syntax = get_node("type", syntax) + if type_syntax != null>() + t = parse_type(type_syntax) + var children = vec(_identifier(concat(get_node("identifier", syntax)), t)) children += get_nodes("boolean_expression", syntax).map(syntax_to_ast_helper) return _declaration(children) } else if (syntax->data.name == "assignment_statement") @@ -377,10 +390,6 @@ fun syntax_to_ast(file_name: str, syntax: *tree, import_paths: ref vec>() } var result = _translation_unit(file_name, syntax->children.map(syntax_to_ast_helper)) - printlnerr("made") - print_tree(result, 1) - printlnerr("from") - print_tree(syntax, 1) return result } fun print_tree(t: *tree, level: int) { diff --git a/stdlib/bytecode_generator.krak b/stdlib/bytecode_generator.krak index c470bef..cbd82a3 100644 --- a/stdlib/bytecode_generator.krak +++ b/stdlib/bytecode_generator.krak @@ -11,7 +11,6 @@ import symbol:* import ast_nodes:* // for error with syntax tree import pass_common:* -import poset:* fun type_size(t: *type): ulong return type_size_and_alignment(t).first diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index 29a3eb0..6abbf06 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -177,22 +177,22 @@ obj c_generator (Object) { match (*node) { ast_node::function(backing) generate_function_definition(node) ast_node::type_def(backing) { - type_poset.add_vertex(node) + type_poset.add_job(node) backing.variables.for_each(fun(i: *ast_node) { var var_type = get_ast_type(i->declaration_statement.identifier) if (!var_type->indirection && var_type->type_def) - type_poset.add_relationship(node, var_type->type_def) + type_poset.add_open_dep(node, var_type->type_def) }) } } }) } ast_node::type_def(backing) { - type_poset.add_vertex(child) + type_poset.add_job(child) backing.variables.for_each(fun(i: *ast_node) { var var_type = get_ast_type(i->declaration_statement.identifier) if (!var_type->indirection && var_type->type_def) - type_poset.add_relationship(child, var_type->type_def) + type_poset.add_open_dep(child, var_type->type_def) }) } ast_node::adt_def(backing) error("ADT remaining!") diff --git a/stdlib/map.krak b/stdlib/map.krak index ec4ba42..adde257 100644 --- a/stdlib/map.krak +++ b/stdlib/map.krak @@ -111,5 +111,9 @@ obj map (Object, Serializable) { for (var i = 0; i < keys.size; i++;) func(keys[i], values[i]) } + fun for_each(func: fun(ref T, ref U):void) { + for (var i = 0; i < keys.size; i++;) + func(keys[i], values[i]) + } } diff --git a/stdlib/poset.krak b/stdlib/poset.krak index 6485c2b..cdb134d 100644 --- a/stdlib/poset.krak +++ b/stdlib/poset.krak @@ -10,98 +10,81 @@ fun poset(): poset { } obj poset (Object) { - var adj_matrix: map> + var open_deps: map> + var close_deps: map> + var opened: set + var closed: set fun construct(): *poset { - adj_matrix.construct() + open_deps.construct() + close_deps.construct() + opened.construct() + closed.construct() return this } fun copy_construct(old: *poset) { - adj_matrix.copy_construct(&old->adj_matrix) + open_deps.copy_construct(&old->open_deps) + close_deps.copy_construct(&old->close_deps) + opened.copy_construct(&old->opened) + closed.copy_construct(&old->closed) } fun operator=(other: ref poset) { destruct() copy_construct(&other) } fun destruct() { - adj_matrix.destruct() + open_deps.destruct() + close_deps.destruct() + opened.destruct() + closed.destruct() } fun size(): int { - return adj_matrix.size() + return open_deps.size() } - fun add_relationship(first: T, second: T) { - if (!adj_matrix.contains_key(first)) - add_vertex(first) - if (!adj_matrix.contains_key(second)) - add_vertex(second) - adj_matrix[first].add(second) + fun add_open_dep(first: T, second: T) { + add_job(first) + add_job(second) + open_deps[first].add(second) } - fun add_vertex(vertex: T) { - if (adj_matrix.contains_key(vertex)) + fun add_close_dep(first: T, second: T) { + add_job(first) + add_job(second) + close_deps[first].add(second) + } + fun add_job(vertex: T) { + if (open_deps.contains_key(vertex)) return; - adj_matrix.set(vertex, set()) + open_deps.set(vertex, set()) + close_deps.set(vertex, set()) } - fun get_depends_on(vertex: T): set { - var depends_on = set() - adj_matrix.for_each(fun(key: T, value: set) { - if (value.contains(vertex)) - depends_on.add(key) - }) - return depends_on + fun done(job: T): bool { + return closed.contains(job) } - fun top(): T { - for (var i = 0; i < adj_matrix.keys.size; i++;) { - if (adj_matrix.values[i].size() == 0) { - return adj_matrix.keys[i] - } - } - error("Nothing to top") - } - fun remove(x: ref T) { - var dependencies = adj_matrix.get_ptr_or_null(x) - if (dependencies == null>()) - error("Trying to remove item from poset that doesn't contain it!") - if (dependencies->size() != 0) - error("Trying to remove item from poset that still has dependencies on it!") - - for (var j = 0; j < adj_matrix.keys.size; j++;) { - // remove is ok if it doesn't exist - adj_matrix.values[j].remove(x) - } - adj_matrix.remove(x) - } - fun pop(): T { - for (var i = 0; i < adj_matrix.keys.size; i++;) { - if (adj_matrix.values[i].size() == 0) { - var to_ret = adj_matrix.keys[i] - for (var j = 0; j < adj_matrix.keys.size; j++;) { - // remove is ok if it doesn't exist - /*if (adj_matrix.values[i].contains(to_ret)) {*/ - adj_matrix.values[j].remove(to_ret) - /*}*/ + fun run(f: fun(T): void) { + opened = set() + closed = set() + while closed.size() != size() { + // intentionally not refs, as it can change out from under us + open_deps.for_each(fun(v: T, ods: set) { + if !closed.contains(v) && closed.contains(ods) { + if !opened.contains(v) { + f(v) + if closed.contains(open_deps[v]) { + opened.add(v) + } + } + if closed.contains(open_deps[v]) && closed.contains(close_deps[v]) { + closed.add(v) + } } - adj_matrix.remove(to_ret) - return to_ret - } - } - error("Nothing to pop") - } - fun get_sorted(): vec { - var sorted = vec() - var to_do = queue() - // because we're going to destructivly update - var temp_adj_matrix = adj_matrix - temp_adj_matrix.for_each(fun(key: T, value: set) - if (temp_adj_matrix[key].size() == 0) to_do.push(key);) - while (!to_do.empty()) { - var current = to_do.pop() - sorted.add(current) - get_depends_on(current).for_each(fun(vert: T) { - temp_adj_matrix[vert].remove(current) - if (temp_adj_matrix[vert].size() == 0) - to_do.push(vert) }) } - return sorted + } + fun get_sorted(): vec { + var to_ret = vec() + run(fun(i: T) { + to_ret.add(i) + }) + return to_ret } }