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:
@@ -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
|
||||
|
||||
@@ -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
49
stdlib/type.krak
Normal 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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user