More skeleton, including a trivial second_pass_function, fix a bug with ADTs that have members with the same name (may still be a problem if the ADT itself has the same name)

This commit is contained in:
Nathan Braswell
2016-01-05 21:40:00 -05:00
parent 79065c032f
commit f29fdcd463
6 changed files with 121 additions and 18 deletions

View File

@@ -9,6 +9,7 @@ import mem:*
import io:*
import importer:*
import ast_nodes:*
import type:*
/*Importer * importer;*/
/*NodeTree<ASTData>* builtin_trans_unit; // the top scope for language level stuff*/
@@ -29,7 +30,7 @@ obj ast_transformation (Object) {
}
fun destruct() {
}
// first pass defines all type_defs (objects and aliases), ADTs, and top-level if/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): *ast_node {
var translation_unit = ast_translation_unit_ptr(file_name)
importer->register(file_name, parse_tree, translation_unit)
@@ -48,12 +49,12 @@ obj ast_transformation (Object) {
add_to_scope("~enclosing_scope", translation_unit, adt_def_node)
add_to_scope(name, adt_def_node, translation_unit)
} else if (child->data.name == "if_comp") {
var if_comp_node = transform(child, translation_unit)
var if_comp_node = transform_if_comp(child, translation_unit)
translation_unit->translation_unit.children.add(if_comp_node)
}
})
// now do all inports (done second so that if it imports this translation_unit,
// now do all imports (done second so that if it imports this translation_unit,
// this one already has all its types defined
parse_tree->children.for_each(fun(child: *tree<symbol>) {
if (child->data.name == "import") {
@@ -62,13 +63,38 @@ obj ast_transformation (Object) {
var import_node = ast_import_ptr(name)
translation_unit->translation_unit.children.add(import_node)
add_to_scope("~enclosing_scope", translation_unit, import_node)
var outside_translation_unit = importer->import(name + ".krak")
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<symbol>):string return concat_symbol_tree(ident);))
}
})
return translation_unit
}
// defines inside of objects + ADTs, outside declaration statements, and function prototypes
fun second_pass(parse_tree: *tree<symbol>, translation_unit: *ast_node) {
println(string("Second Pass for ") + translation_unit->translation_unit.name)
parse_tree->children.for_each(fun(child: *tree<symbol>) {
if (child->data.name == "type_def") {
// second pass class stuff
// class insides calls into second_pass_declaration and second_pass_function...
} else if (child->data.name == "adt_def") {
// set up options and all the generated functions (operator==, operator!=, copy_construct, operator=, destruct)
} else if (child->data.name == "function") {
translation_unit->translation_unit.children.add(second_pass_function(child, translation_unit, map<string, *type>()))
} else if (child->data.name == "declaration_statement") {
// second pass declaration can actually just call a normal transform (but maybe should be it's own method to do so because typedef has to do it too?)...
}
})
}
fun second_pass_function(parse_tree: *tree<symbol>, translation_unit: *ast_node, template_replacements: map<string, *type>): *ast_node {
return ast_function_ptr()
}
fun third_pass(parse_tree: *tree<symbol>, translation_unit: *ast_node) {
println(string("Third Pass for ") + translation_unit->translation_unit.name)
}
fun fourth_pass(parse_tree: *tree<symbol>, translation_unit: *ast_node) {
println(string("Fourth Pass for ") + translation_unit->translation_unit.name)
}
/*NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::vector<Type> types, bool limitToFunction, std::map<std::string, Type*> templateTypeReplacements) {*/
fun transform(node: *tree<symbol>, scope: *ast_node): *ast_node {
var name = node->data.name

View File

@@ -36,6 +36,24 @@ obj importer (Object) {
name_ast_map.destruct()
}
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 {
if (name_ast_map.contains_key(file_name))
return name_ast_map[file_name].second
@@ -47,10 +65,9 @@ obj importer (Object) {
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)
print("pre-first-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))
print("post-first-ast: "); println(file_name)
return ast
}
fun register(file_name: string, parse_tree: *tree<symbol>, translation_unit: *ast_node) {

49
stdlib/type.krak Normal file
View File

@@ -0,0 +1,49 @@
// hmm, like the ast_node, this is another candadate for being fully an ADT
// one issue is that there are properties shared between most of the options (indirection, say)
adt base_type {
none,
template,
template_type,
void_return,
boolean,
character,
integer,
floating,
double_precision,
function
}
fun type(): type {
var to_ret.construct(): type
return to_ret
}
fun type(base: base_type): type {
var to_ret.construct(base): type
return to_ret
}
obj type (Object) {
var base: base_type
fun construct(): *type {
base.copy_construct(&base_type::none())
return this
}
fun construct(base_in: base_type): *type {
base.copy_construct(&base_in)
return this
}
fun copy_construct(old: *type) {
base = old->base
}
fun operator=(other: ref type) {
destruct()
copy_construct(&other)
}
fun destruct() {
base.destruct()
}
}