More clean up; need to add return type checking pass so that can clean up c_generator more.

This commit is contained in:
Nathan Braswell
2017-10-23 01:08:25 -04:00
parent 6964df5ac8
commit 13f1e9df89
4 changed files with 93 additions and 143 deletions

View File

@@ -10,6 +10,7 @@ import serialize:*
import interpreter:* import interpreter:*
import os:* import os:*
import ast_transformation:* import ast_transformation:*
import importer:*
import adt_lower:* import adt_lower:*
import obj_lower:* import obj_lower:*
import defer_lower:* import defer_lower:*
@@ -138,52 +139,51 @@ fun main(argc: int, argv: **char):int {
var executable_name = string(".").join(kraken_file_name.split('.').slice(0,-2)) var executable_name = string(".").join(kraken_file_name.split('.').slice(0,-2))
if (positional_args.size > 1) if (positional_args.size > 1)
executable_name = positional_args[1] executable_name = positional_args[1]
var importer.construct(parsers, ast_pass, vector(string(), base_dir + "/stdlib/")): importer var name_ast_map = import(kraken_file_name, parsers, ast_pass, vector(string(), base_dir + "/stdlib/"))
importer.import(kraken_file_name)
// Passes // Passes
/*printlnerr("Counting Nodes")*/ /*printlnerr("Counting Nodes")*/
/*node_counter(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/ /*node_counter(&name_ast_map, &ast_pass.ast_to_syntax)*/
printlnerr("Lowering ADTs") printlnerr("Lowering ADTs")
adt_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) adt_lower(&name_ast_map, &ast_pass.ast_to_syntax)
/*printlnerr("Counting Nodes")*/ /*printlnerr("Counting Nodes")*/
/*node_counter(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/ /*node_counter(&name_ast_map, &ast_pass.ast_to_syntax)*/
printlnerr("Lowering Objects") printlnerr("Lowering Objects")
obj_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) obj_lower(&name_ast_map, &ast_pass.ast_to_syntax)
/*printlnerr("Counting Nodes")*/ /*printlnerr("Counting Nodes")*/
/*node_counter(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/ /*node_counter(&name_ast_map, &ast_pass.ast_to_syntax)*/
printlnerr("Lowering Defer") printlnerr("Lowering Defer")
defer_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) defer_lower(&name_ast_map, &ast_pass.ast_to_syntax)
/*printlnerr("Counting Nodes")*/ /*printlnerr("Counting Nodes")*/
/*node_counter(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/ /*node_counter(&name_ast_map, &ast_pass.ast_to_syntax)*/
// Should come after lowering of ADTs and before lowering of Refs // Should come after lowering of ADTs and before lowering of Refs
printlnerr("Lowering Function Values (Lambdas, etc)") printlnerr("Lowering Function Values (Lambdas, etc)")
function_value_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) function_value_lower(&name_ast_map, &ast_pass.ast_to_syntax)
/*printlnerr("Counting Nodes")*/ /*printlnerr("Counting Nodes")*/
/*node_counter(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/ /*node_counter(&name_ast_map, &ast_pass.ast_to_syntax)*/
printlnerr("Lowering Ref") printlnerr("Lowering Ref")
ref_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) ref_lower(&name_ast_map, &ast_pass.ast_to_syntax)
/*printlnerr("Counting Nodes")*/ /*printlnerr("Counting Nodes")*/
/*node_counter(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/ /*node_counter(&name_ast_map, &ast_pass.ast_to_syntax)*/
// Lowers #ctce and the current #ctce_pass // Lowers #ctce and the current #ctce_pass
printlnerr("Lowering CTCE") printlnerr("Lowering CTCE")
ctce_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) ctce_lower(&name_ast_map, &ast_pass.ast_to_syntax)
/*printlnerr("Counting Nodes")*/ /*printlnerr("Counting Nodes")*/
/*node_counter(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)*/ /*node_counter(&name_ast_map, &ast_pass.ast_to_syntax)*/
// Makes sure that & always takes reference to a variable // Makes sure that & always takes reference to a variable
printlnerr("Lowering & to always have variable") printlnerr("Lowering & to always have variable")
address_of_ensure_variable_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) address_of_ensure_variable_lower(&name_ast_map, &ast_pass.ast_to_syntax)
if (interpret_instead) { if (interpret_instead) {
printlnerr("Interpreting!") printlnerr("Interpreting!")
call_main(importer.name_ast_map) call_main(name_ast_map)
} else { } else {
if (line_ctrl) { if (line_ctrl) {
printlnerr("running C-specific passes") printlnerr("running C-specific passes")
printlnerr("running #line") printlnerr("running #line")
c_line_control(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) c_line_control(&name_ast_map, &ast_pass.ast_to_syntax)
} }
printlnerr("Generating C") printlnerr("Generating C")
var c_generator.construct(): c_generator var c_generator.construct(): c_generator
var c_output_pair = c_generator.generate_c(importer.name_ast_map, importer.ast_pass.ast_to_syntax) var c_output_pair = c_generator.generate_c(name_ast_map, ast_pass.ast_to_syntax)
var kraken_c_output_name = kraken_file_name + ".c" var kraken_c_output_name = kraken_file_name + ".c"
write_file(kraken_c_output_name, c_output_pair.first) write_file(kraken_c_output_name, c_output_pair.first)
if (compile_c) { if (compile_c) {

View File

@@ -44,7 +44,7 @@ obj ast_transformation (Object) {
fourth_pass_worklist.destruct() fourth_pass_worklist.destruct()
} }
// first pass defines all type_defs (objects and aliases), ADTs, and top-level if-comps/passthroughs // first pass defines all type_defs (objects and aliases), ADTs, and top-level if-comps/passthroughs
fun first_pass(file_name: string, parse_tree: *tree<symbol>, importer: *importer): pair<*ast_node, vector<*ast_node>> { fun first_pass(file_name: string, parse_tree: *tree<symbol>): pair<*ast_node, vector<*ast_node>> {
var translation_unit = ast_translation_unit_ptr(file_name) var translation_unit = ast_translation_unit_ptr(file_name)
parse_tree->children.for_each(fun(child: *tree<symbol>) { parse_tree->children.for_each(fun(child: *tree<symbol>) {
if (child->data.name == "type_def") { if (child->data.name == "type_def") {

View File

@@ -165,7 +165,7 @@ obj c_generator (Object) {
if (!backing.is_extern) if (!backing.is_extern)
function_definitions += prototype_and_header.second function_definitions += prototype_and_header.second
if (backing.body_statement) { if (backing.body_statement) {
function_definitions += " {\n" + generate(backing.body_statement, enclosing_object, child, false) function_definitions += " {\n" + generate(backing.body_statement, enclosing_object, child)
function_definitions += ";\n}\n" function_definitions += ";\n}\n"
} else if (!backing.is_extern) { } else if (!backing.is_extern) {
error("Empty function statement and not extern - no ADTs anymore!") error("Empty function statement and not extern - no ADTs anymore!")
@@ -190,7 +190,7 @@ obj c_generator (Object) {
tree_pair.second->translation_unit.children.for_each(fun(child: *ast_node) { tree_pair.second->translation_unit.children.for_each(fun(child: *ast_node) {
match (*child) { match (*child) {
ast_node::if_comp(backing) error("if_comp not currently supported") ast_node::if_comp(backing) error("if_comp not currently supported")
ast_node::simple_passthrough(backing) error("simple_passthrough deprecated") ast_node::simple_passthrough(backing) error("simple_passthrough removed")
ast_node::declaration_statement(backing) variable_declarations += generate_declaration_statement(child, null<ast_node>(), null<ast_node>()) + ";\n" // false - don't do defer ast_node::declaration_statement(backing) variable_declarations += generate_declaration_statement(child, null<ast_node>(), null<ast_node>()) + ";\n" // false - don't do defer
// shouldn't need to do anything with return, as the intrinsic should be something like link // shouldn't need to do anything with return, as the intrinsic should be something like link
ast_node::compiler_intrinsic(backing) generate_compiler_intrinsic(child) ast_node::compiler_intrinsic(backing) generate_compiler_intrinsic(child)
@@ -221,9 +221,7 @@ obj c_generator (Object) {
type_poset.add_relationship(child, var_type->type_def) type_poset.add_relationship(child, var_type->type_def)
}) })
} }
ast_node::adt_def(backing) { ast_node::adt_def(backing) error("ADT remaining!")
error("ADT remaining!")
}
} }
}) })
}) })
@@ -257,57 +255,48 @@ obj c_generator (Object) {
fun generate_declaration_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string { fun generate_declaration_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
var identifier = node->declaration_statement.identifier var identifier = node->declaration_statement.identifier
var ident_type = identifier->identifier.type var ident_type = identifier->identifier.type
// we do the declaration in the pre now so that we can take it's address to close over it for things like recursive closures
// we only make it first if it's a function type though, so that global levels still work
var to_ret = type_to_c(identifier->identifier.type) + " " + get_name(identifier) var to_ret = type_to_c(identifier->identifier.type) + " " + get_name(identifier)
if (identifier->identifier.is_extern) if (identifier->identifier.is_extern)
to_ret = "extern " + to_ret to_ret = "extern " + to_ret
if (node->declaration_statement.expression) { if (node->declaration_statement.expression) {
if (ident_type->is_function()) { // in case of recursive closures, make sure variable is declared before assignment
to_ret += ";\n" to_ret += ";\n"
to_ret += get_name(identifier) + " = " + generate(node->declaration_statement.expression, enclosing_object, enclosing_func, false) to_ret += get_name(identifier) + " = " + generate(node->declaration_statement.expression, enclosing_object, enclosing_func)
} else {
// some shifting around to get it to work in all cases
// what cases?
to_ret += " = " + generate(node->declaration_statement.expression, enclosing_object, enclosing_func, false)
}
} }
if (node->declaration_statement.init_method_call) { if (node->declaration_statement.init_method_call) {
to_ret += ";\n" to_ret += ";\n"
to_ret += generate(node->declaration_statement.init_method_call, enclosing_object, enclosing_func, false) to_ret += generate(node->declaration_statement.init_method_call, enclosing_object, enclosing_func)
} }
return to_ret return to_ret
} }
fun generate_assignment_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string { fun generate_assignment_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
return generate(node->assignment_statement.to, enclosing_object, enclosing_func, false) + " = " + generate(node->assignment_statement.from, enclosing_object, enclosing_func, false) return generate(node->assignment_statement.to, enclosing_object, enclosing_func) + " = " + generate(node->assignment_statement.from, enclosing_object, enclosing_func)
} }
fun generate_if_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string { fun generate_if_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
var if_str = "if (" + generate(node->if_statement.condition, enclosing_object, enclosing_func, false) + ") {\n" + generate(node->if_statement.then_part, enclosing_object, enclosing_func, false) + "}" var if_str = "if (" + generate(node->if_statement.condition, enclosing_object, enclosing_func) + ") {\n" + generate(node->if_statement.then_part, enclosing_object, enclosing_func) + "}"
if (node->if_statement.else_part) if (node->if_statement.else_part)
if_str += " else {\n" + generate(node->if_statement.else_part, enclosing_object, enclosing_func, false) + "}" if_str += " else {\n" + generate(node->if_statement.else_part, enclosing_object, enclosing_func) + "}"
return if_str + "\n" return if_str + "\n"
} }
fun generate_while_loop(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string { fun generate_while_loop(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
return "while (" + generate(node->while_loop.condition, enclosing_object, enclosing_func, false) + ")\n" + generate(node->while_loop.statement, enclosing_object, enclosing_func, false) return "while (" + generate(node->while_loop.condition, enclosing_object, enclosing_func) + ")\n" + generate(node->while_loop.statement, enclosing_object, enclosing_func)
} }
fun generate_for_loop(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string { fun generate_for_loop(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
// gotta take off last semicolon
var init = string(";") var init = string(";")
if (node->for_loop.init) if (node->for_loop.init)
init = generate(node->for_loop.init, enclosing_object, enclosing_func, false) init = generate(node->for_loop.init, enclosing_object, enclosing_func)
var cond = string(";") var cond = string(";")
if (node->for_loop.condition) if (node->for_loop.condition)
cond = generate(node->for_loop.condition, enclosing_object, enclosing_func, false) cond = generate(node->for_loop.condition, enclosing_object, enclosing_func)
// gotta take off last semicolon
var update = string() var update = string()
if (node->for_loop.update) { if (node->for_loop.update) {
update = generate(node->for_loop.update, enclosing_object, enclosing_func, false) update = generate(node->for_loop.update, enclosing_object, enclosing_func)
if (update.length() < 2) if (update.length() < 2)
error("update less than 2! Likely legal, but need easy compiler mod here") error("update less than 2! Likely legal, but need easy compiler mod here")
update = update.slice(0,-2) update = update.slice(0,-2)
} }
var to_ret = string("for (") + init + cond + "; " + update + ")\n" + return "for (" + init + cond + "; " + update + ")\n" + generate(node->for_loop.body, enclosing_object, enclosing_func)
generate(node->for_loop.body, enclosing_object, enclosing_func, false)
return to_ret
} }
fun generate_identifier(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string { fun generate_identifier(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
if (get_ast_type(node)->is_ref) if (get_ast_type(node)->is_ref)
@@ -326,7 +315,7 @@ obj c_generator (Object) {
error("still exsisting ref in return") error("still exsisting ref in return")
if (return_value) if (return_value)
return "return " + generate(return_value, enclosing_object, enclosing_func, false) return "return " + generate(return_value, enclosing_object, enclosing_func)
return string("return") return string("return")
} }
fun generate_branching_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string { fun generate_branching_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
@@ -342,7 +331,7 @@ obj c_generator (Object) {
error("remaining match") error("remaining match")
} }
fun generate_cast(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string { fun generate_cast(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
return "((" + type_to_c(node->cast.to_type) + ")(" + generate(node->cast.value, enclosing_object, enclosing_func, false) + "))" return "((" + type_to_c(node->cast.to_type) + ")(" + generate(node->cast.value, enclosing_object, enclosing_func) + "))"
} }
fun generate_value(node: *ast_node): string { fun generate_value(node: *ast_node): string {
var value = node->value.string_value var value = node->value.string_value
@@ -370,14 +359,14 @@ obj c_generator (Object) {
} }
fun generate_code_block(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string { fun generate_code_block(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
var to_ret = string("{\n") var to_ret = string("{\n")
node->code_block.children.for_each(fun(child: *ast_node) to_ret += generate(child, enclosing_object, enclosing_func, false) + ";\n";) node->code_block.children.for_each(fun(child: *ast_node) to_ret += generate(child, enclosing_object, enclosing_func) + ";\n";)
return to_ret + "}" return to_ret + "}"
} }
// this generates the function as a value, not the actual function // this generates the function as a value, not the actual function
fun generate_function(node: *ast_node): string { fun generate_function(node: *ast_node): string {
return get_name(node) return get_name(node)
} }
fun generate_function_call(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, need_variable: bool): string { fun generate_function_call(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
var func_name = string() var func_name = string()
var call_string = string() var call_string = string()
var func_return_type = get_ast_type(node) var func_return_type = get_ast_type(node)
@@ -390,9 +379,9 @@ obj c_generator (Object) {
if (node->function_call.func->function_call.func->function.name == ".") if (node->function_call.func->function_call.func->function.name == ".")
call_string += "&" call_string += "&"
call_string += generate(node->function_call.func->function_call.parameters[0], enclosing_object, enclosing_func, true) call_string += generate(node->function_call.func->function_call.parameters[0], enclosing_object, enclosing_func)
} else { } else {
func_name = generate(node->function_call.func, enclosing_object, enclosing_func, false) func_name = generate(node->function_call.func, enclosing_object, enclosing_func)
// handle method call from inside method of same object // handle method call from inside method of same object
if (enclosing_object && method_in_object(node->function_call.func, enclosing_object)) { if (enclosing_object && method_in_object(node->function_call.func, enclosing_object)) {
@@ -406,25 +395,22 @@ obj c_generator (Object) {
|| func_name == "==" || func_name == "!=" || func_name == "%" || func_name == "^" || func_name == "==" || func_name == "!=" || func_name == "%" || func_name == "^"
|| func_name == "|" || func_name == "&" || func_name == ">>" || func_name == "<<" || func_name == "|" || func_name == "&" || func_name == ">>" || func_name == "<<"
)) ))
return "(" + generate(parameters[0], enclosing_object, enclosing_func, false) + func_name + generate(parameters[1], enclosing_object, enclosing_func, false) + ")" return "(" + generate(parameters[0], enclosing_object, enclosing_func) + func_name + generate(parameters[1], enclosing_object, enclosing_func) + ")"
if ( parameters.size == 2 && (func_name == "||" || func_name == "&&")) { if ( parameters.size == 2 && (func_name == "||" || func_name == "&&"))
error("Remaining || or &&") error("Remaining || or &&")
}
// don't propegate enclosing function down right of access // don't propegate enclosing function down right of access
// XXX what about enclosing object? should it be the thing on the left? // XXX what about enclosing object? should it be the thing on the left?
if (func_name == "." || func_name == "->") { if (func_name == "." || func_name == "->")
return "(" + generate(parameters[0], enclosing_object, enclosing_func, false) + func_name + generate(parameters[1], null<ast_node>(), null<ast_node>(), false) + ")" return "(" + generate(parameters[0], enclosing_object, enclosing_func) + func_name + generate(parameters[1], null<ast_node>(), null<ast_node>()) + ")"
}
if (func_name == "[]") if (func_name == "[]")
return "(" + generate(parameters[0], enclosing_object, enclosing_func, false) + "[" + generate(parameters[1], enclosing_object, enclosing_func, false) + "])" return "(" + generate(parameters[0], enclosing_object, enclosing_func) + "[" + generate(parameters[1], enclosing_object, enclosing_func) + "])"
// the post ones need to be post-ed specifically, and take the p off // the post ones need to be post-ed specifically, and take the p off
if (func_name == "++p" || func_name == "--p") if (func_name == "++p" || func_name == "--p")
return "(" + generate(parameters[0], enclosing_object, enclosing_func, false) + ")" + func_name.slice(0,-2) return "(" + generate(parameters[0], enclosing_object, enclosing_func) + ")" + func_name.slice(0,-2)
// So we don't end up copy_constructing etc, we just handle the unary operators right here // So we don't end up copy_constructing etc, we just handle the unary operators right here
// note also the passing down need_variable for &
if (func_name == "*" || func_name == "&") if (func_name == "*" || func_name == "&")
return "(" + func_name + generate(parameters[0], enclosing_object, enclosing_func, func_name == "&") + ")" return "(" + func_name + generate(parameters[0], enclosing_object, enclosing_func) + ")"
var func_type = get_ast_type(node->function_call.func) var func_type = get_ast_type(node->function_call.func)
// regular parameter generation // regular parameter generation
@@ -443,8 +429,7 @@ obj c_generator (Object) {
error(string("problem :") + (node->function_call.func) cast int + " " + get_fully_scoped_name(node->function_call.func) + ": still ref in function calling, func_type: " + func_type->to_string()) error(string("problem :") + (node->function_call.func) cast int + " " + get_fully_scoped_name(node->function_call.func) + ": still ref in function calling, func_type: " + func_type->to_string())
} }
var param_type = get_ast_type(param) call_string += generate(param, enclosing_object, enclosing_func)
call_string += generate(param, enclosing_object, enclosing_func, false)
} }
call_string = func_name + "(" + call_string + ")" call_string = func_name + "(" + call_string + ")"
return call_string return call_string
@@ -466,7 +451,7 @@ obj c_generator (Object) {
} }
// for now, anyway // for now, anyway
fun generate(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, need_variable: bool): string { fun generate(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): string {
if (!node) return string("/*NULL*/") if (!node) return string("/*NULL*/")
match (*node) { match (*node) {
ast_node::declaration_statement(backing) return generate_declaration_statement(node, enclosing_object, enclosing_func) ast_node::declaration_statement(backing) return generate_declaration_statement(node, enclosing_object, enclosing_func)
@@ -475,7 +460,7 @@ obj c_generator (Object) {
ast_node::while_loop(backing) return generate_while_loop(node, enclosing_object, enclosing_func) ast_node::while_loop(backing) return generate_while_loop(node, enclosing_object, enclosing_func)
ast_node::for_loop(backing) return generate_for_loop(node, enclosing_object, enclosing_func) ast_node::for_loop(backing) return generate_for_loop(node, enclosing_object, enclosing_func)
ast_node::function(backing) return generate_function(node) ast_node::function(backing) return generate_function(node)
ast_node::function_call(backing) return generate_function_call(node, enclosing_object, enclosing_func, need_variable) ast_node::function_call(backing) return generate_function_call(node, enclosing_object, enclosing_func)
ast_node::compiler_intrinsic(backing) return generate_compiler_intrinsic(node) ast_node::compiler_intrinsic(backing) return generate_compiler_intrinsic(node)
ast_node::code_block(backing) return generate_code_block(node, enclosing_object, enclosing_func) ast_node::code_block(backing) return generate_code_block(node, enclosing_object, enclosing_func)
ast_node::return_statement(backing) return generate_return_statement(node, enclosing_object, enclosing_func) ast_node::return_statement(backing) return generate_return_statement(node, enclosing_object, enclosing_func)

View File

@@ -11,35 +11,8 @@ import ast_nodes:*
import ast_transformation:* import ast_transformation:*
import parser:* import parser:*
obj importer (Object) { fun import(file_name: string, parsers: ref vector<parser>, ast_pass: ref ast_transformation, import_paths: vector<string>): map<string, pair<*tree<symbol>,*ast_node>> {
var parsers: vector<parser> var name_ast_map = map<string, pair<*tree<symbol>,*ast_node>>()
var ast_pass: ast_transformation
var name_ast_map: map<string, pair<*tree<symbol>,*ast_node>>
var import_paths: vector<string>
fun construct(parsersIn: ref vector<parser>, ast_passIn: ref ast_transformation, import_paths_in: vector<string>): *importer {
parsers.copy_construct(&parsersIn)
ast_pass.copy_construct(&ast_passIn)
name_ast_map.construct()
import_paths.copy_construct(&import_paths_in)
return this
}
fun copy_construct(old: *importer) {
parsers.copy_construct(&old->parsers)
ast_pass.copy_construct(&old->ast_pass)
name_ast_map.copy_construct(&old->name_ast_map)
import_paths.copy_construct(&old->import_paths)
}
fun operator=(old: ref importer) {
destruct()
copy_construct(&old)
}
fun destruct() {
parsers.destruct()
ast_pass.destruct()
name_ast_map.destruct()
import_paths.destruct()
}
fun import(file_name: string) {
// lambda closes over our fix-up list // lambda closes over our fix-up list
var imports_to_fix = vector<*ast_node>() var imports_to_fix = vector<*ast_node>()
var import_first_pass = fun(file_name_idx: pair<string,int>) { var import_first_pass = fun(file_name_idx: pair<string,int>) {
@@ -54,7 +27,7 @@ obj importer (Object) {
printerr(file_name + ", ") printerr(file_name + ", ")
var parse_tree = parsers[file_name_idx.second].parse_input(file, file_name) var parse_tree = parsers[file_name_idx.second].parse_input(file, file_name)
trim(parse_tree) trim(parse_tree)
var ast_and_imports = ast_pass.first_pass(file_name, parse_tree, this) var ast_and_imports = ast_pass.first_pass(file_name, parse_tree)
imports_to_fix += ast_and_imports.second imports_to_fix += ast_and_imports.second
name_ast_map[file_name] = make_pair(parse_tree, ast_and_imports.first) name_ast_map[file_name] = make_pair(parse_tree, ast_and_imports.first)
} }
@@ -77,10 +50,10 @@ obj importer (Object) {
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);) 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);)
printlnerr("**Third Pass**") printlnerr("**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);) 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
printlnerr("**Fourth Pass**") printlnerr("**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>) ast_pass.fourth_pass(tree_pair.first, tree_pair.second);)
}
return name_ast_map
} }
fun trim(parse_tree: *tree<symbol>): *tree<symbol> { fun trim(parse_tree: *tree<symbol>): *tree<symbol> {
@@ -134,17 +107,9 @@ fun remove_node(remove: symbol, parse_tree: *tree<symbol>) {
var node = to_process.pop() var node = to_process.pop()
for (var i = 0; i < node->children.size; i++;) { 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] || 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) node->children.remove(i)
i--; i--;
} else { } else {
/*println(remove.to_string() + " not equal " + node->children[i]->data.to_string())*/
to_process.push(node->children[i]) to_process.push(node->children[i])
} }
} }