work on string, bug fixes, overloaded assignment operator. Still need to get overloaded copy_construct for declaration assignment

This commit is contained in:
Nathan Braswell
2015-06-01 01:43:23 -04:00
parent bbcebf7c17
commit 6f9ceaa717
10 changed files with 124 additions and 55 deletions

View File

@@ -50,7 +50,7 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
NodeTree<ASTData>* functionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types);
NodeTree<ASTData>* templateFunctionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type*>* templateInstantiationTypes, std::vector<Type> types, std::map<std::string, Type*> scopeTypeMap);
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules = false);
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::vector<NodeTree<ASTData>*> visited);
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::set<NodeTree<ASTData>*> visited);
NodeTree<ASTData>* getUpperTranslationUnit(NodeTree<ASTData>* node);
NodeTree<ASTData>* addToScope(std::string name, NodeTree<ASTData>* toAdd, NodeTree<ASTData>* addTo);

View File

@@ -12,7 +12,7 @@ class CCodeTriple {
CCodeTriple(const char* val);
CCodeTriple();
~CCodeTriple();
std::string oneString();
std::string oneString(bool endValue = false);
CCodeTriple & operator=(const CCodeTriple &rhs);
CCodeTriple & operator+=(const CCodeTriple &rhs);

View File

@@ -29,6 +29,7 @@ ASTTransformation::ASTTransformation(Importer *importerIn) {
languageLevelOperators["||"].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol("||", true), new Type(boolean)))));
languageLevelOperators["!"].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol("!", true), new Type(boolean)))));
languageLevelOperators["*="].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol("*=", true), NULL))));
languageLevelOperators["="].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol("=", true), NULL))));
languageLevelOperators["+="].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol("+=", true), NULL))));
languageLevelOperators["-="].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol("-=", true), NULL))));
languageLevelOperators["."].push_back(addToScope("~enclosing_scope", builtin_trans_unit, new NodeTree<ASTData>("function", ASTData(function, Symbol(".", true), NULL))));
@@ -592,16 +593,21 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
} else if (name == "defer_statement") {
newNode = new NodeTree<ASTData>(name, ASTData(defer_statement));
} else if (name == "assignment_statement") {
newNode = new NodeTree<ASTData>(name, ASTData(assignment_statement));
std::string assignFuncName = concatSymbolTree(children[1]);
NodeTree<ASTData>* lhs = transform(children[0], scope, types, templateTypeReplacements);
NodeTree<ASTData>* rhs = transform(children[2], scope, types, templateTypeReplacements);
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(lhs); transformedChildren.push_back(rhs);
// see if this is an overloaded assignment
NodeTree<ASTData>* function = doFunction(scope, assignFuncName, transformedChildren, templateTypeReplacements);
if (function)
return function;
newNode = new NodeTree<ASTData>(name, ASTData(assignment_statement));
if (assignFuncName == "=") {
newNode->addChild(transform(children[0], scope, types, templateTypeReplacements));
newNode->addChild(transform(children[2], scope, types, templateTypeReplacements));
newNode->addChildren(transformedChildren);
} else {
//For assignments like += or *=, expand the syntatic sugar.
NodeTree<ASTData>* lhs = transform(children[0], scope, types, templateTypeReplacements);
NodeTree<ASTData>* rhs = transform(children[2], scope, types, templateTypeReplacements);
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(lhs); transformedChildren.push_back(rhs);
std::string functionName = assignFuncName.substr(0,1);
NodeTree<ASTData>* operatorCall = doFunction(scope, functionName, transformedChildren, templateTypeReplacements);
if (operatorCall == NULL) {
@@ -1218,13 +1224,15 @@ std::map<std::string, Type*> ASTTransformation::makeTemplateFunctionTypeMap(Node
// We need recursion protection
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules) {
return scopeLookup(scope, lookup, includeModules, std::vector<NodeTree<ASTData>*>());
return scopeLookup(scope, lookup, includeModules, std::set<NodeTree<ASTData>*>());
}
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::vector<NodeTree<ASTData>*> visited) {
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::set<NodeTree<ASTData>*> visited) {
std::cout << "Scp]|[e looking up " << lookup << std::endl;
// Don't visit this node again when looking for the smae lookup. Note that we don't prevent coming back for the scope operator, as that should be able to come back.
visited.push_back(scope);
if (visited.find(scope) != visited.end())
return std::vector<NodeTree<ASTData>*>();
visited.insert(scope);
//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 = languageLevelReservedWords.find(lookup);
if (LLElementIterator != languageLevelReservedWords.end()) {
@@ -1463,6 +1471,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
std::cout << "\n\nFinding or instantiating templated function\n\n" << std::endl;
std::string functionName = concatSymbolTree(children[0]);
std::string fullyInstantiatedName;
std::string scopelessFullyInstantiatedName;
std::vector<Type*> templateActualTypes;
NodeTree<ASTData>* templateDefinition = NULL;
@@ -1529,6 +1538,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
std::cout << functionName << " search turned up null, returing null" << std::endl;
return NULL;
}
scopelessFullyInstantiatedName = templateDefinition->getDataRef()->symbol.getName() + "<" + instTypeString + ">";
NodeTree<Symbol>* templateSyntaxTree = templateDefinition->getDataRef()->valueType->templateDefinition;
// Makes a map between the names of the template placeholder parameters and the provided types
@@ -1539,14 +1549,10 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::vec
std::cout << ", " << i << " : " << templateChildren[i]->getDataRef()->getName();
std::cout << std::endl;
instantiatedFunction = new NodeTree<ASTData>("function", ASTData(function, Symbol(fullyInstantiatedName, true), typeFromTypeNode(templateChildren[templateChildren.size()-2], scope, newTemplateTypeReplacement)));
instantiatedFunction = new NodeTree<ASTData>("function", ASTData(function, Symbol(scopelessFullyInstantiatedName, true), typeFromTypeNode(templateChildren[templateChildren.size()-2], scope, newTemplateTypeReplacement)));
addToScope("~enclosing_scope", templateDefinition->getDataRef()->scope["~enclosing_scope"][0], instantiatedFunction);
// Arrrrrgh this has a hard time working because the functions will need to see their parameter once they are emitted as C.
// HAHAHAHAHA DOESN'T MATTER ALL ONE C FILE NOW, swap back to old way
// OR, THIS IS A TEMPLATE METHOD AND ADD TO THE OBJECT
auto templateTopScope = objectForTemplateMethod ? objectForTemplateMethod : getUpperTranslationUnit(templateDefinition);
addToScope(fullyInstantiatedName, instantiatedFunction, templateTopScope);
templateTopScope->addChild(instantiatedFunction); // Add this object the the highest scope's
addToScope(scopelessFullyInstantiatedName, instantiatedFunction, templateDefinition->getDataRef()->scope["~enclosing_scope"][0]);
templateDefinition->getDataRef()->scope["~enclosing_scope"][0]->addChild(instantiatedFunction); // Add this object the the highest scope's
std::cout << "About to do children of " << functionName << " to " << fullyInstantiatedName << std::endl;

View File

@@ -19,8 +19,8 @@ CCodeTriple::CCodeTriple() {
CCodeTriple::~CCodeTriple() {
}
std::string CCodeTriple::oneString() {
return preValue + value + postValue;
std::string CCodeTriple::oneString(bool endValue) {
return preValue + value + (endValue ? ";" : "") + postValue;
}
CCodeTriple & CCodeTriple::operator=(const CCodeTriple &rhs) {

View File

@@ -10,7 +10,7 @@ CGenerator::~CGenerator() {
// Note the use of std::pair to hold two strings - the running string for the header file and the running string for the c file.
void CGenerator::generateCompSet(std::map<std::string, NodeTree<ASTData>*> ASTs, std::string outputName) {
//Generate an entire set of files
std::string buildString = "#!/bin/sh\ncc -std=c99 ";
std::string buildString = "#!/bin/sh\ncc -g -std=c99 ";
std::cout << "\n\n =====GENERATE PASS===== \n\n" << std::endl;
std::cout << "\n\nGenerate pass for: " << outputName << std::endl;
buildString += outputName + ".c ";
@@ -305,8 +305,13 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
parameters += ValueTypeToCType(children[j]->getData().valueType, generate(children[j], enclosingObject, justFuncName).oneString());
nameDecoration += "_" + ValueTypeToCTypeDecoration(children[j]->getData().valueType);
// add parameters to distructDoubleStack so that their destructors will be called at return (if they exist)
std::cout << "HAHA: " << generate(children[j], enclosingObject, justFuncName).oneString() << std::endl;
distructDoubleStack.back().push_back(children[j]);
}
if (children.size() == 1)
std::cout << "HEHE: " << data.symbol.getName() << " has only one child" << std::endl;
else if (children.size() == 0)
std::cout << "HEHE: " << data.symbol.getName() << " has only 0 child" << std::endl;
// this is for using functions as values
if (justFuncName) {
output = ((data.symbol.getName() == "main") ? "" : scopePrefix(from)) + CifyName(data.symbol.getName() + nameDecoration);
@@ -455,7 +460,6 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
deferDoubleStack.back().push_back(children[0]);
return CCodeTriple("/*defer " + generate(children[0], enclosingObject, justFuncName).oneString() + "*/");
case assignment_statement:
//if (methodExists(retType, "operator=")) {
return generate(children[0], enclosingObject, justFuncName).oneString() + " = " + generate(children[1], enclosingObject, true);
case declaration_statement:
// adding declaration to the distructDoubleStack so that we can call their destructors when leaving scope (}, return, break, continue)
@@ -469,7 +473,8 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
&& 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, justFuncName).oneString()) + "; " + generate(children[1], enclosingObject, true).oneString() + "/*Init Position Call*/";
// be sure to end value by passing oneString true
return ValueTypeToCType(children[0]->getData().valueType, generate(children[0], enclosingObject, justFuncName).oneString()) + "; " + generate(children[1], enclosingObject, true).oneString(true) + "/*Init Position Call*/";
} else {
// copy constructor if of the same type
if (*children[0]->getDataRef()->valueType == *children[1]->getDataRef()->valueType && methodExists(children[1]->getDataRef()->valueType, "copy_construct")) {
@@ -533,7 +538,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
if (name == "[]")
return "(" + generate(children[1], enclosingObject, true) + ")[" + generate(children[2],enclosingObject, true) + "]";
if (name == "+" || name == "-" || name == "*" || name == "/" || name == "==" || name == ">=" || name == "<=" || name == "!="
|| name == "<" || name == ">" || name == "%" || name == "+=" || name == "-=" || name == "*=" || name == "/=" || name == "||"
|| name == "<" || name == ">" || name == "%" || name == "=" || name == "+=" || name == "-=" || name == "*=" || name == "/=" || name == "||"
|| name == "&&") {
std::cout << "THIS IS IT NAME: " << name << std::endl;
return "((" + generate(children[1], enclosingObject, true).oneString() + ")" + name + "(" + generate(children[2], enclosingObject, true).oneString() + "))";
@@ -643,6 +648,8 @@ NodeTree<ASTData>* CGenerator::getMethodsObjectType(NodeTree<ASTData>* scope, st
// Returns the function prototype in the out param and the full definition normally
std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject, NodeTree<ASTData>* from, std::string *functionPrototype) {
distructDoubleStack.push_back(std::vector<NodeTree<ASTData>*>());
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.increaseIndirection();
@@ -651,12 +658,20 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
for (int i = 0; i < children.size()-1; i++) {
parameters += ", " + ValueTypeToCType(children[i]->getData().valueType, generate(children[i]).oneString());
nameDecoration += "_" + ValueTypeToCTypeDecoration(children[i]->getData().valueType);
distructDoubleStack.back().push_back(children[i]);
}
std::string functionSignature = "\n" + ValueTypeToCType(data.valueType->returnType, scopePrefix(from) + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__"
+ CifyName(data.symbol.getName()) + nameDecoration) + "(" + ValueTypeToCType(&enclosingObjectType, "this") + parameters + ")";
*functionPrototype += functionSignature + ";\n";
// Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock
return functionSignature + " {\n" + generate(children[children.size()-1], enclosingObject).oneString() + "}\n"; //Pass in the object so we can properly handle access to member stuff
//
std::string output;
output += functionSignature + " {\n" + generate(children[children.size()-1], enclosingObject).oneString();
output += emitDestructors(reverse(distructDoubleStack.back()), enclosingObject);
output += "}\n"; //Pass in the object so we can properly handle access to member stuff
distructDoubleStack.pop_back();
return output;
}
NodeTree<ASTData>* CGenerator::getMethod(Type* type, std::string method) {
@@ -683,6 +698,8 @@ std::string CGenerator::generateMethodIfExists(Type* type, std::string method, s
for (Type *paramType : methodDef->getDataRef()->valueType->parameterTypes)
nameDecoration += "_" + ValueTypeToCTypeDecoration(paramType);
return scopePrefix(typeDefinition) + CifyName(typeDefinition->getDataRef()->symbol.getName()) + "__" + method + nameDecoration + "(" + parameter + ");\n";
} else {
std::cout << method << " DOESN'T EXIST FOR TYPE " << type->toString() << std::endl;
}
return "";
}

View File

@@ -1,4 +1,5 @@
import string:*;
import mem:*
__if_comp__ __C__ simple_passthrough """
#include <stdio.h>
@@ -8,6 +9,11 @@ fun println() : void {
print("\n");
}
fun println<T>(toPrint: T) : void {
print(toPrint)
print("\n")
}
fun print(toPrint: char*) : void {
__if_comp__ __C__ {
simple_passthrough(toPrint = toPrint::) """
@@ -17,17 +23,10 @@ fun print(toPrint: char*) : void {
return;
}
fun println(toPrint: char*) : void {
print(toPrint);
println();
}
fun print(toPrint: string) : void {
print(toPrint.toCharArray());
}
fun println(toPrint: string): void {
println(toPrint.toCharArray());
var charArr = toPrint.toCharArray()
defer delete(charArr)
print(charArr);
}
fun print(toPrint: int): void {
@@ -39,11 +38,6 @@ fun print(toPrint: int): void {
return;
}
fun println(toPrint: int): void {
print(toPrint);
println();
}
fun print(toPrint: float): void {
__if_comp__ __C__ {
simple_passthrough(toPrint = toPrint::) """
@@ -62,15 +56,3 @@ fun print(toPrint: double) : void{
return;
}
fun println(toPrint: float): void {
print(toPrint);
println();
}
fun println(toPrint: double): void {
print(toPrint);
println();
}

View File

@@ -13,15 +13,45 @@ obj string (Destructable) {
data.addEnd(*str);
str += 1;
}
// no null terminator
return this;
}
fun construct(vec: vector::vector<char>): string* {
data.copy_construct(&vec);
return this;
}
fun copy_construct(old: string*): void {
data.copy_construct(&old->data)
}
fun destruct():void {
data.destruct()
}
fun operator=(str: char*): void {
destruct();
construct(str)
}
fun operator+(str: char*): string {
var newStr.construct(str):string
var ret.construct(data + newStr.data):string
return ret
}
fun operator+=(str: char*): void {
var newStr.construct(str):string
data += newStr.data
}
fun toCharArray(): char* {
var out: char* = mem::new<char>(data.size);
var out: char* = mem::new<char>(data.size+1);
for (var i: int = 0; i < data.size; i++;)
out[i] = data.get(i);
// null terminator
out[data.size] = 0
return out;
}
};

View File

@@ -29,7 +29,29 @@ obj vector<T> (Destructable) {
}
fun destruct(): void {
delete<T>(data);
if (data)
delete<T>(data);
data = 0
}
fun operator=(other:vector<T>):void {
resize(other.size)
for (var i = 0; i < other.size; i++;)
set(i, other.get(i))
}
fun operator+(other:vector<T>):vector<T> {
var newVec.construct(size + other.size):vector<T>
for (var i = 0; i < size; i++;)
newVec.set(i, get(i))
for (var i = 0; i < other.size; i++;)
newVec.set(i+size, other.get(i))
return newVec
}
fun operator+=(other:vector<T>):void {
for (var i = 0; i < other.size; i++;)
addEnd(other.get(i))
}
fun clone(): vector<T> {
@@ -48,6 +70,7 @@ obj vector<T> (Destructable) {
delete<T>(data, 0);
data = newData;
available = newSize;
size = lesser(size, newSize)
return true;
}

View File

@@ -1 +1,4 @@
hello strings
assignment overload
assignment overload2
assignment overload with additional

View File

@@ -5,6 +5,14 @@ import string;
fun main(): int {
var str.construct("hello strings"): string::string;
io::println(str);
str = "assignment overload"
io::println(str);
io::println(str + "2");
str += " with additional"
io::println(str);
//var initilized:string::string = "hope"
//io::println(initilized)
//io::println(initilized+ "3")
return 0;
}