2015-12-01 16:19:44 -05:00
import symbol:*
import tree:*
import vector:*
import stack:*
import map:*
import util:*
import string:*
import mem:*
import io:*
2015-12-05 07:13:32 -05:00
import importer:*
2016-01-04 00:38:59 -05:00
import ast_nodes:*
2016-01-05 21:40:00 -05:00
import type:*
2015-12-05 07:13:32 -05:00
/*Importer * importer;*/
/*NodeTree<ASTData>* builtin_trans_unit; // the top scope for language level stuff*/
/*std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelReservedWords;*/
/*std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelOperators;*/
/*std::map<NodeTree<ASTData>*, NodeTree<ASTData>*> this_map; // used to map implicit "this" variables to their type*/
/*NodeTree<ASTData>* topScope; //maintained for templates that need to add themselves to the top scope no matter where they are instantiated*/
/*int lambdaID = 0;*/
2015-12-01 16:19:44 -05:00
obj ast_transformation (Object) {
fun construct(): *ast_transformation {
return this
}
fun copy_construct(old: *ast_transformation) {
}
fun operator=(old: ref ast_transformation) {
destruct()
copy_construct(&old)
}
fun destruct() {
}
2016-01-05 21:40:00 -05:00
// first pass defines all type_defs (objects and aliases), ADTs, and top-level if-comps/passthroughs
2015-12-05 07:13:32 -05:00
fun first_pass(file_name: string, parse_tree: *tree<symbol>, importer: *importer): *ast_node {
2015-12-06 18:44:04 -05:00
var translation_unit = ast_translation_unit_ptr(file_name)
2015-12-05 07:13:32 -05:00
importer->register(file_name, parse_tree, translation_unit)
2015-12-06 15:15:33 -05:00
parse_tree->children.for_each(fun(child: *tree<symbol>) {
if (child->data.name == "type_def") {
var name = concat_symbol_tree(get_node("identifier", child))
2015-12-06 18:44:04 -05:00
var type_def_node = ast_type_def_ptr(name)
2015-12-06 15:15:33 -05:00
translation_unit->translation_unit.children.add(type_def_node)
2015-12-07 13:43:22 -05:00
add_to_scope("~enclosing_scope", translation_unit, type_def_node)
add_to_scope(name, type_def_node, translation_unit)
2015-12-06 18:44:04 -05:00
// set up type - self-referential, traits, template, etc
} else if (child->data.name == "adt_def") {
var name = concat_symbol_tree(get_node("identifier", child))
var adt_def_node = ast_adt_def_ptr(name)
translation_unit->translation_unit.children.add(adt_def_node)
2015-12-07 13:43:22 -05:00
add_to_scope("~enclosing_scope", translation_unit, adt_def_node)
add_to_scope(name, adt_def_node, translation_unit)
2015-12-06 18:44:04 -05:00
} else if (child->data.name == "if_comp") {
2016-01-05 21:40:00 -05:00
var if_comp_node = transform_if_comp(child, translation_unit)
2015-12-06 18:44:04 -05:00
translation_unit->translation_unit.children.add(if_comp_node)
}
})
2016-01-05 21:40:00 -05:00
// now do all imports (done second so that if it imports this translation_unit,
2015-12-06 18:44:04 -05:00
// this one already has all its types defined
parse_tree->children.for_each(fun(child: *tree<symbol>) {
if (child->data.name == "import") {
2015-12-28 03:34:40 -05:00
var import_identifier_children = get_nodes("identifier", child)
var name = concat_symbol_tree(import_identifier_children[0])
2015-12-06 18:44:04 -05:00
var import_node = ast_import_ptr(name)
translation_unit->translation_unit.children.add(import_node)
2015-12-07 13:43:22 -05:00
add_to_scope("~enclosing_scope", translation_unit, import_node)
2016-01-05 21:40:00 -05:00
var outside_translation_unit = importer->import_first_pass(name + ".krak")
2015-12-07 13:43:22 -05:00
add_to_scope(name, outside_translation_unit, translation_unit)
2015-12-28 03:34:40 -05:00
import_node->import.imported = from_vector(import_identifier_children.slice(1,-1).map(fun(ident: *tree<symbol>):string return concat_symbol_tree(ident);))
2015-12-06 15:15:33 -05:00
}
})
2015-12-05 07:13:32 -05:00
return translation_unit
2015-12-01 16:19:44 -05:00
}
2016-01-05 21:40:00 -05:00
// 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)
}
2015-12-28 03:34:40 -05:00
/*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
if (name == "identifier" || name == "scoped_identifier") {
2016-01-01 23:42:00 -05:00
return transform_identifier(node, scope)
2015-12-28 03:34:40 -05:00
} else if (name == "code_block") {
2016-01-01 23:42:00 -05:00
return transform_code_block(node, scope)
} else if (name == "if_comp") {
return transform_if_comp(node, scope)
} else if (name == "simple_passthrough") {
return transform_simple_passthrough(node, scope)
2016-01-04 02:00:06 -05:00
} else if (name == "statement") {
return transform_statement(node, scope)
2015-12-28 03:34:40 -05:00
}
print("FAILED TO TRANSFORM: "); println(concat_symbol_tree(node))
return null<ast_node>()
}
fun transform_all(nodes: vector<*tree<symbol>>, scope: *ast_node): vector<*ast_node> {
return nodes.map(fun(node: *tree<symbol>): *ast_node return transform(node, scope);)
}
2016-01-01 23:42:00 -05:00
fun transform_identifier(node: *tree<symbol>, scope: *ast_node): *ast_node {
// for identifier we have to do scope lookup, etc, and maybe limit to function
var name = concat_symbol_tree(node)
return ast_identifier_ptr(name)
}
fun transform_code_block(node: *tree<symbol>, scope: *ast_node): *ast_node {
var new_block = ast_code_block_ptr()
add_to_scope("~enclosing_scope", scope, new_block)
new_block->code_block.children = transform_all(node->children, new_block)
return new_block
}
fun transform_if_comp(node: *tree<symbol>, scope: *ast_node): *ast_node {
var new_if_comp = ast_if_comp_ptr()
2016-01-02 01:43:41 -05:00
new_if_comp->if_comp.wanted_generator = concat_symbol_tree(get_node("identifier", node))
2016-01-04 00:38:59 -05:00
new_if_comp->if_comp.statement = transform_statement(get_node("statement", node), scope)
2016-01-01 23:42:00 -05:00
return new_if_comp
}
fun transform_simple_passthrough(node: *tree<symbol>, scope: *ast_node): *ast_node {
var new_passthrough = ast_simple_passthrough_ptr()
// setup passthrough params and string
2016-01-04 02:00:06 -05:00
new_passthrough->simple_passthrough.passthrough_str = concat_symbol_tree(get_node("triple_quoted_string", node)).slice(3,-4)
2016-01-01 23:42:00 -05:00
return new_passthrough
}
2016-01-04 00:38:59 -05:00
fun transform_statement(node: *tree<symbol>, scope: *ast_node): *ast_node {
var new_statement = ast_statement_ptr()
new_statement->statement.child = transform(node->children[0], scope)
return new_statement
}
2015-12-01 16:19:44 -05:00
}
2015-12-06 15:15:33 -05:00
fun concat_symbol_tree(node: *tree<symbol>): string {
var str.construct(): string
if (node->data.data != "no_value")
str += node->data.data
node->children.for_each(fun(child: *tree<symbol>) str += concat_symbol_tree(child);)
return str
}
fun get_node(lookup: *char, parent: *tree<symbol>): *tree<symbol> {
return get_node(string(lookup), parent)
}
fun get_node(lookup: string, parent: *tree<symbol>): *tree<symbol> {
var results = get_nodes(lookup, parent)
if (results.size > 1)
println("too many results!")
if (results.size)
return results[0]
return null<tree<symbol>>()
}
2015-12-28 03:34:40 -05:00
fun get_nodes(lookup: *char, parent: *tree<symbol>): vector<*tree<symbol>> {
return get_nodes(string(lookup), parent)
}
2015-12-06 15:15:33 -05:00
fun get_nodes(lookup: string, parent: *tree<symbol>): vector<*tree<symbol>> {
return parent->children.filter(fun(node: *tree<symbol>):bool return node->data.name == lookup;)
}
2015-12-07 13:43:22 -05:00
fun add_to_scope(name: *char, to_add: *ast_node, add_to: *ast_node) {
add_to_scope(string(name), to_add, add_to)
}
fun add_to_scope(name: string, to_add: *ast_node, add_to: *ast_node) {
var add_to_map = get_ast_scope(add_to)
if (add_to_map->contains_key(name))
(*add_to_map)[name].add(to_add)
else
add_to_map->set(name, vector(to_add))
}
2015-12-01 16:19:44 -05:00