Wooo passthrough and more cleanup! Remove 3rd pass!

This commit is contained in:
Nathan Braswell
2015-03-24 18:29:21 -04:00
parent 48dc1f8e4d
commit 414113f954
8 changed files with 67 additions and 52 deletions

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ stats
*.swp
*.png
*krakout*
kraklist.txt

View File

@@ -29,13 +29,10 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
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);
//Third pass redoes all imports to import the new function prototypes and identifiers
void thirdPass(NodeTree<ASTData>* ast);
//The fourth pass finishes up by doing all function bodies
void fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* parseTree);
//The third pass finishes up by doing all function bodies
void thirdPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* parseTree);
NodeTree<ASTData>* searchScopeForFunctionDef(NodeTree<ASTData>* scope, NodeTree<Symbol>* parseTree, std::map<std::string, Type*> templateTypeReplacements);
void fourthPassFunction(NodeTree<Symbol>* from, NodeTree<ASTData>* functionDef, std::map<std::string, Type*> templateTypeReplacements);
void thirdPassFunction(NodeTree<Symbol>* from, NodeTree<ASTData>* functionDef, std::map<std::string, Type*> templateTypeReplacements);
virtual NodeTree<ASTData>* transform(NodeTree<Symbol>* from);
NodeTree<ASTData>* transform(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements);

View File

