Simple Templates work! Even Templates in other files work. Happy day
This commit is contained in:
@@ -8,9 +8,15 @@ set( MY_INCLUDES ${PROJECT_SOURCE_DIR}/include)
|
|||||||
|
|
||||||
set( MY_SOURCES main.cpp src/Parser.cpp src/LALRParser.cpp src/GraphStructuredStack.cpp src/RNGLRParser.cpp src/ParseAction.cpp src/ParseRule.cpp src/Symbol.cpp src/StringReader.cpp src/State.cpp src/util.cpp src/Lexer.cpp src/RegEx.cpp src/RegExState.cpp src/Table.cpp src/ASTData.cpp src/ASTTransformation.cpp src/CGenerator.cpp src/Type.cpp src/Importer.cpp )
|
set( MY_SOURCES main.cpp src/Parser.cpp src/LALRParser.cpp src/GraphStructuredStack.cpp src/RNGLRParser.cpp src/ParseAction.cpp src/ParseRule.cpp src/Symbol.cpp src/StringReader.cpp src/State.cpp src/util.cpp src/Lexer.cpp src/RegEx.cpp src/RegExState.cpp src/Table.cpp src/ASTData.cpp src/ASTTransformation.cpp src/CGenerator.cpp src/Type.cpp src/Importer.cpp )
|
||||||
|
|
||||||
|
add_custom_target(STDLibCopy ALL)
|
||||||
|
add_custom_command(TARGET STDLibCopy POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
"${PROJECT_SOURCE_DIR}/stdlib"
|
||||||
|
"${PROJECT_BINARY_DIR}/stdlib")
|
||||||
|
|
||||||
include_directories( ${MY_INCLUDES} )
|
include_directories( ${MY_INCLUDES} )
|
||||||
|
|
||||||
add_executable(kraken ${MY_SOURCES})
|
add_executable(kraken ${MY_SOURCES})
|
||||||
|
|
||||||
file(COPY stdlib DESTINATION .)
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
|||||||
private:
|
private:
|
||||||
Importer * importer;
|
Importer * importer;
|
||||||
std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelScope;
|
std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelScope;
|
||||||
|
NodeTree<ASTData>* topScope; //maintained for templates that need to add themselves to the top scope no matter where they are instantiated
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class CGenerator {
|
|||||||
std::string generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enclosingObject = NULL);
|
std::string generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enclosingObject = NULL);
|
||||||
static std::string ValueTypeToCType(Type *type);
|
static std::string ValueTypeToCType(Type *type);
|
||||||
static std::string ValueTypeToCTypeDecoration(Type *type);
|
static std::string ValueTypeToCTypeDecoration(Type *type);
|
||||||
static std::string CifyFunctionName(std::string name);
|
static std::string CifyName(std::string name);
|
||||||
std::string generateObjectMethod(NodeTree<ASTData>* enclosingObject, NodeTree<ASTData>* from);
|
std::string generateObjectMethod(NodeTree<ASTData>* enclosingObject, NodeTree<ASTData>* from);
|
||||||
|
|
||||||
std::string generatorString;
|
std::string generatorString;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
ASTTransformation::ASTTransformation(Importer *importerIn) {
|
ASTTransformation::ASTTransformation(Importer *importerIn) {
|
||||||
importer = importerIn;
|
importer = importerIn;
|
||||||
|
topScope = NULL;
|
||||||
//Set up language level special scope. (the final scope checked)
|
//Set up language level special scope. (the final scope checked)
|
||||||
//Note the NULL type
|
//Note the NULL type
|
||||||
languageLevelScope["+"].push_back( new NodeTree<ASTData>("function", ASTData(function, Symbol("+", true), NULL)));
|
languageLevelScope["+"].push_back( new NodeTree<ASTData>("function", ASTData(function, Symbol("+", true), NULL)));
|
||||||
@@ -45,6 +46,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
if (name == "translation_unit") {
|
if (name == "translation_unit") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(translation_unit));
|
newNode = new NodeTree<ASTData>(name, ASTData(translation_unit));
|
||||||
scope = newNode;
|
scope = newNode;
|
||||||
|
topScope = newNode; //Top scope is maintained for templates, which need to add themselves to the top scope from where ever they are instantiated
|
||||||
} else if (name == "interpreter_directive") {
|
} else if (name == "interpreter_directive") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(interpreter_directive));
|
newNode = new NodeTree<ASTData>(name, ASTData(interpreter_directive));
|
||||||
} else if (name == "import" && !current.isTerminal()) {
|
} else if (name == "import" && !current.isTerminal()) {
|
||||||
@@ -536,8 +538,7 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
|||||||
templateTypeReplacement->indirection += indirection;
|
templateTypeReplacement->indirection += indirection;
|
||||||
return templateTypeReplacement;
|
return templateTypeReplacement;
|
||||||
}
|
}
|
||||||
//If not, we better instantiate it and then add it to the scope
|
//If not, we better instantiate it and then add it to the highest (not current) scope
|
||||||
//Note that this means the template instantiation is scoped, which is inefficient, though it has a nice correctness about it
|
|
||||||
if (typeDefinition == NULL && typeNode->getChildren().size() > 1 && typeNode->getChildren()[1]->getData().getName() == "template_inst") {
|
if (typeDefinition == NULL && typeNode->getChildren().size() > 1 && typeNode->getChildren()[1]->getData().getName() == "template_inst") {
|
||||||
std::cout << "Template type: " << edited << " not yet instantiated" << std::endl;
|
std::cout << "Template type: " << edited << " not yet instantiated" << std::endl;
|
||||||
//Look up this template's plain definition. It's type has the syntax tree that we need to parse
|
//Look up this template's plain definition. It's type has the syntax tree that we need to parse
|
||||||
@@ -560,7 +561,12 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
|||||||
typeDefinition = new NodeTree<ASTData>("type_def", ASTData(type_def, Symbol(fullyInstantiatedName, true, fullyInstantiatedName)));
|
typeDefinition = new NodeTree<ASTData>("type_def", ASTData(type_def, Symbol(fullyInstantiatedName, true, fullyInstantiatedName)));
|
||||||
typeDefinition->getDataRef()->valueType = new Type(typeDefinition);; //Type is self-referential since this is the definition
|
typeDefinition->getDataRef()->valueType = new Type(typeDefinition);; //Type is self-referential since this is the definition
|
||||||
|
|
||||||
scope->getDataRef()->scope[fullyInstantiatedName].push_back(typeDefinition);
|
//Note that we're adding to the current top scope. This makes it more efficient by preventing multiple instantiation and should not cause any problems
|
||||||
|
//It also makes sure it gets generated in the right place
|
||||||
|
topScope->getDataRef()->scope[fullyInstantiatedName].push_back(typeDefinition);
|
||||||
|
topScope->addChild(typeDefinition); //Add this object the the highest scope's
|
||||||
|
|
||||||
|
|
||||||
//Note that the instantiated template's scope is the template's definition.
|
//Note that the instantiated template's scope is the template's definition.
|
||||||
typeDefinition->getDataRef()->scope["~enclosing_scope"].push_back(templateDefinition);
|
typeDefinition->getDataRef()->scope["~enclosing_scope"].push_back(templateDefinition);
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
parameters += ValueTypeToCType(decChildren[j]->getData().valueType) + " " + generate(decChildren[j], enclosingObject);
|
parameters += ValueTypeToCType(decChildren[j]->getData().valueType) + " " + generate(decChildren[j], enclosingObject);
|
||||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType);
|
nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType);
|
||||||
}
|
}
|
||||||
output += CifyFunctionName(declarationData.symbol.getName()) + nameDecoration + "(" + parameters + "); /*func*/\n";
|
output += CifyName(declarationData.symbol.getName()) + nameDecoration + "(" + parameters + "); /*func*/\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case type_def:
|
case type_def:
|
||||||
@@ -104,13 +104,15 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
if (false)
|
if (false)
|
||||||
for (int j = 0; j < children.size()-1; j++)
|
for (int j = 0; j < children.size()-1; j++)
|
||||||
preName += ValueTypeToCType(children[j]->getData().valueType) + "_";
|
preName += ValueTypeToCType(children[j]->getData().valueType) + "_";
|
||||||
return preName + CifyFunctionName(data.symbol.getName()); //Cifying does nothing if not an operator overload
|
return preName + CifyName(data.symbol.getName()); //Cifying does nothing if not an operator overload
|
||||||
}
|
}
|
||||||
case type_def:
|
case type_def:
|
||||||
if (children.size() == 0) {
|
if (data.valueType->baseType == template_type) {
|
||||||
|
return "/* non instantiated template " + data.symbol.getName() + " */";
|
||||||
|
} else if (children.size() == 0) {
|
||||||
return "typedef " + ValueTypeToCType(data.valueType) + " " + data.symbol.getName() + ";";
|
return "typedef " + ValueTypeToCType(data.valueType) + " " + data.symbol.getName() + ";";
|
||||||
} else {
|
} else {
|
||||||
std::string objectString = "typedef struct __struct_dummy_" + data.symbol.getName() + "__ {\n";
|
std::string objectString = "typedef struct __struct_dummy_" + CifyName(data.symbol.getName()) + "__ {\n";
|
||||||
std::string postString; //The functions have to be outside the struct definition
|
std::string postString; //The functions have to be outside the struct definition
|
||||||
for (int i = 0; i < children.size(); i++) {
|
for (int i = 0; i < children.size(); i++) {
|
||||||
std::cout << children[i]->getName() << std::endl;
|
std::cout << children[i]->getName() << std::endl;
|
||||||
@@ -119,7 +121,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
else
|
else
|
||||||
objectString += generate(children[i], enclosingObject) + "\n";
|
objectString += generate(children[i], enclosingObject) + "\n";
|
||||||
}
|
}
|
||||||
objectString += "} " + data.symbol.getName() + ";";
|
objectString += "} " + CifyName(data.symbol.getName()) + ";";
|
||||||
return objectString + postString; //Functions come after the declaration of the struct
|
return objectString + postString; //Functions come after the declaration of the struct
|
||||||
}
|
}
|
||||||
case function:
|
case function:
|
||||||
@@ -132,7 +134,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
parameters += ValueTypeToCType(children[j]->getData().valueType) + " " + generate(children[j], enclosingObject);
|
parameters += ValueTypeToCType(children[j]->getData().valueType) + " " + generate(children[j], enclosingObject);
|
||||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(children[j]->getData().valueType);
|
nameDecoration += "_" + ValueTypeToCTypeDecoration(children[j]->getData().valueType);
|
||||||
}
|
}
|
||||||
output += CifyFunctionName(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;
|
return output;
|
||||||
}
|
}
|
||||||
case code_block:
|
case code_block:
|
||||||
@@ -220,7 +222,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
std::cout << "Decorating (in access-should be object) " << name << " " << functionDefChildren.size() << std::endl;
|
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++)
|
for (int i = 0; i < (functionDefChildren.size() > 0 ? functionDefChildren.size()-1 : 0); i++)
|
||||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(functionDefChildren[i]->getData().valueType);
|
nameDecoration += "_" + ValueTypeToCTypeDecoration(functionDefChildren[i]->getData().valueType);
|
||||||
/*HERE*/ return possibleObjectType->getDataRef()->symbol.getName() +"__" + CifyFunctionName(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
|
//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 {
|
} else {
|
||||||
@@ -242,7 +244,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
bool isSelfObjectMethod = enclosingObject && contains(enclosingObject->getChildren(), children[0]);
|
bool isSelfObjectMethod = enclosingObject && contains(enclosingObject->getChildren(), children[0]);
|
||||||
if (isSelfObjectMethod)
|
if (isSelfObjectMethod)
|
||||||
output += enclosingObject->getDataRef()->symbol.getName() +"__";
|
output += enclosingObject->getDataRef()->symbol.getName() +"__";
|
||||||
/*HERE*/ output += CifyFunctionName(name) + nameDecoration + "(";
|
/*HERE*/ output += CifyName(name) + nameDecoration + "(";
|
||||||
if (isSelfObjectMethod)
|
if (isSelfObjectMethod)
|
||||||
output += children.size() > 1 ? "self," : "self";
|
output += children.size() > 1 ? "self," : "self";
|
||||||
}
|
}
|
||||||
@@ -286,8 +288,8 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
|
|||||||
parameters += ", " + ValueTypeToCType(children[i]->getData().valueType) + " " + generate(children[i]);
|
parameters += ", " + ValueTypeToCType(children[i]->getData().valueType) + " " + generate(children[i]);
|
||||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(children[i]->getData().valueType);
|
nameDecoration += "_" + ValueTypeToCTypeDecoration(children[i]->getData().valueType);
|
||||||
}
|
}
|
||||||
output += "\n" + ValueTypeToCType(data.valueType) + " " + enclosingObject->getDataRef()->symbol.getName() +"__"
|
output += "\n" + ValueTypeToCType(data.valueType) + " " + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__"
|
||||||
+ CifyFunctionName(data.symbol.getName()) + nameDecoration + "(" + ValueTypeToCType(&enclosingObjectType)
|
+ CifyName(data.symbol.getName()) + nameDecoration + "(" + ValueTypeToCType(&enclosingObjectType)
|
||||||
+ " self" + parameters + ")\n" + generate(children[children.size()-1], enclosingObject); //Pass in the object so we can properly handle access to member stuff
|
+ " self" + parameters + ")\n" + generate(children[children.size()-1], enclosingObject); //Pass in the object so we can properly handle access to member stuff
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@@ -297,7 +299,7 @@ std::string CGenerator::ValueTypeToCType(Type *type) {
|
|||||||
switch (type->baseType) {
|
switch (type->baseType) {
|
||||||
case none:
|
case none:
|
||||||
if (type->typeDefinition)
|
if (type->typeDefinition)
|
||||||
return_type = type->typeDefinition->getDataRef()->symbol.getName();
|
return_type = CifyName(type->typeDefinition->getDataRef()->symbol.getName());
|
||||||
else
|
else
|
||||||
return_type = "none";
|
return_type = "none";
|
||||||
break;
|
break;
|
||||||
@@ -364,7 +366,7 @@ std::string CGenerator::ValueTypeToCTypeDecoration(Type *type) {
|
|||||||
return return_type;
|
return return_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CGenerator::CifyFunctionName(std::string name) {
|
std::string CGenerator::CifyName(std::string name) {
|
||||||
std::string operatorsToReplace[] = { "+", "plus",
|
std::string operatorsToReplace[] = { "+", "plus",
|
||||||
"-", "minus",
|
"-", "minus",
|
||||||
"*", "star",
|
"*", "star",
|
||||||
@@ -394,6 +396,8 @@ std::string CGenerator::CifyFunctionName(std::string name) {
|
|||||||
"|=", "pipeequals",
|
"|=", "pipeequals",
|
||||||
"*=", "starequals",
|
"*=", "starequals",
|
||||||
"<<=", "doublerightequals",
|
"<<=", "doublerightequals",
|
||||||
|
"<", "lessthan",
|
||||||
|
">", "greaterthan",
|
||||||
">>=", "doubleleftequals",
|
">>=", "doubleleftequals",
|
||||||
"->", "arrow" };
|
"->", "arrow" };
|
||||||
int length = sizeof(operatorsToReplace)/sizeof(std::string);
|
int length = sizeof(operatorsToReplace)/sizeof(std::string);
|
||||||
|
|||||||
Reference in New Issue
Block a user