Added "Init Position Call" (takes the place of implicit constructors) and the this keyword! This was the structure needed for more sensable memory management. At least delete will need some updating before it becomes very usable, though. (Figuring out the types for function template instantiation) Anyway, good progress here!
This commit is contained in:
@@ -45,7 +45,8 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
|
|||||||
NodeTree<ASTData>* findOrInstantiateFunctionTemplate(std::vector<NodeTree<Symbol>*> children, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements);
|
NodeTree<ASTData>* findOrInstantiateFunctionTemplate(std::vector<NodeTree<Symbol>*> children, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements);
|
||||||
private:
|
private:
|
||||||
Importer * importer;
|
Importer * importer;
|
||||||
std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelScope;
|
std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelReservedWords;
|
||||||
|
std::map<std::string, std::vector<NodeTree<ASTData>*>> languageLevelOperators;
|
||||||
NodeTree<ASTData>* topScope; //maintained for templates that need to add themselves to the top scope no matter where they are instantiated
|
NodeTree<ASTData>* topScope; //maintained for templates that need to add themselves to the top scope no matter where they are instantiated
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ number = integer | float | double ;
|
|||||||
access_operation = unarad "." identifier | unarad "->" identifier ;
|
access_operation = unarad "." identifier | unarad "->" identifier ;
|
||||||
|
|
||||||
assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS boolean_expression | factor WS "-=" WS boolean_expression | factor WS "\*=" WS boolean_expression | factor WS "/=" WS boolean_expression ;
|
assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS boolean_expression | factor WS "-=" WS boolean_expression | factor WS "\*=" WS boolean_expression | factor WS "/=" WS boolean_expression ;
|
||||||
declaration_statement = type WS identifier WS "=" WS boolean_expression | type WS identifier ;
|
declaration_statement = type WS identifier WS "=" WS boolean_expression | type WS identifier | type WS identifier WS "." WS identifier WS "\(" WS opt_parameter_list WS "\)" ;
|
||||||
|
|
||||||
alphanumeric = alphanumeric numeric | alphanumeric alpha | numeric | alpha ;
|
alphanumeric = alphanumeric numeric | alphanumeric alpha | numeric | alpha ;
|
||||||
hexadecimal = "0x(1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+" ;
|
hexadecimal = "0x(1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)+" ;
|
||||||
|
|||||||
@@ -3,30 +3,34 @@
|
|||||||
ASTTransformation::ASTTransformation(Importer *importerIn) {
|
ASTTransformation::ASTTransformation(Importer *importerIn) {
|
||||||
importer = importerIn;
|
importer = importerIn;
|
||||||
topScope = NULL;
|
topScope = NULL;
|
||||||
//Set up language level special scope. (the final scope checked)
|
|
||||||
|
//Set up language level reserved identifier scope (only this, right now)
|
||||||
|
languageLevelReservedWords["this"].push_back(new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol("this", true), NULL)));
|
||||||
|
|
||||||
|
//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)));
|
languageLevelOperators["+"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("+", true), NULL)));
|
||||||
languageLevelScope["-"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("-", true), NULL)));
|
languageLevelOperators["-"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("-", true), NULL)));
|
||||||
languageLevelScope["*"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("*", true), NULL)));
|
languageLevelOperators["*"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("*", true), NULL)));
|
||||||
languageLevelScope["/"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("/", true), NULL)));
|
languageLevelOperators["/"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("/", true), NULL)));
|
||||||
languageLevelScope["%"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("%", true), NULL)));
|
languageLevelOperators["%"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("%", true), NULL)));
|
||||||
languageLevelScope["&"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("&", true), NULL)));
|
languageLevelOperators["&"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("&", true), NULL)));
|
||||||
languageLevelScope["--"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("--", true), NULL)));
|
languageLevelOperators["--"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("--", true), NULL)));
|
||||||
languageLevelScope["++"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("++", true), NULL)));
|
languageLevelOperators["++"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("++", true), NULL)));
|
||||||
languageLevelScope["=="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("==", true), NULL)));
|
languageLevelOperators["=="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("==", true), NULL)));
|
||||||
languageLevelScope["<="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("<=", true), NULL)));
|
languageLevelOperators["<="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("<=", true), NULL)));
|
||||||
languageLevelScope[">="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol(">=", true), NULL)));
|
languageLevelOperators[">="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol(">=", true), NULL)));
|
||||||
languageLevelScope["<"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("<", true), NULL)));
|
languageLevelOperators["<"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("<", true), NULL)));
|
||||||
languageLevelScope[">"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol(">", true), NULL)));
|
languageLevelOperators[">"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol(">", true), NULL)));
|
||||||
languageLevelScope["&&"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("&&", true), NULL)));
|
languageLevelOperators["&&"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("&&", true), NULL)));
|
||||||
languageLevelScope["||"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("||", true), NULL)));
|
languageLevelOperators["||"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("||", true), NULL)));
|
||||||
languageLevelScope["!"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("!", true), NULL)));
|
languageLevelOperators["!"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("!", true), NULL)));
|
||||||
languageLevelScope["*="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("*=", true), NULL)));
|
languageLevelOperators["*="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("*=", true), NULL)));
|
||||||
languageLevelScope["+="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("+=", true), NULL)));
|
languageLevelOperators["+="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("+=", true), NULL)));
|
||||||
languageLevelScope["-="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("-=", true), NULL)));
|
languageLevelOperators["-="].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("-=", true), NULL)));
|
||||||
languageLevelScope["."].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol(".", true), NULL)));
|
languageLevelOperators["."].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol(".", true), NULL)));
|
||||||
languageLevelScope["->"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("->", true), NULL)));
|
languageLevelOperators["->"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("->", true), NULL)));
|
||||||
languageLevelScope["[]"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("[]", true), NULL)));
|
languageLevelOperators["[]"].push_back(new NodeTree<ASTData>("function", ASTData(function, Symbol("[]", true), NULL)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTTransformation::~ASTTransformation() {
|
ASTTransformation::~ASTTransformation() {
|
||||||
@@ -132,7 +136,8 @@ void ASTTransformation::secondPassDoClassInsides(NodeTree<ASTData>* typeDef, std
|
|||||||
|
|
||||||
//This function may need to partially instantiate a class template
|
//This function may need to partially instantiate a class template
|
||||||
NodeTree<ASTData>* ASTTransformation::secondPassDeclaration(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::map<std::string, Type*> templateTypeReplacements) {
|
NodeTree<ASTData>* ASTTransformation::secondPassDeclaration(NodeTree<Symbol>* from, NodeTree<ASTData>* scope, std::map<std::string, Type*> templateTypeReplacements) {
|
||||||
NodeTree<ASTData>* decStmt = new NodeTree<ASTData>("declaration_statement", ASTData(declaration_statement));
|
//Check here for method call (an error here)
|
||||||
|
NodeTree<ASTData>* decStmt = new NodeTree<ASTData>("declaration_statement", ASTData(declaration_statement));
|
||||||
std::string newIdentifierStr = concatSymbolTree(from->getChildren()[1]);
|
std::string newIdentifierStr = concatSymbolTree(from->getChildren()[1]);
|
||||||
Type* identifierType = typeFromTypeNode(from->getChildren()[0], scope, templateTypeReplacements, false);
|
Type* identifierType = typeFromTypeNode(from->getChildren()[0], scope, templateTypeReplacements, false);
|
||||||
std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
|
std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
|
||||||
@@ -576,9 +581,33 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
newNode->getDataRef()->scope["~enclosing_scope"].push_back(scope);
|
newNode->getDataRef()->scope["~enclosing_scope"].push_back(scope);
|
||||||
newNode->addChild(newIdentifier);
|
newNode->addChild(newIdentifier);
|
||||||
|
|
||||||
|
if (children.size() > 2 && concatSymbolTree(children[2]) == ".") {
|
||||||
|
//A bit of a special case for declarations - if there's anything after just the normal 1 node declaration, it's either
|
||||||
|
//an expression that is assigned to the declaration (int a = 4;) or a member call (Object a.constructAThing())
|
||||||
|
//This code is a simplified version of the code in function_call with respect to access_operation.
|
||||||
|
//Note that in this case, what is lhs there is our newIdentifier here (the declaration of the left side of the access operation)
|
||||||
|
auto sliced = slice(children, 4, -1);
|
||||||
|
std::vector<NodeTree<ASTData>*> initPositionFuncParams = transformChildren(sliced, std::set<int>(), scope, types, templateTypeReplacements, instantiateTemplates);
|
||||||
|
NodeTree<ASTData>* rhs = transform(children[3], identifierType->typeDefinition, mapNodesToTypes(initPositionFuncParams), templateTypeReplacements, instantiateTemplates); //If an access operation, then the right side will be in the lhs's type's scope
|
||||||
|
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(newIdentifier); transformedChildren.push_back(rhs);
|
||||||
|
NodeTree<ASTData>* accessFuncCall = doFunction(scope, ".", transformedChildren, templateTypeReplacements);
|
||||||
|
accessFuncCall->getDataRef()->valueType = rhs->getDataRef()->valueType;
|
||||||
|
//Now we borrow a bit of code from function_call below to actually use our new accessFuncCall to setup a "initPosition" function call
|
||||||
|
//that will follow the identifier in this declaration node
|
||||||
|
std::string initPosFuncName = newIdentifierStr + "." + concatSymbolTree(children[3]);
|
||||||
|
NodeTree<ASTData>* initPositionFuncCall = new NodeTree<ASTData>(initPosFuncName, ASTData(function_call, Symbol(initPosFuncName, true)));
|
||||||
|
initPositionFuncCall->addChild(accessFuncCall);
|
||||||
|
initPositionFuncCall->getDataRef()->valueType = accessFuncCall->getDataRef()->valueType;
|
||||||
|
initPositionFuncCall->addChildren(initPositionFuncParams);
|
||||||
|
newNode->addChild(initPositionFuncCall);
|
||||||
|
return newNode;
|
||||||
|
}
|
||||||
|
|
||||||
skipChildren.insert(0); //These, the type and the identifier, have been taken care of.
|
skipChildren.insert(0); //These, the type and the identifier, have been taken care of.
|
||||||
skipChildren.insert(1);
|
skipChildren.insert(1);
|
||||||
} else if (name == "if_comp") {
|
newNode->addChildren(transformChildren(children, skipChildren, scope, types, templateTypeReplacements, instantiateTemplates));
|
||||||
|
return newNode;
|
||||||
|
} else if (name == "if_comp") {
|
||||||
newNode = new NodeTree<ASTData>(name, ASTData(if_comp));
|
newNode = new NodeTree<ASTData>(name, ASTData(if_comp));
|
||||||
newNode->addChild(new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(concatSymbolTree(children[0]),true))));
|
newNode->addChild(new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(concatSymbolTree(children[0]),true))));
|
||||||
skipChildren.insert(0); //Don't do the identifier. The identifier lookup will fail. That's why we do it here.
|
skipChildren.insert(0); //Don't do the identifier. The identifier lookup will fail. That's why we do it here.
|
||||||
@@ -627,15 +656,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Do all children but the ones we skip
|
//Do all children but the ones we skip
|
||||||
for (int i = 0; i < children.size(); i++) {
|
newNode->addChildren(transformChildren(children, skipChildren, scope, types, templateTypeReplacements, instantiateTemplates));
|
||||||
if (skipChildren.find(i) == skipChildren.end()) {
|
|
||||||
NodeTree<ASTData>* transChild = transform(children[i], scope, types, templateTypeReplacements, instantiateTemplates);
|
|
||||||
if (transChild->getDataRef()->type) //Only add the children that have a real ASTData::ASTType, that is, legit ASTData.
|
|
||||||
newNode->addChild(transChild);
|
|
||||||
else
|
|
||||||
delete transChild;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -680,9 +701,9 @@ std::string ASTTransformation::concatSymbolTree(NodeTree<Symbol>* root) {
|
|||||||
|
|
||||||
//We pass in the actual children (parameters) to allow us to handle overloaded operator methods (where a parameter is actually the scope of the method)
|
//We pass in the actual children (parameters) to allow us to handle overloaded operator methods (where a parameter is actually the scope of the method)
|
||||||
NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes, std::map<std::string, Type*> templateTypeReplacements) {
|
NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::string lookup, std::vector<NodeTree<ASTData>*> nodes, std::map<std::string, Type*> templateTypeReplacements) {
|
||||||
auto LLElementIterator = languageLevelScope.find(lookup);
|
auto LLElementIterator = languageLevelOperators.find(lookup);
|
||||||
NodeTree<ASTData>* newNode;
|
NodeTree<ASTData>* newNode;
|
||||||
if (LLElementIterator != languageLevelScope.end()) {
|
if (LLElementIterator != languageLevelOperators.end()) {
|
||||||
std::cout << "Checking for early method level operator overload" << std::endl;
|
std::cout << "Checking for early method level operator overload" << std::endl;
|
||||||
std::string lookupOp = "operator" + lookup;
|
std::string lookupOp = "operator" + lookup;
|
||||||
for (auto i : nodes)
|
for (auto i : nodes)
|
||||||
@@ -697,7 +718,7 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
|
|||||||
//return operatorMethod;
|
//return operatorMethod;
|
||||||
NodeTree<ASTData>* newNode = new NodeTree<ASTData>(lookupOp, ASTData(function_call, Symbol(lookupOp, true)));
|
NodeTree<ASTData>* newNode = new NodeTree<ASTData>(lookupOp, ASTData(function_call, Symbol(lookupOp, true)));
|
||||||
NodeTree<ASTData>* dotFunctionCall = new NodeTree<ASTData>(".", ASTData(function_call, Symbol(".", true)));
|
NodeTree<ASTData>* dotFunctionCall = new NodeTree<ASTData>(".", ASTData(function_call, Symbol(".", true)));
|
||||||
dotFunctionCall->addChild(languageLevelScope["."][0]); //function definition
|
dotFunctionCall->addChild(languageLevelOperators["."][0]); //function definition
|
||||||
dotFunctionCall->addChild(nodes[0]); // The object whose method we're calling
|
dotFunctionCall->addChild(nodes[0]); // The object whose method we're calling
|
||||||
dotFunctionCall->addChild(operatorMethod); //The method we're calling
|
dotFunctionCall->addChild(operatorMethod); //The method we're calling
|
||||||
newNode->addChild(dotFunctionCall); // First child of function call is a link to the function definition
|
newNode->addChild(dotFunctionCall); // First child of function call is a link to the function definition
|
||||||
@@ -740,9 +761,15 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
|
|||||||
//Search recursively through levels of scope (each ASTData, that is, every node, has its own scope)
|
//Search recursively through levels of scope (each ASTData, that is, every node, has its own scope)
|
||||||
//We pass in types so that if we're searching for a function we can find the right overloaded one
|
//We pass in types so that if we're searching for a function we can find the right overloaded one
|
||||||
NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types) {
|
NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types) {
|
||||||
//We first search the languageLevelScope to see if it's an operator. If so, we modifiy the lookup with a preceding "operator"
|
//We first check to see if it's one of the special reserved identifiers (only this, for now) and return early if it is.
|
||||||
auto LLElementIterator = languageLevelScope.find(lookup);
|
auto LLElementIterator = languageLevelReservedWords.find(lookup);
|
||||||
if (LLElementIterator != languageLevelScope.end())
|
if (LLElementIterator != languageLevelReservedWords.end()) {
|
||||||
|
std::cout << "found it at language level as reserved word." << std::endl;
|
||||||
|
return LLElementIterator->second[0];
|
||||||
|
}
|
||||||
|
//We search the languageLevelOperators to see if it's an operator. If so, we modifiy the lookup with a preceding "operator"
|
||||||
|
LLElementIterator = languageLevelOperators.find(lookup);
|
||||||
|
if (LLElementIterator != languageLevelOperators.end())
|
||||||
lookup = "operator" + lookup;
|
lookup = "operator" + lookup;
|
||||||
//Search the map
|
//Search the map
|
||||||
auto scopeMap = scope->getDataRef()->scope;
|
auto scopeMap = scope->getDataRef()->scope;
|
||||||
@@ -802,7 +829,7 @@ NodeTree<ASTData>* ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std:
|
|||||||
std::cout << "could not find " << lookup << " in standard scope, checking for operator" << std::endl;
|
std::cout << "could not find " << lookup << " in standard scope, checking for operator" << std::endl;
|
||||||
//Note that we don't check for types. At some point we should, as we don't know how to add objects/structs without overloaded operators, etc
|
//Note that we don't check for types. At some point we should, as we don't know how to add objects/structs without overloaded operators, etc
|
||||||
//Also, we've already searched for the element because this is also how we keep track of operator overloading
|
//Also, we've already searched for the element because this is also how we keep track of operator overloading
|
||||||
if (LLElementIterator != languageLevelScope.end()) {
|
if (LLElementIterator != languageLevelOperators.end()) {
|
||||||
std::cout << "found it at language level as operator." << std::endl;
|
std::cout << "found it at language level as operator." << std::endl;
|
||||||
return LLElementIterator->second[0];
|
return LLElementIterator->second[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
Poset<NodeTree<ASTData>*> typedefPoset;
|
Poset<NodeTree<ASTData>*> typedefPoset;
|
||||||
for (int i = 0; i < children.size(); i++) {
|
for (int i = 0; i < children.size(); i++) {
|
||||||
if (children[i]->getDataRef()->type == type_def) {
|
if (children[i]->getDataRef()->type == type_def) {
|
||||||
typedefPoset.addVertex(children[i]); //We add this definition by itself just in case there are no dependencies.
|
typedefPoset.addVertex(children[i]); //We add this definition by itthis just in case there are no dependencies.
|
||||||
//If it has dependencies, there's no harm in adding it here
|
//If it has dependencies, there's no harm in adding it here
|
||||||
//Go through every child in the class looking for declaration statements. For each of these that is not a primitive type
|
//Go through every child in the class looking for declaration statements. For each of these that is not a primitive type
|
||||||
//we will add a dependency from this definition to that definition in the poset.
|
//we will add a dependency from this definition to that definition in the poset.
|
||||||
@@ -129,10 +129,16 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
//return "#include <" + data.symbol.getName() + ">\n";
|
//return "#include <" + data.symbol.getName() + ">\n";
|
||||||
case identifier:
|
case identifier:
|
||||||
{
|
{
|
||||||
//If we're in an object method, and our enclosing scope is that object, we're a member of the object and should use the self reference.
|
//but first, if we're this, we should just emit. (assuming enclosing object) (note that technically this would fall through, but for errors)
|
||||||
|
if (data.symbol.getName() == "this")
|
||||||
|
if (enclosingObject)
|
||||||
|
return "this";
|
||||||
|
else
|
||||||
|
std::cout << "Error: this used in non-object scope" << std::endl;
|
||||||
|
//If we're in an object method, and our enclosing scope is that object, we're a member of the object and should use the this reference.
|
||||||
std::string preName;
|
std::string preName;
|
||||||
if (enclosingObject && enclosingObject->getDataRef()->scope.find(data.symbol.getName()) != enclosingObject->getDataRef()->scope.end())
|
if (enclosingObject && enclosingObject->getDataRef()->scope.find(data.symbol.getName()) != enclosingObject->getDataRef()->scope.end())
|
||||||
preName += "self->";
|
preName += "this->";
|
||||||
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) + "_";
|
||||||
@@ -213,7 +219,12 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
case declaration_statement:
|
case declaration_statement:
|
||||||
if (children.size() == 1)
|
if (children.size() == 1)
|
||||||
return ValueTypeToCType(children[0]->getData().valueType) + " " + generate(children[0], enclosingObject) + ";";
|
return ValueTypeToCType(children[0]->getData().valueType) + " " + generate(children[0], enclosingObject) + ";";
|
||||||
else
|
else if (children[1]->getChildren().size() && children[1]->getChildren()[0]->getChildren().size() > 1
|
||||||
|
&& children[1]->getChildren()[0]->getChildren()[1] == children[0]) {
|
||||||
|
//That is, if we're a declaration with an init position call (Object a.construct())
|
||||||
|
//We can tell if our function call (children[1])'s access operation([0])'s lhs ([1]) is the thing we just declared (children[0])
|
||||||
|
return ValueTypeToCType(children[0]->getData().valueType) + " " + generate(children[0], enclosingObject) + "; " + generate(children[1]) + "/*Init Position Call*/";
|
||||||
|
} else
|
||||||
return ValueTypeToCType(children[0]->getData().valueType) + " " + generate(children[0], enclosingObject) + " = " + generate(children[1], enclosingObject) + ";";
|
return ValueTypeToCType(children[0]->getData().valueType) + " " + generate(children[0], enclosingObject) + " = " + generate(children[1], enclosingObject) + ";";
|
||||||
case if_comp:
|
case if_comp:
|
||||||
if (generate(children[0], enclosingObject) == generatorString)
|
if (generate(children[0], enclosingObject) == generatorString)
|
||||||
@@ -288,7 +299,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
output += enclosingObject->getDataRef()->symbol.getName() +"__";
|
output += enclosingObject->getDataRef()->symbol.getName() +"__";
|
||||||
/*HERE*/ output += CifyName(name + nameDecoration) + "(";
|
/*HERE*/ output += CifyName(name + nameDecoration) + "(";
|
||||||
if (isSelfObjectMethod)
|
if (isSelfObjectMethod)
|
||||||
output += children.size() > 1 ? "self," : "self";
|
output += children.size() > 1 ? "this," : "this";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//This part handles cases where our definition isn't the function definition (that is, it is probabally the return from another function)
|
//This part handles cases where our definition isn't the function definition (that is, it is probabally the return from another function)
|
||||||
@@ -337,7 +348,7 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
|
|||||||
}
|
}
|
||||||
output += "\n" + ValueTypeToCType(data.valueType) + " " + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__"
|
output += "\n" + ValueTypeToCType(data.valueType) + " " + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__"
|
||||||
+ CifyName(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
|
+ " this" + 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ void print(char* toPrint) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void println(char* toPrint) {
|
||||||
|
print(toPrint);
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
void print(int toPrint) {
|
void print(int toPrint) {
|
||||||
__if_comp__ __C__ {
|
__if_comp__ __C__ {
|
||||||
__simple_passthrough__ """
|
__simple_passthrough__ """
|
||||||
@@ -20,6 +25,11 @@ void print(int toPrint) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void println(int toPrint) {
|
||||||
|
print(toPrint);
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
void print(float toPrint) {
|
void print(float toPrint) {
|
||||||
__if_comp__ __C__ {
|
__if_comp__ __C__ {
|
||||||
__simple_passthrough__ """
|
__simple_passthrough__ """
|
||||||
@@ -27,4 +37,10 @@ void print(float toPrint) {
|
|||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void println(float toPrint) {
|
||||||
|
print(toPrint);
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
3
tests/declarationsTest.expected_results
Normal file
3
tests/declarationsTest.expected_results
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
4
|
||||||
|
8
|
||||||
|
11
|
||||||
26
tests/declarationsTest.krak
Normal file
26
tests/declarationsTest.krak
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import io;
|
||||||
|
import mem;
|
||||||
|
|
||||||
|
typedef ClassWithConstructor {
|
||||||
|
int data;
|
||||||
|
ClassWithConstructor* construct(int inData) {
|
||||||
|
data = inData;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
void printData() {
|
||||||
|
println(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
ClassWithConstructor object.construct(4);
|
||||||
|
//ClassWithConstructor object;
|
||||||
|
//object.construct(4);
|
||||||
|
object.printData();
|
||||||
|
int a = 8;
|
||||||
|
println(a);
|
||||||
|
ClassWithConstructor* objPtr = new<ClassWithConstructor>()->construct(11);
|
||||||
|
objPtr->printData();
|
||||||
|
delete<ClassWithConstructor>(objPtr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user