Fixed a ton of stuff with function templates. Works well now. Next up: multiple template types and fixing object definition ordering (both where templates should go and objects with other pointers)

This commit is contained in:
Nathan Braswell
2014-05-19 20:00:35 -04:00
parent b2c61b00f2
commit 39f945940d
8 changed files with 174 additions and 47 deletions

View File

@@ -5,6 +5,10 @@
#define NULL ((void*)0) #define NULL ((void*)0)
#endif #endif
#ifndef SEGFAULT
#define SEGFAULT (*((char*)0)), std::cout << "\t\t\t\tNEGATIVE*************************************************************************" << std::endl;
#endif
#include <string> #include <string>
#include <iostream> #include <iostream>
@@ -13,7 +17,7 @@ class ASTData;
#include "ASTData.h" #include "ASTData.h"
#include "util.h" #include "util.h"
enum ValueType {none, template_type, void_type, boolean, integer, floating, double_percision, character }; enum ValueType {none, template_type, template_type_type, void_type, boolean, integer, floating, double_percision, character };
class Type { class Type {
@@ -30,11 +34,17 @@ class Type {
bool const operator!=(const Type &other)const; bool const operator!=(const Type &other)const;
Type* clone(); Type* clone();
std::string toString(); std::string toString();
int getIndirection();
void setIndirection(int indirectionIn);
void increaseIndirection();
void decreaseIndirection();
void modifyIndirection(int mod);
void check();
ValueType baseType; ValueType baseType;
NodeTree<ASTData>* typeDefinition; NodeTree<ASTData>* typeDefinition;
int indirection;
NodeTree<Symbol>* templateDefinition; NodeTree<Symbol>* templateDefinition;
private: private:
int indirection;
}; };
#endif #endif

View File

@@ -42,7 +42,7 @@ opt_parameter_list = parameter_list | ;
parameter_list = parameter_list WS "," WS parameter | parameter ; parameter_list = parameter_list WS "," WS parameter | parameter ;
parameter = boolean_expression ; parameter = boolean_expression ;
type_def = "typedef" WS identifier WS type | "typedef" WS template_dec WS identifier WS "{" WS class_innerds WS "}" | "typedef" WS identifier WS "{" WS class_innerds WS "}" | "typedef" WS template_dec WS identifier WS "{" WS declaration_block WS "}" ; type_def = "typedef" WS identifier WS type | "typedef" WS template_dec WS identifier WS "{" WS class_innerds WS "}" | "typedef" WS identifier WS "{" WS class_innerds WS "}" | "typedef" WS template_dec WS identifier WS "{" WS declaration_block WS "}" | "typedef" WS identifier WS "{" WS declaration_block WS "}" ;
template_dec = "template" WS "<" WS identifier WS ">" ; template_dec = "template" WS "<" WS identifier WS ">" ;
class_innerds = visibility_block WS class_innerds | visibility_block ; class_innerds = visibility_block WS class_innerds | visibility_block ;
visibility_block = "public:" WS declaration_block | "protected:" WS declaration_block | "private:" WS declaration_block ; visibility_block = "public:" WS declaration_block | "protected:" WS declaration_block | "private:" WS declaration_block ;

View File

@@ -8,6 +8,8 @@ ASTTransformation::ASTTransformation(Importer *importerIn) {
languageLevelScope["+"].push_back( new NodeTree<ASTData>("function", ASTData(function, Symbol("+", true), NULL))); languageLevelScope["+"].push_back( new NodeTree<ASTData>("function", ASTData(function, Symbol("+", true), NULL)));
languageLevelScope["-"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("-", true), NULL))); languageLevelScope["-"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("-", true), NULL)));
languageLevelScope["*"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("*", true), NULL))); languageLevelScope["*"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("*", true), NULL)));
languageLevelScope["/"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("/", true), NULL)));
languageLevelScope["%"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("%", true), NULL)));
languageLevelScope["&"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("&", true), NULL))); languageLevelScope["&"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("&", true), NULL)));
languageLevelScope["--"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("--", true), NULL))); languageLevelScope["--"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("--", true), NULL)));
languageLevelScope["++"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("++", true), NULL))); languageLevelScope["++"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("++", true), NULL)));
@@ -117,6 +119,18 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
newNode = new NodeTree<ASTData>(name, ASTData(function, Symbol(functionName, true), new Type(template_type, from))); newNode = new NodeTree<ASTData>(name, ASTData(function, Symbol(functionName, true), new Type(template_type, from)));
scope->getDataRef()->scope[functionName].push_back(newNode); scope->getDataRef()->scope[functionName].push_back(newNode);
newNode->getDataRef()->scope["~enclosing_scope"].push_back(scope); newNode->getDataRef()->scope["~enclosing_scope"].push_back(scope);
std::map<std::string, Type*> yetToBeInstantiatedTemplateTypes; //So that template types (like T) that have not been placed yet are found and given
//a special Type() - baseType = template_type_type
yetToBeInstantiatedTemplateTypes[concatSymbolTree(children[0]->getChildren()[1])] = new Type(template_type_type); //This may have to be combined with templateTypeReplacements if we do templated member functions inside of templated classes
auto transChildren = transformChildren(slice(children,3,-2), std::set<int>(), newNode, types, yetToBeInstantiatedTemplateTypes);
std::cout << "Template function " << functionName << " has these parameters: ";
for (auto i : transChildren)
std::cout << "||" << i->getDataRef()->toString() << "|| ";
std::cout << "??||" << std::endl;
newNode->addChildren(transChildren);
std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
return newNode; return newNode;
} }
functionName = concatSymbolTree(children[1]); functionName = concatSymbolTree(children[1]);
@@ -188,28 +202,18 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
std::string functionCallName = concatSymbolTree(children[1]); std::string functionCallName = concatSymbolTree(children[1]);
//std::cout << "scope lookup from expression or similar" << std::endl; //std::cout << "scope lookup from expression or similar" << std::endl;
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(lhs); transformedChildren.push_back(rhs); std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(lhs); transformedChildren.push_back(rhs);
NodeTree<ASTData>* function = doFunction(scope, functionCallName, transformedChildren, templateTypeReplacements); newNode = doFunction(scope, functionCallName, transformedChildren, templateTypeReplacements);
if (function == NULL) { if (newNode == NULL) {
std::cout << "scope lookup error! Could not find " << functionCallName << " in expression " << std::endl; std::cout << "scope lookup error! Could not find " << functionCallName << " in expression " << std::endl;
throw "LOOKUP ERROR: " + functionCallName; throw "LOOKUP ERROR: " + functionCallName;
} }
newNode = function;
// newNode = new NodeTree<ASTData>(functionCallName, ASTData(function_call, Symbol(functionCallName, true)));
// newNode->addChild(function); // First child of function call is a link to the function definition
// newNode->addChild(lhs);
// newNode->addChild(rhs);
// if (name == "access_operation")
// std::cout << "Access Operation: " << lhs->getDataRef()->symbol.getName() << " : " << rhs->getDataRef()->symbol.getName() << std::endl;
// std::cout << functionCallName << " - " << function->getName() << " has value type " << function->getDataRef()->valueType << " and rhs " << rhs->getDataRef()->valueType << std::endl;
// //Set the value of this function call // //Set the value of this function call
if (function->getDataRef()->valueType) if (newNode->getDataRef()->valueType == NULL && rhs->getDataRef()->valueType)
newNode->getDataRef()->valueType = function->getDataRef()->valueType;
else if (rhs->getDataRef()->valueType)
newNode->getDataRef()->valueType = rhs->getDataRef()->valueType; newNode->getDataRef()->valueType = rhs->getDataRef()->valueType;
else else
newNode->getDataRef()->valueType = NULL; newNode->getDataRef()->valueType = NULL;
std::cout << "function call to " << functionCallName << " - " << function->getName() << " is now " << newNode->getDataRef()->valueType << std::endl; std::cout << "function call to " << functionCallName << " - " << newNode->getName() << " is now " << newNode->getDataRef()->valueType << std::endl;
return newNode; return newNode;
//skipChildren.insert(1); //skipChildren.insert(1);
} else if (children.size() == 2) { } else if (children.size() == 2) {
@@ -444,9 +448,13 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
std::cout<<std::endl; std::cout<<std::endl;
std::vector<Type> oldTypes = mapNodesToTypes(nodes); std::vector<Type> oldTypes = mapNodesToTypes(nodes);
if (lookup == "*" || lookup == "&" || lookup == "[]") { if ((nodes.size() != 2 && lookup == "*") || lookup == "&" || lookup == "[]") {
Type* newType = oldTypes[0].clone(); Type* newType = oldTypes[0].clone();
lookup == "*" || lookup == "[]" ? newType->indirection-- : newType->indirection++; if (lookup == "*" || lookup == "[]")
newType->increaseIndirection();
else
newType->decreaseIndirection();
newNode->getDataRef()->valueType = newType, std::cout << "Operator " + lookup << " is altering indirection "<< std::endl; newNode->getDataRef()->valueType = newType, std::cout << "Operator " + lookup << " is altering indirection "<< std::endl;
} else { } else {
newNode->getDataRef()->valueType = function->getDataRef()->valueType, std::cout << "Some other ||" << lookup << "||" << std::endl; newNode->getDataRef()->valueType = function->getDataRef()->valueType, std::cout << "Some other ||" << lookup << "||" << std::endl;
@@ -475,7 +483,9 @@ NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std:
return *i; return *i;
std::vector<NodeTree<ASTData>*> children = (*i)->getChildren(); std::vector<NodeTree<ASTData>*> children = (*i)->getChildren();
if (types.size() != ((children.size() > 0) ? children.size()-1 : 0)) { //We subtract one from the children to get the type size only if there is at least one child AND this function is not a
//non-instantiated template (which would not have a body node, which is why we subtract one)
if (types.size() != ((children.size() > 0 && (*i)->getDataRef()->valueType->baseType != template_type ) ? children.size()-1 : children.size())) {
std::cout << "Type sizes do not match between two " << lookup << "(" << types.size() << "," << ((children.size() > 0) ? children.size()-1 : 0) << "), types are: "; std::cout << "Type sizes do not match between two " << lookup << "(" << types.size() << "," << ((children.size() > 0) ? children.size()-1 : 0) << "), types are: ";
for (auto j : types) for (auto j : types)
std::cout << j.toString() << " "; std::cout << j.toString() << " ";
@@ -484,9 +494,12 @@ NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std:
} }
bool typesMatch = true; bool typesMatch = true;
for (int j = 0; j < types.size(); j++) { for (int j = 0; j < types.size(); j++) {
if (types[j] != *(children[j]->getDataRef()->valueType)) { Type* tmpType = children[j]->getDataRef()->valueType;
//Don't worry if types don't match if it's a template type
if (types[j] != *tmpType && tmpType->baseType != template_type_type) {
typesMatch = false; typesMatch = false;
std::cout << "Types do not match between two " << lookup << " " << types[j].toString() << " vs " << children[j]->getDataRef()->valueType->toString() << std::endl; std::cout << "Types do not match between two " << lookup << " " << types[j].toString();
std::cout << " vs " << children[j]->getDataRef()->valueType->toString() << std::endl;
break; break;
} }
} }
@@ -546,7 +559,7 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
if (templateTypeReplacements.find(edited) != templateTypeReplacements.end()) { if (templateTypeReplacements.find(edited) != templateTypeReplacements.end()) {
std::cout << "Template type! (" << edited << ")" << std::endl; std::cout << "Template type! (" << edited << ")" << std::endl;
Type* templateTypeReplacement = templateTypeReplacements[edited]->clone(); Type* templateTypeReplacement = templateTypeReplacements[edited]->clone();
templateTypeReplacement->indirection += indirection; templateTypeReplacement->modifyIndirection(indirection);
return templateTypeReplacement; return templateTypeReplacement;
} else { } else {
std::cout << edited << " was not found in templateTypeReplacements" << std::endl; std::cout << edited << " was not found in templateTypeReplacements" << std::endl;
@@ -592,6 +605,9 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
skipChildren.insert(1); //Identifier lookup will be ourselves, as we just added ourselves to the scope skipChildren.insert(1); //Identifier lookup will be ourselves, as we just added ourselves to the scope
typeDefinition->addChildren(transformChildren(templateSyntaxTree->getChildren(), skipChildren, typeDefinition, std::vector<Type>(), newTemplateTypeReplacement)); typeDefinition->addChildren(transformChildren(templateSyntaxTree->getChildren(), skipChildren, typeDefinition, std::vector<Type>(), newTemplateTypeReplacement));
std::cout << "Done instantating " << fullyInstantiatedName << " that had template parameter " << templateParameterName << " with " << replacementType->toString() << std::endl; std::cout << "Done instantating " << fullyInstantiatedName << " that had template parameter " << templateParameterName << " with " << replacementType->toString() << std::endl;
} else if (typeDefinition == NULL) {
std::cout << "Could not find type " << edited << ", returning NULL" << std::endl;
return NULL;
} else { } else {
std::cout << "Type: " << edited << " already instantiated with " << typeDefinition << ", will be " << Type(baseType, typeDefinition, indirection).toString() << std::endl; std::cout << "Type: " << edited << " already instantiated with " << typeDefinition << ", will be " << Type(baseType, typeDefinition, indirection).toString() << std::endl;
} }
@@ -605,20 +621,37 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
//First look to see if we can find this already instantiated //First look to see if we can find this already instantiated
std::cout << "Finding or instantiating templated function" << std::endl; std::cout << "Finding or instantiating templated function" << std::endl;
std::string functionName = concatSymbolTree(children[0]); std::string functionName = concatSymbolTree(children[0]);
std::string fullyInstantiatedName = functionName + concatSymbolTree(children[1]); Type* templateActualType = typeFromTypeNode(children[1]->getChildren()[1], scope, templateTypeReplacements);
std::string fullyInstantiatedName = functionName + "<" + templateActualType->toString() + ">";
std::cout << "Looking for " << fullyInstantiatedName << std::endl; std::cout << "Looking for " << fullyInstantiatedName << std::endl;
NodeTree<ASTData>* instantiatedFunction = scopeLookup(scope, fullyInstantiatedName);
std::cout << "Types are : ";
for (auto i : types)
std::cout << " " << i.toString();
std::cout << std::endl;
NodeTree<ASTData>* instantiatedFunction = scopeLookup(scope, fullyInstantiatedName,types);
//If it already exists, return it //If it already exists, return it
if (instantiatedFunction) if (instantiatedFunction) {
std::cout << fullyInstantiatedName << " already exists! Returning" << std::endl;
return instantiatedFunction; return instantiatedFunction;
} else {
std::cout << fullyInstantiatedName << " does NOT exist" << std::endl;
}
//Otherwise, we're going to instantiate it //Otherwise, we're going to instantiate it
//Find the template definition //Find the template definition
NodeTree<ASTData>* templateDefinition = scopeLookup(scope,functionName); NodeTree<ASTData>* templateDefinition = scopeLookup(scope,functionName,types);
if (templateDefinition == NULL) {
std::cout << functionName << " search turned up null, returing null" << std::endl;
return NULL;
}
NodeTree<Symbol>* templateSyntaxTree = templateDefinition->getDataRef()->valueType->templateDefinition; NodeTree<Symbol>* templateSyntaxTree = templateDefinition->getDataRef()->valueType->templateDefinition;
std::string templateParameterName = concatSymbolTree(templateSyntaxTree->getChildren()[0]->getChildren()[1]); std::string templateParameterName = concatSymbolTree(templateSyntaxTree->getChildren()[0]->getChildren()[1]);
std::map<std::string, Type*> newTemplateTypeReplacement; std::map<std::string, Type*> newTemplateTypeReplacement;
newTemplateTypeReplacement[templateParameterName] = typeFromTypeNode(children[1]->getChildren()[1], scope, templateTypeReplacements); newTemplateTypeReplacement[templateParameterName] = templateActualType;
std::vector<NodeTree<Symbol>*> templateChildren = templateSyntaxTree->getChildren(); std::vector<NodeTree<Symbol>*> templateChildren = templateSyntaxTree->getChildren();
for (int i = 0; i < templateChildren.size(); i++) for (int i = 0; i < templateChildren.size(); i++)

View File

@@ -58,10 +58,11 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
break; break;
case function: case function:
{ {
if (decChildren.size() == 0) { //Not a real function, must be a built in passthrough { if (declarationData.valueType->baseType == template_type)
output += "/* built in function: " + declarationData.toString() + " */\n"; output += "/* template function " + declarationData.symbol.toString() + " */\n";
break; else if (decChildren.size() == 0) //Not a real function, must be a built in passthrough
} output += "/* built in function: " + declarationData.symbol.toString() + " */\n";
else {
output += "\n" + ValueTypeToCType(declarationData.valueType) + " "; output += "\n" + ValueTypeToCType(declarationData.valueType) + " ";
std::string nameDecoration, parameters; std::string nameDecoration, parameters;
for (int j = 0; j < decChildren.size()-1; j++) { for (int j = 0; j < decChildren.size()-1; j++) {
@@ -71,8 +72,9 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType); 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;
} }
}
break;
case type_def: case type_def:
//type //type
output += "/*typedef " + declarationData.symbol.getName() + " */\n"; output += "/*typedef " + declarationData.symbol.getName() + " */\n";
@@ -114,13 +116,15 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
} else { } else {
std::string objectString = "typedef struct __struct_dummy_" + CifyName(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
tabLevel++;
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;
if (children[i]->getName() == "function") //If object method if (children[i]->getName() == "function") //If object method
postString += generateObjectMethod(from, children[i]) + "\n"; postString += generateObjectMethod(from, children[i]) + "\n";
else else
objectString += generate(children[i], enclosingObject) + "\n"; objectString += tabs() + generate(children[i], enclosingObject) + "\n";
} }
tabLevel--;
objectString += "} " + CifyName(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
} }
@@ -202,7 +206,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
if (funcType == function) { if (funcType == function) {
if (name == "++" || name == "--") if (name == "++" || name == "--")
return generate(children[1], enclosingObject) + name; return generate(children[1], enclosingObject) + name;
if (name == "*" || name == "&" && children.size() == 2) //Is dereference, not multiplication, or address-of if ( (name == "*" || name == "&") && children.size() == 2) //Is dereference, not multiplication, or address-of
return name + "(" + generate(children[1], enclosingObject) + ")"; return name + "(" + generate(children[1], enclosingObject) + ")";
if (name == "[]") if (name == "[]")
return "(" + generate(children[1], enclosingObject) + ")[" +generate(children[2],enclosingObject) + "]"; return "(" + generate(children[1], enclosingObject) + ")[" +generate(children[2],enclosingObject) + "]";
@@ -283,7 +287,7 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
std::string output; std::string output;
ASTData data = from->getData(); ASTData data = from->getData();
Type enclosingObjectType = *(enclosingObject->getDataRef()->valueType); //Copy a new type so we can turn it into a pointer if we need to Type enclosingObjectType = *(enclosingObject->getDataRef()->valueType); //Copy a new type so we can turn it into a pointer if we need to
enclosingObjectType.indirection++; enclosingObjectType.increaseIndirection();
std::vector<NodeTree<ASTData>*> children = from->getChildren(); std::vector<NodeTree<ASTData>*> children = from->getChildren();
std::string nameDecoration, parameters; std::string nameDecoration, parameters;
for (int i = 0; i < children.size()-1; i++) { for (int i = 0; i < children.size()-1; i++) {
@@ -327,7 +331,7 @@ std::string CGenerator::ValueTypeToCType(Type *type) {
return_type = "unknown_ValueType"; return_type = "unknown_ValueType";
break; break;
} }
for (int i = 0; i < type->indirection; i++) for (int i = 0; i < type->getIndirection(); i++)
return_type += "*"; return_type += "*";
return return_type; return return_type;
} }
@@ -363,7 +367,7 @@ std::string CGenerator::ValueTypeToCTypeDecoration(Type *type) {
return_type = "unknown_ValueType"; return_type = "unknown_ValueType";
break; break;
} }
for (int i = 0; i < type->indirection; i++) for (int i = 0; i < type->getIndirection(); i++)
return_type += "_P__"; return_type += "_P__";
return return_type; return return_type;
} }

