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

@@ -56,7 +56,7 @@ class Type {
std::set<std::string> traits;
std::vector<Type*> parameterTypes;
Type *returnType;
bool is_reference;;
bool is_reference;
private:
int indirection;
};

View File

@@ -76,11 +76,13 @@ std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
// if this is not a plain no-data adt member (so if it is a primitive or doesn't have a reference back to)
// wait a sec, this is easier
if ( child->getDataRef()->valueType->typeDefinition != from)
structString += tabs() + ValueTypeToCType(child->getDataRef()->valueType, child->getDataRef()->symbol.getName()) + "; /* adt data member */\n";
structString += tabs() + ValueTypeToCType(child->getDataRef()->valueType, prefixIfNeeded(scopePrefix(child), child->getDataRef()->symbol.getName())) + "; /* adt data member */\n";
} else {
structString += tabs() + generate(child, nullptr).oneString() + "\n";
}
enumString += tabs() + data.symbol.getName() + "__" + generate(child, nullptr).oneString() + (data.type == adt_def ? ",\n" : "\n");
//enumString += tabs() + data.symbol.getName() + "__" + generate(child, nullptr).oneString() + (data.type == adt_def ? ",\n" : "\n");
// this was prefixing when it shouldn't have, since we prefix with the name of the adt anyway. Probs the entire thing should be prefixed, but we'll cross that bridge when we come to it
enumString += tabs() + data.symbol.getName() + "__" + child->getDataRef()->symbol.getName() + (data.type == adt_def ? ",\n" : "\n");
}
}
tabLevel--;
@@ -335,6 +337,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
for (auto child : decChildren) {
if (child->getName() != "function" && child->getDataRef()->valueType->typeDefinition != declaration) {
std::string option_name = child->getDataRef()->symbol.getName();
std::string prefixed_option_name = prefixIfNeeded(scopePrefix(declaration),option_name);
functionDefinitions += " else if (this->flag == " + declarationData.symbol.getName() + "__" + option_name + ") {\n";
NodeTree<ASTData>* method = nullptr;
if (method = getMethod(child->getDataRef()->valueType, "operator==", std::vector<Type>{*child->getDataRef()->valueType})) {
@@ -345,17 +348,17 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
if (need_temporary) {
functionDefinitions += " " + ValueTypeToCType(child->getDataRef()->valueType, "copy_constructTemporary") + ";\n";
functionDefinitions += " " + generateMethodIfExists(child->getDataRef()->valueType, "copy_construct",
"&copy_constructTemporary, &in->" + option_name, itemTypeVector) + ";\n";
"&copy_constructTemporary, &in->" + prefixed_option_name, itemTypeVector) + ";\n";
}
std::string otherValue = (is_reference ? "&" : "") + (need_temporary ? "copy_constructTemporary" : "in->" + option_name);
std::string otherValue = (is_reference ? "&" : "") + (need_temporary ? "copy_constructTemporary" : "in->" + prefixed_option_name);
functionDefinitions += " equal = " + generateMethodIfExists(child->getDataRef()->valueType, "operator==",
"&this->" + option_name + ", " + otherValue,
"&this->" + prefixed_option_name + ", " + otherValue,
std::vector<Type>{*child->getDataRef()->valueType}) + ";\n";
// Remember, we don't destruct copy_constructTemporary because the function will do that
functionDefinitions += "}\n";
} else {
functionDefinitions += " equal = this->" + option_name + " == in->" + option_name + ";\n}\n";
functionDefinitions += " equal = this->" + prefixed_option_name + " == in->" + prefixed_option_name + ";\n}\n";
}
}
}
@@ -380,15 +383,16 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
for (auto child : decChildren) {
if (child->getName() != "function" && child->getDataRef()->valueType->typeDefinition != declaration) {
std::string option_name = child->getDataRef()->symbol.getName();
std::string prefixed_option_name = prefixIfNeeded(scopePrefix(declaration),option_name);
functionDefinitions += " " + elsePrefix + " if (in->flag == " + declarationData.symbol.getName() + "__" + option_name + ") {\n";
elsePrefix = "else";
NodeTree<ASTData>* method = nullptr;
auto itemTypeVector = std::vector<Type>{child->getDataRef()->valueType->withIncreasedIndirection()};
if (method = getMethod(child->getDataRef()->valueType, "copy_construct", itemTypeVector)) {
functionDefinitions += " " + generateMethodIfExists(child->getDataRef()->valueType, "copy_construct",
"&this->" + option_name + ", &in->" + option_name, itemTypeVector) + ";\n";
"&this->" + prefixed_option_name + ", &in->" + prefixed_option_name, itemTypeVector) + ";\n";
} else {
functionDefinitions += "this->" + option_name + " = in->" + option_name + ";\n";
functionDefinitions += "this->" + prefixed_option_name + " = in->" + prefixed_option_name + ";\n";
}
functionDefinitions += " }\n";
}
@@ -421,9 +425,9 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
functionDefinitions += "/*" + ValueTypeToCType(paramType, "") + "*/\n";
if (method = getMethod(paramType, "copy_construct", itemTypeVector)) {
functionDefinitions += " " + generateMethodIfExists(paramType, "copy_construct",
"&toRet." + orig_fun_name + ", &in", itemTypeVector) + ";\n";
"&toRet." + prefixIfNeeded(scopePrefix(declaration),orig_fun_name) + ", &in", itemTypeVector) + ";\n";
} else {
functionDefinitions += " toRet." + orig_fun_name + " = in;\n";
functionDefinitions += " toRet." + prefixIfNeeded(scopePrefix(declaration),orig_fun_name) + " = in;\n";
}
if (method = getMethod(paramType, "destruct", std::vector<Type>())) {

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()
}
}

View File

@@ -1,5 +1,12 @@
import to_import: a,b
obj Something (ObjectTrait) {
var member: int
fun method():int {
return 5
}
}
fun main(): int {
return 0
}