import symbol:* import tree:* import vector:* import queue:* import map:* import util:* import string:* import mem:* import io:* import ast_node:* import ast_transformation:* import parser:* obj importer (Object) { var parse: parser var ast_pass: ast_transformation var name_ast_map: map,*ast_node>> fun construct(parseIn: ref parser, ast_passIn: ref ast_transformation): *importer { parse.copy_construct(&parseIn) ast_pass.copy_construct(&ast_passIn) name_ast_map.construct() return this } fun copy_construct(old: *importer) { parse.copy_construct(&old->parse) ast_pass.copy_construct(&old->ast_pass) name_ast_map.copy_construct(&old->name_ast_map) } fun operator=(old: ref importer) { destruct() copy_construct(&old) } fun destruct() { parse.destruct() ast_pass.destruct() name_ast_map.destruct() } fun import(file_name: string): *ast_node { if (name_ast_map.contains_key(file_name)) return name_ast_map[file_name].second print("pre-parse: "); println(file_name) var parse_tree = parse.parse_input(read_file(file_name), file_name) print("post-parse: "); println(file_name) write_file(file_name + ".parse.dot", syntax_tree_to_dot(parse_tree)) print("pre-trim: "); println(file_name) trim(parse_tree) print("post-trim: "); println(file_name) write_file(file_name + ".trimmed_parse.dot", syntax_tree_to_dot(parse_tree)) print("pre-ast: "); println(file_name) var ast = ast_pass.first_pass(file_name, parse_tree, this) print("post-ast: "); println(file_name) write_file(file_name + ".ast.dot", ast_to_dot(ast)) return ast } fun register(file_name: string, parse_tree: *tree, translation_unit: *ast_node) { name_ast_map.set(file_name, make_pair(parse_tree, translation_unit)) print("Registered parse_tree+translation_unit for ") println(file_name) } fun trim(parse_tree: *tree) { remove_node(symbol("$NULL$", false), parse_tree) remove_node(symbol("WS", false), parse_tree) remove_node(symbol("\\(", true), parse_tree) remove_node(symbol("\\)", true), parse_tree) remove_node(symbol("var", true), parse_tree) remove_node(symbol("fun", 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("def_nonterm", false), parse_tree) remove_node(symbol("obj_nonterm", false), parse_tree) remove_node(symbol("adt_nonterm", false), parse_tree) remove_node(symbol("template", true), parse_tree) remove_node(symbol("\\|", true), 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("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 = queue<*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)) { if (!node->children[i]) println("not because null") else { print("not because "); println(remove.name) } node->children.remove(i) i--; } else { to_process.push(node->children[i]) } } } } fun collapse_node(remove: symbol, parse_tree: *tree) { var to_process = queue<*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]) } } } } }