Files
kraken/stdlib/ast_transformation.krak

112 lines
4.8 KiB
Plaintext
Raw Normal View History

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:*
import ast_node:*
/*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;*/
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() {
}
2015-12-06 15:15:33 -05:00
// first pass defines all type_defs (objects and aliases), ADTs, and top-level if/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
// add to scope, the reverse
// 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
// add to scope, the reverse
} else if (child->data.name == "if_comp") {
var if_comp_node = ast_if_comp_ptr()
translation_unit->translation_unit.children.add(if_comp_node)
2015-12-07 13:43:22 -05:00
add_to_scope("~enclosing_scope", translation_unit, if_comp_node)
2015-12-06 18:44:04 -05:00
// add parent to scope?
// do children...
}
})
// now do all inports (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") {
var name = concat_symbol_tree(get_node("identifier", child))
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)
var outside_translation_unit = importer->import(name + ".krak")
add_to_scope(name, outside_translation_unit, translation_unit)
2015-12-06 18:44:04 -05:00
// call out to importer
// go through what is imported - *, or individual names
// for names undefined right now (i.e. not of a type), leave an empty vector?
2015-12-06 15:15:33 -05:00
}
})
2015-12-05 07:13:32 -05:00
return translation_unit
}
}
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>>()
}
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))
}