From 417e5ed89882849f2985fe781146e7f958e00ebf Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Fri, 19 Dec 2014 18:29:33 -0500 Subject: [PATCH 1/2] Scope work progressing. Gotta fix bugs. Good save spot. --- .gitignore | 6 ++ include/.ASTData.h.swp | Bin 0 -> 12288 bytes include/ASTTransformation.h | 1 + krakenGrammer.kgm | 11 +-- src/.ASTTransformation.cpp.swp | Bin 0 -> 102400 bytes src/ASTTransformation.cpp | 116 +++++++++++++++++++++++++----- src/Importer.cpp | 4 +- tests/newScoping.expected_results | 13 ++++ tests/newScoping.krak | 32 +++++++++ tests/scopeQualified.krak | 27 +++++++ tests/scopeUnqualified.krak | 27 +++++++ 11 files changed, 214 insertions(+), 23 deletions(-) create mode 100644 .gitignore create mode 100644 include/.ASTData.h.swp create mode 100644 src/.ASTTransformation.cpp.swp create mode 100644 tests/newScoping.expected_results create mode 100644 tests/newScoping.krak create mode 100644 tests/scopeQualified.krak create mode 100644 tests/scopeUnqualified.krak diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85f38a8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +_site +build +*.comp +stats +*.swp +*.png diff --git a/include/.ASTData.h.swp b/include/.ASTData.h.swp new file mode 100644 index 0000000000000000000000000000000000000000..ea4dd95b72c6a5e180a6cd88f99ee8de17bc8928 GIT binary patch literal 12288 zcmYc?2=nw+FxN9-U|?VnU|^Vg|5I>i`4)!7d<+bEi6t3{c_0b=I5#mbE3qgazaj<( zhB}CW`q@Q^*{ON@nR&@Mr75ZUj=>==i6x1883YX&RWKR?qai?E2$Ytj>00nI7#kTH zfDBMpQdAHY3I#Do@n{H)hQMeDjE2By2#kinXb6mkz-S1JhQJ63fsz77hI$4D1}3O~ zRiQK^8V%)+QllX-8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OLofsqQy3V| zax*a0@<8VQVg3Ji{0t0t_!$^(^D{7<m#m~U7lb?ZMDL(^4KR*LQGd}}EAwL5{ z0Y3vnGCu=@H$MY|3qJ#cGd}~vb3O)!DSQkJ27C+*zj+xLe(^Feyy9hGc*x7ZaD|tF zVKFZQLozP|Lnto;gEcP$13NDR!*?DAh9^7>43~Kr7$);DFm&=TFm&)RFtqY8FtqSM z+*bo~;}8tvQ74avz-S1JhQMeDjE2By2#kinXb6mkz-S0CFfb^m=A~q&F)-9xGca%# z6lInrmZVxSaB>!xq*z(yCKlL$8O0?DVl%|51AR))#5D-(Lq!Oa1xFoS8 zGZ|tD#6|_El92phunRPxe6SWxkQrbXK^2$4RDoscpzhKD^I#lg19TKnT&be~c8wO? zjS993exW`-c=QvY0i?U2G$|)D*@_`KC$YE~}5E(!Au7%>2Cg4mj9T;tLXs5_3~aQj2sHQY#9IQj3c-^Ye5RlJfI&QWNvyk;RaVOwB9J1^FEu zX4R#6DXD2X3MEB}dBr&p>r3-8OLP=6^GZ^S3W`9+$ERc#r6!kTmZj<_Wabv+7lEWx zQu9hO(=tJpgVIer$QXDsR!&Jx%gjp!N1K9%Mp=Glik7B { NodeTree* functionLookup(NodeTree* scope, std::string lookup, std::vector types); NodeTree* templateFunctionLookup(NodeTree* scope, std::string lookup, std::vector templateInstantiationTypes, std::vector types); std::vector*> scopeLookup(NodeTree* scope, std::string lookup, bool includeModules = false); + std::vector*> scopeLookup(NodeTree* scope, std::string lookup, bool includeModules, std::vector*> visited); Type* typeFromTypeNode(NodeTree* typeNode, NodeTree* scope, std::map templateTypeReplacements); NodeTree* templateClassLookup(NodeTree* scope, std::string name, std::vector templateInstantiationTypes); diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index a9af015..732a2eb 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -2,7 +2,7 @@ Goal = translation_unit ; translation_unit = interpreter_directive WS unorderd_list_part WS ; unorderd_list_part = import WS unorderd_list_part | function WS unorderd_list_part | type_def WS ";" WS unorderd_list_part | if_comp WS unorderd_list_part | simple_passthrough WS unorderd_list_part | declaration_statement WS ";" WS unorderd_list_part | import | function | type_def WS ";" | if_comp | simple_passthrough | declaration_statement WS ";" ; -type = type WS "\*" | "void" | "int" | "float" | "double" | "char" | identifier | identifier WS template_inst ; +type = type WS "\*" | "void" | "int" | "float" | "double" | "char" | scoped_identifier | scoped_identifier WS template_inst ; dec_type = "\|" WS type WS "\|" ; template_inst = "<" WS type_list WS ">" ; @@ -12,8 +12,8 @@ template_dec = "template" WS "<" WS template_param_list WS ">" ; template_param_list = template_param_list WS "," WS template_param | template_param ; template_param = identifier WS traits | identifier ; -import = "import" WS identifier WS ";" ; - +import = "import" WS identifier WS ";" | "import" WS identifier WS ":" WS "\*" WS ";" | "import" WS identifier WS ":" WS import_list WS ";" ; +import_list = identifier | identifier WS "," WS import_list ; interpreter_directive = "#!" WS path | ; path = path path_part | path_part ; @@ -37,6 +37,7 @@ triple_quoted_string = "\"\"\"((\"\"(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i |z|x|c|v|b|n|m|,|.|/|~|!|@|#|$|%|^|&|\*|\(|\)|_|\+|Q|W|E|R|T|Y|U|I|O|P|{|}|\||A|S|D|F|G|H|J|K|L|:|Z|X|C|V|B|N|M|<|>|\?| )+))*\"\"\"" ; identifier = alpha | alpha alphanumeric ; +scoped_identifier = scoped_identifier WS "::" WS identifier | identifier ; #Note that to prevent confilct with nested templates (T>) it is a nonterminal contructed as follows right_shift = ">" ">" ; @@ -56,7 +57,7 @@ type_def = "typedef" WS identifier WS type | "typedef" WS template_dec WS identi declaration_block = declaration_statement WS ";" WS declaration_block | function WS declaration_block | declaration_statement WS ";" | function | ; traits = "\(" WS trait_list WS "\)" ; -trait_list = trait_list WS "," WS identifier | identifier ; +trait_list = trait_list WS "," WS scoped_identifier | scoped_identifier ; #Older rule for stuff with visibility labels - this should be added sometime #type_def = "typedef" WS identifier WS type | "typedef" WS template_dec WS identifier WS "{" WS class_innerds WS "}" | "typedef" WS identifier WS "{" WS class_innerds WS "}" | "typedef" WS template_dec WS identifier WS "{" WS declaration_block WS "}" | "typedef" WS identifier WS "{" WS declaration_block WS "}" ; @@ -87,7 +88,7 @@ expression = expression WS "<<" WS term | expression WS right_shift WS shiftand shiftand = shiftand WS "-" WS term | shiftand WS "\+" WS term | term ; term = term WS forward_slash WS factor | term WS "\*" WS factor | term WS "%" WS factor | factor ; factor = "\+\+" WS unarad | unarad WS "\+\+" | "--" WS unarad | unarad WS "--" | "\+" WS unarad | "-" WS unarad | "!" WS unarad | "~" WS unarad | "\(" WS type WS "\)" WS unarad | "\*" WS unarad | "&" WS unarad | unarad ; -unarad = number | identifier | identifier WS template_inst | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | access_operation | unarad WS "[" WS expression WS "]" ; +unarad = number | scoped_identifier | scoped_identifier WS template_inst | function_call | bool | string | character | "\(" WS boolean_expression WS "\)" | access_operation | unarad WS "[" WS expression WS "]" ; number = integer | floating_literal ; access_operation = unarad "." identifier | unarad "->" identifier ; diff --git a/src/.ASTTransformation.cpp.swp b/src/.ASTTransformation.cpp.swp new file mode 100644 index 0000000000000000000000000000000000000000..12f088942fc8a4a376725fa111cf1cce8691253b GIT binary patch literal 102400 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 ASTTransformation::firstPass(std::string fileName, NodeTree* i : children) { if (i->getDataRef()->getName() == "import") { - std::string toImport = concatSymbolTree(i->getChildren()[0]); - translationUnit->addChild(new NodeTree("import", ASTData(import, Symbol(toImport, true)))); + auto importChildren = i->getChildren(); + std::string toImport = concatSymbolTree(importChildren[0]); + auto importNode = new NodeTree("import", ASTData(import, Symbol(toImport, true))); + translationUnit->addChild(importNode); //Do the imported file too NodeTree* outsideTranslationUnit = importer->importFirstPass(toImport + ".krak"); translationUnit->getDataRef()->scope[toImport].push_back(outsideTranslationUnit); //Put this transation_unit in the scope as it's files name - //Now add it to scope - for (auto i = outsideTranslationUnit->getDataRef()->scope.begin(); i != outsideTranslationUnit->getDataRef()->scope.end(); i++) - for (auto j : i->second) - translationUnit->getDataRef()->scope[i->first].push_back(j); + // Now go through and handle anything like import asdf: a; or import asdf: a,b; or import asdf: *; + // We do this by looping through the children and adding links to them as the scope in the import node. If it's *, we add the entire translationUnit link. + // Note that import affects scope in two ways: + // (1) The other file's translationUnit is added to our translationUnit's scope under it's name + // (2) The import node's scope contains the nodes indicated by the qualifiers after the import (i.e. the import a:b; or import a:*;) + for (auto importQualifer : slice(importChildren, 1, -1)) { // Not the first child, that's the name of the file + auto name = concatSymbolTree(importQualifer); + if (name == "*") { + std::vector*> tmp; + tmp.push_back(outsideTranslationUnit); + importNode->getDataRef()->scope["*"] = tmp; + } else { + bool found = false; + for (auto outsideScopeEntry : outsideTranslationUnit->getDataRef()->scope) { + if (name == outsideScopeEntry.first) { + importNode->getDataRef()->scope[outsideScopeEntry.first] = outsideScopeEntry.second; + found = true; + } + } + // If it's not found yet, put it in as a empty vector for pass 3. + // This makes sure that it does appear in the scope map, which is what we iterate through later. + if (!found) + importNode->getDataRef()->scope[name] = std::vector*>(); + } + } } } @@ -223,13 +246,17 @@ void ASTTransformation::thirdPass(NodeTree* ast) { NodeTree* outsideTranslationUnit = importer->getUnit(toImport + ".krak"); //Now add all functions to scope std::cout << "Trying to re-import from " << toImport << std::endl; - for (auto i = outsideTranslationUnit->getDataRef()->scope.begin(); i != outsideTranslationUnit->getDataRef()->scope.end(); i++) { - std::cout << "Looking through " << i->first << std::endl; - for (auto j : i->second) - if (j->getDataRef()->type == function || j->getDataRef()->type == identifier) - std::cout << "Copying " << i->first << std::endl, ast->getDataRef()->scope[i->first].push_back(j); + for (auto j = outsideTranslationUnit->getDataRef()->scope.begin(); j != outsideTranslationUnit->getDataRef()->scope.end(); j++) { + std::cout << "Looking at " << j->first << std::endl; + // If we're supposed to import this... (meaning that this name is in the scope already) + if (i->getDataRef()->scope.find(j->first) == i->getDataRef()->scope.end()) + continue; + std::cout << "Looking through " << j->first << std::endl; + for (auto k : j->second) + if (k->getDataRef()->type == function || k->getDataRef()->type == identifier) + std::cout << "Copying " << j->first << std::endl, i->getDataRef()->scope[j->first].push_back(k); else - std::cout << "Not Copying " << i->first << std::endl; + std::cout << "Not Copying " << j->first << std::endl; } } } @@ -332,7 +359,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree std::vector*> children = from->getChildren(); std::set skipChildren; - if (name == "identifier") { + if (name == "identifier" || name == "scoped_identifier") { //Make sure we get the entire name std::string lookupName = concatSymbolTree(from); std::cout << "Looking up: " << lookupName << std::endl; @@ -350,6 +377,7 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree } newNode = possibleMatches[0]; } + return newNode; } else if (name == "type_def") { //If it is an alisis of a type std::string typeAlias; @@ -416,6 +444,8 @@ NodeTree* ASTTransformation::transform(NodeTree* from, NodeTree return newNode; } functionName = concatSymbolTree(children[1]); + for (auto child: children) + std::cout << "Function child: " << child->getDataRef()->toString() << std::endl; newNode = new NodeTree(name, ASTData(function, Symbol(functionName, true), typeFromTypeNode(children[0], scope, templateTypeReplacements))); skipChildren.insert(0); skipChildren.insert(1); @@ -795,11 +825,19 @@ NodeTree* ASTTransformation::functionLookup(NodeTree* scope, s //We subtract one from the children to get the type size only if there is at least one child AND // the last node is actually a body node, as it may not have been generated yet if we're in the body //and this function is recursive or if this is a non-instantiated template function - if (types.size() != ((children.size() > 0 && children[children.size()-1]->getDataRef()->type == code_block) ? children.size()-1 : children.size())) { - std::cout << "Type sizes do not match between two " << lookup << "(" << types.size() << "," << ((children.size() > 0 && children[children.size()-1]->getDataRef()->type == code_block) ? children.size()-1 : children.size()) << "), types are: "; + int numTypes = (children.size() > 0 && children[children.size()-1]->getDataRef()->type == code_block) ? children.size()-1 : children.size(); + if (types.size() != numTypes) { + std::cout << "Type sizes do not match between two " << lookup << "(" << types.size() << "," << numTypes << "), types are: "; for (auto j : types) std::cout << j.toString() << " "; std::cout << std::endl; + std::cout << "Versus" << std::endl; + for (int j = 0; j < numTypes; j++) { + std::cout << " vs " << children[j]->getDataRef()->valueType->toString() << std::endl; + } + for (auto child: children) + std::cout << "\t" << child->getDataRef()->toString() << std::endl; + std::cout << std::endl; continue; } bool typesMatch = true; @@ -1005,7 +1043,15 @@ std::map ASTTransformation::makeTemplateFunctionTypeMap(Node return typeMap; } +// We need recursion protection std::vector*> ASTTransformation::scopeLookup(NodeTree* scope, std::string lookup, bool includeModules) { + return scopeLookup(scope, lookup, includeModules, std::vector*>()); +} + +std::vector*> ASTTransformation::scopeLookup(NodeTree* scope, std::string lookup, bool includeModules, std::vector*> 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); //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()) { @@ -1013,6 +1059,20 @@ std::vector*> ASTTransformation::scopeLookup(NodeTree return LLElementIterator->second; } std::vector*> matches; + // First, we check for scope operator (::) but only if occurs before a "<" as this would signal the beginning of a template instatiation inside type + // If we find it, we look up the left side of the :: and then use the resuts as the scope for looking up the right side, recursively. + size_t scopeOpPos = lookup.find("::"); + size_t angleBrktPos = lookup.find("<"); + if (scopeOpPos != std::string::npos && (angleBrktPos == std::string::npos || scopeOpPos < angleBrktPos)) { + std::cout << "Has :: operator, doing left then right" << std::endl; + for (auto scopeMatch : scopeLookup(scope, strSlice(lookup, 0, scopeOpPos), true)) { + std::cout << "Trying right side with found left side " << scopeMatch->getDataRef()->toString() << std::endl; + auto addMatches = scopeLookup(scopeMatch, strSlice(lookup, scopeOpPos+2, -1), includeModules); + matches.insert(matches.end(), addMatches.begin(), addMatches.end()); + } + return matches; + } + std::map*>> scopeMap = scope->getDataRef()->scope; auto possibleMatches = scopeMap.find(lookup); if (possibleMatches != scopeMap.end()) { @@ -1021,11 +1081,33 @@ std::vector*> ASTTransformation::scopeLookup(NodeTree matches.push_back(i); std::cout << "Found " << possibleMatches->second.size() << " match(s) at " << scope->getDataRef()->toString() << std::endl; } - // Add results from our enclosing scope, if it exists + // Add results from our enclosing scope, if it exists. + // If it doesn't we should be at the top of a translation unit, and we should check the scope of import statements. auto enclosingIterator = scopeMap.find("~enclosing_scope"); if (enclosingIterator != scopeMap.end()) { - std::vector*> upperResult = scopeLookup(enclosingIterator->second[0], lookup); + std::vector*> upperResult = scopeLookup(enclosingIterator->second[0], lookup, includeModules, visited); matches.insert(matches.end(), upperResult.begin(), upperResult.end()); + } else { + // Ok, let's iterate through and check for imports + for (auto child : scope->getChildren()) { + if (child->getDataRef()->type == import) { + auto importScope = child->getDataRef()->scope; + // Check if there is a match named explicily in the import's scope (i.e. looking for a and the import is import somefile: a;) + // If so, add it's members to our matches + auto importLookupItr = importScope.find(lookup); + if (importLookupItr != importScope.end()) { + auto addMatches = importLookupItr->second; + matches.insert(matches.end(), addMatches.begin(), addMatches.end()); + } + // Check if there is an uncionditional import to follow (i.e. import somefile: *;) + // If so, continue the search in that scope + auto importStarItr = importScope.find("*"); + if (importStarItr != importScope.end()) { + auto addMatches = scopeLookup(importStarItr->second[0], lookup, includeModules, visited); + matches.insert(matches.end(), addMatches.begin(), addMatches.end()); + } + } + } } return matches; } diff --git a/src/Importer.cpp b/src/Importer.cpp index 7d6ac37..36b84d2 100644 --- a/src/Importer.cpp +++ b/src/Importer.cpp @@ -10,7 +10,8 @@ Importer::Importer(Parser* parserIn, std::vector includePaths) { removeSymbols.push_back(Symbol("WS", false)); removeSymbols.push_back(Symbol("\\(", true)); removeSymbols.push_back(Symbol("\\)", true)); - removeSymbols.push_back(Symbol("::", true)); + //removeSymbols.push_back(Symbol("::", true)); + removeSymbols.push_back(Symbol(":", true)); removeSymbols.push_back(Symbol(";", true)); removeSymbols.push_back(Symbol("{", true)); removeSymbols.push_back(Symbol("}", true)); @@ -26,6 +27,7 @@ Importer::Importer(Parser* parserIn, std::vector includePaths) { removeSymbols.push_back(Symbol("template", true)); removeSymbols.push_back(Symbol("\\|", true)); + //collapseSymbols.push_back(Symbol("scoped_identifier", false)); collapseSymbols.push_back(Symbol("opt_typed_parameter_list", false)); collapseSymbols.push_back(Symbol("opt_parameter_list", false)); collapseSymbols.push_back(Symbol("opt_import_list", false)); diff --git a/tests/newScoping.expected_results b/tests/newScoping.expected_results new file mode 100644 index 0000000..1e96910 --- /dev/null +++ b/tests/newScoping.expected_results @@ -0,0 +1,13 @@ +Qualified io! +7 +9 +11 +Qualified Container! +Even template functions qualified! + +Unqualified io! +8 +10 +12 +Unqualified Container! +Even template functions unqualified! diff --git a/tests/newScoping.krak b/tests/newScoping.krak new file mode 100644 index 0000000..9a081af --- /dev/null +++ b/tests/newScoping.krak @@ -0,0 +1,32 @@ +import io; +import scopeQualified; +import scopeUnqualified : * ; + +|int| main() { + io::println("Qualified io!"); + + // Defined in scopeQualified + io::println(scopeQualified::qualified_variable); + io::println(scopeQualified::qualified_func()); + |scopeQualified::qualified_class| qClass.construct(11); + io::println(qClass.get()); + + |scopeQualified::qualified_container| sayQualified.construct("Qualified Container!"); + io::println(sayQualified.get()); + io::println(scopeQualified::qualified_id("Even template functions qualified!")); + + io::println(); + + io::println("Unqualified io!"); + // Defined in scopeUnqualified + io::println(unqualifed_variable); + io::println(unqualified_func()); + |unqualified_class| uqClass.construct(12); + io::println(uqClass.get()); + + |unqualified_container| sayUnqualified.construct("Unqualified Container!"); + io::println(sayUnqualified.get()); + io::println(unqualified_id("Even template functions unqualified!")); + + return 0; +} diff --git a/tests/scopeQualified.krak b/tests/scopeQualified.krak new file mode 100644 index 0000000..c862136 --- /dev/null +++ b/tests/scopeQualified.krak @@ -0,0 +1,27 @@ +|int| qualified_variable = 7; +|int| qualified_func() { return 9; } + +typedef qualified_class { + |int| number; + |qualified_class*| construct(|int| num) { + number = num; + return this; + } + |int| get() { + return number; + } +}; + +typedef template qualified_container { + |T| data; + |qualified_container*| construct(|T| dataIn) { + data = dataIn; + } + |T| get() { + return data; + } +}; + +template |T| qualified_id(|T| it) { + return it; +} diff --git a/tests/scopeUnqualified.krak b/tests/scopeUnqualified.krak new file mode 100644 index 0000000..8e0035b --- /dev/null +++ b/tests/scopeUnqualified.krak @@ -0,0 +1,27 @@ +|int| unqualifed_variable = 8; +|int| unqualified_func() { return 10; } + +typedef unqualified_class { + |int| number; + |qualified_class*| construct(|int| num) { + number = num; + return this; + } + |int| get() { + return number; + } +}; + +typedef template unqualified_container { + |T| data; + |unqualified_container*| construct(|T| dataIn) { + data = dataIn; + } + |T| get() { + return data; + } +}; + +template |T| unqualified_id(|T| it) { + return it; +} From aaca71a211365a1021a2f95ce504badfaeb68773 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Tue, 30 Dec 2014 01:22:09 -0500 Subject: [PATCH 2/2] Got the new scoping working! Still some odd stuff happening to certian templates, and I think vector is having problems with new/traits. Really need to get canonnical filenames and what not worked out --- future_features.txt | 11 +- include/.ASTData.h.swp | Bin 12288 -> 0 bytes include/CGenerator.h | 9 +- include/Tester.h | 4 +- src/.ASTTransformation.cpp.swp | Bin 102400 -> 0 bytes src/CGenerator.cpp | 344 +++++++++++--------- src/Tester.cpp | 31 +- stdlib/trivial_container.krak | 2 +- tests/OperatorOverloadTest.krak | 2 +- tests/RecursiveTest.krak | 2 +- tests/commentFirstTest.krak | 2 +- tests/declarationsTest.krak | 4 +- tests/destructorTest.krak | 2 +- tests/emptyBracesFunction.krak | 2 +- tests/functionMultipleTemplateTest.krak | 2 +- tests/functionOrderingTest.krak | 2 +- tests/functionTemplateTest.krak | 4 +- tests/memTest.krak | 4 +- tests/moreComplexObjectTest.krak | 2 +- tests/moreObjectTemplateTest.krak | 4 +- tests/newScoping.expected_results | 4 +- tests/objectOrderingTest.krak | 2 +- tests/runTests.sh | 3 +- tests/scopeUnqualified.krak | 2 +- tests/simpleFunctionTest.krak | 2 +- tests/simpleObjectMultipleTemplateTest.krak | 12 +- tests/simpleObjectTemplateTest.krak | 12 +- tests/simpleObjectTest.krak | 7 +- tests/templateTest.krak | 4 +- tests/testArrayNotation.krak | 4 +- tests/topLevelVarInit.expected_results | 1 + tests/topLevelVarInit.krak | 8 + tests/traitsTest.krak | 6 +- tests/typeExpr.krak | 4 +- tests/vectorTest.krak | 10 +- 35 files changed, 282 insertions(+), 232 deletions(-) delete mode 100644 include/.ASTData.h.swp delete mode 100644 src/.ASTTransformation.cpp.swp create mode 100644 tests/topLevelVarInit.expected_results create mode 100644 tests/topLevelVarInit.krak diff --git a/future_features.txt b/future_features.txt index 88b0a92..0a26ad2 100644 --- a/future_features.txt +++ b/future_features.txt @@ -1,5 +1,12 @@ -Declaration of a pointer and multiplication are ambigious! -( T* a; maybe either a declaration or a multiplication) +correctly importing / running tests is a nightmare with relative paths. + +Namespaces +Imports allow renaming of either entire scope or individual members, and can import from within a scope + +correct c genration for triple mutually recursive types across 2 files (wehre +A depends on B depends on C, but two of them are in the same file and there's +also pointers for the other two) Will need splitting into multiple C files to +be cleanest, I think) Fix destructors being placed after return. Fix functions before declaration? (in class? (this is from an old file)) diff --git a/include/.ASTData.h.swp b/include/.ASTData.h.swp deleted file mode 100644 index ea4dd95b72c6a5e180a6cd88f99ee8de17bc8928..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmYc?2=nw+FxN9-U|?VnU|^Vg|5I>i`4)!7d<+bEi6t3{c_0b=I5#mbE3qgazaj<( zhB}CW`q@Q^*{ON@nR&@Mr75ZUj=>==i6x1883YX&RWKR?qai?E2$Ytj>00nI7#kTH zfDBMpQdAHY3I#Do@n{H)hQMeDjE2By2#kinXb6mkz-S1JhQJ63fsz77hI$4D1}3O~ zRiQK^8V%)+QllX-8UmvsFd71*Aut*OqaiRF0;3@?8UmvsFd71*Aut*OLofsqQy3V| zax*a0@<8VQVg3Ji{0t0t_!$^(^D{7<m#m~U7lb?ZMDL(^4KR*LQGd}}EAwL5{ z0Y3vnGCu=@H$MY|3qJ#cGd}~vb3O)!DSQkJ27C+*zj+xLe(^Feyy9hGc*x7ZaD|tF zVKFZQLozP|Lnto;gEcP$13NDR!*?DAh9^7>43~Kr7$);DFm&=TFm&)RFtqY8FtqSM z+*bo~;}8tvQ74avz-S1JhQMeDjE2By2#kinXb6mkz-S0CFfb^m=A~q&F)-9xGca%# z6lInrmZVxSaB>!xq*z(yCKlL$8O0?DVl%|51AR))#5D-(Lq!Oa1xFoS8 zGZ|tD#6|_El92phunRPxe6SWxkQrbXK^2$4RDoscpzhKD^I#lg19TKnT&be~c8wO? zjS993exW`-c=QvY0i?U2G$|)D*@_`KC$YE~}5E(!Au7%>2Cg4mj9T;tLXs5_3~aQj2sHQY#9IQj3c-^Ye5RlJfI&QWNvyk;RaVOwB9J1^FEu zX4R#6DXD2X3MEB}dBr&p>r3-8OLP=6^GZ^S3W`9+$ERc#r6!kTmZj<_Wabv+7lEWx zQu9hO(=tJpgVIer$QXDsR!&Jx%gjp!N1K9%Mp=Glik7B #include #include +#include +#include #include "NodeTree.h" #include "ASTData.h" @@ -12,6 +14,7 @@ #include "util.h" #include "Poset.h" +// 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. class CGenerator { public: @@ -19,12 +22,16 @@ class CGenerator { ~CGenerator(); void generateCompSet(std::map*> ASTs, std::string outputName); std::string generateClassStruct(NodeTree* from); + bool isUnderTranslationUnit(NodeTree* from, NodeTree* typeDefinition); + NodeTree* highestScope(NodeTree* node); + std::pair generateTranslationUnit(NodeTree* from); std::string generate(NodeTree* from, NodeTree* enclosingObject = NULL); std::string generateAliasChains(NodeTree* scopeNode, NodeTree* definition); static std::string ValueTypeToCType(Type *type); static std::string ValueTypeToCTypeDecoration(Type *type); + static std::string ValueTypeToCTypeThingHelper(Type *type, std::string ptrStr); static std::string CifyName(std::string name); - std::string generateObjectMethod(NodeTree* enclosingObject, NodeTree* from, std::string *functionPrototype); + std::string generateObjectMethod(NodeTree* enclosingObject, NodeTree* from, std::string *functionPrototype); NodeTree* getMethodsObjectType(NodeTree* scope, std::string functionName); std::string generatorString; private: diff --git a/include/Tester.h b/include/Tester.h index 7bf1815..6aa6be2 100644 --- a/include/Tester.h +++ b/include/Tester.h @@ -15,7 +15,7 @@ class Tester { int ssystem(std::string command); bool run(std::string fileName); bool compareFiles(std::string file1Path, std::string file2Path); - void cleanExtras(std::string fileName); + void cleanExtras(std::string path); private: std::string krakenInvocation; @@ -27,5 +27,7 @@ class Tester { std::string shell; std::string changePermissions; std::string redirect; + std::string sep; + std::string cd; }; #endif diff --git a/src/.ASTTransformation.cpp.swp b/src/.ASTTransformation.cpp.swp deleted file mode 100644 index 12f088942fc8a4a376725fa111cf1cce8691253b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102400 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 ASTs, std::string outputName) { //Generate an entire set of files std::string buildString = "#!/bin/sh\ncc -std=c99 "; + std::cout << "\n\n =====GENERATE PASS===== \n\n" << std::endl; + if (mkdir(("./" + outputName).c_str(), 0755)) { + std::cout << "Could not make directory " << outputName << std::endl; + //throw "could not make directory "; + } for (auto i = ASTs.begin(); i != ASTs.end(); i++) { + std::cout << "\n\nGenerate pass for: " << i->first << std::endl; buildString += i->first + ".c "; - std::ofstream outputCFile; - outputCFile.open(i->first + ".c"); - if (outputCFile.is_open()) { + std::ofstream outputCFile, outputHFile; + outputCFile.open(outputName + "/" + i->first + ".c"); + outputHFile.open(outputName + "/" + i->first + ".h"); + if (outputCFile.is_open() || outputHFile.is_open()) { // Prequel common to all files - outputCFile << "#include \n#include \n#include \n" << generate(i->second); + auto chPair = generateTranslationUnit(i->second); + outputHFile << "#include \n#include \n#include \n" << chPair.first; + outputCFile << "#include \"" + i->first + ".h\"\n\n" << chPair.second; } else { - std::cout << "Cannot open file " << i->first << ".c" << std::endl; + std::cout << "Cannot open file " << i->first << ".c/h" << std::endl; } outputCFile.close(); + outputHFile.close(); } buildString += "-o " + outputName; std::ofstream outputBuild; - outputBuild.open(outputName + ".sh"); + outputBuild.open(outputName + "/" + split(outputName, '/').back() + ".sh"); outputBuild << buildString; outputBuild.close(); } @@ -70,6 +81,164 @@ std::string CGenerator::generateAliasChains(NodeTree* scopeNode, NodeTr return output; } +bool CGenerator::isUnderTranslationUnit(NodeTree* from, NodeTree* node) { + auto scope = from->getDataRef()->scope; + for (auto i : scope) + for (auto j : i.second) + if (j == node) + return true; + + auto upper = scope.find("~enclosing_scope"); + if (upper != scope.end()) + return isUnderTranslationUnit(upper->second[0], node); + return false; +} + +NodeTree* CGenerator::highestScope(NodeTree* node) { + auto it = node->getDataRef()->scope.find("~enclosing_scope"); + while (it != node->getDataRef()->scope.end()) { + node = it->second[0]; + it = node->getDataRef()->scope.find("~enclosing_scope"); + } + return node; +} + +// We do translation units in their own function so they can do the pariwise h/c stuff and regualr in function body generation does not +std::pair CGenerator::generateTranslationUnit(NodeTree* from) { + ASTData data = from->getData(); + std::vector*> children = from->getChildren(); + std::string cOutput, hOutput; + // Ok, so we've got to do this in passes to preserve mututally recursive definitions. + // + // First Pass: All classes get "struct dummy_thing; typedef struct dummy_thing thing;". + // Also, other typedefs follow after their naming. + // Second Pass: All top level variable declarations + // Third Pass: Define all actual structs of a class, in correct order (done with posets) + // Fourth Pass: Declare all function prototypes (as functions may be mutually recursive too). + // (this includes object methods) + // Fifth Pass: Define all functions (including object methods). + + // However, most of these do not actually have to be done as separate passes. First, second, fourth, and fifth + // are done simultanously, but append to different strings that are then concatinated properly, in order. + + std::string importIncludes = "/**\n * Import Includes\n */\n\n"; + std::string variableExternDeclarations = "/**\n * Extern Variable Declarations \n */\n\n"; + std::string plainTypedefs = "/**\n * Plain Typedefs\n */\n\n"; + std::string variableDeclarations = "/**\n * Variable Declarations \n */\n\n"; + std::string classStructs = "/**\n * Class Structs\n */\n\n"; + std::string functionPrototypes = "/**\n * Function Prototypes\n */\n\n"; + std::string functionDefinitions = "/**\n * Function Definitions\n */\n\n"; + + // Ok, let's handle the included files + for (auto i : from->getChildren()) + if (i->getDataRef()->type == import) + importIncludes += "#include \"" + i->getDataRef()->symbol.getName() + ".krak.h\" //woo importing!\n"; + + // And get the correct order for emiting classes, but not if they're not in our file, then they will get included + // Note that this is not sufsticated enough for some multiple file mutually recursive types, but I want to get this simple version working first + Poset*> typedefPoset; + for (int i = 0; i < children.size(); i++) { + if (children[i]->getDataRef()->type == type_def) { + // If we're an alias type, continue. We handle those differently + if (children[i]->getDataRef()->valueType->typeDefinition != children[i]) + continue; + + typedefPoset.addVertex(children[i]); // We add this definition by itself just in case there are no dependencies. + // 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 + // we will add a dependency from this definition to that definition in the poset. + std::vector*> classChildren = children[i]->getChildren(); + for (auto j : classChildren) { + if (j->getDataRef()->type == declaration_statement) { + Type* decType = j->getChildren()[0]->getDataRef()->valueType; // Type of the declaration + if (decType->typeDefinition && decType->getIndirection() == 0 && isUnderTranslationUnit(from, decType->typeDefinition)) // If this is a custom type and not a pointer and actually should be defined in this file + typedefPoset.addRelationship(children[i], decType->typeDefinition); // Add a dependency + } + } + } + } + //Now generate the typedef's in the correct, topological order + for (NodeTree* i : typedefPoset.getTopoSort()) + classStructs += generateClassStruct(i) + "\n"; + + // Declare everything in translation unit scope here. (allows stuff from other files, automatic forward declarations) + // Also, everything in all of the import's scopes + std::map*>> combinedMap; + combinedMap = from->getDataRef()->scope; // Actually, just do this file. We're moving back to using include files + for (auto i = combinedMap.begin(); i != combinedMap.end(); i++) { + for (auto declaration : i->second) { + std::vector*> decChildren = declaration->getChildren(); + ASTData declarationData = declaration->getData(); + switch(declarationData.type) { + case identifier: + variableDeclarations += ValueTypeToCType(declarationData.valueType) + " " + declarationData.symbol.getName() + "; /*identifier*/\n"; + variableExternDeclarations += "extern " + ValueTypeToCType(declarationData.valueType) + " " + declarationData.symbol.getName() + "; /*extern identifier*/\n"; + break; + case function: + { + if (declarationData.valueType->baseType == template_type) + functionPrototypes += "/* template function " + declarationData.symbol.toString() + " */\n"; + else if (decChildren.size() == 0) //Not a real function, must be a built in passthrough + functionPrototypes += "/* built in function: " + declarationData.symbol.toString() + " */\n"; + else { + functionPrototypes += "\n" + ValueTypeToCType(declarationData.valueType) + " "; + std::string nameDecoration, parameters; + for (int j = 0; j < decChildren.size()-1; j++) { + if (j > 0) + parameters += ", "; + parameters += ValueTypeToCType(decChildren[j]->getData().valueType) + " " + generate(decChildren[j], nullptr); + nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType); + } + functionPrototypes += CifyName(declarationData.symbol.getName() + nameDecoration) + "(" + parameters + "); /*func*/\n"; + // Only generate function if this is the unit it was defined in + std::cout << "Generating " << CifyName(declarationData.symbol.getName()) << std::endl; + if (contains(children, declaration)) + functionDefinitions += generate(declaration, nullptr); + } + } + break; + case type_def: + //type + plainTypedefs += "/*typedef " + declarationData.symbol.getName() + " */\n"; + + if (declarationData.valueType->baseType == template_type) { + plainTypedefs += "/* non instantiated template " + declarationData.symbol.getName() + " */"; + } else if (declarationData.valueType->typeDefinition != declaration) { + if (declarationData.valueType->typeDefinition) + continue; // Aliases of objects are done with the thing it alises + // Otherwise, we're actually a renaming of a primitive, can generate here + plainTypedefs += "typedef " + ValueTypeToCType(declarationData.valueType) + " " + CifyName(declarationData.symbol.getName()) + ";\n"; + plainTypedefs += generateAliasChains(from, declaration); + } else { + plainTypedefs += "typedef struct __struct_dummy_" + CifyName(declarationData.symbol.getName()) + "__ " + CifyName(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 + std::string objectFunctionDefinitions = "/* Method Definitions for " + declarationData.symbol.getName() + " */\n"; + for (int j = 0; j < decChildren.size(); j++) { + std::cout << decChildren[j]->getName() << std::endl; + if (decChildren[j]->getName() == "function") //If object method + objectFunctionDefinitions += generateObjectMethod(declaration, decChildren[j], &functionPrototypes) + "\n"; + } + // Add all aliases to the plain typedefs. This will add any alias that aliases to this object, and any alias that aliases to that, and so on + plainTypedefs += generateAliasChains(from, declaration); + functionPrototypes += "/* Done with " + declarationData.symbol.getName() + " */\n"; + // If this is the file the object is defined in, include methods + if (contains(children, declaration)) + functionDefinitions += objectFunctionDefinitions + "/* Done with " + declarationData.symbol.getName() + " */\n"; + } + break; + default: + //std::cout << "Declaration? named " << declaration->getName() << " of unknown type " << ASTData::ASTTypeToString(declarationData.type) << " in translation unit scope" << std::endl; + cOutput += "/*unknown declaration named " + declaration->getName() + "*/\n"; + hOutput += "/*unknown declaration named " + declaration->getName() + "*/\n"; + } + } + } + hOutput += plainTypedefs + importIncludes + variableExternDeclarations + classStructs + functionPrototypes; + cOutput += variableDeclarations + functionDefinitions; + return std::make_pair(hOutput, cOutput); +} + //The enclosing object is for when we're generating the inside of object methods. They allow us to check scope lookups against the object we're in std::string CGenerator::generate(NodeTree* from, NodeTree* enclosingObject) { ASTData data = from->getData(); @@ -78,127 +247,17 @@ std::string CGenerator::generate(NodeTree* from, NodeTree* enc switch (data.type) { case translation_unit: { - // Ok, so we've got to do this in passes to preserve mututally recursive definitions. - // - // First Pass: All classes get "struct dummy_thing; typedef struct dummy_thing thing;". - // Also, other typedefs follow after their naming. - // Second Pass: All top level variable declarations - // Third Pass: Define all actual structs of a class, in correct order (done with posets) - // Fourth Pass: Declare all function prototypes (as functions may be mutually recursive too). - // (this includes object methods) - // Fifth Pass: Define all functions (including object methods). - - // However, most of these do not actually have to be done as separate passes. First, second, fourth, and fifth - // are done simultanously, but append to different strings that are then concatinated properly, in order. - - std::string plainTypedefs = "/**\n * Plain Typedefs\n */\n\n"; - std::string variableDeclarations = "/**\n * Variable Declarations \n */\n\n"; - std::string classStructs = "/**\n * Class Structs\n */\n\n"; - std::string functionPrototypes = "/**\n * Function Prototypes\n */\n\n"; - std::string functionDefinitions = "/**\n * Function Definitions\n */\n\n"; - - Poset*> typedefPoset; - for (int i = 0; i < children.size(); i++) { - if (children[i]->getDataRef()->type == type_def) { - // If we're an alias type, continue. We handle those differently - if (children[i]->getDataRef()->valueType->typeDefinition != children[i]) - continue; - - typedefPoset.addVertex(children[i]); // We add this definition by itself just in case there are no dependencies. - // 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 - // we will add a dependency from this definition to that definition in the poset. - std::vector*> classChildren = children[i]->getChildren(); - for (auto j : classChildren) { - if (j->getDataRef()->type == declaration_statement) { - Type* decType = j->getChildren()[0]->getDataRef()->valueType; // Type of the declaration - if (decType->typeDefinition && decType->getIndirection() == 0) // If this is a custom type and not a pointer - typedefPoset.addRelationship(children[i], decType->typeDefinition); // Add a dependency - } - } - } - } - //Now generate the typedef's in the correct, topological order - for (NodeTree* i : typedefPoset.getTopoSort()) - classStructs += generateClassStruct(i) + "\n"; - - //Declare everything in translation unit scope here. (allows stuff from other files, automatic forward declarations) - for (auto i = data.scope.begin(); i != data.scope.end(); i++) { - for (auto declaration : i->second) { - std::vector*> decChildren = declaration->getChildren(); - ASTData declarationData = declaration->getData(); - switch(declarationData.type) { - case identifier: - variableDeclarations += ValueTypeToCType(declarationData.valueType) + " " + declarationData.symbol.getName() + "; /*identifier*/\n"; - break; - case function: - { - if (declarationData.valueType->baseType == template_type) - functionPrototypes += "/* template function " + declarationData.symbol.toString() + " */\n"; - else if (decChildren.size() == 0) //Not a real function, must be a built in passthrough - functionPrototypes += "/* built in function: " + declarationData.symbol.toString() + " */\n"; - else { - functionPrototypes += "\n" + ValueTypeToCType(declarationData.valueType) + " "; - std::string nameDecoration, parameters; - for (int j = 0; j < decChildren.size()-1; j++) { - if (j > 0) - parameters += ", "; - parameters += ValueTypeToCType(decChildren[j]->getData().valueType) + " " + generate(decChildren[j], enclosingObject); - nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType); - } - functionPrototypes += CifyName(declarationData.symbol.getName() + nameDecoration) + "(" + parameters + "); /*func*/\n"; - // Only generate function if this is the unit it was defined in - std::cout << "Generating " << CifyName(declarationData.symbol.getName()) << std::endl; - if (contains(children, declaration)) - functionDefinitions += generate(declaration, enclosingObject); - } - } - break; - case type_def: - //type - plainTypedefs += "/*typedef " + declarationData.symbol.getName() + " */\n"; - - if (declarationData.valueType->baseType == template_type) { - plainTypedefs += "/* non instantiated template " + declarationData.symbol.getName() + " */"; - } else if (declarationData.valueType->typeDefinition != declaration) { - if (declarationData.valueType->typeDefinition) - continue; // Aliases of objects are done with the thing it alises - // Otherwise, we're actually a renaming of a primitive, can generate here - plainTypedefs += "typedef " + ValueTypeToCType(declarationData.valueType) + " " + CifyName(declarationData.symbol.getName()) + ";\n"; - plainTypedefs += generateAliasChains(from, declaration); - } else { - plainTypedefs += "typedef struct __struct_dummy_" + CifyName(declarationData.symbol.getName()) + "__ " + CifyName(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 - std::string objectFunctionDefinitions = "/* Method Definitions for " + declarationData.symbol.getName() + " */\n"; - for (int j = 0; j < decChildren.size(); j++) { - std::cout << decChildren[j]->getName() << std::endl; - if (decChildren[j]->getName() == "function") //If object method - objectFunctionDefinitions += generateObjectMethod(declaration, decChildren[j], &functionPrototypes) + "\n"; - } - // Add all aliases to the plain typedefs. This will add any alias that aliases to this object, and any alias that aliases to that, and so on - plainTypedefs += generateAliasChains(from, declaration); - functionPrototypes += "/* Done with " + declarationData.symbol.getName() + " */\n"; - // If this is the file the object is defined in, include methods - if (contains(children, declaration)) - functionDefinitions += objectFunctionDefinitions + "/* Done with " + declarationData.symbol.getName() + " */\n"; - } - break; - default: - //std::cout << "Declaration? named " << declaration->getName() << " of unknown type " << ASTData::ASTTypeToString(declarationData.type) << " in translation unit scope" << std::endl; - output += "/*unknown declaration named " + declaration->getName() + "*/\n"; - } - } - } - output += plainTypedefs + variableDeclarations + classStructs + functionPrototypes + functionDefinitions; - return output; + // Should not happen! We do this in it's own function now! + std::cout << "Trying to normal generate a translation unit! That's a nono! (" << from->getDataRef()->toString() << ")" << std::endl; + throw "That's not gonna work"; } break; case interpreter_directive: //Do nothing break; case import: - return "/* would import \"" + data.symbol.getName() + "\" but....*/\n"; + return "/* never reached import? */\n"; + //return "include \"" + data.symbol.getName() + ".h\" //woo importing!\n"; //return "#include <" + data.symbol.getName() + ">\n"; case identifier: { @@ -421,7 +480,9 @@ std::string CGenerator::generateObjectMethod(NodeTree* enclosingObject, return functionSignature + "\n" + generate(children[children.size()-1], enclosingObject); //Pass in the object so we can properly handle access to member stuff } -std::string CGenerator::ValueTypeToCType(Type *type) { +std::string CGenerator::ValueTypeToCType(Type *type) { return ValueTypeToCTypeThingHelper(type, "*"); } +std::string CGenerator::ValueTypeToCTypeDecoration(Type *type) { return ValueTypeToCTypeThingHelper(type, "_P__"); } +std::string CGenerator::ValueTypeToCTypeThingHelper(Type *type, std::string ptrStr) { std::string return_type; switch (type->baseType) { case none: @@ -453,43 +514,7 @@ std::string CGenerator::ValueTypeToCType(Type *type) { break; } for (int i = 0; i < type->getIndirection(); i++) - return_type += "*"; - return return_type; -} - -std::string CGenerator::ValueTypeToCTypeDecoration(Type *type) { - std::string return_type; - switch (type->baseType) { - case none: - if (type->typeDefinition) - return_type = CifyName(type->typeDefinition->getDataRef()->symbol.getName()); - else - return_type = "none"; - break; - case void_type: - return_type = "void"; - break; - case boolean: - return_type = "bool"; - break; - case integer: - return_type = "int"; - break; - case floating: - return_type = "float"; - break; - case double_percision: - return_type = "double"; - break; - case character: - return_type = "char"; - break; - default: - return_type = "unknown_ValueType"; - break; - } - for (int i = 0; i < type->getIndirection(); i++) - return_type += "_P__"; + return_type += ptrStr; return return_type; } @@ -510,6 +535,7 @@ std::string CGenerator::CifyName(std::string name) { "--", "doubleminus", "<<", "doubleleft", ">>", "doubleright", + "::", "scopeop", "==", "doubleequals", "!=", "notequals", "&&", "doubleamprsnd", diff --git a/src/Tester.cpp b/src/Tester.cpp index 3f4cbdf..99642fc 100644 --- a/src/Tester.cpp +++ b/src/Tester.cpp @@ -2,13 +2,15 @@ Tester::Tester(std::string krakenInvocation, std::string krakenGrammerLocation) : krakenInvocation(krakenInvocation), krakenGrammerLocation(krakenGrammerLocation) { //initlization list - removeCmd = "rm"; + removeCmd = "rm -r"; resultsExtention = ".results"; expectedExtention = ".expected_results"; krakenExtention = ".krak"; changePermissions = "chmod 755"; shell = "sh"; + cd = "cd"; redirect = ">"; + sep = "/"; } Tester::~Tester() { @@ -21,27 +23,24 @@ int Tester::ssystem(std::string command) { void Tester::cleanExtras(std::string fileName) { ssystem(removeCmd + " " + fileName); - ssystem(removeCmd + " " + fileName + krakenExtention + "out*"); - ssystem(removeCmd + " " + fileName + krakenExtention + ".c"); - ssystem(removeCmd + " " + fileName + ".sh"); - ssystem(removeCmd + " " + fileName + resultsExtention); } -bool Tester::run(std::string fileName) { +bool Tester::run(std::string path) { + std::string fileName = split(path, *sep.c_str()).back(); std::cout << "Testing: " << fileName << " with " << krakenInvocation << " and " << krakenGrammerLocation << std::endl; - - cleanExtras(fileName); - - ssystem(changePermissions + " " + fileName); - ssystem(krakenInvocation + " " + fileName + krakenExtention + " " + krakenGrammerLocation + " " + fileName); - ssystem(shell + " " + fileName + ".sh"); - ssystem(fileName + " " + redirect + " " + fileName + resultsExtention); - bool result = compareFiles(fileName + expectedExtention, fileName + resultsExtention); - + cleanExtras(path); + ssystem(krakenInvocation + " " + path + krakenExtention + " " + krakenGrammerLocation + " " + path); + ssystem(changePermissions + " " + path + sep + fileName + ".sh"); + ssystem(cd + " " + path + "; " + "./" + fileName + ".sh"); + ssystem(changePermissions + " " + path + sep + fileName); + ssystem(path + sep + fileName + " " + redirect + " " + path + sep + fileName + resultsExtention); + + bool result = compareFiles(fileName + expectedExtention, path + sep + fileName + resultsExtention); + //If the test was succesful, we don't need all the extra files if (result) - cleanExtras(fileName); + cleanExtras(path); return result; } diff --git a/stdlib/trivial_container.krak b/stdlib/trivial_container.krak index 80bebeb..4b70141 100644 --- a/stdlib/trivial_container.krak +++ b/stdlib/trivial_container.krak @@ -3,7 +3,7 @@ import io; typedef template trivialContainer { |T| data; |void| print() { - print(data); + io::print(data); } }; diff --git a/tests/OperatorOverloadTest.krak b/tests/OperatorOverloadTest.krak index bcc1d78..4218ba2 100644 --- a/tests/OperatorOverloadTest.krak +++ b/tests/OperatorOverloadTest.krak @@ -1,4 +1,4 @@ -import io; +import io:*; typedef Vec2 { |int| x; diff --git a/tests/RecursiveTest.krak b/tests/RecursiveTest.krak index 03c8b9f..87deed8 100644 --- a/tests/RecursiveTest.krak +++ b/tests/RecursiveTest.krak @@ -1,4 +1,4 @@ -import io; +import io:*; |int| fibanacci(|int| num) { if (num < 2) diff --git a/tests/commentFirstTest.krak b/tests/commentFirstTest.krak index 0cd8f27..4030ec5 100644 --- a/tests/commentFirstTest.krak +++ b/tests/commentFirstTest.krak @@ -1,5 +1,5 @@ /* Comment first! */ -import io; +import io:*; |int| main() { println(1337); diff --git a/tests/declarationsTest.krak b/tests/declarationsTest.krak index 4e29cc4..84e8ee3 100644 --- a/tests/declarationsTest.krak +++ b/tests/declarationsTest.krak @@ -1,5 +1,5 @@ -import io; -import mem; +import io:*; +import mem:*; typedef ClassWithConstructor { |int| data; diff --git a/tests/destructorTest.krak b/tests/destructorTest.krak index a63276f..65223f1 100644 --- a/tests/destructorTest.krak +++ b/tests/destructorTest.krak @@ -1,4 +1,4 @@ -import io; +import io:*; typedef DestructorPrint { |char*| myStr; diff --git a/tests/emptyBracesFunction.krak b/tests/emptyBracesFunction.krak index d02cbd7..1413c75 100644 --- a/tests/emptyBracesFunction.krak +++ b/tests/emptyBracesFunction.krak @@ -4,6 +4,6 @@ import io; |int| main() { nothing(); - println("It was nothing"); + io::println("It was nothing"); return 0; } diff --git a/tests/functionMultipleTemplateTest.krak b/tests/functionMultipleTemplateTest.krak index a30f9d5..e6ff2dc 100644 --- a/tests/functionMultipleTemplateTest.krak +++ b/tests/functionMultipleTemplateTest.krak @@ -1,4 +1,4 @@ -import io; +import io:*; template |void| addAndPrint(|T| a, |J| b) { print(a+b); diff --git a/tests/functionOrderingTest.krak b/tests/functionOrderingTest.krak index c26f5a9..9c89e95 100644 --- a/tests/functionOrderingTest.krak +++ b/tests/functionOrderingTest.krak @@ -1,4 +1,4 @@ -import io; +import io:*; |int| ret1() { return ret2() / 2; diff --git a/tests/functionTemplateTest.krak b/tests/functionTemplateTest.krak index e6b2597..e104d20 100644 --- a/tests/functionTemplateTest.krak +++ b/tests/functionTemplateTest.krak @@ -1,13 +1,13 @@ import io; template |T| addAndPrint(|T| a, |T| b) { - print(a+b); + io::print(a+b); return a+b; } |int| main() { addAndPrint(10,12); - print("\n"); + io::print("\n"); return 0; } diff --git a/tests/memTest.krak b/tests/memTest.krak index 6ddbac9..b9a2c41 100644 --- a/tests/memTest.krak +++ b/tests/memTest.krak @@ -1,5 +1,5 @@ -import mem; -import io; +import mem:*; +import io:*; typedef AnObject { |int| a; diff --git a/tests/moreComplexObjectTest.krak b/tests/moreComplexObjectTest.krak index 2c06e6b..59fe0df 100644 --- a/tests/moreComplexObjectTest.krak +++ b/tests/moreComplexObjectTest.krak @@ -1,4 +1,4 @@ -import io; +import io:*; typedef firstObject { |int| objectNum; diff --git a/tests/moreObjectTemplateTest.krak b/tests/moreObjectTemplateTest.krak index 6c7ae78..e4be5b2 100644 --- a/tests/moreObjectTemplateTest.krak +++ b/tests/moreObjectTemplateTest.krak @@ -1,5 +1,5 @@ -import io; -import trivial_container; +import io:*; +import trivial_container:*; typedef RegularObject { |int| num; diff --git a/tests/newScoping.expected_results b/tests/newScoping.expected_results index 1e96910..2d170cc 100644 --- a/tests/newScoping.expected_results +++ b/tests/newScoping.expected_results @@ -1,12 +1,12 @@ Qualified io! -7 +0 9 11 Qualified Container! Even template functions qualified! Unqualified io! -8 +0 10 12 Unqualified Container! diff --git a/tests/objectOrderingTest.krak b/tests/objectOrderingTest.krak index 4812bb8..7fb978f 100644 --- a/tests/objectOrderingTest.krak +++ b/tests/objectOrderingTest.krak @@ -1,4 +1,4 @@ -import io; +import io:*; typedef objectA { |int| a; diff --git a/tests/runTests.sh b/tests/runTests.sh index f86e0bf..26182d2 100755 --- a/tests/runTests.sh +++ b/tests/runTests.sh @@ -1,7 +1,8 @@ #!/bin/bash krakenPath="../build/kraken" -testDir=${1:-"../tests"} +#testDir=${1:-"../tests"} +testDir="." ext=${2:-"krak"} fileList="" diff --git a/tests/scopeUnqualified.krak b/tests/scopeUnqualified.krak index 8e0035b..f540dbf 100644 --- a/tests/scopeUnqualified.krak +++ b/tests/scopeUnqualified.krak @@ -3,7 +3,7 @@ typedef unqualified_class { |int| number; - |qualified_class*| construct(|int| num) { + |unqualified_class*| construct(|int| num) { number = num; return this; } diff --git a/tests/simpleFunctionTest.krak b/tests/simpleFunctionTest.krak index 2e45927..146e497 100644 --- a/tests/simpleFunctionTest.krak +++ b/tests/simpleFunctionTest.krak @@ -1,4 +1,4 @@ -import io; +import io:*; |int| addAndPrintInt(|int| a, |int| b) { print(a+b); diff --git a/tests/simpleObjectMultipleTemplateTest.krak b/tests/simpleObjectMultipleTemplateTest.krak index f3615e4..c67136f 100644 --- a/tests/simpleObjectMultipleTemplateTest.krak +++ b/tests/simpleObjectMultipleTemplateTest.krak @@ -5,12 +5,12 @@ typedef template TemplateTest { |T| a; |J| b; |void| print() { - print("a: "); - print(a); - print("\n"); - print("b: "); - print(b); - print("\n"); + io::print("a: "); + io::print(a); + io::print("\n"); + io::print("b: "); + io::print(b); + io::print("\n"); } }; diff --git a/tests/simpleObjectTemplateTest.krak b/tests/simpleObjectTemplateTest.krak index 7aeebc2..396e6ff 100644 --- a/tests/simpleObjectTemplateTest.krak +++ b/tests/simpleObjectTemplateTest.krak @@ -5,12 +5,12 @@ typedef template TemplateTest { |int| a; |T| b; |void| print() { - print("a: "); - print(a); - print("\n"); - print("b: "); - print(b); - print("\n"); + io::print("a: "); + io::print(a); + io::print("\n"); + io::print("b: "); + io::print(b); + io::print("\n"); } }; diff --git a/tests/simpleObjectTest.krak b/tests/simpleObjectTest.krak index 3e8f14f..a06ed8a 100644 --- a/tests/simpleObjectTest.krak +++ b/tests/simpleObjectTest.krak @@ -1,11 +1,10 @@ - import io; typedef FirstObject { |int| objectNum; |void| PrintSelf(|int| a) { - print(objectNum); - print(a); + io::print(objectNum); + io::print(a); } }; @@ -13,6 +12,6 @@ typedef FirstObject { |FirstObject| wooObject; wooObject.objectNum = 5; wooObject.PrintSelf(7); - print("\n"); + io::print("\n"); return 0; } diff --git a/tests/templateTest.krak b/tests/templateTest.krak index 8843126..91b4fef 100644 --- a/tests/templateTest.krak +++ b/tests/templateTest.krak @@ -1,5 +1,5 @@ -import io; -import trivial_container; +import io:*; +import trivial_container:*; typedef template TemplateTest { |int| a; diff --git a/tests/testArrayNotation.krak b/tests/testArrayNotation.krak index 9b04b25..02402f3 100644 --- a/tests/testArrayNotation.krak +++ b/tests/testArrayNotation.krak @@ -1,5 +1,5 @@ -import io; -import mem; +import io:*; +import mem:*; |int| main() { |int| b; diff --git a/tests/topLevelVarInit.expected_results b/tests/topLevelVarInit.expected_results new file mode 100644 index 0000000..d81cc07 --- /dev/null +++ b/tests/topLevelVarInit.expected_results @@ -0,0 +1 @@ +42 diff --git a/tests/topLevelVarInit.krak b/tests/topLevelVarInit.krak new file mode 100644 index 0000000..9f8aa92 --- /dev/null +++ b/tests/topLevelVarInit.krak @@ -0,0 +1,8 @@ +import io; + +|int| a = 42; + +|int| main() { + io::println(a); + return 0; +} diff --git a/tests/traitsTest.krak b/tests/traitsTest.krak index 566e5ed..b9b55b0 100644 --- a/tests/traitsTest.krak +++ b/tests/traitsTest.krak @@ -1,4 +1,4 @@ -import io; +import io:*; typedef NoTraits {}; @@ -48,13 +48,13 @@ typedef template OneTwoObj {}; |Trait2| c; |TwoTrait| d; |AlreadySpecilized| e; - + OneTwoFunc(a); OneTwoFunc(b); OneTwoFunc(c); OneTwoFunc(d); // OneTwoFunc(e); - + println(); |OneTwoObj| alpha; diff --git a/tests/typeExpr.krak b/tests/typeExpr.krak index e7dcae2..4b2db33 100644 --- a/tests/typeExpr.krak +++ b/tests/typeExpr.krak @@ -7,7 +7,7 @@ typedef ClassWithConstructor { return this; } |void| printData() { - println(data); + io::println(data); } }; @@ -15,6 +15,6 @@ typedef ClassWithConstructor { |ClassWithConstructor| object.construct(4); object.printData(); |int| a = 8; - println(a); + io::println(a); return 0; } diff --git a/tests/vectorTest.krak b/tests/vectorTest.krak index 579fe24..c47e3de 100644 --- a/tests/vectorTest.krak +++ b/tests/vectorTest.krak @@ -1,6 +1,6 @@ -import io; -import mem; -import vector; +import io:*; +import mem:*; +import vector:*; typedef AbleToBeDestroyed (Destructable) { |void| destruct() { @@ -16,9 +16,9 @@ typedef AbleToBeDestroyed (Destructable) { intVec.addEnd(7); for (|int| i = 0; i < intVec.size; i++;) print(intVec.at(i)); - + println(); - + |vector*| desVec = new>()->construct(); |AbleToBeDestroyed| testDestruct; desVec->addEnd(testDestruct);