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:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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",
|
||||
"©_constructTemporary, &in->" + option_name, itemTypeVector) + ";\n";
|
||||
"©_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>())) {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user