Fixed a limitToFunction bug or two, work on ADTs
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,6 +5,7 @@ build-ninja
|
|||||||
stats
|
stats
|
||||||
*.swp
|
*.swp
|
||||||
*.swm
|
*.swm
|
||||||
|
*.swn
|
||||||
*.swo
|
*.swo
|
||||||
*.png
|
*.png
|
||||||
*krakout*
|
*krakout*
|
||||||
@@ -16,3 +17,4 @@ callgrind*
|
|||||||
*.comp_bac
|
*.comp_bac
|
||||||
bintest.bin
|
bintest.bin
|
||||||
*.dot
|
*.dot
|
||||||
|
.stfolder
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class CGenerator {
|
|||||||
~CGenerator();
|
~CGenerator();
|
||||||
void generateCompSet(std::map<std::string, NodeTree<ASTData>*> ASTs, std::string outputName);
|
void generateCompSet(std::map<std::string, NodeTree<ASTData>*> ASTs, std::string outputName);
|
||||||
std::string generateTypeStruct(NodeTree<ASTData>* from);
|
std::string generateTypeStruct(NodeTree<ASTData>* from);
|
||||||
|
bool isUnderNodeWithType(NodeTree<ASTData>* from, ASTType type);
|
||||||
bool isUnderTranslationUnit(NodeTree<ASTData>* from, NodeTree<ASTData>* typeDefinition);
|
bool isUnderTranslationUnit(NodeTree<ASTData>* from, NodeTree<ASTData>* typeDefinition);
|
||||||
NodeTree<ASTData>* highestScope(NodeTree<ASTData>* node);
|
NodeTree<ASTData>* highestScope(NodeTree<ASTData>* node);
|
||||||
std::pair<std::string, std::string> generateTranslationUnit(std::string name, std::map<std::string, NodeTree<ASTData>*> ASTs);
|
std::pair<std::string, std::string> generateTranslationUnit(std::string name, std::map<std::string, NodeTree<ASTData>*> ASTs);
|
||||||
@@ -40,6 +41,8 @@ class CGenerator {
|
|||||||
std::string ValueTypeToCTypeThingHelper(Type *type, std::string ptrStr, ClosureTypeSpecialType closureSpecial);
|
std::string ValueTypeToCTypeThingHelper(Type *type, std::string ptrStr, ClosureTypeSpecialType closureSpecial);
|
||||||
static std::string CifyName(std::string name);
|
static std::string CifyName(std::string name);
|
||||||
static std::string scopePrefix(NodeTree<ASTData>* from);
|
static std::string scopePrefix(NodeTree<ASTData>* from);
|
||||||
|
std::string simpleComplexName(std::string simpleName, std::string complexName);
|
||||||
|
std::string prefixIfNeeded(std::string prefix, std::string name);
|
||||||
std::string generateObjectMethod(NodeTree<ASTData>* enclosingObject, NodeTree<ASTData>* from, std::string *functionPrototype);
|
std::string generateObjectMethod(NodeTree<ASTData>* enclosingObject, NodeTree<ASTData>* from, std::string *functionPrototype);
|
||||||
NodeTree<ASTData>* getMethodsObjectType(NodeTree<ASTData>* scope, std::string functionName);
|
NodeTree<ASTData>* getMethodsObjectType(NodeTree<ASTData>* scope, std::string functionName);
|
||||||
NodeTree<ASTData>* getMethod(Type* type, std::string method, std::vector<Type> types);
|
NodeTree<ASTData>* getMethod(Type* type, std::string method, std::vector<Type> types);
|
||||||
@@ -56,6 +59,8 @@ class CGenerator {
|
|||||||
std::string linkerString;
|
std::string linkerString;
|
||||||
std::string functionTypedefString;
|
std::string functionTypedefString;
|
||||||
std::string functionTypedefStringPre;
|
std::string functionTypedefStringPre;
|
||||||
|
std::set<std::string> usedNameSet;
|
||||||
|
std::map<std::string, std::string> simpleComplexNameMap;
|
||||||
std::map<Type, triple<std::string, std::string, std::string>> functionTypedefMap;
|
std::map<Type, triple<std::string, std::string, std::string>> functionTypedefMap;
|
||||||
std::map<std::set<NodeTree<ASTData>*>, std::string> closureStructMap;
|
std::map<std::set<NodeTree<ASTData>*>, std::string> closureStructMap;
|
||||||
std::vector<std::vector<NodeTree<ASTData>*>> distructDoubleStack;
|
std::vector<std::vector<NodeTree<ASTData>*>> distructDoubleStack;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ template_param_list = template_param_list WS "," WS template_param | template_pa
|
|||||||
template_param = identifier WS traits | identifier ;
|
template_param = identifier WS traits | identifier ;
|
||||||
|
|
||||||
import = "import" WS identifier line_end | "import" WS identifier WS ":" WS "\*" line_end | "import" WS identifier WS ":" WS identifier_list line_end ;
|
import = "import" WS identifier line_end | "import" WS identifier WS ":" WS "\*" line_end | "import" WS identifier WS ":" WS identifier_list line_end ;
|
||||||
|
identifier_list = identifier | identifier WS "," WS identifier_list ;
|
||||||
|
|
||||||
# all for optional semicolons
|
# all for optional semicolons
|
||||||
line_break = "
|
line_break = "
|
||||||
@@ -57,7 +58,6 @@ triple_quoted_string = "\"\"\"((\"\"(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i
|
|||||||
|
|
||||||
#identifier = alpha_alphanumeric ;
|
#identifier = alpha_alphanumeric ;
|
||||||
identifier = augmented_alpha_alphanumeric ;
|
identifier = augmented_alpha_alphanumeric ;
|
||||||
identifier_list = identifier | identifier WS "," WS identifier_list ;
|
|
||||||
scope_op = ":" ":" ;
|
scope_op = ":" ":" ;
|
||||||
scoped_identifier = scoped_identifier WS scope_op WS identifier | identifier ;
|
scoped_identifier = scoped_identifier WS scope_op WS identifier | identifier ;
|
||||||
|
|
||||||
@@ -89,7 +89,9 @@ traits = "\(" WS trait_list WS "\)" ;
|
|||||||
trait_list = trait_list WS "," WS scoped_identifier | scoped_identifier ;
|
trait_list = trait_list WS "," WS scoped_identifier | scoped_identifier ;
|
||||||
|
|
||||||
adt_nonterm = "adt" ;
|
adt_nonterm = "adt" ;
|
||||||
adt_def = adt_nonterm WS identifier WS "{" WS identifier_list WS "}" ;
|
adt_def = adt_nonterm WS identifier WS "{" WS adt_option_list WS "}" ;
|
||||||
|
adt_option_list = adt_option | adt_option WS "," WS adt_option_list ;
|
||||||
|
adt_option = identifier | identifier WS dec_type ;
|
||||||
|
|
||||||
if_statement = "if" WS "\(" WS boolean_expression WS "\)" WS statement | "if" WS "\(" WS boolean_expression WS "\)" WS statement WS "else" WS statement ;
|
if_statement = "if" WS "\(" WS boolean_expression WS "\)" WS statement | "if" WS "\(" WS boolean_expression WS "\)" WS statement WS "else" WS statement ;
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<S
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if (i->getDataRef()->getName() == "adt_def") {
|
} else if (i->getDataRef()->getName() == "adt_def") {
|
||||||
std::string name = concatSymbolTree(i->getChildren()[0]);
|
std::string name = concatSymbolTree(getNode("identifier", i));
|
||||||
NodeTree<ASTData>* adt_dec = addToScope("~enclosing_scope", translationUnit, new NodeTree<ASTData>("adt_def", ASTData(adt_def, Symbol(name, true, name))));
|
NodeTree<ASTData>* adt_dec = addToScope("~enclosing_scope", translationUnit, new NodeTree<ASTData>("adt_def", ASTData(adt_def, Symbol(name, true, name))));
|
||||||
addToScope(name, adt_dec, translationUnit);
|
addToScope(name, adt_dec, translationUnit);
|
||||||
translationUnit->addChild(adt_dec);
|
translationUnit->addChild(adt_dec);
|
||||||
@@ -193,16 +193,37 @@ void ASTTransformation::secondPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
|
|||||||
//Do the inside of classes here
|
//Do the inside of classes here
|
||||||
secondPassDoClassInsides(typeDef, typedefChildren, std::map<std::string, Type*>());
|
secondPassDoClassInsides(typeDef, typedefChildren, std::map<std::string, Type*>());
|
||||||
} else if (i->getDataRef()->getName() == "adt_def") {
|
} else if (i->getDataRef()->getName() == "adt_def") {
|
||||||
std::string name = concatSymbolTree(i->getChildren()[0]);
|
std::cout << "ADT DEF" << std::endl;
|
||||||
|
std::cout << "there are " << getNodes("adt_option", i).size() << " adt_options" << std::endl;
|
||||||
|
std::string name = concatSymbolTree(getNode("identifier", i));
|
||||||
NodeTree<ASTData>* adtDef = ast->getDataRef()->scope[name][0]; //No overloaded types (besides uninstantiated templates, which can have multiple versions based on types or specilizations)
|
NodeTree<ASTData>* adtDef = ast->getDataRef()->scope[name][0]; //No overloaded types (besides uninstantiated templates, which can have multiple versions based on types or specilizations)
|
||||||
for (NodeTree<Symbol>* j : i->getChildren()) {
|
for (NodeTree<Symbol>* j : getNodes("adt_option", i)) {
|
||||||
if (j->getDataRef()->getName() == "identifier") {
|
std::string ident_name = concatSymbolTree(getNode("identifier", j));
|
||||||
std::string ident_name = concatSymbolTree(j);
|
|
||||||
std::cout << "add ing " << ident_name << " to " << name << " for ADT" << std::endl;
|
std::cout << "add ing " << ident_name << " to " << name << " for ADT" << std::endl;
|
||||||
NodeTree<ASTData>* enum_variant_identifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(ident_name, true), adtDef->getDataRef()->valueType));
|
NodeTree<ASTData>* enum_variant_identifier;
|
||||||
|
NodeTree<Symbol>* possibleType = getNode("type", j);
|
||||||
|
NodeTree<ASTData>* enum_variant_function = nullptr;
|
||||||
|
if (possibleType) {
|
||||||
|
Type* actual_type = typeFromTypeNode(possibleType, adtDef, std::map<std::string, Type*>());
|
||||||
|
enum_variant_identifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(ident_name, true), actual_type));
|
||||||
|
|
||||||
|
// also make a function prototype for a function that returns an instance of this type. If we don't contain a type, it's just the literal
|
||||||
|
//enum_variant_function = new NodeTree<ASTData>("function", ASTData(function, Symbol("fun_"+ident_name, true), new Type(std::vector<Type*>{actual_type}, adtDef->getDataRef()->valueType)));
|
||||||
|
enum_variant_function = new NodeTree<ASTData>("function", ASTData(function, Symbol(ident_name, true), new Type(std::vector<Type*>{actual_type}, adtDef->getDataRef()->valueType)));
|
||||||
|
} else {
|
||||||
|
enum_variant_identifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(ident_name, true), adtDef->getDataRef()->valueType));
|
||||||
|
// now a function in both cases...
|
||||||
|
enum_variant_function = new NodeTree<ASTData>("function", ASTData(function, Symbol(ident_name, true), new Type(std::vector<Type*>(), adtDef->getDataRef()->valueType)));
|
||||||
|
}
|
||||||
adtDef->addChild(enum_variant_identifier);
|
adtDef->addChild(enum_variant_identifier);
|
||||||
addToScope(ident_name, enum_variant_identifier, adtDef);
|
addToScope(ident_name, enum_variant_identifier, adtDef);
|
||||||
addToScope("~enclosing_scope", adtDef, enum_variant_identifier);
|
addToScope("~enclosing_scope", adtDef, enum_variant_identifier);
|
||||||
|
// this comes second so it is added to the enclosing scope second so that the function is found last on identifer lookup so we can still access members that are not functions
|
||||||
|
// as their names alias each other
|
||||||
|
if (enum_variant_function) {
|
||||||
|
adtDef->addChild(enum_variant_function);
|
||||||
|
addToScope(ident_name, enum_variant_function, adtDef);
|
||||||
|
addToScope("~enclosing_scope", adtDef, enum_variant_function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (i->getDataRef()->getName() == "function") {
|
} else if (i->getDataRef()->getName() == "function") {
|
||||||
@@ -518,7 +539,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
newNode->addChildren(parameters);
|
newNode->addChildren(parameters);
|
||||||
// update type with actual type
|
// update type with actual type
|
||||||
newNode->getDataRef()->valueType = new Type(mapNodesToTypePointers(parameters), newNode->getDataRef()->valueType);
|
newNode->getDataRef()->valueType = new Type(mapNodesToTypePointers(parameters), newNode->getDataRef()->valueType);
|
||||||
auto statement = transform(getNode("statement", children), scope, types, limitToFunction, templateTypeReplacements);
|
auto statement = transform(getNode("statement", children), scope, types, false, templateTypeReplacements); // definitly do not limit this statement to functions
|
||||||
if (name == "lambda")
|
if (name == "lambda")
|
||||||
newNode->getDataRef()->closedVariables = findVariablesToClose(newNode, statement, scope);
|
newNode->getDataRef()->closedVariables = findVariablesToClose(newNode, statement, scope);
|
||||||
for (auto i : newNode->getDataRef()->closedVariables)
|
for (auto i : newNode->getDataRef()->closedVariables)
|
||||||
@@ -564,7 +585,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
|||||||
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad" || name == "access_operation") {
|
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad" || name == "access_operation") {
|
||||||
//If this is an actual part of an expression, not just a premoted child
|
//If this is an actual part of an expression, not just a premoted child
|
||||||
if (children.size() > 2) {
|
if (children.size() > 2) {
|
||||||
NodeTree<ASTData>* lhs = transform(children[0], scope, std::vector<Type>(),limitToFunction, templateTypeReplacements); //LHS does not inherit types
|
NodeTree<ASTData>* lhs = transform(children[0], scope, std::vector<Type>(),false, templateTypeReplacements); //LHS does not inherit types, or limittofunction
|
||||||
NodeTree<ASTData>* rhs;
|
NodeTree<ASTData>* rhs;
|
||||||
if (name == "access_operation") {
|
if (name == "access_operation") {
|
||||||
std::cout << "lhs is: " << lhs->getDataRef()->toString() << std::endl;
|
std::cout << "lhs is: " << lhs->getDataRef()->toString() << std::endl;
|
||||||
@@ -1033,7 +1054,9 @@ NodeTree<ASTData>* ASTTransformation::functionLookup(NodeTree<ASTData>* scope, s
|
|||||||
if (possibleMatches.size()) {
|
if (possibleMatches.size()) {
|
||||||
for (auto i : possibleMatches) {
|
for (auto i : possibleMatches) {
|
||||||
//We're not looking for types
|
//We're not looking for types
|
||||||
if (i->getDataRef()->type == type_def || i->getDataRef()->type == adt_def)
|
//if (i->getDataRef()->type == type_def || i->getDataRef()->type == adt_def)
|
||||||
|
// actually, lets make it we're only looking for things with type function
|
||||||
|
if (i->getDataRef()->valueType->baseType != function_type)
|
||||||
continue;
|
continue;
|
||||||
Type* functionType = i->getDataRef()->valueType;
|
Type* functionType = i->getDataRef()->valueType;
|
||||||
|
|
||||||
@@ -1389,11 +1412,6 @@ std::map<std::string, Type*> ASTTransformation::makeTemplateFunctionTypeMap(Node
|
|||||||
return typeMap;
|
return typeMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need recursion protection
|
|
||||||
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules) {
|
|
||||||
return scopeLookup(scope, lookup, includeModules, std::set<NodeTree<ASTData>*>());
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeTree<ASTData>* ASTTransformation::generateThis(NodeTree<ASTData>* scope) {
|
NodeTree<ASTData>* ASTTransformation::generateThis(NodeTree<ASTData>* scope) {
|
||||||
// if we're looking for this, traverse up until we find the declaration of this object and assign it's type to this
|
// if we're looking for this, traverse up until we find the declaration of this object and assign it's type to this
|
||||||
NodeTree<ASTData>* trans;
|
NodeTree<ASTData>* trans;
|
||||||
@@ -1410,6 +1428,11 @@ NodeTree<ASTData>* ASTTransformation::generateThis(NodeTree<ASTData>* scope) {
|
|||||||
return identifier;
|
return identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need recursion protection
|
||||||
|
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules) {
|
||||||
|
return scopeLookup(scope, lookup, includeModules, std::set<NodeTree<ASTData>*>());
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::set<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;
|
std::cout << "Scp]|[e looking up " << lookup << std::endl;
|
||||||
std::cout << "current: " << scope->getDataRef()->toString() << std::endl;
|
std::cout << "current: " << scope->getDataRef()->toString() << std::endl;
|
||||||
|
|||||||
@@ -17,19 +17,22 @@ void CGenerator::generateCompSet(std::map<std::string, NodeTree<ASTData>*> ASTs,
|
|||||||
std::cout << "\n\n =====GENERATE PASS===== \n\n" << std::endl;
|
std::cout << "\n\n =====GENERATE PASS===== \n\n" << std::endl;
|
||||||
std::cout << "\n\nGenerate pass for: " << outputName << std::endl;
|
std::cout << "\n\nGenerate pass for: " << outputName << std::endl;
|
||||||
buildString += outputName + ".c ";
|
buildString += outputName + ".c ";
|
||||||
std::ofstream outputCFile, outputHFile;
|
//std::ofstream outputCFile, outputHFile;
|
||||||
|
std::ofstream outputCFile;
|
||||||
outputCFile.open(outputName + "/" + outputName + ".c");
|
outputCFile.open(outputName + "/" + outputName + ".c");
|
||||||
outputHFile.open(outputName + "/" + outputName + ".h");
|
//outputHFile.open(outputName + "/" + outputName + ".h");
|
||||||
if (outputCFile.is_open() || outputHFile.is_open()) {
|
//if (outputCFile.is_open() || outputHFile.is_open()) {
|
||||||
|
if (outputCFile.is_open()) {
|
||||||
// Prequel common to all files
|
// Prequel common to all files
|
||||||
auto chPair = generateTranslationUnit(outputName, ASTs);
|
auto chPair = generateTranslationUnit(outputName, ASTs);
|
||||||
outputHFile << "#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n" << chPair.first;
|
//outputHFile << "#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n" << chPair.first;
|
||||||
outputCFile << "#include \"" + outputName + ".h\"\n\n" << chPair.second;
|
//outputCFile << "#include \"" + outputName + ".h\"\n\n" << chPair.second;
|
||||||
|
outputCFile << "#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n" << chPair.first << "\n\n// C FILE BEGIN\n\n" << chPair.second;
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Cannot open file " << outputName << ".c/h" << std::endl;
|
std::cerr << "Cannot open file " << outputName << ".c/h" << std::endl;
|
||||||
}
|
}
|
||||||
outputCFile.close();
|
outputCFile.close();
|
||||||
outputHFile.close();
|
//outputHFile.close();
|
||||||
|
|
||||||
buildString += linkerString;
|
buildString += linkerString;
|
||||||
buildString += "-o " + outputName;
|
buildString += "-o " + outputName;
|
||||||
@@ -54,21 +57,46 @@ std::string CGenerator::getID() {
|
|||||||
std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
|
std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
|
||||||
auto data = from->getData();
|
auto data = from->getData();
|
||||||
auto children = from->getChildren();
|
auto children = from->getChildren();
|
||||||
std::string objectString;
|
std::string structString, enumString, functionString;
|
||||||
if (data.type == type_def)
|
std::string enumName = "__enum_dummy_" + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())+"__");
|
||||||
objectString = "struct __struct_dummy_";
|
enumString = "enum " + enumName + " {\n";
|
||||||
else if (data.type == adt_def)
|
structString = "struct __struct_dummy_";
|
||||||
objectString = "enum __adt_dummy_";
|
structString += prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())+"__") + " {\n";
|
||||||
objectString += scopePrefix(from) + CifyName(data.symbol.getName()) + "__ {\n";
|
if (data.type == adt_def) {
|
||||||
|
structString = "typedef " + structString + "enum " + enumName + " flag;\n union { \n";
|
||||||
|
}
|
||||||
tabLevel++;
|
tabLevel++;
|
||||||
for (int i = (data.type == adt_def ? 1 : 0); i < children.size(); i++) {
|
|
||||||
|
for (auto child : children) {
|
||||||
//std::cout << children[i]->getName() << std::endl;
|
//std::cout << children[i]->getName() << std::endl;
|
||||||
if (children[i]->getName() != "function")
|
if (child->getName() != "function") {
|
||||||
objectString += tabs() + generate(children[i], nullptr).oneString() + (data.type == adt_def ? ",\n" : "\n");
|
if (data.type == adt_def) {
|
||||||
|
// if this is not a plain no-data adt member (so if it is a primitive or doesn't have a reference back to)
|
||||||
|
// wait a sec, this is easier
|
||||||
|
if ( child->getDataRef()->valueType->typeDefinition != from)
|
||||||
|
structString += tabs() + ValueTypeToCType(child->getDataRef()->valueType, child->getDataRef()->symbol.getName()) + "; /* adt data member */\n";
|
||||||
|
} else {
|
||||||
|
structString += tabs() + generate(child, nullptr).oneString() + "\n";
|
||||||
|
}
|
||||||
|
enumString += tabs() + generate(child, nullptr).oneString() + (data.type == adt_def ? ",\n" : "\n");
|
||||||
|
} else {
|
||||||
|
if (data.type == adt_def) {
|
||||||
|
functionString += "\n" + ValueTypeToCType(child->getDataRef()->valueType->returnType, "fun_" + child->getDataRef()->symbol.getName()) + "(" +
|
||||||
|
(child->getDataRef()->valueType->parameterTypes.size() ? ValueTypeToCType(child->getDataRef()->valueType->parameterTypes[0], "in") : "") + "); /*adt func*/\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tabLevel--;
|
tabLevel--;
|
||||||
objectString += "};";
|
if (data.type == adt_def) {
|
||||||
return objectString;
|
//structString += "} data; /*end union*/ \n";
|
||||||
|
structString += "}; /*end union*/\n } " + CifyName(data.symbol.getName()) + "; /* end struct */";
|
||||||
|
} else {
|
||||||
|
structString += "};";
|
||||||
|
}
|
||||||
|
enumString += "};\n";
|
||||||
|
if (data.type == adt_def)
|
||||||
|
return enumString + structString + functionString;
|
||||||
|
return structString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method recurseivly generates all aliases of some definition
|
// This method recurseivly generates all aliases of some definition
|
||||||
@@ -82,8 +110,8 @@ std::string CGenerator::generateAliasChains(std::map<std::string, NodeTree<ASTDa
|
|||||||
&& declarationData->valueType->typeDefinition != declaration
|
&& declarationData->valueType->typeDefinition != declaration
|
||||||
&& declarationData->valueType->typeDefinition == definition) {
|
&& declarationData->valueType->typeDefinition == definition) {
|
||||||
output += "typedef " +
|
output += "typedef " +
|
||||||
scopePrefix(definition) + CifyName(definition->getDataRef()->symbol.getName()) + " " +
|
prefixIfNeeded(scopePrefix(definition), CifyName(definition->getDataRef()->symbol.getName())) + " " +
|
||||||
scopePrefix(declaration) + CifyName(declarationData->symbol.getName()) + ";\n";
|
prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData->symbol.getName())) + ";\n";
|
||||||
// Recursively add the ones that depend on this one
|
// Recursively add the ones that depend on this one
|
||||||
output += generateAliasChains(ASTs, declaration);
|
output += generateAliasChains(ASTs, declaration);
|
||||||
}
|
}
|
||||||
@@ -93,6 +121,17 @@ std::string CGenerator::generateAliasChains(std::map<std::string, NodeTree<ASTDa
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGenerator::isUnderNodeWithType(NodeTree<ASTData>* from, ASTType type) {
|
||||||
|
auto scope = from->getDataRef()->scope;
|
||||||
|
auto upper = scope.find("~enclosing_scope");
|
||||||
|
if (upper != scope.end()) {
|
||||||
|
if (upper->second[0]->getDataRef()->type == type)
|
||||||
|
return true;
|
||||||
|
return isUnderNodeWithType(upper->second[0], type);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CGenerator::isUnderTranslationUnit(NodeTree<ASTData>* from, NodeTree<ASTData>* node) {
|
bool CGenerator::isUnderTranslationUnit(NodeTree<ASTData>* from, NodeTree<ASTData>* node) {
|
||||||
auto scope = from->getDataRef()->scope;
|
auto scope = from->getDataRef()->scope;
|
||||||
for (auto i : scope)
|
for (auto i : scope)
|
||||||
@@ -195,7 +234,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
|||||||
{
|
{
|
||||||
auto parent = declaration->getDataRef()->scope["~enclosing_scope"][0];
|
auto parent = declaration->getDataRef()->scope["~enclosing_scope"][0];
|
||||||
if (parent->getChildren().size() == 1)
|
if (parent->getChildren().size() == 1)
|
||||||
variableDeclarations += ValueTypeToCType(declarationData.valueType, scopePrefix(declaration) + declarationData.symbol.getName()) + "; /*identifier*/\n";
|
variableDeclarations += ValueTypeToCType(declarationData.valueType, prefixIfNeeded(scopePrefix(declaration), declarationData.symbol.getName())) + "; /*identifier*/\n";
|
||||||
else
|
else
|
||||||
variableDeclarations += ValueTypeToCType(declarationData.valueType, generate(parent->getChildren()[0], nullptr, true, nullptr).oneString()) + " = " + generate(parent->getChildren()[1], nullptr, true, nullptr).oneString() + ";";
|
variableDeclarations += ValueTypeToCType(declarationData.valueType, generate(parent->getChildren()[0], nullptr, true, nullptr).oneString()) + " = " + generate(parent->getChildren()[1], nullptr, true, nullptr).oneString() + ";";
|
||||||
variableExternDeclarations += "extern " + ValueTypeToCType(declarationData.valueType, declarationData.symbol.getName()) + "; /*extern identifier*/\n";
|
variableExternDeclarations += "extern " + ValueTypeToCType(declarationData.valueType, declarationData.symbol.getName()) + "; /*extern identifier*/\n";
|
||||||
@@ -217,12 +256,11 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
|||||||
parameters += ValueTypeToCType(decChildren[j]->getData().valueType, generate(decChildren[j], nullptr).oneString());
|
parameters += ValueTypeToCType(decChildren[j]->getData().valueType, generate(decChildren[j], nullptr).oneString());
|
||||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType);
|
nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType);
|
||||||
}
|
}
|
||||||
functionPrototypes += "\n" + ValueTypeToCType(declarationData.valueType->returnType, ((declarationData.symbol.getName() == "main") ? "" : function_header + scopePrefix(declaration)) +
|
std::string funName = (declarationData.symbol.getName() == "main") ? "main" :
|
||||||
CifyName(declarationData.symbol.getName() + nameDecoration)) +
|
function_header + prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName() + nameDecoration));
|
||||||
"(" + parameters + "); /*func*/\n";
|
functionPrototypes += "\n" + ValueTypeToCType(declarationData.valueType->returnType, funName) + "(" + parameters + "); /*func*/\n";
|
||||||
// generate function
|
// generate function
|
||||||
std::cout << "Generating " << scopePrefix(declaration) +
|
std::cout << "Generating " << prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())) << std::endl;
|
||||||
CifyName(declarationData.symbol.getName()) << std::endl;
|
|
||||||
functionDefinitions += generate(declaration, nullptr).oneString();
|
functionDefinitions += generate(declaration, nullptr).oneString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,13 +276,12 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
|||||||
continue; // Aliases of objects are done with the thing it alises
|
continue; // Aliases of objects are done with the thing it alises
|
||||||
// Otherwise, we're actually a renaming of a primitive, can generate here
|
// Otherwise, we're actually a renaming of a primitive, can generate here
|
||||||
plainTypedefs += "typedef " + ValueTypeToCType(declarationData.valueType,
|
plainTypedefs += "typedef " + ValueTypeToCType(declarationData.valueType,
|
||||||
scopePrefix(declaration) +
|
prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName()))) + ";\n";
|
||||||
CifyName(declarationData.symbol.getName())) + ";\n";
|
|
||||||
plainTypedefs += generateAliasChains(ASTs, declaration);
|
plainTypedefs += generateAliasChains(ASTs, declaration);
|
||||||
} else {
|
} else {
|
||||||
plainTypedefs += "typedef struct __struct_dummy_" +
|
plainTypedefs += "typedef struct __struct_dummy_" +
|
||||||
scopePrefix(declaration) + CifyName(declarationData.symbol.getName()) + "__ " +
|
prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName()) + "__") + " " +
|
||||||
scopePrefix(declaration) + CifyName(declarationData.symbol.getName()) + ";\n";
|
prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())) + ";\n";
|
||||||
functionPrototypes += "/* Method Prototypes for " + declarationData.symbol.getName() + " */\n";
|
functionPrototypes += "/* Method Prototypes for " + declarationData.symbol.getName() + " */\n";
|
||||||
// We use a seperate string for this because we only include it if this is the file we're defined in
|
// We use a seperate string for this because we only include it if this is the file we're defined in
|
||||||
std::string objectFunctionDefinitions = "/* Method Definitions for " + declarationData.symbol.getName() + " */\n";
|
std::string objectFunctionDefinitions = "/* Method Definitions for " + declarationData.symbol.getName() + " */\n";
|
||||||
@@ -264,19 +301,15 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
|||||||
case adt_def:
|
case adt_def:
|
||||||
{
|
{
|
||||||
//type
|
//type
|
||||||
plainTypedefs += "/* adt " + declarationData.symbol.getName() + " */\n";
|
//don't even need to do this anymore, it's all earlier
|
||||||
//plainTypedefs += "typedef struct __adt_dummy_" +
|
//plainTypedefs += "/* adt " + declarationData.symbol.getName() + " */\n";
|
||||||
plainTypedefs += "typedef enum __adt_dummy_" +
|
//plainTypedefs += "typedef struct __struct_dummy_" +
|
||||||
scopePrefix(declaration) + CifyName(declarationData.symbol.getName()) + "__ " +
|
//prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())+ "__") + " " +
|
||||||
scopePrefix(declaration) + CifyName(declarationData.symbol.getName()) + ";\n";
|
//prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())) + ";\n";
|
||||||
// We use a seperate string for this because we only include it if this is the file we're defined in
|
//// skip the name of the thing
|
||||||
std::string enumString = "/* Enum Definition for " + declarationData.symbol.getName() + " */\n";
|
//for (int j = 1; j < decChildren.size(); j++) {
|
||||||
// skip the name of the thing
|
//std::cout << decChildren[j]->getName() << std::endl;
|
||||||
for (int j = 1; j < decChildren.size(); j++) {
|
//}
|
||||||
std::cout << decChildren[j]->getName() << std::endl;
|
|
||||||
if (decChildren[j]->getName() == "identifier") //If object method and not template
|
|
||||||
enumString += "an_option \n";
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -344,8 +377,8 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
preName += "(*";
|
preName += "(*";
|
||||||
postName += ")";
|
postName += ")";
|
||||||
}
|
}
|
||||||
// we're scope prefixing EVERYTHING
|
// we're scope prefixing EVERYTHING, but only if needed
|
||||||
return preName + scopePrefix(from) + CifyName(data.symbol.getName()) + postName; //Cifying does nothing if not an operator overload
|
return preName + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())) + postName; //Cifying does nothing if not an operator overload
|
||||||
}
|
}
|
||||||
case function:
|
case function:
|
||||||
{
|
{
|
||||||
@@ -370,7 +403,8 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
if (justFuncName) {
|
if (justFuncName) {
|
||||||
std::string funcName;
|
std::string funcName;
|
||||||
if (data.symbol.getName() != "main")
|
if (data.symbol.getName() != "main")
|
||||||
funcName += function_header + scopePrefix(from);
|
funcName += function_header + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName() + nameDecoration));
|
||||||
|
else
|
||||||
funcName += CifyName(data.symbol.getName() + nameDecoration);
|
funcName += CifyName(data.symbol.getName() + nameDecoration);
|
||||||
if (from->getDataRef()->closedVariables.size()) {
|
if (from->getDataRef()->closedVariables.size()) {
|
||||||
std::string tmpStruct = "closureStruct" + getID();
|
std::string tmpStruct = "closureStruct" + getID();
|
||||||
@@ -384,7 +418,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
std::string preName;
|
std::string preName;
|
||||||
if (enclosingObject && enclosingObject->getDataRef()->scope.find(varName) != enclosingObject->getDataRef()->scope.end())
|
if (enclosingObject && enclosingObject->getDataRef()->scope.find(varName) != enclosingObject->getDataRef()->scope.end())
|
||||||
preName += "this->";
|
preName += "this->";
|
||||||
varName = (varName == "this") ? varName : scopePrefix(var) + varName;
|
varName = (varName == "this") ? varName : prefixIfNeeded(scopePrefix(var), varName);
|
||||||
// so that we can close over things that have been closed over by an enclosing closure
|
// so that we can close over things that have been closed over by an enclosing closure
|
||||||
output.preValue += "." + varName + " = &/*woo*/" + generate(var, enclosingObject, justFuncName, enclosingFunction).oneString() + "/*woo*/";
|
output.preValue += "." + varName + " = &/*woo*/" + generate(var, enclosingObject, justFuncName, enclosingFunction).oneString() + "/*woo*/";
|
||||||
//output.preValue += "." + varName + " = &" + preName + varName;
|
//output.preValue += "." + varName + " = &" + preName + varName;
|
||||||
@@ -396,8 +430,9 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock
|
// Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock
|
||||||
output = "\n" + ValueTypeToCType(data.valueType->returnType, ((data.symbol.getName() == "main") ? "" : function_header + scopePrefix(from)) +
|
std::string funName = (data.symbol.getName() == "main") ? "main" : function_header + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName() + nameDecoration));
|
||||||
CifyName(data.symbol.getName() + nameDecoration)) + "(" + parameters + ") {\n" + generate(children[children.size()-1], enclosingObject, justFuncName, from).oneString();
|
output = "\n" + ValueTypeToCType(data.valueType->returnType, funName) + "(" + parameters + ") {\n" +
|
||||||
|
generate(children[children.size()-1], enclosingObject, justFuncName, from).oneString();
|
||||||
output += emitDestructors(reverse(distructDoubleStack.back()), enclosingObject);
|
output += emitDestructors(reverse(distructDoubleStack.back()), enclosingObject);
|
||||||
output += "}\n";
|
output += "}\n";
|
||||||
}
|
}
|
||||||
@@ -615,6 +650,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
return CCodeTriple("");
|
return CCodeTriple("");
|
||||||
case simple_passthrough:
|
case simple_passthrough:
|
||||||
{
|
{
|
||||||
|
std::string pre_end_dec, end_assign;
|
||||||
// Stuff is bit more interesting now! XXX
|
// Stuff is bit more interesting now! XXX
|
||||||
std::string pre_passthrough, post_passthrough;
|
std::string pre_passthrough, post_passthrough;
|
||||||
// Handle input/output parameters
|
// Handle input/output parameters
|
||||||
@@ -623,17 +659,27 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
for (auto in_or_out : optParamAssignLists) {
|
for (auto in_or_out : optParamAssignLists) {
|
||||||
for (auto assign : in_or_out->getChildren()) {
|
for (auto assign : in_or_out->getChildren()) {
|
||||||
auto assignChildren = assign->getChildren();
|
auto assignChildren = assign->getChildren();
|
||||||
if (in_or_out->getDataRef()->type == in_passthrough_params)
|
if (in_or_out->getDataRef()->type == in_passthrough_params) {
|
||||||
|
std::string currentName = generate(assignChildren[0], enclosingObject, enclosingFunction).oneString();
|
||||||
|
std::string toName;
|
||||||
if (assignChildren.size() == 2)
|
if (assignChildren.size() == 2)
|
||||||
pre_passthrough += ValueTypeToCType(assignChildren[0]->getDataRef()->valueType, assignChildren[1]->getDataRef()->symbol.getName()) + " = " + generate(assignChildren[0], enclosingObject, enclosingFunction).oneString() + ";\n";
|
toName = assignChildren[1]->getDataRef()->symbol.getName();
|
||||||
else
|
else
|
||||||
pre_passthrough += ValueTypeToCType(assignChildren[0]->getDataRef()->valueType, assignChildren[0]->getDataRef()->symbol.getName()) + " = " + generate(assignChildren[0], enclosingObject, enclosingFunction).oneString() + ";\n";
|
toName = assignChildren[0]->getDataRef()->symbol.getName();
|
||||||
else if (in_or_out->getDataRef()->type == out_passthrough_params)
|
if (currentName != toName)
|
||||||
|
pre_passthrough += ValueTypeToCType(assignChildren[0]->getDataRef()->valueType, toName) + " = " + currentName + ";\n";
|
||||||
|
} else if (in_or_out->getDataRef()->type == out_passthrough_params) {
|
||||||
|
std::string currentName = generate(assignChildren[0], enclosingObject, justFuncName, enclosingFunction).oneString();
|
||||||
|
std::string toName;
|
||||||
if (assignChildren.size() == 2)
|
if (assignChildren.size() == 2)
|
||||||
post_passthrough += generate(assignChildren[0], enclosingObject, justFuncName, enclosingFunction).oneString() + " = " + assignChildren[1]->getDataRef()->symbol.getName() + ";\n";
|
toName = assignChildren[1]->getDataRef()->symbol.getName();
|
||||||
else
|
|
||||||
post_passthrough += generate(assignChildren[0], enclosingObject, justFuncName, enclosingFunction).oneString() + " = " + assignChildren[0]->getDataRef()->symbol.getName() + ";\n";
|
|
||||||
else
|
else
|
||||||
|
toName += assignChildren[0]->getDataRef()->symbol.getName();
|
||||||
|
std::string trans_dec_name = currentName + "_end_assign";
|
||||||
|
pre_end_dec += ValueTypeToCType(assignChildren[0]->getDataRef()->valueType, trans_dec_name) + ";\n";
|
||||||
|
post_passthrough += trans_dec_name + " = " + toName + ";\n";
|
||||||
|
end_assign += currentName + " = " + trans_dec_name + ";\n";
|
||||||
|
} else
|
||||||
linkerString += " " + strSlice(generate(in_or_out, enclosingObject, justFuncName, enclosingFunction).oneString(), 1, -2) + " ";
|
linkerString += " " + strSlice(generate(in_or_out, enclosingObject, justFuncName, enclosingFunction).oneString(), 1, -2) + " ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -641,8 +687,11 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
// The actual passthrough string is the last child now, as we might
|
// The actual passthrough string is the last child now, as we might
|
||||||
// have passthrough_params be the first child
|
// have passthrough_params be the first child
|
||||||
// we don't generate, as that will escape the returns and we don't want that. We'll just grab the string
|
// we don't generate, as that will escape the returns and we don't want that. We'll just grab the string
|
||||||
//return pre_passthrough + strSlice(generate(children.back(, enclosingFunction), enclosingObject, justFuncName).oneString(), 3, -4) + post_passthrough;
|
// we don't want the scope stuff if we're at top level for an include, etc....
|
||||||
return pre_passthrough + strSlice(children.back()->getDataRef()->symbol.getName(), 3, -4) + post_passthrough;
|
if (isUnderNodeWithType(from,function))
|
||||||
|
return pre_end_dec + "{" + pre_passthrough + strSlice(children.back()->getDataRef()->symbol.getName(), 3, -4) + post_passthrough + "}\n" + end_assign;
|
||||||
|
else
|
||||||
|
return strSlice(children.back()->getDataRef()->symbol.getName(), 3, -4);
|
||||||
}
|
}
|
||||||
case function_call:
|
case function_call:
|
||||||
{
|
{
|
||||||
@@ -704,7 +753,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
for (int i = 0; i < (functionDefChildren.size() > 0 ? functionDefChildren.size()-1 : 0); i++)
|
for (int i = 0; i < (functionDefChildren.size() > 0 ? functionDefChildren.size()-1 : 0); i++)
|
||||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(functionDefChildren[i]->getData().valueType);
|
nameDecoration += "_" + ValueTypeToCTypeDecoration(functionDefChildren[i]->getData().valueType);
|
||||||
// Note that we only add scoping to the object, as this specifies our member function too
|
// Note that we only add scoping to the object, as this specifies our member function too
|
||||||
/*HERE*/ return function_header + scopePrefix(unaliasedTypeDef) + CifyName(unaliasedTypeDef->getDataRef()->symbol.getName()) +"__" +
|
/*HERE*/ return function_header + prefixIfNeeded(scopePrefix(unaliasedTypeDef), CifyName(unaliasedTypeDef->getDataRef()->symbol.getName())) +"__" +
|
||||||
CifyName(functionName + nameDecoration) + "(" + (name == "." ? "&" : "") + generate(children[1], enclosingObject, true, enclosingFunction) + ",";
|
CifyName(functionName + nameDecoration) + "(" + (name == "." ? "&" : "") + generate(children[1], enclosingObject, true, enclosingFunction) + ",";
|
||||||
//The comma lets the upper function call know we already started the param list
|
//The comma lets the upper function call know we already started the param list
|
||||||
//Note that we got here from a function call. We just pass up this special case and let them finish with the perentheses
|
//Note that we got here from a function call. We just pass up this special case and let them finish with the perentheses
|
||||||
@@ -746,11 +795,11 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
//Check to see if we're inside of an object and this is a method call
|
//Check to see if we're inside of an object and this is a method call
|
||||||
bool isSelfObjectMethod = enclosingObject && contains(enclosingObject->getChildren(), children[0]);
|
bool isSelfObjectMethod = enclosingObject && contains(enclosingObject->getChildren(), children[0]);
|
||||||
if (isSelfObjectMethod) {
|
if (isSelfObjectMethod) {
|
||||||
output += function_header + scopePrefix(children[0]) + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__";
|
output += function_header + prefixIfNeeded(scopePrefix(children[0]), CifyName(enclosingObject->getDataRef()->symbol.getName())) +"__";
|
||||||
output += CifyName(name + nameDecoration) + "(";
|
output += CifyName(name + nameDecoration) + "(";
|
||||||
output += std::string(addClosedOver ? "(*closed_variables->this)" : "this") + (children.size() > 1 ? "," : "");
|
output += std::string(addClosedOver ? "(*closed_variables->this)" : "this") + (children.size() > 1 ? "," : "");
|
||||||
} else {
|
} else {
|
||||||
output += function_header + scopePrefix(children[0]) + CifyName(name + nameDecoration) + "(";
|
output += function_header + prefixIfNeeded(scopePrefix(children[0]), CifyName(name + nameDecoration)) + "(";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -877,8 +926,9 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
|
|||||||
|
|
||||||
distructDoubleStack.back().push_back(children[i]);
|
distructDoubleStack.back().push_back(children[i]);
|
||||||
}
|
}
|
||||||
std::string functionSignature = "\n" + ValueTypeToCType(data.valueType->returnType, function_header + scopePrefix(from) + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__"
|
std::string functionSignature = "\n" + ValueTypeToCType(data.valueType->returnType, function_header +
|
||||||
+ CifyName(data.symbol.getName()) + nameDecoration) + "(" + ValueTypeToCType(&enclosingObjectType, "this") + parameters + ")";
|
prefixIfNeeded(scopePrefix(from), CifyName(enclosingObject->getDataRef()->symbol.getName())) + "__" +
|
||||||
|
CifyName(data.symbol.getName()) + nameDecoration) + "(" + ValueTypeToCType(&enclosingObjectType, "this") + parameters + ")";
|
||||||
*functionPrototype += functionSignature + ";\n";
|
*functionPrototype += functionSignature + ";\n";
|
||||||
// Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock
|
// Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock
|
||||||
//
|
//
|
||||||
@@ -928,7 +978,7 @@ std::string CGenerator::generateMethodIfExists(Type* type, std::string method, s
|
|||||||
std::string nameDecoration;
|
std::string nameDecoration;
|
||||||
for (Type *paramType : methodDef->getDataRef()->valueType->parameterTypes)
|
for (Type *paramType : methodDef->getDataRef()->valueType->parameterTypes)
|
||||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(paramType);
|
nameDecoration += "_" + ValueTypeToCTypeDecoration(paramType);
|
||||||
return function_header + scopePrefix(typeDefinition) + CifyName(typeDefinition->getDataRef()->symbol.getName()) + "__" + method + nameDecoration + "(" + parameter + ");\n";
|
return function_header + prefixIfNeeded(scopePrefix(typeDefinition), CifyName(typeDefinition->getDataRef()->symbol.getName())) + "__" + method + nameDecoration + "(" + parameter + ");\n";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -952,7 +1002,7 @@ std::string CGenerator::closureStructType(std::set<NodeTree<ASTData>*> closedVar
|
|||||||
// will actually change the underlying function's type. We cheat and just add a *
|
// will actually change the underlying function's type. We cheat and just add a *
|
||||||
//auto tmp = var->getDataRef()->valueType->withIncreasedIndirection();
|
//auto tmp = var->getDataRef()->valueType->withIncreasedIndirection();
|
||||||
std::string varName = var->getDataRef()->symbol.getName();
|
std::string varName = var->getDataRef()->symbol.getName();
|
||||||
varName = (varName == "this") ? varName : scopePrefix(var) + varName;
|
varName = (varName == "this") ? varName : prefixIfNeeded(scopePrefix(var), varName);
|
||||||
typedefString += ValueTypeToCType(var->getDataRef()->valueType->withoutReference(), "*"+varName) + ";";
|
typedefString += ValueTypeToCType(var->getDataRef()->valueType->withoutReference(), "*"+varName) + ";";
|
||||||
}
|
}
|
||||||
std::string structName = "closureStructType" + getID();
|
std::string structName = "closureStructType" + getID();
|
||||||
@@ -970,7 +1020,7 @@ std::string CGenerator::ValueTypeToCTypeThingHelper(Type *type, std::string decl
|
|||||||
switch (type->baseType) {
|
switch (type->baseType) {
|
||||||
case none:
|
case none:
|
||||||
if (type->typeDefinition)
|
if (type->typeDefinition)
|
||||||
return_type = scopePrefix(type->typeDefinition) + CifyName(type->typeDefinition->getDataRef()->symbol.getName());
|
return_type = prefixIfNeeded(scopePrefix(type->typeDefinition), CifyName(type->typeDefinition->getDataRef()->symbol.getName()));
|
||||||
else
|
else
|
||||||
return_type = "none";
|
return_type = "none";
|
||||||
break;
|
break;
|
||||||
@@ -1128,4 +1178,20 @@ std::string CGenerator::scopePrefix(NodeTree<ASTData>* from) {
|
|||||||
// that parent object will get scoped. When we add a package system, we'll have to then add their scoping here
|
// that parent object will get scoped. When we add a package system, we'll have to then add their scoping here
|
||||||
return scopePrefix(from->getDataRef()->scope["~enclosing_scope"][0]);
|
return scopePrefix(from->getDataRef()->scope["~enclosing_scope"][0]);
|
||||||
}
|
}
|
||||||
|
std::string CGenerator::prefixIfNeeded(std::string prefix, std::string name) {
|
||||||
|
return simpleComplexName(name, prefix + name);
|
||||||
|
}
|
||||||
|
std::string CGenerator::simpleComplexName(std::string simpleName, std::string complexName) {
|
||||||
|
auto already = simpleComplexNameMap.find(complexName);
|
||||||
|
if (already != simpleComplexNameMap.end())
|
||||||
|
return already->second;
|
||||||
|
if (usedNameSet.find(simpleName) == usedNameSet.end()) {
|
||||||
|
usedNameSet.insert(simpleName);
|
||||||
|
simpleComplexNameMap[complexName] = simpleName;
|
||||||
|
return simpleName;
|
||||||
|
}
|
||||||
|
usedNameSet.insert(complexName);
|
||||||
|
simpleComplexNameMap[complexName] = complexName;
|
||||||
|
return complexName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ Importer::Importer(Parser* parserIn, std::vector<std::string> includePaths, std:
|
|||||||
collapseSymbols.push_back(Symbol("opt_typed_parameter_list", false));
|
collapseSymbols.push_back(Symbol("opt_typed_parameter_list", false));
|
||||||
collapseSymbols.push_back(Symbol("opt_parameter_list", false));
|
collapseSymbols.push_back(Symbol("opt_parameter_list", false));
|
||||||
collapseSymbols.push_back(Symbol("identifier_list", false));
|
collapseSymbols.push_back(Symbol("identifier_list", false));
|
||||||
|
collapseSymbols.push_back(Symbol("adt_option_list", false));
|
||||||
collapseSymbols.push_back(Symbol("statement_list", false));
|
collapseSymbols.push_back(Symbol("statement_list", false));
|
||||||
collapseSymbols.push_back(Symbol("parameter_list", false));
|
collapseSymbols.push_back(Symbol("parameter_list", false));
|
||||||
collapseSymbols.push_back(Symbol("typed_parameter_list", false));
|
collapseSymbols.push_back(Symbol("typed_parameter_list", false));
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ fun read_file_binary(path: string::string): vector::vector<char> {
|
|||||||
|
|
||||||
__if_comp__ __C__ {
|
__if_comp__ __C__ {
|
||||||
simple_passthrough(data = data::) """
|
simple_passthrough(data = data::) """
|
||||||
free(data)
|
free(data);
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
return toRet
|
return toRet
|
||||||
|
|||||||
@@ -5,16 +5,42 @@ adt options {
|
|||||||
option1
|
option1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adt maybe_int {
|
||||||
|
no_int,
|
||||||
|
an_int: int
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handle_possibility(it: maybe_int) {
|
||||||
|
if (it == maybe_int::no_int())
|
||||||
|
println("no int")
|
||||||
|
/*if (it == maybe_int::an_int) {*/
|
||||||
|
else {
|
||||||
|
print("an int: ")
|
||||||
|
println(it.an_int)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun give_maybe(give_it: bool): maybe_int {
|
||||||
|
if (give_it)
|
||||||
|
return maybe_int::an_int(7)
|
||||||
|
return maybe_int::no_int()
|
||||||
|
}
|
||||||
|
|
||||||
fun can_pass(it: options): options {
|
fun can_pass(it: options): options {
|
||||||
return options::option1
|
return it
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main():int {
|
fun main():int {
|
||||||
var it: options = can_pass(options::option0)
|
var it: options = can_pass(options::option0())
|
||||||
if (it == options::option0)
|
if (it == options::option0())
|
||||||
println("nope")
|
println("nope")
|
||||||
if (it == options::option1)
|
if (it == options::option1())
|
||||||
println("option1")
|
println("option1")
|
||||||
|
|
||||||
|
var possibility = give_maybe(false)
|
||||||
|
handle_possibility(possibility)
|
||||||
|
possibility = give_maybe(true)
|
||||||
|
handle_possibility(possibility)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user