diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 0b1ab53..c7c2077 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -144,7 +144,8 @@ alpha_alphanumeric = "(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C augmented_alpha_alphanumeric = alpha_alphanumeric augmented_alpha_alphanumeric | keywords_also_identifiers augmented_alpha_alphanumeric | alpha_alphanumeric | keywords_also_identifiers ; numeric = "(0|1|2|3|4|5|6|7|8|9)+" ; -string = triple_quoted_string | "\"(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'| +# note the hacks around \things +string = triple_quoted_string | "\"(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|(\\\\)|(\\n)|(\\t)|(\\0)|a|s|d|f|g|h|j|k|l|;|'| |z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| |(\\\"))*\"" ; comment = cpp_comment | c_comment ; cpp_comment = "//(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i|o|p|[|]|\\|a|s|d|f|g|h|j|k|l|;|'|z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|\"|Z|X|C|V|B|N|M|<|>|\?| )* diff --git a/stdlib/ast_nodes.krak b/stdlib/ast_nodes.krak index ba3a2e8..f042e57 100644 --- a/stdlib/ast_nodes.krak +++ b/stdlib/ast_nodes.krak @@ -88,8 +88,8 @@ obj translation_unit (Object) { return children == other.children && name == other.name } } -fun ast_import_ptr(name: string): *ast_node { - var to_ret.construct(name): import +fun ast_import_ptr(name: string, translation_unit: *ast_node): *ast_node { + var to_ret.construct(name, translation_unit): import var ptr = new() ptr->copy_construct(&ast_node::import(to_ret)) return ptr @@ -103,17 +103,20 @@ fun is_import(node: *ast_node): bool { obj import (Object) { var scope: map> var imported: set + var translation_unit: *ast_node var name: string - fun construct(nameIn: string): *import { + fun construct(nameIn: string, translation_unit_in: *ast_node): *import { scope.construct() imported.construct() name.copy_construct(&nameIn) + translation_unit = translation_unit_in return this } fun copy_construct(old: *import) { scope.copy_construct(&old->scope) imported.copy_construct(&old->imported) name.copy_construct(&old->name) + translation_unit = old->translation_unit } fun destruct() { scope.destruct() @@ -125,7 +128,7 @@ obj import (Object) { copy_construct(&other) } fun operator==(other: ref import): bool { - return imported == other.imported && name == other.name + return imported == other.imported && name == other.name && translation_unit == other.translation_unit } } fun ast_identifier_ptr(name: *char, type: *type): *ast_node { @@ -784,8 +787,8 @@ obj simple_passthrough (Object) { return scope == other.scope && passthrough_str == other.passthrough_str } } -fun ast_function_call_ptr(): *ast_node { - var to_ret.construct(): function_call +fun ast_function_call_ptr(func: *ast_node, parameters: vector<*ast_node>): *ast_node { + var to_ret.construct(func, parameters): function_call var ptr = new() ptr->copy_construct(&ast_node::function_call(to_ret)) return ptr @@ -797,23 +800,26 @@ fun is_function_call(node: *ast_node): bool { return false } obj function_call (Object) { - var scope: map> - fun construct(): *function_call { - scope.construct() + var func: *ast_node + var parameters: vector<*ast_node> + fun construct(func_in: *ast_node, parameters_in: vector<*ast_node>): *function_call { + func = func_in + parameters.copy_construct(¶meters_in) return this } fun copy_construct(old: *function_call) { - scope.copy_construct(&old->scope) + func = old->func + parameters.copy_construct(&old->parameters) } fun destruct() { - scope.destruct() + parameters.destruct() } fun operator=(other: ref function_call) { destruct() copy_construct(&other) } fun operator==(other: ref function_call): bool { - return true + return func == func && parameters == other.parameters } } fun ast_value_ptr(string_value: string, value_type: *type): *ast_node { @@ -879,7 +885,7 @@ fun get_ast_children(node: *ast_node): vector<*ast_node> { ast_node::declaration_statement(backing) return vector<*ast_node>() ast_node::if_comp(backing) return vector<*ast_node>(backing.statement) ast_node::simple_passthrough(backing) return vector<*ast_node>() - ast_node::function_call(backing) return vector<*ast_node>() + ast_node::function_call(backing) return vector(backing.func) + backing.parameters ast_node::value(backing) return vector<*ast_node>() } } @@ -906,7 +912,7 @@ fun get_ast_name(node: *ast_node): string { ast_node::declaration_statement(backing) return string("declaration_statement") ast_node::if_comp(backing) return string("if_comp: ") + backing.wanted_generator ast_node::simple_passthrough(backing) return string("simple_passthrough: , string:") + backing.passthrough_str - ast_node::function_call(backing) return string("function_call") + ast_node::function_call(backing) return string("function_call:(") + backing.parameters.size + ")" ast_node::value(backing) return string("value: ") + backing.string_value + ": " + backing.value_type->to_string() } } @@ -933,7 +939,7 @@ fun get_ast_scope(node: *ast_node): *map> { ast_node::declaration_statement() return &node->declaration_statement.scope ast_node::if_comp() return null>>() ast_node::simple_passthrough() return &node->simple_passthrough.scope - ast_node::function_call() return &node->function_call.scope + ast_node::function_call() return null>>() ast_node::value() return &node->value.scope } } diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index d8820ff..e2c39bb 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -67,12 +67,12 @@ obj ast_transformation (Object) { if (child->data.name == "import") { var import_identifier_children = get_nodes("identifier", child) var name = concat_symbol_tree(import_identifier_children[0]) - var import_node = ast_import_ptr(name) + var outside_translation_unit = importer->import_first_pass(name + ".krak") + add_to_scope(name, outside_translation_unit, translation_unit) + var import_node = ast_import_ptr(name, outside_translation_unit) translation_unit->translation_unit.children.add(import_node) ast_to_syntax.set(import_node, child) add_to_scope("~enclosing_scope", translation_unit, import_node) - var outside_translation_unit = importer->import_first_pass(name + ".krak") - add_to_scope(name, outside_translation_unit, translation_unit) import_node->import.imported = from_vector(import_identifier_children.slice(1,-1).map(fun(ident: *tree):string return concat_symbol_tree(ident);)) } }) @@ -185,6 +185,8 @@ obj ast_transformation (Object) { return transform_statement(node, scope) } else if (name == "return_statement") { return transform_return_statement(node, scope) + } else if (name == "function_call") { + return transform_function_call(node, scope) } else if (name == "boolean_expression" || name == "and_boolean_expression" || name == "bool_exp" || name == "expression" || name == "shiftand" || name == "term" @@ -208,14 +210,15 @@ obj ast_transformation (Object) { // for identifier we have to do scope lookup, etc, and maybe limit to function // NOT THIS var name = concat_symbol_tree(node) - return ast_identifier_ptr(name, type_ptr(base_type::void_return())) + /*return ast_identifier_ptr(name, type_ptr(base_type::void_return()))*/ + return identifier_lookup(name, scope) } fun transform_value(node: *tree, scope: *ast_node): *ast_node { var value_str = concat_symbol_tree(node) var value_type = null() if (value_str[0] == '"') value_type = type_ptr(base_type::character(), 1) - else if (value_str[0] == '\'') + else if (value_str[0] == '\'') //' lol, comment hack for vim syntax highlighting (my fault, of course) value_type = type_ptr(base_type::character()) else { // should differentiate between float and double... @@ -236,7 +239,7 @@ obj ast_transformation (Object) { fun transform_expression(node: *tree, scope: *ast_node): *ast_node { // figure out what the expression is, handle overloads, or you know // ignore everything and do a passthrough - println(string("passing through: ") + node->data.name) + /*println(string("passing through: ") + node->data.name)*/ return transform(node->children[0], scope) } fun transform_code_block(node: *tree, scope: *ast_node): *ast_node { @@ -265,6 +268,56 @@ obj ast_transformation (Object) { fun transform_return_statement(node: *tree, scope: *ast_node): *ast_node { return ast_return_statement_ptr(transform(node->children[0], scope)) } + fun transform_function_call(node: *tree, scope: *ast_node): *ast_node { + // don't bother a full transform for parameter, just get the boolean expression from it + var parameters = get_nodes("parameter", node).map(fun(child: *tree): *ast_node return transform(get_node("boolean_expression", child), scope);) + /*return ast_function_call_ptr(function_lookup(concat_symbol_tree(get_node("unarad", node)), scope), parameters)*/ + var f = ast_function_call_ptr(function_lookup(concat_symbol_tree(get_node("unarad", node)), scope), parameters) + print("function call function ") + println(f->function_call.func) + print("function call parameters ") + f->function_call.parameters.for_each(fun(param: *ast_node) print(param);) + return f + } + fun identifier_lookup(name: string, scope: *ast_node): *ast_node { + var results = scope_lookup(name, scope) + if (!results.size) { + println(string("identifier lookup failed for ") + name) + return null() + } + return results[0] + } + fun function_lookup(name: string, scope: *ast_node): *ast_node { + var results = scope_lookup(name, scope) + if (!results.size) { + println(string("identifier lookup failed for ") + name) + return null() + } + return results[0] + } + fun scope_lookup(name: string, scope: *ast_node): vector<*ast_node> { + // need to do properly scopded lookups + // prevent re-checking the same one... + print("scope is: ") + get_ast_scope(scope)->for_each(fun(key: string, value: vector<*ast_node>) print(key + " ");) + println() + var results = vector<*ast_node>() + if (get_ast_scope(scope)->contains_key(name)) { + println(name + " is in scope, adding to results") + results += get_ast_scope(scope)->get(name) + } + if (get_ast_scope(scope)->contains_key(string("~enclosing_scope"))) + results += scope_lookup(name, get_ast_scope(scope)->get(string("~enclosing_scope"))[0]) + if (is_translation_unit(scope)) { + scope->translation_unit.children.for_each(fun(child: *ast_node) { + if (is_import(child) && child->import.imported.contains(name)) { + println(name + " is indeed imported") + results += scope_lookup(name, child->import.translation_unit) + } else println(name + " is not imported (this time)") + }) + } + return results + } } fun concat_symbol_tree(node: *tree): string { diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index a317cad..3771df4 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -84,6 +84,19 @@ obj c_generator (Object) { node->code_block.children.for_each(fun(child: *ast_node) to_ret += generate(child);) return to_ret + "}" } + // this generates the function as a value, not the actuall function + fun generate_function(node: *ast_node): string { + return node->function.name + } + fun generate_function_call(node: *ast_node): string { + var call_string = string() + node->function_call.parameters.for_each(fun(param: *ast_node) { + if (call_string != "") + call_string += ", " + call_string += generate(param) + }) + return generate(node->function_call.func) + "(" + call_string + ")" + } // for now, anyway fun generate(node: *ast_node): string { @@ -91,6 +104,8 @@ obj c_generator (Object) { match (*node) { ast_node::simple_passthrough(backing) return generate_simple_passthrough(node) ast_node::statement(backing) return generate_statement(node) + ast_node::function(backing) return generate_function(node) + ast_node::function_call(backing) return generate_function_call(node) ast_node::code_block(backing) return generate_code_block(node) ast_node::return_statement(backing) return generate_return_statement(node) ast_node::value(backing) return generate_value(node) diff --git a/stdlib/importer.krak b/stdlib/importer.krak index 772165a..c499099 100644 --- a/stdlib/importer.krak +++ b/stdlib/importer.krak @@ -126,11 +126,13 @@ obj importer (Object) { var node = to_process.pop() for (var i = 0; i < node->children.size; i++;) { if (!node->children[i] || node->children[i]->data.equal_wo_data(remove)) { + /* if (!node->children[i]) println("not because null") else { print("not because "); println(remove.name) } + */ node->children.remove(i) i--; } else { diff --git a/stdlib/io.krak b/stdlib/io.krak index 6d38329..ff0df15 100644 --- a/stdlib/io.krak +++ b/stdlib/io.krak @@ -15,6 +15,15 @@ fun println(toPrint: T) : void { print("\n") } +fun print(toPrint: *T) : void{ + __if_comp__ __C__ { + simple_passthrough(toPrint = toPrint::) """ + printf("%p", (void*)toPrint); + """ + } + return; +} + fun print(toPrint: *char) : void { __if_comp__ __C__ { simple_passthrough(toPrint = toPrint::) """ @@ -175,7 +184,7 @@ fun BoldCyan(): void{ } fun Reset(): void{ - print("\033[0m"); + print("\033[0m"); } diff --git a/stdlib/parser.krak b/stdlib/parser.krak index 2dc4ad8..5d33e97 100644 --- a/stdlib/parser.krak +++ b/stdlib/parser.krak @@ -62,7 +62,7 @@ obj parser (Object) { // if the zero state contains any reductions for state 0 and eof, then // it must be reducing to the goal state - println("checking the bidness") + /*println("checking the bidness")*/ if (inputStr == "" && gram.parse_table.get(0, eof_symbol()).contains(action(action_type::reduce(), 0))) { println("Accept on no input for ") println(name) @@ -91,14 +91,16 @@ obj parser (Object) { var null_symbol_tree = null>() gram.parse_table.get(0, input[0]).for_each(fun(act: action) { - println("for each action") + /*println("for each action") act.print() + */ if (act.act == action_type::push()) to_shift.push(make_pair(v0, act.state_or_rule)) /*else if (act.act == reduce && fully_reduces_to_null(gram.rules[act.state_or_rule])) {*/ else if (act.act == action_type::reduce() && act.rule_position == 0) { - print("act == reduce() && == 0 Adding reduction from state: ") + /*print("act == reduce() && == 0 Adding reduction from state: ") println(v0->data) + */ to_reduce.push(reduction(v0, gram.rules[act.state_or_rule].lhs, 0, null_symbol_tree, null_symbol_tree)) } }) @@ -117,10 +119,12 @@ obj parser (Object) { return null>() } SPPFStepNodes.clear() + /* print("to_reduce size: ") println(to_reduce.size()) print("to_shift size: ") println(to_shift.size()) + */ while (to_reduce.size()) reducer(i) shifter(i) @@ -141,16 +145,17 @@ obj parser (Object) { return null>() } fun reducer(i: int) { - print("reducing from state: ") var curr_reduction = to_reduce.pop() + /*print("reducing from state: ") println(curr_reduction.from->data) print("curr_reduction.length (not length-1) is: ") println(curr_reduction.length) + */ gss.get_reachable_paths(curr_reduction.from, max(0, curr_reduction.length-1)). for_each(fun(path: ref vector<*tree>) { - println("in get_reachable_paths for_each loop") + /*println("in get_reachable_paths for_each loop")*/ var path_edges = range(path.size-1).map(fun(indx: int): *tree { return gss.get_edge(path[indx], path[indx+1]);}).reverse() - print("path ") + /*print("path ") path.for_each(fun(part: *tree) { print(part->data) print(" ") @@ -159,26 +164,29 @@ obj parser (Object) { println("got path edges") println("there are this many:") println(path_edges.size) + */ if (curr_reduction.length != 0) { path_edges.addEnd(curr_reduction.label) - println("also adding the one from the reduction") + /*println("also adding the one from the reduction") println(curr_reduction.label->data.to_string()) + */ } var curr_reached = path.last() - print("checking shift for state ") + /*print("checking shift for state ") print(curr_reached->data) print(" and ") println(curr_reduction.sym.to_string()) + */ // if this is the Goal = a type reduction, then skip the actual reduction part. // 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) { - println("would accept here") + /*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") + /*println("got shift to")*/ var new_label = null>() if (curr_reduction.length == 0) { new_label = curr_reduction.nullable_parts @@ -210,8 +218,9 @@ obj parser (Object) { act.rule_position, get_nullable_parts(reduce_rule), new_label)) - print("(non null) Adding reduction from state: ") + /*print("(non null) Adding reduction from state: ") println(curr_reached->data) + */ } }) } @@ -231,14 +240,16 @@ obj parser (Object) { to_reduce.push(reduction(shift_to_node, action_rule.lhs, 0, get_nullable_parts(action_rule), null>() )) - print("null reduces Adding reduction from state: ") + /*print("null reduces Adding reduction from state: ") println(shift_to_node->data) + */ } else if (curr_reduction.length != 0) { to_reduce.push(reduction(curr_reached, action_rule.lhs, act.rule_position, get_nullable_parts(action_rule), new_label )) - print("null does not reduce Adding reduction from state: ") + /*print("null does not reduce Adding reduction from state: ") println(curr_reached->data) + */ } } }) @@ -248,22 +259,24 @@ obj parser (Object) { }) } fun shifter(i: int) { - println("shifting") + /*println("shifting")*/ if (i >= input.size-1) return; // darn ambiguity - print("shifting on ") + /*print("shifting on ") println(input[i].to_string()) + */ var next_shifts = stack< pair<*tree, int> >() var new_label = new>()->construct(input[i]) while (!to_shift.empty()) { - println("to_shift not empty") + /*println("to_shift not empty")*/ var shift = to_shift.pop() - println("post pop") + /*println("post pop")*/ var shift_to_node = gss.in_frontier(i+1, shift.second) - println("post in_frontier") + /*println("post in_frontier")*/ if (shift_to_node) { - print("already in frontier ") + /*print("already in frontier ") println(i+1) + */ gss.add_edge(shift_to_node, shift.first, new_label) gram.parse_table.get_reduces(shift.second, input[i+1]).for_each(fun(action: action) { var reduce_rule = gram.rules[action.state_or_rule] @@ -272,43 +285,47 @@ obj parser (Object) { to_reduce.push(reduction(shift.first, reduce_rule.lhs, action.rule_position, get_nullable_parts(reduce_rule), new_label )) - print("if shift to node Adding reduction from state: ") + /*print("if shift to node Adding reduction from state: ") println(shift.first->data) + */ } }) } else { - print("adding to frontier ") + /*print("adding to frontier ") println(i+1) + */ shift_to_node = gss.new_node(shift.second) gss.add_to_frontier(i+1, shift_to_node) - println("post add to frontier") + /*println("post add to frontier")*/ gss.add_edge(shift_to_node, shift.first, new_label) - println("post add edger") + /*println("post add edger")*/ gram.parse_table.get(shift.second, input[i+1]).for_each(fun(action: action) { - println("looking at an action") + /*println("looking at an action")*/ if (action.act == action_type::push()) { - println("is push") + /*println("is push")*/ next_shifts.push(make_pair(shift_to_node, action.state_or_rule)) } else { - println("is reduce") + /*println("is reduce")*/ var action_rule = gram.rules[action.state_or_rule] /*if (!fully_reduces_to_null(action_rule)) {*/ if (action.rule_position != 0) { - println("does not reduce to null") + /*println("does not reduce to null")*/ to_reduce.push(reduction(shift.first, action_rule.lhs, action.rule_position, get_nullable_parts(action_rule), new_label )) - print("not shift to, reduce, != 0 Adding reduction from state: ") + /*print("not shift to, reduce, != 0 Adding reduction from state: ") println(shift.first->data) print("added ruduction rule+position: ") println(action.rule_position) + */ } else { - println("does reduce to null") + /*println("does reduce to null")*/ to_reduce.push(reduction(shift_to_node, action_rule.lhs, 0, get_nullable_parts(action_rule), null>() )) - print("not shift to, reduce, == 0 Adding reduction from state: ") + /*print("not shift to, reduce, == 0 Adding reduction from state: ") println(shift_to_node->data) + */ } } }) @@ -512,10 +529,13 @@ fun syntax_tree_to_dot(root: *tree): string { return node_name_map[node] var escaped = string("") node->data.to_string().data.for_each(fun(c: char) { - if (c != '"') + if (c != '"' && c != '\\') escaped += c - else + else if (c == '"') escaped += "\\\"" + else if (c == '\\') + escaped += "\\\\" + }) escaped += to_string(counter++) node_name_map.set(node, escaped) diff --git a/stdlib/set.krak b/stdlib/set.krak index 6618dce..8a99ca5 100644 --- a/stdlib/set.krak +++ b/stdlib/set.krak @@ -41,8 +41,6 @@ obj set (Object, Serializable) { return serialize::serialize(data) } fun unserialize(it: ref vector::vector, pos: int): int { - /*construct()*/ - /*util::unpack(data, pos) = serialize::unserialize>(it, pos)*/ return data.unserialize(it, pos) } fun operator==(rhs: set): bool { diff --git a/tests/test_compiler.krak b/tests/test_compiler.krak index b9fab02..24680a1 100644 --- a/tests/test_compiler.krak +++ b/tests/test_compiler.krak @@ -60,19 +60,6 @@ fun main():int { write_file_binary(compiled_name, serialize(file_contents) + serialize(gram)) println("done writing") } - /*println(gram.to_string())*/ - - /*var parse.construct(gram): parser*/ - /*var parse_tree = parse.parse_input(read_file(string("to_parse.krak")), string("fun name"))*/ - /*println("the tree")*/ - /*println(syntax_tree_to_dot(parse_tree))*/ - /*write_file(string("syntax_tree.dot"), syntax_tree_to_dot(parse_tree))*/ - - /*var ast_pass.construct(): ast_transformation*/ - /*var ast = ast_pass.transform(parse_tree)*/ - /*println("the AST")*/ - /*println(ast_to_dot(ast))*/ - /*write_file(string("ast.dot"), ast_to_dot(ast))*/ var kraken_file_name = string("to_parse.krak") var parse.construct(gram): parser @@ -89,4 +76,3 @@ fun main():int { return 0 } - diff --git a/tests/to_parse.krak b/tests/to_parse.krak index eafd1e8..6f62a69 100644 --- a/tests/to_parse.krak +++ b/tests/to_parse.krak @@ -1,4 +1,4 @@ -import to_import: a,b +import to_import: simple_print, a, b obj Something (ObjectTrait) { var member: int