Wooo passthrough and more cleanup! Remove 3rd pass!
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,3 +6,4 @@ stats
|
||||
*.swp
|
||||
*.png
|
||||
*krakout*
|
||||
kraklist.txt
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,7 +72,15 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
//Now go through and do all imports
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
11
tests/c_passthrough_diff.krak
Normal file
11
tests/c_passthrough_diff.krak
Normal 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);
|
||||
"""
|
||||
}
|
||||
2
tests/test_c_passthrough.expected_results
Normal file
2
tests/test_c_passthrough.expected_results
Normal file
@@ -0,0 +1,2 @@
|
||||
same_file: 5
|
||||
diff_file: 7
|
||||
19
tests/test_c_passthrough.krak
Normal file
19
tests/test_c_passthrough.krak
Normal 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
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user