Files
kraken/stdlib/importer.krak

181 lines
8.0 KiB
Plaintext
Raw Normal View History

2015-12-05 07:13:32 -05:00
import symbol:*
import tree:*
import vector:*
2015-12-05 17:31:11 -05:00
import queue:*
2015-12-05 07:13:32 -05:00
import map:*
import util:*
import string:*
import mem:*
import io:*
import ast_nodes:*
2015-12-05 07:13:32 -05:00
import ast_transformation:*
import parser:*
obj importer (Object) {
var parse: parser
var ast_pass: ast_transformation
2015-12-28 03:34:40 -05:00
var name_ast_map: map<string, pair<*tree<symbol>,*ast_node>>
var import_paths: vector<string>
fun construct(parseIn: ref parser, ast_passIn: ref ast_transformation, import_paths_in: vector<string>): *importer {
2015-12-05 07:13:32 -05:00
parse.copy_construct(&parseIn)
ast_pass.copy_construct(&ast_passIn)
2015-12-28 03:34:40 -05:00
name_ast_map.construct()
import_paths.copy_construct(&import_paths_in)
2015-12-05 07:13:32 -05:00
return this
}
fun copy_construct(old: *importer) {
parse.copy_construct(&old->parse)
ast_pass.copy_construct(&old->ast_pass)
2015-12-28 03:34:40 -05:00
name_ast_map.copy_construct(&old->name_ast_map)
import_paths.copy_construct(&old->import_paths)
2015-12-05 07:13:32 -05:00
}
fun operator=(old: ref importer) {
destruct()
copy_construct(&old)
}
fun destruct() {
parse.destruct()
ast_pass.destruct()
2015-12-28 03:34:40 -05:00
name_ast_map.destruct()
import_paths.destruct()
2015-12-05 07:13:32 -05:00
}
2015-12-07 13:43:22 -05:00
fun import(file_name: string): *ast_node {
println("**First Pass**")
var to_ret = import_first_pass(file_name)
println("**Second Pass**")
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>, *ast_node>) ast_pass.second_pass(tree_pair.first, tree_pair.second);)
println("**Third Pass**")
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>, *ast_node>) ast_pass.third_pass(tree_pair.first, tree_pair.second);)
// this needs to be modified to do chaotic iteration on instantiating template classes, based on what I see in the C++ version
println("**Fourth Pass**")
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>, *ast_node>) ast_pass.fourth_pass(tree_pair.first, tree_pair.second);)
name_ast_map.for_each(fun(name: string, tree_pair: pair<*tree<symbol>, *ast_node>) {
print("writing ast for: "); println(name)
write_file(name + ".ast.dot", ast_to_dot(tree_pair.second))
})
return to_ret
}
fun import_first_pass(file_name: string): *ast_node {
2015-12-28 03:34:40 -05:00
if (name_ast_map.contains_key(file_name))
return name_ast_map[file_name].second
2015-12-05 07:13:32 -05:00
print("pre-parse: "); println(file_name)
var file = string()
import_paths.for_each(fun(path: string) {
println(string("Checking ") + path + " for " + file_name)
if (file_exists(path + file_name)) {
println("Found it!")
file = read_file(path + file_name)
return
} else
println("did not find it")
})
var parse_tree = parse.parse_input(file, file_name)
2015-12-05 07:13:32 -05:00
print("post-parse: "); println(file_name)
write_file(file_name + ".parse.dot", syntax_tree_to_dot(parse_tree))
2015-12-05 17:31:11 -05:00
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-first-ast: "); println(file_name)
2015-12-05 07:13:32 -05:00
var ast = ast_pass.first_pass(file_name, parse_tree, this)
print("post-first-ast: "); println(file_name)
2015-12-07 13:43:22 -05:00
return ast
2015-12-05 07:13:32 -05:00
}
2015-12-28 03:34:40 -05:00
fun register(file_name: string, parse_tree: *tree<symbol>, 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)
}
2015-12-05 17:31:11 -05:00
fun trim(parse_tree: *tree<symbol>) {
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("\"var\"", true), parse_tree)
remove_node(symbol("\"fun\"", 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)
2015-12-05 17:31:11 -05:00
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)
2015-12-05 17:31:11 -05:00
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("\"\\|\"", true), parse_tree)
2015-12-05 17:31:11 -05:00
2015-12-05 18:36:35 -05:00
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)
}
2015-12-05 17:31:11 -05:00
fun remove_node(remove: symbol, parse_tree: *tree<symbol>) {
var to_process = queue<*tree<symbol>>()
to_process.push(parse_tree)
while(!to_process.empty()) {
var node = to_process.pop()
for (var i = 0; i < node->children.size; i++;) {
2015-12-07 13:43:22 -05:00
if (!node->children[i] || node->children[i]->data.equal_wo_data(remove)) {
/*
2015-12-07 13:43:22 -05:00
if (!node->children[i])
println("not because null")
else {
print("not because "); println(remove.name)
}
*/
2015-12-05 17:31:11 -05:00
node->children.remove(i)
i--;
} else {
/*println(remove.to_string() + " not equal " + node->children[i]->data.to_string())*/
2015-12-05 17:31:11 -05:00
to_process.push(node->children[i])
}
}
}
}
2015-12-05 18:36:35 -05:00
fun collapse_node(remove: symbol, parse_tree: *tree<symbol>) {
var to_process = queue<*tree<symbol>>()
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])
}
}
}
}
2015-12-05 07:13:32 -05:00
}