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:
@@ -5,6 +5,10 @@
|
||||
#define NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
#ifndef SEGFAULT
|
||||
#define SEGFAULT (*((char*)0)), std::cout << "\t\t\t\tNEGATIVE*************************************************************************" << std::endl;
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
@@ -13,7 +17,7 @@ class ASTData;
|
||||
#include "ASTData.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 {
|
||||
@@ -30,11 +34,17 @@ class Type {
|
||||
bool const operator!=(const Type &other)const;
|
||||
Type* clone();
|
||||
std::string toString();
|
||||
int getIndirection();
|
||||
void setIndirection(int indirectionIn);
|
||||
void increaseIndirection();
|
||||
void decreaseIndirection();
|
||||
void modifyIndirection(int mod);
|
||||
void check();
|
||||
ValueType baseType;
|
||||
NodeTree<ASTData>* typeDefinition;
|
||||
int indirection;
|
||||
NodeTree<Symbol>* templateDefinition;
|
||||
private:
|
||||
int indirection;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -42,7 +42,7 @@ opt_parameter_list = parameter_list | ;
|
||||
parameter_list = parameter_list WS "," WS parameter | parameter ;
|
||||
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 ">" ;
|
||||
class_innerds = visibility_block WS class_innerds | visibility_block ;
|
||||
visibility_block = "public:" WS declaration_block | "protected:" WS declaration_block | "private:" WS declaration_block ;
|
||||
|
||||
@@ -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)));
|
||||
@@ -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)));
|
||||
scope->getDataRef()->scope[functionName].push_back(newNode);
|
||||
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;
|
||||
}
|
||||
functionName = concatSymbolTree(children[1]);
|
||||
@@ -188,28 +202,18 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
std::string functionCallName = concatSymbolTree(children[1]);
|
||||
//std::cout << "scope lookup from expression or similar" << std::endl;
|
||||
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(lhs); transformedChildren.push_back(rhs);
|
||||
NodeTree<ASTData>* function = doFunction(scope, functionCallName, transformedChildren, templateTypeReplacements);
|
||||
if (function == NULL) {
|
||||
newNode = doFunction(scope, functionCallName, transformedChildren, templateTypeReplacements);
|
||||
if (newNode == NULL) {
|
||||
std::cout << "scope lookup error! Could not find " << functionCallName << " in expression " << std::endl;
|
||||
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
|
||||
if (function->getDataRef()->valueType)
|
||||
newNode->getDataRef()->valueType = function->getDataRef()->valueType;
|
||||
else if (rhs->getDataRef()->valueType)
|
||||
if (newNode->getDataRef()->valueType == NULL && rhs->getDataRef()->valueType)
|
||||
newNode->getDataRef()->valueType = rhs->getDataRef()->valueType;
|
||||
else
|
||||
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;
|
||||
//skipChildren.insert(1);
|
||||
} else if (children.size() == 2) {
|
||||
@@ -444,9 +448,13 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
|
||||
std::cout<<std::endl;
|
||||
|
||||
std::vector<Type> oldTypes = mapNodesToTypes(nodes);
|
||||
if (lookup == "*" || lookup == "&" || lookup == "[]") {
|
||||
if ((nodes.size() != 2 && lookup == "*") || lookup == "&" || lookup == "[]") {
|
||||
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;
|
||||
} else {
|
||||
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;
|
||||
|
||||
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: ";
|
||||
for (auto j : types)
|
||||
std::cout << j.toString() << " ";
|
||||
@@ -484,9 +494,12 @@ NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std:
|
||||
}
|
||||
bool typesMatch = true;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -546,7 +559,7 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
||||
if (templateTypeReplacements.find(edited) != templateTypeReplacements.end()) {
|
||||
std::cout << "Template type! (" << edited << ")" << std::endl;
|
||||
Type* templateTypeReplacement = templateTypeReplacements[edited]->clone();
|
||||
templateTypeReplacement->indirection += indirection;
|
||||
templateTypeReplacement->modifyIndirection(indirection);
|
||||
return templateTypeReplacement;
|
||||
} else {
|
||||
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
|
||||
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;
|
||||
} else if (typeDefinition == NULL) {
|
||||
std::cout << "Could not find type " << edited << ", returning NULL" << std::endl;
|
||||
return NULL;
|
||||
} else {
|
||||
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
|
||||
std::cout << "Finding or instantiating templated function" << std::endl;
|
||||
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;
|
||||
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 (instantiatedFunction)
|
||||
if (instantiatedFunction) {
|
||||
std::cout << fullyInstantiatedName << " already exists! Returning" << std::endl;
|
||||
return instantiatedFunction;
|
||||
} else {
|
||||
std::cout << fullyInstantiatedName << " does NOT exist" << std::endl;
|
||||
}
|
||||
|
||||
//Otherwise, we're going to instantiate it
|
||||
//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;
|
||||
std::string templateParameterName = concatSymbolTree(templateSyntaxTree->getChildren()[0]->getChildren()[1]);
|
||||
|
||||
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();
|
||||
for (int i = 0; i < templateChildren.size(); i++)
|
||||
|
||||
@@ -58,21 +58,23 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
break;
|
||||
case function:
|
||||
{
|
||||
if (decChildren.size() == 0) { //Not a real function, must be a built in passthrough {
|
||||
output += "/* built in function: " + declarationData.toString() + " */\n";
|
||||
break;
|
||||
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";
|
||||
else {
|
||||
output += "\n" + ValueTypeToCType(declarationData.valueType) + " ";
|
||||
std::string nameDecoration, parameters;
|
||||
for (int j = 0; j < decChildren.size()-1; j++) {
|
||||
if (j > 0)
|
||||
parameters += ", ";
|
||||
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 += "\n" + ValueTypeToCType(declarationData.valueType) + " ";
|
||||
std::string nameDecoration, parameters;
|
||||
for (int j = 0; j < decChildren.size()-1; j++) {
|
||||
if (j > 0)
|
||||
parameters += ", ";
|
||||
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";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case type_def:
|
||||
//type
|
||||
output += "/*typedef " + declarationData.symbol.getName() + " */\n";
|
||||
@@ -114,13 +116,15 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
} else {
|
||||
std::string objectString = "typedef struct __struct_dummy_" + CifyName(data.symbol.getName()) + "__ {\n";
|
||||
std::string postString; //The functions have to be outside the struct definition
|
||||
tabLevel++;
|
||||
for (int i = 0; i < children.size(); i++) {
|
||||
std::cout << children[i]->getName() << std::endl;
|
||||
if (children[i]->getName() == "function") //If object method
|
||||
postString += generateObjectMethod(from, children[i]) + "\n";
|
||||
else
|
||||
objectString += generate(children[i], enclosingObject) + "\n";
|
||||
objectString += tabs() + generate(children[i], enclosingObject) + "\n";
|
||||
}
|
||||
tabLevel--;
|
||||
objectString += "} " + CifyName(data.symbol.getName()) + ";";
|
||||
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 (name == "++" || 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) + ")";
|
||||
if (name == "[]")
|
||||
return "(" + generate(children[1], enclosingObject) + ")[" +generate(children[2],enclosingObject) + "]";
|
||||
@@ -283,7 +287,7 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
|
||||
std::string output;
|
||||
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
|
||||
enclosingObjectType.indirection++;
|
||||
enclosingObjectType.increaseIndirection();
|
||||
std::vector<NodeTree<ASTData>*> children = from->getChildren();
|
||||
std::string nameDecoration, parameters;
|
||||
for (int i = 0; i < children.size()-1; i++) {
|
||||
@@ -327,7 +331,7 @@ std::string CGenerator::ValueTypeToCType(Type *type) {
|
||||
return_type = "unknown_ValueType";
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < type->indirection; i++)
|
||||
for (int i = 0; i < type->getIndirection(); i++)
|
||||
return_type += "*";
|
||||
return return_type;
|
||||
}
|
||||
@@ -363,7 +367,7 @@ std::string CGenerator::ValueTypeToCTypeDecoration(Type *type) {
|
||||
return_type = "unknown_ValueType";
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < type->indirection; i++)
|
||||
for (int i = 0; i < type->getIndirection(); i++)
|
||||
return_type += "_P__";
|
||||
return return_type;
|
||||
}
|
||||
|
||||
@@ -40,9 +40,14 @@ Importer::~Importer() {
|
||||
}
|
||||
|
||||
NodeTree<ASTData>* Importer::import(std::string fileName) {
|
||||
|
||||
std::cout << "\n\nImporting " << fileName << " ";
|
||||
//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];
|
||||
}
|
||||
std::cout << "Not yet imported" << std::endl;
|
||||
|
||||
std::ifstream programInFile;
|
||||
std::ofstream outFile, outFileTransformed, outFileAST;
|
||||
@@ -126,6 +131,8 @@ NodeTree<ASTData>* Importer::import(std::string fileName) {
|
||||
|
||||
imported[fileName] = AST;
|
||||
|
||||
std::cout << "Done importing " << fileName << "\n\n" << std::endl;
|
||||
|
||||
return AST;
|
||||
}
|
||||
|
||||
|
||||
32
src/Type.cpp
32
src/Type.cpp
@@ -19,6 +19,7 @@ Type::Type(ValueType typeIn, int indirectionIn) {
|
||||
baseType = typeIn;
|
||||
typeDefinition = NULL;
|
||||
templateDefinition = NULL;
|
||||
if (indirection < 0) SEGFAULT
|
||||
}
|
||||
|
||||
Type::Type(NodeTree<ASTData>* typeDefinitionIn) {
|
||||
@@ -32,6 +33,7 @@ Type::Type(NodeTree<ASTData>* typeDefinitionIn, int indirectionIn) {
|
||||
baseType = none;
|
||||
typeDefinition = typeDefinitionIn;
|
||||
templateDefinition = NULL;
|
||||
if (indirection < 0) SEGFAULT
|
||||
}
|
||||
|
||||
Type::Type(ValueType typeIn, NodeTree<ASTData>* typeDefinitionIn, int indirectionIn) {
|
||||
@@ -39,6 +41,7 @@ Type::Type(ValueType typeIn, NodeTree<ASTData>* typeDefinitionIn, int indirectio
|
||||
indirection = indirectionIn;
|
||||
typeDefinition = typeDefinitionIn;
|
||||
templateDefinition = NULL;
|
||||
if (indirection < 0) SEGFAULT
|
||||
}
|
||||
Type::Type(ValueType typeIn, NodeTree<Symbol>* templateDefinitionIn) {
|
||||
indirection = 0;
|
||||
@@ -70,6 +73,10 @@ std::string Type::toString() {
|
||||
break;
|
||||
case template_type:
|
||||
typeString = "template: " + templateDefinition->getDataRef()->toString();
|
||||
break;
|
||||
case template_type_type:
|
||||
typeString = "template_type_type";
|
||||
break;
|
||||
case void_type:
|
||||
typeString = "void";
|
||||
break;
|
||||
@@ -96,9 +103,34 @@ std::string Type::toString() {
|
||||
}
|
||||
for (int i = 0; i < indirection; i++)
|
||||
typeString += "*";
|
||||
//std::cout << "Extra components of " << typeString << " are " << indirection << " " << typeDefinition << " " << templateDefinition << std::endl;
|
||||
return typeString;
|
||||
}
|
||||
|
||||
Type* Type::clone() {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
9
stdlib/trivial_container.krak
Normal file
9
stdlib/trivial_container.krak
Normal file
@@ -0,0 +1,9 @@
|
||||
import io;
|
||||
|
||||
typedef template <T> trivialContainer {
|
||||
T data;
|
||||
void print() {
|
||||
print(data);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user