@@ -38,7 +38,7 @@ ASTTransformation::~ASTTransformation() {
//
}
//First pass defines all type_defs (objects and ailises)
//First pass defines all type_defs (objects and ailises), and if_comp/simple_passthrough
NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<Symbol>* parseTree) {
NodeTree<ASTData>* translationUnit = new NodeTree<ASTData>("translation_unit", ASTData(translation_unit));
std::vector<NodeTree<Symbol>*> children = parseTree->getChildren();
@@ -72,6 +72,14 @@ NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<S
translationUnit->addChild(firstDec);
translationUnit->getDataRef()->scope[name].push_back(firstDec);
firstDec->getDataRef()->scope["~enclosing_scope"].push_back(translationUnit);
} else if (i->getDataRef()->getName() == "if_comp") {
std::cout << "IF COMP" << std::endl;
NodeTree<ASTData>* newNode = new NodeTree<ASTData>(i->getDataRef()->getName(), ASTData(if_comp));
newNode->addChild(new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(concatSymbolTree(i->getChildren()[0]),true))));
std::set<int> skipChildren;
skipChildren.insert(0); //Don't do the identifier. The identifier lookup will fail. That's why we do it here.
newNode->addChildren(transformChildren(i->getChildren(), skipChildren, translationUnit, std::vector<Type>(), std::map<std::string, Type*>()));
translationUnit->addChild(newNode);
}
}
@@ -236,36 +244,8 @@ NodeTree<ASTData>* ASTTransformation::secondPassFunction(NodeTree<Symbol>* from,
return functionDef;
}
//Third pass redoes all imports to import the new function prototypes and identifiers
void ASTTransformation::thirdPass(NodeTree<ASTData>* ast) {
std::vector<NodeTree<ASTData>*> children = ast->getChildren();
//Go through and do all imports again
for (NodeTree<ASTData>* i : children) {
if (i->getDataRef()->type == import) {
std::string toImport = i->getDataRef()->symbol.getName();
NodeTree<ASTData>* outsideTranslationUnit = importer->getUnit(toImport + ".krak");
//Now add all functions to scope
std::cout << "Trying to re-import from " << toImport << std::endl;
for (auto j = outsideTranslationUnit->getDataRef()->scope.begin(); j != outsideTranslationUnit->getDataRef()->scope.end(); j++) {
std::cout << "Looking at " << j->first << std::endl;
// If we're supposed to import this... (meaning that this name is in the scope already)
if (i->getDataRef()->scope.find(j->first) == i->getDataRef()->scope.end())
continue;
std::cout << "Looking through " << j->first << std::endl;
for (auto k : j->second)
if (k->getDataRef()->type == function || k->getDataRef()->type == identifier)
std::cout << "Copying " << j->first << std::endl, i->getDataRef()->scope[j->first].push_back(k);
else
std::cout << "Not Copying " << j->first << std::endl;
}
}
}
}
//The fourth pass finishes up by doing all function bodies
void ASTTransformation::fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* parseTree) {
//The third pass finishes up by doing all function bodies
void ASTTransformation::thirdPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* parseTree) {
topScope = ast; //Top scope is maintained for templates, which need to add themselves to the top scope from where ever they are instantiated
std::vector<NodeTree<Symbol>*> children = parseTree->getChildren();
@@ -286,14 +266,14 @@ void ASTTransformation::fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
//Do the inside of classes here
for (NodeTree<Symbol>* j : typedefChildren) {
if (j->getDataRef()->getName() == "function") {
fourthPassFunction(j, searchScopeForFunctionDef(typeDef, j, std::map<std::string, Type*>()), std::map<std::string, Type*>()); //do member method
thirdPassFunction(j, searchScopeForFunctionDef(typeDef, j, std::map<std::string, Type*>()), std::map<std::string, Type*>()); //do member method
}
}
} else if (i->getDataRef()->getName() == "function") {
//Do prototypes of functions
if (i->getChildren()[0]->getData().getName() == "template_dec")
continue; //We've already set up function templates
fourthPassFunction(i, searchScopeForFunctionDef(ast, i, std::map<std::string, Type*>()), std::map<std::string, Type*>());
thirdPassFunction(i, searchScopeForFunctionDef(ast, i, std::map<std::string, Type*>()), std::map<std::string, Type*>());
}
}
@@ -316,7 +296,7 @@ void ASTTransformation::fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
std::cout << "Instantiating template " << i->getDataRef()->toString() << std::endl;
for (NodeTree<Symbol>* j : classTemplateType->templateDefinition->getChildren())
if (j->getDataRef()->getName() == "function")
fourthPassFunction(j, searchScopeForFunctionDef(i, j, classTemplateType->templateTypeReplacement), classTemplateType->templateTypeReplacement); //do member method
thirdPassFunction(j, searchScopeForFunctionDef(i, j, classTemplateType->templateTypeReplacement), classTemplateType->templateTypeReplacement); //do member method
classTemplateType->templateTypeReplacement.clear(); // This template has been fully instantiated, clear it's map so it won't be instantiated again
}
}
@@ -342,9 +322,9 @@ NodeTree<ASTData>* ASTTransformation::searchScopeForFunctionDef(NodeTree<ASTData
}
//This function does the function bodies given its start (the prototype)
//It is used in the fourth pass to finish things up
//It is used in the third pass to finish things up
//Note that it may instantiate class OR function templates, which need to be fully instantiated
void ASTTransformation::fourthPassFunction(NodeTree<Symbol>* from, NodeTree<ASTData>* functionDef, std::map<std::string, Type*> templateTypeReplacements) {
void ASTTransformation::thirdPassFunction(NodeTree<Symbol>* from, NodeTree<ASTData>* functionDef, std::map<std::string, Type*> templateTypeReplacements) {
NodeTree<Symbol>* codeBlock = from->getChildren()[from->getChildren().size()-1];
functionDef->addChild(transform(codeBlock, functionDef, std::vector<Type>(), templateTypeReplacements));
}

View File

@@ -123,6 +123,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
// are done simultanously, but append to different strings that are then concatinated properly, in order.
std::string importIncludes = "/**\n * Import Includes\n */\n\n";
std::string topLevelCPassthrough = "/**\n * Top Level C Passthrough\n */\n\n";
std::string variableExternDeclarations = "/**\n * Extern Variable Declarations \n */\n\n";
std::string plainTypedefs = "/**\n * Plain Typedefs\n */\n\n";
std::string variableDeclarations = "/**\n * Variable Declarations \n */\n\n";
@@ -163,7 +164,14 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
// Declare everything in translation unit scope here (now for ALL translation units). (allows stuff from other files, automatic forward declarations)
// Also, everything in all of the import's scopes
// Also c passthrough
for (auto trans : ASTs) {
// First go through and emit all the passthroughs, etc
for (auto i : trans.second->getChildren()) {
if (i->getDataRef()->type == if_comp)
topLevelCPassthrough += generate(i, nullptr);
}
for (auto i = trans.second->getDataRef()->scope.begin(); i != trans.second->getDataRef()->scope.end(); i++) {
for (auto declaration : i->second) {
std::vector<NodeTree<ASTData>*> decChildren = declaration->getChildren();
@@ -232,7 +240,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
}
}
}
hOutput += plainTypedefs + importIncludes + variableExternDeclarations + classStructs + functionPrototypes;
hOutput += plainTypedefs + importIncludes + topLevelCPassthrough + variableExternDeclarations + classStructs + functionPrototypes;
cOutput += variableDeclarations + functionDefinitions;
return std::make_pair(hOutput, cOutput);
}