View File

@@ -40,9 +40,14 @@ Importer::~Importer() {
} }
NodeTree<ASTData>* Importer::import(std::string fileName) { NodeTree<ASTData>* Importer::import(std::string fileName) {
std::cout << "\n\nImporting " << fileName << " ";
//Check to see if we've already done it //Check to see if we've already done it
if (imported.find(fileName) != imported.end()) if (imported.find(fileName) != imported.end()) {
std::cout << "Already Imported!" << std::endl;
return imported[fileName]; return imported[fileName];
}
std::cout << "Not yet imported" << std::endl;
std::ifstream programInFile; std::ifstream programInFile;
std::ofstream outFile, outFileTransformed, outFileAST; std::ofstream outFile, outFileTransformed, outFileAST;
@@ -126,6 +131,8 @@ NodeTree<ASTData>* Importer::import(std::string fileName) {
imported[fileName] = AST; imported[fileName] = AST;
std::cout << "Done importing " << fileName << "\n\n" << std::endl;
return AST; return AST;
} }

View File

@@ -19,6 +19,7 @@ Type::Type(ValueType typeIn, int indirectionIn) {
baseType = typeIn; baseType = typeIn;
typeDefinition = NULL; typeDefinition = NULL;
templateDefinition = NULL; templateDefinition = NULL;
if (indirection < 0) SEGFAULT
} }
Type::Type(NodeTree<ASTData>* typeDefinitionIn) { Type::Type(NodeTree<ASTData>* typeDefinitionIn) {
@@ -32,6 +33,7 @@ Type::Type(NodeTree<ASTData>* typeDefinitionIn, int indirectionIn) {
baseType = none; baseType = none;
typeDefinition = typeDefinitionIn; typeDefinition = typeDefinitionIn;
templateDefinition = NULL; templateDefinition = NULL;
if (indirection < 0) SEGFAULT
} }
Type::Type(ValueType typeIn, NodeTree<ASTData>* typeDefinitionIn, int indirectionIn) { Type::Type(ValueType typeIn, NodeTree<ASTData>* typeDefinitionIn, int indirectionIn) {
@@ -39,6 +41,7 @@ Type::Type(ValueType typeIn, NodeTree<ASTData>* typeDefinitionIn, int indirectio
indirection = indirectionIn; indirection = indirectionIn;
typeDefinition = typeDefinitionIn; typeDefinition = typeDefinitionIn;
templateDefinition = NULL; templateDefinition = NULL;
if (indirection < 0) SEGFAULT
} }
Type::Type(ValueType typeIn, NodeTree<Symbol>* templateDefinitionIn) { Type::Type(ValueType typeIn, NodeTree<Symbol>* templateDefinitionIn) {
indirection = 0; indirection = 0;
@@ -70,6 +73,10 @@ std::string Type::toString() {
break; break;
case template_type: case template_type:
typeString = "template: " + templateDefinition->getDataRef()->toString(); typeString = "template: " + templateDefinition->getDataRef()->toString();
break;
case template_type_type:
typeString = "template_type_type";
break;
case void_type: case void_type:
typeString = "void"; typeString = "void";
break; break;
@@ -96,9 +103,34 @@ std::string Type::toString() {
} }
for (int i = 0; i < indirection; i++) for (int i = 0; i < indirection; i++)
typeString += "*"; typeString += "*";
//std::cout << "Extra components of " << typeString << " are " << indirection << " " << typeDefinition << " " << templateDefinition << std::endl;
return typeString; return typeString;
} }
Type* Type::clone() { Type* Type::clone() {
return new Type(baseType, typeDefinition, indirection); return new Type(baseType, typeDefinition, indirection);
} }
void Type::check() {
if (indirection < 0) SEGFAULT
}
int Type::getIndirection() {
return indirection;
}
void Type::setIndirection(int indirectionIn) {
indirection = indirectionIn;
check();
}
void Type::increaseIndirection() {
setIndirection(indirection+1);
}
void Type::decreaseIndirection() {
setIndirection(indirection-1);
}
void Type::modifyIndirection(int mod) {
setIndirection(indirection + mod);
}

View File

@@ -21,3 +21,35 @@ void free(char* memPtr) {
""" """
} }
} }
template <T> void free(T* memPtr) {
__if_comp__ __C__ {
__simple_passthrough__ """
free(memPtr);
"""
}
}
template <T> int sizeof() {
int result = 0;
T testObj;
__if_comp__ __C__ {
__simple_passthrough__ """
result = sizeof(testObj);
"""
}
return result;
}
template <T> T* new(int count) {
return malloc( sizeof<T>() * count );
}
template <T> T* new() {
return new<T>(1);
}
template <T> void delete(T* toDelete) {
free<T>(toDelete);
}

View File

@@ -0,0 +1,9 @@
import io;
typedef template <T> trivialContainer {
T data;
void print() {
print(data);
}
};