From a8d4b4eb7fa779bc840916179035af17ec80180b Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Wed, 20 Jun 2018 00:49:49 -0400 Subject: [PATCH] Parses everything but templates into new AST, including imports adding to dependency poset --- k.krak | 228 +++++++++++++++++++++++++++++++++++++++++++-- stdlib/ast.krak | 22 ++--- stdlib/simple.krak | 3 - stdlib/str.krak | 12 ++- 4 files changed, 240 insertions(+), 25 deletions(-) delete mode 100644 stdlib/simple.krak diff --git a/k.krak b/k.krak index c2fde4e..10140a5 100644 --- a/k.krak +++ b/k.krak @@ -6,6 +6,7 @@ import parser:* import str:* import serialize:* import os:* +import set:* import vec:* import vec_literals:* import poset:* @@ -84,7 +85,8 @@ fun main(argc: int, argv: **char): int { var pass_poset = poset>() var name_ast_map = map>() var import_paths = vec(str(), base_dir + "/stdlib/") - var passes = vec( + var passes = vec>() + passes = vec( fun(file_name: str): *tree { var file = str() for (var i = 0; i < import_paths.size; i++;) { @@ -98,12 +100,28 @@ fun main(argc: int, argv: **char): int { error("File: " + file_name + ", not found in any import path - none of [" + str(",").join(import_paths) + "]") printerr(file_name + ", ") var parse_tree = parse.parse_input(file, file_name) + trim(parse_tree) return syntax_to_ast(file_name, parse_tree) }, fun(file_name: str): *tree { - println("Doing thing 2 to " + file_name) - printlnerr("just gonna ret") - print_tree(name_ast_map[file_name], 1) + println("Checking for imports in " + file_name) + name_ast_map[file_name]->children.for_each(fun(n: *tree) { + match (n->data) { + ast::_import(b) { + var imported_file_name = n->children[0]->data._identifier.first + ".krak" + for (var i = 0; i < passes.size; i++;) { + if (i == 0) + pass_poset.add_relationship(make_pair(file_name, 2), make_pair(imported_file_name, 0)) + else + pass_poset.add_relationship(make_pair(imported_file_name, i), make_pair(imported_file_name, i-1)) + } + } + } + }) + return name_ast_map[file_name] + }, + fun(file_name: str): *tree { + println("Doing thing 3 to " + file_name) return name_ast_map[file_name] } ) @@ -143,8 +161,88 @@ fun main(argc: int, argv: **char): int { } fun syntax_to_ast(file_name: str, syntax: *tree): *tree { - /*return _translation_unit(file_name)*/ - var result = _translation_unit(file_name) + var syntax_to_ast_helper: fun(*tree): *tree = fun(syntax: *tree): *tree { + printlnerr("syntax_to_ast " + syntax->data.name) + if (syntax->data.name == "import") { + return _import(from_vector(syntax->children.slice(2,-1).filter(fun(s:*tree):bool { + return s->data.name == "identifier" || s->data.data == "*" + }).map(fun(s: *tree): str { + return concat(s) + })), vec(syntax_to_ast_helper(syntax->children[1]))) + } else if (syntax->data.name == "function") + return _function(concat(get_node("func_identifier", syntax)), null(), + (get_nodes("typed_parameter", syntax) + + get_nodes("statement", syntax)).map(syntax_to_ast_helper)) + else if (syntax->data.name == "typed_parameter") + return _identifier(concat(get_node("identifier", syntax)), null()) + else if (syntax->data.name == "type_def") + return _type_def(concat(get_node("identifier", syntax)), + get_nodes("declaration_statement", syntax).map(syntax_to_ast_helper)) + else if (syntax->data.name == "adt_def") + return _type_def(concat(get_node("identifier", syntax)), + get_nodes("adt_option", syntax).map(fun(s: *tree): *tree { + return _identifier(concat(get_node("identifier", s)), null()) + })) + else if (syntax->data.name == "statement") + return syntax_to_ast_helper(syntax->children[0]) + else if (syntax->data.name == "code_block") + return _block(syntax->children.map(syntax_to_ast_helper)) + else if (syntax->data.name == "return_statement") + return _return(syntax->children.map(syntax_to_ast_helper)) + else if (syntax->data.name == "defer_statement") + return _defer(syntax->children.map(syntax_to_ast_helper)) + else if (syntax->data.name == "match_statement") { + return _match(vec(syntax_to_ast_helper(get_node("boolean_expression", syntax))) + + get_nodes("case_statement", syntax).map(fun(s: *tree): *tree { + return _case(s->children.map(syntax_to_ast_helper)) + })) + } else if (syntax->data.name == "declaration_statement") { + var children = vec(_identifier(concat(get_node("identifier", syntax)), null())) + children += get_nodes("boolean_expression", syntax).map(syntax_to_ast_helper) + return _declaration(children) + } else if (syntax->data.name == "assignment_statement") + return _assignment(vec(_binding(concat(syntax->children[1]), null>()), + syntax_to_ast_helper(syntax->children[0]), + syntax_to_ast_helper(syntax->children[2]))) + else if (syntax->data.name == "function_call") + return _call(syntax->children.map(fun(s: *tree): *tree { + return syntax_to_ast_helper(s->children[0]) + })) + else if (syntax->data.name == "boolean_expression" || + syntax->data.name == "and_boolean_expression" || + syntax->data.name == "bitwise_or" || + syntax->data.name == "bitwise_xor" || + syntax->data.name == "bitwise_and" || + syntax->data.name == "bool_exp" || + syntax->data.name == "expression" || + syntax->data.name == "shiftand" || + syntax->data.name == "term" || + syntax->data.name == "factor" || + syntax->data.name == "unarad" || + syntax->data.name == "access_operation") { + if (syntax->children.size == 1) { + return syntax_to_ast_helper(syntax->children[0]) + } else if (syntax->children.size == 2) { + if (syntax->children[0]->data.terminal) { + return _call(vec(_binding(concat(syntax->children[0]), null>()), + syntax_to_ast_helper(syntax->children[1]))) + } else { + return _call(vec(_binding(concat(syntax->children[1]), null>()), + syntax_to_ast_helper(syntax->children[0]))) + } + } else { + return _call(vec(_binding(concat(syntax->children[1]), null>()), + syntax_to_ast_helper(syntax->children[0]), + syntax_to_ast_helper(syntax->children[2]))) + } + } else if (syntax->data.name == "number") + return _value(concat(syntax), null()) + else if (syntax->data.name == "scoped_identifier" || syntax->data.name == "identifier") + return _binding(concat(syntax), null>()) + else + return null>() + } + var result = _translation_unit(file_name, syntax->children.map(syntax_to_ast_helper)) printlnerr("made") print_tree(result, 1) printlnerr("from") @@ -157,5 +255,121 @@ fun print_tree(t: *tree, level: int) { if (t->children[i]) print_tree(t->children[i], level+1) else - printlnerr("\t" * level + "null!") + printlnerr("\t" * (level + 1) + "null!") +} +fun get_node(lookup: *char, parent: *tree): *tree { + return get_node(str(lookup), parent) +} +fun get_node(lookup: str, parent: *tree): *tree { + var results = get_nodes(lookup, parent) + if (results.size > 1) + error(parent, "get node too many results!") + if (results.size) + return results[0] + return null>() +} +fun get_nodes(lookup: *char, parent: *tree): vec<*tree> { + return get_nodes(str(lookup), parent) +} +fun get_nodes(lookup: str, parent: *tree): vec<*tree> { + return parent->children.filter(fun(node: *tree):bool return node->data.name == lookup;) +} +fun concat(node: *tree): str { + var str.construct(): str + if (node->data.data != "no_value") + str += node->data.data + node->children.for_each(fun(child: *tree) str += concat(child);) + return str +} +fun get_first_terminal(source: *tree): *tree { + if (!source) + return null>() + if (source->data.terminal) + return source + if (source->children.size == 0) + return null>() + return get_first_terminal(source->children.first()) +} +fun error(source: *tree, message: *char) error(source, str(message)); +fun error(source: *tree, message: str) { + var first = get_first_terminal(source) + if (first) + error("***error |" + concat(source) + "| *** " + first->data.source + ": " + first->data.position + " " + message) + error(message) +} +fun trim(parse_tree: *tree) { + remove_node(symbol("$NULL$", false), parse_tree) + remove_node(symbol("WS", false), parse_tree) + // the terminals have " around them, which we have to escape + remove_node(symbol("\"\\(\"", true), parse_tree) + remove_node(symbol("\"\\)\"", true), parse_tree) + remove_node(symbol("\"template\"", true), parse_tree) + remove_node(symbol("\"return\"", true), parse_tree) + remove_node(symbol("\"defer\"", true), parse_tree) + remove_node(symbol("\";\"", true), parse_tree) + remove_node(symbol("line_end", false), parse_tree) + remove_node(symbol("\"{\"", true), parse_tree) + remove_node(symbol("\"}\"", true), parse_tree) + remove_node(symbol("\"(\"", true), parse_tree) + remove_node(symbol("\")\"", true), parse_tree) + remove_node(symbol("\"if\"", true), parse_tree) + remove_node(symbol("\"while\"", true), parse_tree) + remove_node(symbol("\"__if_comp__\"", true), parse_tree) + remove_node(symbol("\"comp_simple_passthrough\"", true), parse_tree) + /*remove_node(symbol("obj_nonterm", false), parse_tree)*/ + remove_node(symbol("adt_nonterm", false), parse_tree) + + collapse_node(symbol("case_statement_list", false), parse_tree) + collapse_node(symbol("opt_param_assign_list", false), parse_tree) + collapse_node(symbol("param_assign_list", false), parse_tree) + collapse_node(symbol("opt_typed_parameter_list", false), parse_tree) + collapse_node(symbol("opt_parameter_list", false), parse_tree) + collapse_node(symbol("intrinsic_parameter_list", false), parse_tree) + collapse_node(symbol("identifier_list", false), parse_tree) + collapse_node(symbol("adt_option_list", false), parse_tree) + collapse_node(symbol("statement_list", false), parse_tree) + collapse_node(symbol("parameter_list", false), parse_tree) + collapse_node(symbol("typed_parameter_list", false), parse_tree) + collapse_node(symbol("unorderd_list_part", false), parse_tree) + collapse_node(symbol("if_comp_pred", false), parse_tree) + collapse_node(symbol("declaration_block", false), parse_tree) + collapse_node(symbol("type_list", false), parse_tree) + collapse_node(symbol("opt_type_list", false), parse_tree) + collapse_node(symbol("template_param_list", false), parse_tree) + collapse_node(symbol("trait_list", false), parse_tree) + collapse_node(symbol("dec_type", false), parse_tree) +} +fun remove_node(remove: symbol, parse_tree: *tree) { + var to_process = stack<*tree>() + to_process.push(parse_tree) + while(!to_process.empty()) { + 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)) { + node->children.remove(i) + i--; + } else { + to_process.push(node->children[i]) + } + } + } +} +fun collapse_node(remove: symbol, parse_tree: *tree) { + var to_process = stack<*tree>() + to_process.push(parse_tree) + while(!to_process.empty()) { + var node = to_process.pop() + for (var i = 0; i < node->children.size; i++;) { + if (node->children[i]->data.equal_wo_data(remove)) { + var add_children = node->children[i]->children; + // stick child's children between the current children divided + // on i, without including i + node->children = node->children.slice(0,i) + + add_children + node->children.slice(i+1,-1) + i--; + } else { + to_process.push(node->children[i]) + } + } + } } diff --git a/stdlib/ast.krak b/stdlib/ast.krak index 3d89fd0..74c9de5 100644 --- a/stdlib/ast.krak +++ b/stdlib/ast.krak @@ -34,14 +34,14 @@ adt ast { } fun to_string(a: ref ast): str { match(a) { - ast::_translation_unit() return str("_translation_unit") - ast::_import() return str("_import") - ast::_identifier() return str("_identifier") - ast::_binding() return str("_binding") - ast::_type_def() return str("_type_def") - ast::_adt_def() return str("_adt_def") - ast::_function() return str("_function") - ast::_template() return str("_template") + ast::_translation_unit(b) return str("_translation_unit(") + b + ")" + ast::_import(b) return str("_import[") + str(",").join(b.data) + "]" + ast::_identifier(b) return str("_identifier(") + b.first + ")" + ast::_binding(b) return str("_binding(") + b.first + ")" + ast::_type_def(b) return str("_type_def(") + b + ")" + ast::_adt_def(b) return str("_adt_def(") + b + ")" + ast::_function(b) return str("_function(") + b.first + ")" + ast::_template(b) return str("_template(") + b.first + ")" ast::_declaration() return str("_declaration") ast::_assignment() return str("_assignment") ast::_block() return str("_block") @@ -55,9 +55,9 @@ fun to_string(a: ref ast): str { ast::_continue() return str("_continue") ast::_defer() return str("_defer") ast::_call() return str("_call") - ast::_compiler_intrinsic() return str("_compiler_intrinsic") - ast::_cast() return str("_cast") - ast::_value() return str("_value") + ast::_compiler_intrinsic(b) return str("_compiler_intrinsic(") + b.first + ")" + ast::_cast(b) return str("_cast") + ast::_value(b) return str("_value(") + b.first + ")" } } fun _translation_unit(p: str): *tree { diff --git a/stdlib/simple.krak b/stdlib/simple.krak deleted file mode 100644 index cfe9e5e..0000000 --- a/stdlib/simple.krak +++ /dev/null @@ -1,3 +0,0 @@ -fun main(argc: int, argv: **char): int { - return 0 -} diff --git a/stdlib/str.krak b/stdlib/str.krak index fe73079..f43b450 100644 --- a/stdlib/str.krak +++ b/stdlib/str.krak @@ -291,10 +291,14 @@ obj str (Object, Serializable, Hashable) { return out } fun join(to_join: ref vec::vec): str { - var to_ret = to_join.first() - for (var i = 1; i < to_join.size; i++;) - to_ret += *this + to_join[i] - return to_ret + if (to_join.size != 0) { + var to_ret = to_join.first() + for (var i = 1; i < to_join.size; i++;) + to_ret += *this + to_join[i] + return to_ret + } else { + return str("") + } } fun for_each(func: fun(char):void) { data.for_each(func)