diff --git a/stdlib/map.krak b/stdlib/map.krak index 3823ddb..36adf6b 100644 --- a/stdlib/map.krak +++ b/stdlib/map.krak @@ -47,7 +47,13 @@ obj map (Object) { return keys.contains(key) } fun get(key: T): ref U { - return values.get(keys.find(key)) + /*return values.get(keys.find(key))*/ + var key_loc = keys.find(key) + if (key_loc == -1) { + io::println("trying to access nonexistant key-value!") + /*while (true) {}*/ + } + return values.get(key_loc) } fun remove(key: T) { var idx = keys.find(key) diff --git a/stdlib/parser.krak b/stdlib/parser.krak index 2219f4c..e5d0c59 100644 --- a/stdlib/parser.krak +++ b/stdlib/parser.krak @@ -158,8 +158,10 @@ obj parser (Object) { // the shift lookup will fail, and likely other things, and this is our accept // criteria anyway /*if (curr_reached->data == 0 && curr_reduction.sym == gram.rules[0].lhs)*/ - if (curr_reduction.sym == gram.rules[0].lhs) + if (curr_reduction.sym == gram.rules[0].lhs) { + println("would accept here") return; + } var shift_to = gram.parse_table.get_shift(curr_reached->data, curr_reduction.sym).state_or_rule println("got shift to") var new_label = null>() @@ -264,12 +266,12 @@ obj parser (Object) { var action_rule = gram.rules[action.state_or_rule] if (!fully_reduces_to_null(action_rule)) { println("does not reduce to null") - to_reduce.push(reduction(shift.first, action_rule.lhs, action.rule_position, + to_reduce.push(reduction(shift.first, action_rule.lhs, action.rule_position, get_nullable_parts(action_rule), new_label )) } else { println("does reduce to null") - to_reduce.push(reduction(shift_to_node, action_rule.lhs, 0, + to_reduce.push(reduction(shift_to_node, action_rule.lhs, 0, get_nullable_parts(action_rule), null>() )) } @@ -283,30 +285,39 @@ obj parser (Object) { if (nullable_parts) children.add(nullable_parts) if (!belongs_to_family(parent, children)) { - parent->children.add_all(children) - } else { - if (!are_packed(parent->children)) { - // ambiguity inner - var sub_parent = new>()->construct(symbol("AmbiguityInner", true)) - set_packed(sub_parent, true) - sub_parent->children.add_all(parent->children) - parent->children.clear() - parent->children.add(sub_parent) + if (parent->children.size == 0) { + parent->children.add_all(children) + } else { + if (!are_packed(parent->children)) { + // ambiguity inner + var sub_parent = new>()->construct(symbol("AmbiguityInner", true)) + set_packed(sub_parent, true) + sub_parent->children.add_all(parent->children) + parent->children.clear() + parent->children.add(sub_parent) + } + // ambiguity outer + var next_sub_parent = new>()->construct(symbol("AmbiguityOuter", true)) + set_packed(next_sub_parent, true) + parent->children.add(next_sub_parent) + next_sub_parent->children.add_all(children) } - // ambiguity outer - var next_sub_parent = new>()->construct(symbol("AmbiguityOuter", true)) - set_packed(next_sub_parent, true) - parent->children.add(next_sub_parent) - next_sub_parent->children.add_all(children) } } fun belongs_to_family(node: *tree, nodes: vector<*tree>): bool { - var family_count = 0 - node->children.for_each(fun(child: *tree) { - if (nodes.contains(child)) - family_count++ - }) - return family_count == nodes.size + for (var i = 0; i < nodes.size; i++;) { + var contains_one = false + for (var j = 0; j < node->children.size; j++;) { + var child = node->children[j] + if (nodes[i] == child || (nodes[i] && child && *nodes[i] == *child)) { + contains_one = true + break + } + } + if (!contains_one) + return false + } + return true } fun are_packed(nodes: vector<*tree>): bool { return nodes.any_true(fun(it: *tree):bool { return packed_map.contains_key(it) && packed_map[it]; }) @@ -439,19 +450,27 @@ obj reduction (Object) { fun syntax_tree_to_dot(root: *tree): string { var ret = string("digraph Kaken {\n") + var counter = 0 + var node_name_map = map<*tree, string>() + var get_name = fun(node: *tree): string { + if (node_name_map.contains_key(node)) + return node_name_map[node] + var escaped = string("") + node->data.to_string().data.for_each(fun(c: char) { + if (c != '"') + escaped += c + else + escaped += "\\\"" + }) + escaped += to_string(counter++) + node_name_map.set(node, escaped) + return escaped + } var helper: fun(*tree):void = fun(node: *tree) { - /*ret += node->data.to_string() + ";;;;\n";*/ node->children.for_each(fun(child: *tree) { if (!child) return; // where on earth does the null come from - var escaped_child = string("") - child->data.to_string().data.for_each(fun(c: char) { - if (c != '"') - escaped_child += c - else - escaped_child += "\\\"" - }) - ret += string("\"") + node->data.to_string() + "\" -> \"" + escaped_child + "\"\n"; + ret += string("\"") + get_name(node) + "\" -> \"" + get_name(child) + "\"\n"; helper(child) }) } diff --git a/stdlib/string.krak b/stdlib/string.krak index 5102ac8..ebbe0e0 100644 --- a/stdlib/string.krak +++ b/stdlib/string.krak @@ -2,6 +2,18 @@ import vector import util import mem +fun to_string(in: int): string { + var dest = mem::new(mem::sizeof() * 8) + defer mem::delete(dest) + __if_comp__ __C__ { + simple_passthrough(dest = dest, in = in::) """ + sprintf(dest, "%d", in); + """ + } + var ret = string(dest) + return ret +} + fun string(in:*char):string { var out.construct(in):string return out diff --git a/stdlib/tree.krak b/stdlib/tree.krak index de0ac40..6fc60a9 100644 --- a/stdlib/tree.krak +++ b/stdlib/tree.krak @@ -20,6 +20,9 @@ obj tree (Object) { destruct() copy_construct(&other) } + fun operator==(other: ref tree):bool { + return data == other.data + } fun destruct() { mem::maybe_destruct(&data) children.destruct() diff --git a/stdlib/vector.krak b/stdlib/vector.krak index 56a9464..c53a8bf 100644 --- a/stdlib/vector.krak +++ b/stdlib/vector.krak @@ -121,6 +121,7 @@ obj vector (Object) { println(index); print("Max Index of vector: "); println(size-1); + /*while(true) {}*/ return data[0]; } return data[index]; diff --git a/tests/grammer2.kgm b/tests/grammer2.kgm index b9ea6fd..214728d 100644 --- a/tests/grammer2.kgm +++ b/tests/grammer2.kgm @@ -1,11 +1,12 @@ # comment Goal = a ; -a = b | rec ; +a = b | rec "end" ; b = "c":named_c ; b = c "d":dname ; c = "a" | d ; d = e post_null post_non_null inherit_null ; inherit_null = e | post_non_null ; +e = ; e = f | ; f = ; post_null = "hi" ; diff --git a/tests/test_grammer.krak b/tests/test_grammer.krak index d531d94..cb37ee4 100644 --- a/tests/test_grammer.krak +++ b/tests/test_grammer.krak @@ -52,11 +52,12 @@ fun main():int { println(a.to_string()) a.calculate_state_automaton() var parse.construct(a): parser - var result = parse.parse_input(string("inport a;"), string("fun name")) + var result = parse.parse_input(read_file(string("to_parse.krak")), string("fun name")) + /*var result = parse.parse_input(string("inport a;"), string("fun name"))*/ /*var result = parse.parse_input(string("fun main():int { return 0; }"), string("fun name"))*/ /*var result = parse.parse_input(string("ad"), string("fun name"))*/ /*var result = parse.parse_input(string("hibyed"), string("fun name"))*/ - /*var result = parse.parse_input(string("hmmhmm"), string("fun name"))*/ + /*var result = parse.parse_input(string("hmmhmmend"), string("fun name"))*/ /*var result = parse.parse_input(string("hid"), string("fun name"))*/ println("the tree") println(syntax_tree_to_dot(result)) diff --git a/tests/to_parse.krak b/tests/to_parse.krak new file mode 100644 index 0000000..c759c23 --- /dev/null +++ b/tests/to_parse.krak @@ -0,0 +1,5 @@ + +fun main(): int { + return 0 +} +