Almost have it working, but member function lookup through a typedef doesn't quite work. (I think the problem's in CGenerator)
This commit is contained in:
@@ -21,7 +21,7 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
||||
|
||||
//Second pass defines data inside objects, outside declaration statements, and function prototpyes (since we have type_defs now)
|
||||
void secondPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* parseTree);
|
||||
void secondPassDoClassInsides(NodeTree<ASTData>* typeDef, std::vector<NodeTree<Symbol>*> typedefChildren);
|
||||
void secondPassDoClassInsides(NodeTree<ASTData>* typeDef, std::vector<NodeTree<Symbol>*> typedefChildren, std::map<std::string, Type*> templateTypeReplacements);
|
||||
NodeTree<ASTData>* secondPassDeclaration(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::map<std::string, Type*> templateTypeReplacements);
|
||||
NodeTree<ASTData>* secondPassFunction(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::map<std::string, Type*> templateTypeReplacements);
|
||||
|
||||
|
||||
10
main.cpp
10
main.cpp
@@ -21,7 +21,13 @@
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
std::vector<std::string> includePaths;
|
||||
includePaths.push_back(""); //Local
|
||||
includePaths.push_back(""); //Local
|
||||
|
||||
if (argc <= 1) {
|
||||
std::cout << "Kraken invocation: kraken sourceFile.krak grammerFile.kgm outputName" << std::endl;
|
||||
std::cout << "Or for testing do: kraken --test [optional list of names of file (.krak .expected_results) without extentions to run]" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc >= 2 && std::string(argv[1]) == "--test") {
|
||||
StringReader::test();
|
||||
@@ -152,4 +158,4 @@ int main(int argc, char* argv[]) {
|
||||
CGenerator().generateCompSet(ASTs, outputName);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -98,12 +98,16 @@ void ASTTransformation::secondPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
|
||||
|
||||
//It's an alias
|
||||
if (typedefChildren[1]->getData().getName() == "type") {
|
||||
/*HERE*/ typeDef->getDataRef()->valueType = typeFromTypeNode(typedefChildren[1], ast, std::map<std::string, Type*>(), false); //No templates, we're in the traslation unit
|
||||
Type* aliasedType = typeFromTypeNode(typedefChildren[1], ast, std::map<std::string, Type*>(), false); //No templates, we're in the traslation unit
|
||||
typeDef->getDataRef()->valueType = aliasedType;
|
||||
typeDef->getDataRef()->scope["~enclosing_scope"][0] = aliasedType->typeDefinition; //So that object lookups find the right member. Note that this overrides translation_unit as a parent scope
|
||||
std::cout << name << " alias's to " << aliasedType->typeDefinition << std::endl;
|
||||
std::cout << "that is " << aliasedType->typeDefinition->getDataRef()->toString() << std::endl;
|
||||
continue;
|
||||
}
|
||||
//Do the inside of classes here
|
||||
typeDef->getDataRef()->valueType = new Type(typeDef);
|
||||
secondPassDoClassInsides(typeDef, typedefChildren);
|
||||
secondPassDoClassInsides(typeDef, typedefChildren, std::map<std::string, Type*>());
|
||||
} else if (i->getDataRef()->getName() == "function") {
|
||||
//Do prototypes of functions
|
||||
ast->addChild(secondPassFunction(i, ast, std::map<std::string, Type*>()));
|
||||
@@ -114,15 +118,15 @@ void ASTTransformation::secondPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
|
||||
}
|
||||
}
|
||||
|
||||
void ASTTransformation::secondPassDoClassInsides(NodeTree<ASTData>* typeDef, std::vector<NodeTree<Symbol>*> typedefChildren) {
|
||||
void ASTTransformation::secondPassDoClassInsides(NodeTree<ASTData>* typeDef, std::vector<NodeTree<Symbol>*> typedefChildren, std::map<std::string, Type*> templateTypeReplacements) {
|
||||
//We pull out this functionality into a new function because this is used in typeFromTypeNode to partially instantiate templates
|
||||
for (NodeTree<Symbol>* j : typedefChildren) {
|
||||
if (j->getDataRef()->getName() == "declaration_statement") {
|
||||
//do declaration
|
||||
typeDef->addChild(secondPassDeclaration(j, typeDef, std::map<std::string, Type*>()));
|
||||
typeDef->addChild(secondPassDeclaration(j, typeDef, templateTypeReplacements));
|
||||
} else if (j->getDataRef()->getName() == "function") {
|
||||
//do member method
|
||||
typeDef->addChild(secondPassFunction(j, typeDef, std::map<std::string, Type*>()));
|
||||
typeDef->addChild(secondPassFunction(j, typeDef, templateTypeReplacements));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -214,11 +218,15 @@ void ASTTransformation::fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
|
||||
|
||||
//First copy unfinished class templates into a new list and do them before anything else, so we know exactly which ones we need to do.
|
||||
std::vector<NodeTree<ASTData>*> classTemplates;
|
||||
for (auto i : ast->getDataRef()->scope)
|
||||
if (i.second[0]->getDataRef()->type == type_def && i.second[0]->getDataRef()->valueType->baseType == template_type)
|
||||
for (auto i : ast->getDataRef()->scope) {
|
||||
if (i.second[0]->getDataRef()->type == type_def && i.second[0]->getDataRef()->valueType->templateTypeReplacement.size()) {
|
||||
classTemplates.push_back(i.second[0]);
|
||||
std::cout << "Saving " << i.second[0]->getDataRef()->toString() << " to instantiate." << std::endl;
|
||||
}
|
||||
}
|
||||
for (auto i : classTemplates) {
|
||||
Type* classTemplateType = i->getDataRef()->valueType;
|
||||
std::cout << "Instantiating template " << i->getDataRef()->toString() << std::endl;
|
||||
for (NodeTree<Symbol>* j : classTemplateType->templateDefinition->getChildren())
|
||||
if (j->getDataRef()->getName() == "function")
|
||||
fourthPassFunction(j, seachScopeForFunctionDef(i, j, classTemplateType->templateTypeReplacement), classTemplateType->templateTypeReplacement); //do member method
|
||||
@@ -874,8 +882,10 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
||||
typeDefinition->getDataRef()->scope["~enclosing_scope"].push_back(templateDefinition);
|
||||
|
||||
if (!instantiateTemplates) {
|
||||
selfType->templateTypeReplacement = newTemplateTypeReplacement; //Save the types for use when this is fully instantiated in pass 4
|
||||
secondPassDoClassInsides(typeDefinition, templateSyntaxTree->getChildren());
|
||||
std::cout << "!instantiateTemplates, so only partially instantiating " << fullyInstantiatedName << std::endl;
|
||||
selfType->templateDefinition = templateSyntaxTree; //We're going to still need this when we finish instantiating
|
||||
selfType->templateTypeReplacement = newTemplateTypeReplacement; //Save the types for use when this is fully instantiated in pass 4
|
||||
secondPassDoClassInsides(typeDefinition, templateSyntaxTree->getChildren(), newTemplateTypeReplacement); //Use these types when instantiating data members
|
||||
} else {
|
||||
//We're fully instantiating types. (we must be in pass 4)
|
||||
std::set<int> skipChildren;
|
||||
|
||||
@@ -64,6 +64,8 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
//In case there are pointer dependencies. If the typedef has no children, then it is a simple renaming and we don't need to predeclare the class (maybe?)
|
||||
if (classChildren.size())
|
||||
output += "struct " + CifyName(children[i]->getDataRef()->symbol.getName()) + ";\n";
|
||||
else if (children[i]->getDataRef()->valueType->typeDefinition != children[i] && !children[i]->getDataRef()->valueType->templateDefinition) //Isn't uninstantiated template or 0 parameter class, so must be alias
|
||||
typedefPoset.addRelationship(children[i], children[i]->getDataRef()->valueType->typeDefinition); //An alias typedef depends on the type it aliases being declared before it
|
||||
}
|
||||
}
|
||||
//Now generate the typedef's in the correct, topological order
|
||||
@@ -82,7 +84,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
break;
|
||||
case function:
|
||||
{
|
||||
if (declarationData.valueType->baseType == template_type)
|
||||
if (declarationData.valueType->baseType == template_type)
|
||||
output += "/* template function " + declarationData.symbol.toString() + " */\n";
|
||||
else if (decChildren.size() == 0) //Not a real function, must be a built in passthrough
|
||||
output += "/* built in function: " + declarationData.symbol.toString() + " */\n";
|
||||
@@ -95,7 +97,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
parameters += ValueTypeToCType(decChildren[j]->getData().valueType) + " " + generate(decChildren[j], enclosingObject);
|
||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType);
|
||||
}
|
||||
output += CifyName(declarationData.symbol.getName()) + nameDecoration + "(" + parameters + "); /*func*/\n";
|
||||
output += CifyName(declarationData.symbol.getName() + nameDecoration) + "(" + parameters + "); /*func*/\n";
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -165,7 +167,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
parameters += ValueTypeToCType(children[j]->getData().valueType) + " " + generate(children[j], enclosingObject);
|
||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(children[j]->getData().valueType);
|
||||
}
|
||||
output += CifyName(data.symbol.getName()) + nameDecoration + "(" + parameters + ")\n" + generate(children[children.size()-1], enclosingObject);
|
||||
output += CifyName(data.symbol.getName() + nameDecoration) + "(" + parameters + ")\n" + generate(children[children.size()-1], enclosingObject);
|
||||
return output;
|
||||
}
|
||||
case code_block:
|
||||
@@ -253,9 +255,9 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
std::cout << "Decorating (in access-should be object) " << name << " " << functionDefChildren.size() << std::endl;
|
||||
for (int i = 0; i < (functionDefChildren.size() > 0 ? functionDefChildren.size()-1 : 0); i++)
|
||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(functionDefChildren[i]->getData().valueType);
|
||||
/*HERE*/ return CifyName(possibleObjectType->getDataRef()->symbol.getName()) +"__" + CifyName(functionName) + nameDecoration + "(" + (name == "." ? "&" : "") + generate(children[1], enclosingObject) + ",";
|
||||
/*HERE*/ return CifyName(possibleObjectType->getDataRef()->symbol.getName()) +"__" + CifyName(functionName + nameDecoration) + "(" + (name == "." ? "&" : "") + generate(children[1], enclosingObject) + ",";
|
||||
//The comma lets the upper function call know we already started the param list
|
||||
//Note that we got here from a function call. We just pass up this special case and let them finish with the perentheses
|
||||
//Note that we got here from a function call. We just pass up this special case and let them finish with the perentheses
|
||||
} else {
|
||||
std::cout << "Is not in scope or not type" << std::endl;
|
||||
return "((" + generate(children[1], enclosingObject) + ")" + name + functionName + ")";
|
||||
@@ -275,7 +277,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
bool isSelfObjectMethod = enclosingObject && contains(enclosingObject->getChildren(), children[0]);
|
||||
if (isSelfObjectMethod)
|
||||
output += enclosingObject->getDataRef()->symbol.getName() +"__";
|
||||
/*HERE*/ output += CifyName(name) + nameDecoration + "(";
|
||||
/*HERE*/ output += CifyName(name + nameDecoration) + "(";
|
||||
if (isSelfObjectMethod)
|
||||
output += children.size() > 1 ? "self," : "self";
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
345Hello!Hello!Hello!
|
||||
45Hello!Hello!Hello!
|
||||
|
||||
@@ -2,7 +2,7 @@ import io;
|
||||
import trivial_container;
|
||||
|
||||
typedef RegularObject {
|
||||
MyInt num;
|
||||
int num;
|
||||
trivialContainer<char*> innerContainer;
|
||||
void set(char* message, int number) {
|
||||
innerContainer.data = message;
|
||||
@@ -18,8 +18,6 @@ typedef RegularObject {
|
||||
};
|
||||
|
||||
typedef MyIntContainer trivialContainer<int>;
|
||||
typedef MyInt int;
|
||||
MyInt c;
|
||||
MyIntContainer roundabout;
|
||||
RegularObject outsideDec;
|
||||
|
||||
@@ -28,14 +26,12 @@ void print(trivialContainer<char*> toPrint) {
|
||||
}
|
||||
|
||||
int main() {
|
||||
c = 3;
|
||||
roundabout.data = 4;
|
||||
outsideDec.set("Hello!", 5);
|
||||
print(c);
|
||||
roundabout.print();
|
||||
outsideDec.print();
|
||||
print(outsideDec.get());
|
||||
print(outsideDec.innerContainer);
|
||||
print("\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user