View File

@@ -24,6 +24,7 @@ Importer::Importer(Parser* parserIn, std::vector<std::string> includePaths, std:
removeSymbols.push_back(Symbol("if", true));
removeSymbols.push_back(Symbol("while", true));
removeSymbols.push_back(Symbol("__if_comp__", true));
removeSymbols.push_back(Symbol("__simple_passthrough__", true));
removeSymbols.push_back(Symbol("comp_simple_passthrough", true));
removeSymbols.push_back(Symbol("typedef", true));
removeSymbols.push_back(Symbol("template", true));
@@ -94,15 +95,11 @@ void Importer::import(std::string fileName) {
std::cout << "\n\nSecond pass for: " << i.name << std::endl, ASTTransformer->secondPass(i.ast, i.syntaxTree); //function prototypes, and identifiers (as we now have all type defs)
std::cout << "\n\n =====THIRD PASS===== \n\n" << std::endl;
for (importTriplet i : importedTrips) //Third pass redoes all imports to import the new function prototypes and identifiers
std::cout << "\n\nThird pass for: " << i.name << std::endl, ASTTransformer->thirdPass(i.ast);
for (importTriplet i : importedTrips) //Third pass finishes up by doing all function bodies
std::cout << "\n\nFourth pass for: " << i.name << std::endl, ASTTransformer->thirdPass(i.ast, i.syntaxTree); //With that, we're done
std::cout << "\n\n =====FOURTH PASS===== \n\n" << std::endl;
for (importTriplet i : importedTrips) //Fourth pass finishes up by doing all function bodies
std::cout << "\n\nFourth pass for: " << i.name << std::endl, ASTTransformer->fourthPass(i.ast, i.syntaxTree); //With that, we're done
//Note that class template instantiation can happen in the second or fourth passes and that function template instantion
//can happen in the fourth pass.
//Note that class template instantiation can happen in the second or third passes and that function template instantion
//can happen in the third pass.
std::ofstream outFileAST;
for (importTriplet i : importedTrips) {

View File

@@ -0,0 +1,11 @@
__if_comp__ __C__ __simple_passthrough__ """
#include <stdio.h>
int diff = 7;
"""
|void| print_it() {
__if_comp__ __C__ __simple_passthrough__ """
printf("diff_file: %d\n", diff);
"""
}

View File

@@ -0,0 +1,2 @@
same_file: 5
diff_file: 7

View File

@@ -0,0 +1,19 @@
import c_passthrough_diff
__if_comp__ __C__ __simple_passthrough__ """
#include <stdio.h>
int same = 5;
"""
|int| main() {
__if_comp__ __C__ __simple_passthrough__ """
printf("same_file: %d\n", same);
"""
c_passthrough_diff::print_it()
return 0
}