Merge branch 'scoping'

This commit is contained in:
Nathan Braswell
2014-12-30 01:24:42 -05:00
40 changed files with 493 additions and 252 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
_site
build
*.comp
stats
*.swp
*.png

View File

@@ -1,5 +1,12 @@
Declaration of a pointer and multiplication are ambigious! correctly importing / running tests is a nightmare with relative paths.
( T* a; maybe either a declaration or a multiplication)
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 destructors being placed after return.
Fix functions before declaration? (in class? (this is from an old file)) Fix functions before declaration? (in class? (this is from an old file))

View File

@@ -47,6 +47,7 @@ class ASTTransformation: public NodeTransformation<Symbol,ASTData> {
NodeTree<ASTData>* functionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types); NodeTree<ASTData>* functionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type> types);
NodeTree<ASTData>* templateFunctionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type*> templateInstantiationTypes, std::vector<Type> types); NodeTree<ASTData>* templateFunctionLookup(NodeTree<ASTData>* scope, std::string lookup, std::vector<Type*> templateInstantiationTypes, std::vector<Type> types);
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules = false); std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules = false);
std::vector<NodeTree<ASTData>*> scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::vector<NodeTree<ASTData>*> visited);
Type* typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<ASTData>* scope, std::map<std::string, Type*> templateTypeReplacements); Type* typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<ASTData>* scope, std::map<std::string, Type*> templateTypeReplacements);
NodeTree<ASTData>* templateClassLookup(NodeTree<ASTData>* scope, std::string name, std::vector<Type*> templateInstantiationTypes); NodeTree<ASTData>* templateClassLookup(NodeTree<ASTData>* scope, std::string name, std::vector<Type*> templateInstantiationTypes);

View File

@@ -4,6 +4,8 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <utility>
#include <sys/stat.h>
#include "NodeTree.h" #include "NodeTree.h"
#include "ASTData.h" #include "ASTData.h"
@@ -12,6 +14,7 @@
#include "util.h" #include "util.h"
#include "Poset.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 { class CGenerator {
public: public:
@@ -19,10 +22,14 @@ 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 generateClassStruct(NodeTree<ASTData>* from); std::string generateClassStruct(NodeTree<ASTData>* from);
bool isUnderTranslationUnit(NodeTree<ASTData>* from, NodeTree<ASTData>* typeDefinition);
NodeTree<ASTData>* highestScope(NodeTree<ASTData>* node);
std::pair<std::string, std::string> generateTranslationUnit(NodeTree<ASTData>* from);
std::string generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enclosingObject = NULL); std::string generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enclosingObject = NULL);
std::string generateAliasChains(NodeTree<ASTData>* scopeNode, NodeTree<ASTData>* definition); std::string generateAliasChains(NodeTree<ASTData>* scopeNode, NodeTree<ASTData>* definition);
static std::string ValueTypeToCType(Type *type); static std::string ValueTypeToCType(Type *type);
static std::string ValueTypeToCTypeDecoration(Type *type); static std::string ValueTypeToCTypeDecoration(Type *type);
static std::string ValueTypeToCTypeThingHelper(Type *type, std::string ptrStr);
static std::string CifyName(std::string name); static std::string CifyName(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);

View File

@@ -15,7 +15,7 @@ class Tester {
int ssystem(std::string command); int ssystem(std::string command);
bool run(std::string fileName); bool run(std::string fileName);
bool compareFiles(std::string file1Path, std::string file2Path); bool compareFiles(std::string file1Path, std::string file2Path);
void cleanExtras(std::string fileName); void cleanExtras(std::string path);
private: private:
std::string krakenInvocation; std::string krakenInvocation;
@@ -27,5 +27,7 @@ class Tester {
std::string shell; std::string shell;
std::string changePermissions; std::string changePermissions;
std::string redirect; std::string redirect;
std::string sep;
std::string cd;
}; };
#endif #endif

View File

@@ -2,7 +2,7 @@ Goal = translation_unit ;
translation_unit = interpreter_directive WS unorderd_list_part WS ; 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 ";" ; 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 "\|" ; dec_type = "\|" WS type WS "\|" ;
template_inst = "<" WS type_list 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_list = template_param_list WS "," WS template_param | template_param ;
template_param = identifier WS traits | identifier ; 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 | ; interpreter_directive = "#!" WS path | ;
path = path path_part | path_part ; 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|<|>|\?| )+))*\"\"\"" ; |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 ; identifier = alpha | alpha alphanumeric ;
scoped_identifier = scoped_identifier WS "::" WS identifier | identifier ;
#Note that to prevent confilct with nested templates (T<A<B>>) it is a nonterminal contructed as follows #Note that to prevent confilct with nested templates (T<A<B>>) it is a nonterminal contructed as follows
right_shift = ">" ">" ; 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 | ; declaration_block = declaration_statement WS ";" WS declaration_block | function WS declaration_block | declaration_statement WS ";" | function | ;
traits = "\(" WS trait_list WS "\)" ; 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 #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 "}" ; #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 ; 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 ; 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 ; 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 ; number = integer | floating_literal ;
access_operation = unarad "." identifier | unarad "->" identifier ; access_operation = unarad "." identifier | unarad "->" identifier ;

View File

@@ -78,15 +78,38 @@ NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<S
//We do this second so that if an import also imports us, all of our stuff has already been defined //We do this second so that if an import also imports us, all of our stuff has already been defined
for (NodeTree<Symbol>* i : children) { for (NodeTree<Symbol>* i : children) {
if (i->getDataRef()->getName() == "import") { if (i->getDataRef()->getName() == "import") {
std::string toImport = concatSymbolTree(i->getChildren()[0]); auto importChildren = i->getChildren();
translationUnit->addChild(new NodeTree<ASTData>("import", ASTData(import, Symbol(toImport, true)))); std::string toImport = concatSymbolTree(importChildren[0]);
auto importNode = new NodeTree<ASTData>("import", ASTData(import, Symbol(toImport, true)));
translationUnit->addChild(importNode);
//Do the imported file too //Do the imported file too
NodeTree<ASTData>* outsideTranslationUnit = importer->importFirstPass(toImport + ".krak"); NodeTree<ASTData>* outsideTranslationUnit = importer->importFirstPass(toImport + ".krak");
translationUnit->getDataRef()->scope[toImport].push_back(outsideTranslationUnit); //Put this transation_unit in the scope as it's files name translationUnit->getDataRef()->scope[toImport].push_back(outsideTranslationUnit); //Put this transation_unit in the scope as it's files name
//Now add it to scope // Now go through and handle anything like import asdf: a; or import asdf: a,b; or import asdf: *;
for (auto i = outsideTranslationUnit->getDataRef()->scope.begin(); i != outsideTranslationUnit->getDataRef()->scope.end(); i++) // 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.
for (auto j : i->second) // Note that import affects scope in two ways:
translationUnit->getDataRef()->scope[i->first].push_back(j); // (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<NodeTree<ASTData>*> 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<NodeTree<ASTData>*>();
}
}
} }
} }
@@ -223,13 +246,17 @@ void ASTTransformation::thirdPass(NodeTree<ASTData>* ast) {
NodeTree<ASTData>* outsideTranslationUnit = importer->getUnit(toImport + ".krak"); NodeTree<ASTData>* outsideTranslationUnit = importer->getUnit(toImport + ".krak");
//Now add all functions to scope //Now add all functions to scope
std::cout << "Trying to re-import from " << toImport << std::endl; std::cout << "Trying to re-import from " << toImport << std::endl;
for (auto i = outsideTranslationUnit->getDataRef()->scope.begin(); i != outsideTranslationUnit->getDataRef()->scope.end(); i++) { for (auto j = outsideTranslationUnit->getDataRef()->scope.begin(); j != outsideTranslationUnit->getDataRef()->scope.end(); j++) {
std::cout << "Looking through " << i->first << std::endl; std::cout << "Looking at " << j->first << std::endl;
for (auto j : i->second) // If we're supposed to import this... (meaning that this name is in the scope already)
if (j->getDataRef()->type == function || j->getDataRef()->type == identifier) if (i->getDataRef()->scope.find(j->first) == i->getDataRef()->scope.end())
std::cout << "Copying " << i->first << std::endl, ast->getDataRef()->scope[i->first].push_back(j); 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 else
std::cout << "Not Copying " << i->first << std::endl; std::cout << "Not Copying " << j->first << std::endl;
} }
} }
} }
@@ -332,7 +359,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
std::vector<NodeTree<Symbol>*> children = from->getChildren(); std::vector<NodeTree<Symbol>*> children = from->getChildren();
std::set<int> skipChildren; std::set<int> skipChildren;
if (name == "identifier") { if (name == "identifier" || name == "scoped_identifier") {
//Make sure we get the entire name //Make sure we get the entire name
std::string lookupName = concatSymbolTree(from); std::string lookupName = concatSymbolTree(from);
std::cout << "Looking up: " << lookupName << std::endl; std::cout << "Looking up: " << lookupName << std::endl;
@@ -350,6 +377,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
} }
newNode = possibleMatches[0]; newNode = possibleMatches[0];
} }
return newNode;
} else if (name == "type_def") { } else if (name == "type_def") {
//If it is an alisis of a type //If it is an alisis of a type
std::string typeAlias; std::string typeAlias;
@@ -416,6 +444,8 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
return newNode; return newNode;
} }
functionName = concatSymbolTree(children[1]); functionName = concatSymbolTree(children[1]);
for (auto child: children)
std::cout << "Function child: " << child->getDataRef()->toString() << std::endl;
newNode = new NodeTree<ASTData>(name, ASTData(function, Symbol(functionName, true), typeFromTypeNode(children[0], scope, templateTypeReplacements))); newNode = new NodeTree<ASTData>(name, ASTData(function, Symbol(functionName, true), typeFromTypeNode(children[0], scope, templateTypeReplacements)));
skipChildren.insert(0); skipChildren.insert(0);
skipChildren.insert(1); skipChildren.insert(1);
@@ -795,11 +825,19 @@ NodeTree<ASTData>* ASTTransformation::functionLookup(NodeTree<ASTData>* scope, s
//We subtract one from the children to get the type size only if there is at least one child AND //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 // 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 //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())) { int numTypes = (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: "; if (types.size() != numTypes) {
std::cout << "Type sizes do not match between two " << lookup << "(" << types.size() << "," << numTypes << "), types are: ";
for (auto j : types) for (auto j : types)
std::cout << j.toString() << " "; std::cout << j.toString() << " ";
std::cout << std::endl; 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; continue;
} }
bool typesMatch = true; bool typesMatch = true;
@@ -1005,7 +1043,15 @@ 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) { std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules) {
return scopeLookup(scope, lookup, includeModules, std::vector<NodeTree<ASTData>*>());
}
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::vector<NodeTree<ASTData>*> visited) {
std::cout << "Scp[e looking up " << lookup << std::endl;
// Don't visit this node again when looking for the smae lookup. Note that we don't prevent coming back for the scope operator, as that should be able to come back.
visited.push_back(scope);
//We first check to see if it's one of the special reserved identifiers (only this, for now) and return early if it is. //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); auto LLElementIterator = languageLevelReservedWords.find(lookup);
if (LLElementIterator != languageLevelReservedWords.end()) { if (LLElementIterator != languageLevelReservedWords.end()) {
@@ -1013,6 +1059,20 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
return LLElementIterator->second; return LLElementIterator->second;
} }
std::vector<NodeTree<ASTData>*> matches; std::vector<NodeTree<ASTData>*> 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<std::string, std::vector<NodeTree<ASTData>*>> scopeMap = scope->getDataRef()->scope; std::map<std::string, std::vector<NodeTree<ASTData>*>> scopeMap = scope->getDataRef()->scope;
auto possibleMatches = scopeMap.find(lookup); auto possibleMatches = scopeMap.find(lookup);
if (possibleMatches != scopeMap.end()) { if (possibleMatches != scopeMap.end()) {
@@ -1021,11 +1081,33 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
matches.push_back(i); matches.push_back(i);
std::cout << "Found " << possibleMatches->second.size() << " match(s) at " << scope->getDataRef()->toString() << std::endl; 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"); auto enclosingIterator = scopeMap.find("~enclosing_scope");
if (enclosingIterator != scopeMap.end()) { if (enclosingIterator != scopeMap.end()) {
std::vector<NodeTree<ASTData>*> upperResult = scopeLookup(enclosingIterator->second[0], lookup); std::vector<NodeTree<ASTData>*> upperResult = scopeLookup(enclosingIterator->second[0], lookup, includeModules, visited);
matches.insert(matches.end(), upperResult.begin(), upperResult.end()); 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; return matches;
} }

View File

@@ -7,24 +7,35 @@ CGenerator::~CGenerator() {
} }
// Note the use of std::pair to hold two strings - the running string for the header file and the running string for the c file.
void CGenerator::generateCompSet(std::map<std::string, NodeTree<ASTData>*> ASTs, std::string outputName) { void CGenerator::generateCompSet(std::map<std::string, NodeTree<ASTData>*> ASTs, std::string outputName) {
//Generate an entire set of files //Generate an entire set of files
std::string buildString = "#!/bin/sh\ncc -std=c99 "; 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++) { for (auto i = ASTs.begin(); i != ASTs.end(); i++) {
std::cout << "\n\nGenerate pass for: " << i->first << std::endl;
buildString += i->first + ".c "; buildString += i->first + ".c ";
std::ofstream outputCFile; std::ofstream outputCFile, outputHFile;
outputCFile.open(i->first + ".c"); outputCFile.open(outputName + "/" + i->first + ".c");
if (outputCFile.is_open()) { outputHFile.open(outputName + "/" + i->first + ".h");
if (outputCFile.is_open() || outputHFile.is_open()) {
// Prequel common to all files // Prequel common to all files
outputCFile << "#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n" << generate(i->second); auto chPair = generateTranslationUnit(i->second);
outputHFile << "#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n" << chPair.first;
outputCFile << "#include \"" + i->first + ".h\"\n\n" << chPair.second;
} else { } else {
std::cout << "Cannot open file " << i->first << ".c" << std::endl; std::cout << "Cannot open file " << i->first << ".c/h" << std::endl;
} }
outputCFile.close(); outputCFile.close();
outputHFile.close();
} }
buildString += "-o " + outputName; buildString += "-o " + outputName;
std::ofstream outputBuild; std::ofstream outputBuild;
outputBuild.open(outputName + ".sh"); outputBuild.open(outputName + "/" + split(outputName, '/').back() + ".sh");
outputBuild << buildString; outputBuild << buildString;
outputBuild.close(); outputBuild.close();
} }
@@ -70,14 +81,33 @@ std::string CGenerator::generateAliasChains(NodeTree<ASTData>* scopeNode, NodeTr
return output; return output;
} }
//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 bool CGenerator::isUnderTranslationUnit(NodeTree<ASTData>* from, NodeTree<ASTData>* node) {
std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enclosingObject) { 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<ASTData>* CGenerator::highestScope(NodeTree<ASTData>* 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<std::string, std::string> CGenerator::generateTranslationUnit(NodeTree<ASTData>* from) {
ASTData data = from->getData(); ASTData data = from->getData();
std::vector<NodeTree<ASTData>*> children = from->getChildren(); std::vector<NodeTree<ASTData>*> children = from->getChildren();
std::string output; std::string cOutput, hOutput;
switch (data.type) {
case translation_unit:
{
// Ok, so we've got to do this in passes to preserve mututally recursive definitions. // 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;". // First Pass: All classes get "struct dummy_thing; typedef struct dummy_thing thing;".
@@ -91,12 +121,21 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
// However, most of these do not actually have to be done as separate passes. First, second, fourth, and fifth // 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. // 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 plainTypedefs = "/**\n * Plain Typedefs\n */\n\n";
std::string variableDeclarations = "/**\n * Variable Declarations \n */\n\n"; std::string variableDeclarations = "/**\n * Variable Declarations \n */\n\n";
std::string classStructs = "/**\n * Class Structs\n */\n\n"; std::string classStructs = "/**\n * Class Structs\n */\n\n";
std::string functionPrototypes = "/**\n * Function Prototypes\n */\n\n"; std::string functionPrototypes = "/**\n * Function Prototypes\n */\n\n";
std::string functionDefinitions = "/**\n * Function Definitions\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<NodeTree<ASTData>*> typedefPoset; Poset<NodeTree<ASTData>*> typedefPoset;
for (int i = 0; i < children.size(); i++) { for (int i = 0; i < children.size(); i++) {
if (children[i]->getDataRef()->type == type_def) { if (children[i]->getDataRef()->type == type_def) {
@@ -112,7 +151,7 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
for (auto j : classChildren) { for (auto j : classChildren) {
if (j->getDataRef()->type == declaration_statement) { if (j->getDataRef()->type == declaration_statement) {
Type* decType = j->getChildren()[0]->getDataRef()->valueType; // Type of the declaration 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 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 typedefPoset.addRelationship(children[i], decType->typeDefinition); // Add a dependency
} }
} }
@@ -123,13 +162,17 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
classStructs += generateClassStruct(i) + "\n"; classStructs += generateClassStruct(i) + "\n";
// Declare everything in translation unit scope here. (allows stuff from other files, automatic forward declarations) // 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++) { // Also, everything in all of the import's scopes
std::map<std::string, std::vector<NodeTree<ASTData>*>> 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) { for (auto declaration : i->second) {
std::vector<NodeTree<ASTData>*> decChildren = declaration->getChildren(); std::vector<NodeTree<ASTData>*> decChildren = declaration->getChildren();
ASTData declarationData = declaration->getData(); ASTData declarationData = declaration->getData();
switch(declarationData.type) { switch(declarationData.type) {
case identifier: case identifier:
variableDeclarations += ValueTypeToCType(declarationData.valueType) + " " + declarationData.symbol.getName() + "; /*identifier*/\n"; variableDeclarations += ValueTypeToCType(declarationData.valueType) + " " + declarationData.symbol.getName() + "; /*identifier*/\n";
variableExternDeclarations += "extern " + ValueTypeToCType(declarationData.valueType) + " " + declarationData.symbol.getName() + "; /*extern identifier*/\n";
break; break;
case function: case function:
{ {
@@ -143,14 +186,14 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
for (int j = 0; j < decChildren.size()-1; j++) { for (int j = 0; j < decChildren.size()-1; j++) {
if (j > 0) if (j > 0)
parameters += ", "; parameters += ", ";
parameters += ValueTypeToCType(decChildren[j]->getData().valueType) + " " + generate(decChildren[j], enclosingObject); parameters += ValueTypeToCType(decChildren[j]->getData().valueType) + " " + generate(decChildren[j], nullptr);
nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType); nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType);
} }
functionPrototypes += CifyName(declarationData.symbol.getName() + nameDecoration) + "(" + parameters + "); /*func*/\n"; functionPrototypes += CifyName(declarationData.symbol.getName() + nameDecoration) + "(" + parameters + "); /*func*/\n";
// Only generate function if this is the unit it was defined in // Only generate function if this is the unit it was defined in
std::cout << "Generating " << CifyName(declarationData.symbol.getName()) << std::endl; std::cout << "Generating " << CifyName(declarationData.symbol.getName()) << std::endl;
if (contains(children, declaration)) if (contains(children, declaration))
functionDefinitions += generate(declaration, enclosingObject); functionDefinitions += generate(declaration, nullptr);
} }
} }
break; break;
@@ -186,19 +229,35 @@ std::string CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
break; break;
default: default:
//std::cout << "Declaration? named " << declaration->getName() << " of unknown type " << ASTData::ASTTypeToString(declarationData.type) << " in translation unit scope" << std::endl; //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"; cOutput += "/*unknown declaration named " + declaration->getName() + "*/\n";
hOutput += "/*unknown declaration named " + declaration->getName() + "*/\n";
} }
} }
} }
output += plainTypedefs + variableDeclarations + classStructs + functionPrototypes + functionDefinitions; hOutput += plainTypedefs + importIncludes + variableExternDeclarations + classStructs + functionPrototypes;
return output; 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<ASTData>* from, NodeTree<ASTData>* enclosingObject) {
ASTData data = from->getData();
std::vector<NodeTree<ASTData>*> children = from->getChildren();
std::string output;
switch (data.type) {
case translation_unit:
{
// 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; break;
case interpreter_directive: case interpreter_directive:
//Do nothing //Do nothing
break; break;
case import: 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"; //return "#include <" + data.symbol.getName() + ">\n";
case identifier: case identifier:
{ {
@@ -421,7 +480,9 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
return functionSignature + "\n" + generate(children[children.size()-1], enclosingObject); //Pass in the object so we can properly handle access to member stuff 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; std::string return_type;
switch (type->baseType) { switch (type->baseType) {
case none: case none:
@@ -453,43 +514,7 @@ std::string CGenerator::ValueTypeToCType(Type *type) {
break; break;
} }
for (int i = 0; i < type->getIndirection(); i++) for (int i = 0; i < type->getIndirection(); i++)
return_type += "*"; return_type += ptrStr;
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 return_type; return return_type;
} }
@@ -510,6 +535,7 @@ std::string CGenerator::CifyName(std::string name) {
"--", "doubleminus", "--", "doubleminus",
"<<", "doubleleft", "<<", "doubleleft",
">>", "doubleright", ">>", "doubleright",
"::", "scopeop",
"==", "doubleequals", "==", "doubleequals",
"!=", "notequals", "!=", "notequals",
"&&", "doubleamprsnd", "&&", "doubleamprsnd",

View File

@@ -10,7 +10,8 @@ Importer::Importer(Parser* parserIn, std::vector<std::string> includePaths) {
removeSymbols.push_back(Symbol("WS", false)); 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)); 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<std::string> includePaths) {
removeSymbols.push_back(Symbol("template", true)); removeSymbols.push_back(Symbol("template", true));
removeSymbols.push_back(Symbol("\\|", 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_typed_parameter_list", false));
collapseSymbols.push_back(Symbol("opt_parameter_list", false)); collapseSymbols.push_back(Symbol("opt_parameter_list", false));
collapseSymbols.push_back(Symbol("opt_import_list", false)); collapseSymbols.push_back(Symbol("opt_import_list", false));

View File

@@ -2,13 +2,15 @@
Tester::Tester(std::string krakenInvocation, std::string krakenGrammerLocation) : krakenInvocation(krakenInvocation), krakenGrammerLocation(krakenGrammerLocation) { Tester::Tester(std::string krakenInvocation, std::string krakenGrammerLocation) : krakenInvocation(krakenInvocation), krakenGrammerLocation(krakenGrammerLocation) {
//initlization list //initlization list
removeCmd = "rm"; removeCmd = "rm -r";
resultsExtention = ".results"; resultsExtention = ".results";
expectedExtention = ".expected_results"; expectedExtention = ".expected_results";
krakenExtention = ".krak"; krakenExtention = ".krak";
changePermissions = "chmod 755"; changePermissions = "chmod 755";
shell = "sh"; shell = "sh";
cd = "cd";
redirect = ">"; redirect = ">";
sep = "/";
} }
Tester::~Tester() { Tester::~Tester() {
@@ -21,27 +23,24 @@ int Tester::ssystem(std::string command) {
void Tester::cleanExtras(std::string fileName) { void Tester::cleanExtras(std::string fileName) {
ssystem(removeCmd + " " + 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; std::cout << "Testing: " << fileName << " with " << krakenInvocation << " and " << krakenGrammerLocation << std::endl;
cleanExtras(fileName); 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);
ssystem(changePermissions + " " + fileName); bool result = compareFiles(fileName + expectedExtention, path + sep + fileName + resultsExtention);
ssystem(krakenInvocation + " " + fileName + krakenExtention + " " + krakenGrammerLocation + " " + fileName);
ssystem(shell + " " + fileName + ".sh");
ssystem(fileName + " " + redirect + " " + fileName + resultsExtention);
bool result = compareFiles(fileName + expectedExtention, fileName + resultsExtention);
//If the test was succesful, we don't need all the extra files //If the test was succesful, we don't need all the extra files
if (result) if (result)
cleanExtras(fileName); cleanExtras(path);
return result; return result;
} }

View File

@@ -3,7 +3,7 @@ import io;
typedef template <T> trivialContainer { typedef template <T> trivialContainer {
|T| data; |T| data;
|void| print() { |void| print() {
print(data); io::print(data);
} }
}; };

View File

@@ -1,4 +1,4 @@
import io; import io:*;
typedef Vec2 { typedef Vec2 {
|int| x; |int| x;

View File

@@ -1,4 +1,4 @@
import io; import io:*;
|int| fibanacci(|int| num) { |int| fibanacci(|int| num) {
if (num < 2) if (num < 2)

View File

@@ -1,5 +1,5 @@
/* Comment first! */ /* Comment first! */
import io; import io:*;
|int| main() { |int| main() {
println(1337); println(1337);

View File

@@ -1,5 +1,5 @@
import io; import io:*;
import mem; import mem:*;
typedef ClassWithConstructor { typedef ClassWithConstructor {
|int| data; |int| data;

View File

@@ -1,4 +1,4 @@
import io; import io:*;
typedef DestructorPrint { typedef DestructorPrint {
|char*| myStr; |char*| myStr;

View File

@@ -4,6 +4,6 @@ import io;
|int| main() { |int| main() {
nothing(); nothing();
println("It was nothing"); io::println("It was nothing");
return 0; return 0;
} }

View File

@@ -1,4 +1,4 @@
import io; import io:*;
template <T,J> |void| addAndPrint(|T| a, |J| b) { template <T,J> |void| addAndPrint(|T| a, |J| b) {
print(a+b); print(a+b);

View File

@@ -1,4 +1,4 @@
import io; import io:*;
|int| ret1() { |int| ret1() {
return ret2() / 2; return ret2() / 2;

View File

@@ -1,13 +1,13 @@
import io; import io;
template <T> |T| addAndPrint(|T| a, |T| b) { template <T> |T| addAndPrint(|T| a, |T| b) {
print(a+b); io::print(a+b);
return a+b; return a+b;
} }
|int| main() { |int| main() {
addAndPrint<int>(10,12); addAndPrint<int>(10,12);
print("\n"); io::print("\n");
return 0; return 0;
} }

View File

@@ -1,5 +1,5 @@
import mem; import mem:*;
import io; import io:*;
typedef AnObject { typedef AnObject {
|int| a; |int| a;

View File

@@ -1,4 +1,4 @@
import io; import io:*;
typedef firstObject { typedef firstObject {
|int| objectNum; |int| objectNum;

View File

@@ -1,5 +1,5 @@
import io; import io:*;
import trivial_container; import trivial_container:*;
typedef RegularObject { typedef RegularObject {
|int| num; |int| num;

View File

@@ -0,0 +1,13 @@
Qualified io!
0
9
11
Qualified Container!
Even template functions qualified!
Unqualified io!
0
10
12
Unqualified Container!
Even template functions unqualified!

32
tests/newScoping.krak Normal file
View File

@@ -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<char*>| sayQualified.construct("Qualified Container!");
io::println(sayQualified.get());
io::println(scopeQualified::qualified_id<char*>("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<char*>| sayUnqualified.construct("Unqualified Container!");
io::println(sayUnqualified.get());
io::println(unqualified_id<char*>("Even template functions unqualified!"));
return 0;
}

View File

@@ -1,4 +1,4 @@
import io; import io:*;
typedef objectA { typedef objectA {
|int| a; |int| a;

View File

@@ -1,7 +1,8 @@
#!/bin/bash #!/bin/bash
krakenPath="../build/kraken" krakenPath="../build/kraken"
testDir=${1:-"../tests"} #testDir=${1:-"../tests"}
testDir="."
ext=${2:-"krak"} ext=${2:-"krak"}
fileList="" fileList=""

27
tests/scopeQualified.krak Normal file
View File

@@ -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 <T> qualified_container {
|T| data;
|qualified_container<T>*| construct(|T| dataIn) {
data = dataIn;
}
|T| get() {
return data;
}
};
template<T> |T| qualified_id(|T| it) {
return it;
}

View File

@@ -0,0 +1,27 @@
|int| unqualifed_variable = 8;
|int| unqualified_func() { return 10; }
typedef unqualified_class {
|int| number;
|unqualified_class*| construct(|int| num) {
number = num;
return this;
}
|int| get() {
return number;
}
};
typedef template <T> unqualified_container {
|T| data;
|unqualified_container<T>*| construct(|T| dataIn) {
data = dataIn;
}
|T| get() {
return data;
}
};
template<T> |T| unqualified_id(|T| it) {
return it;
}

View File

@@ -1,4 +1,4 @@
import io; import io:*;
|int| addAndPrintInt(|int| a, |int| b) { |int| addAndPrintInt(|int| a, |int| b) {
print(a+b); print(a+b);

View File

@@ -5,12 +5,12 @@ typedef template <T,J> TemplateTest {
|T| a; |T| a;
|J| b; |J| b;
|void| print() { |void| print() {
print("a: "); io::print("a: ");
print(a); io::print(a);
print("\n"); io::print("\n");
print("b: "); io::print("b: ");
print(b); io::print(b);
print("\n"); io::print("\n");
} }
}; };

View File

@@ -5,12 +5,12 @@ typedef template <T> TemplateTest {
|int| a; |int| a;
|T| b; |T| b;
|void| print() { |void| print() {
print("a: "); io::print("a: ");
print(a); io::print(a);
print("\n"); io::print("\n");
print("b: "); io::print("b: ");
print(b); io::print(b);
print("\n"); io::print("\n");
} }
}; };

View File

@@ -1,11 +1,10 @@
import io; import io;
typedef FirstObject { typedef FirstObject {
|int| objectNum; |int| objectNum;
|void| PrintSelf(|int| a) { |void| PrintSelf(|int| a) {
print(objectNum); io::print(objectNum);
print(a); io::print(a);
} }
}; };
@@ -13,6 +12,6 @@ typedef FirstObject {
|FirstObject| wooObject; |FirstObject| wooObject;
wooObject.objectNum = 5; wooObject.objectNum = 5;
wooObject.PrintSelf(7); wooObject.PrintSelf(7);
print("\n"); io::print("\n");
return 0; return 0;
} }

View File

@@ -1,5 +1,5 @@
import io; import io:*;
import trivial_container; import trivial_container:*;
typedef template <T> TemplateTest { typedef template <T> TemplateTest {
|int| a; |int| a;

View File

@@ -1,5 +1,5 @@
import io; import io:*;
import mem; import mem:*;
|int| main() { |int| main() {
|int| b; |int| b;

View File

@@ -0,0 +1 @@
42

View File

@@ -0,0 +1,8 @@
import io;
|int| a = 42;
|int| main() {
io::println(a);
return 0;
}

View File

@@ -1,4 +1,4 @@
import io; import io:*;
typedef NoTraits {}; typedef NoTraits {};

View File

@@ -7,7 +7,7 @@ typedef ClassWithConstructor {
return this; return this;
} }
|void| printData() { |void| printData() {
println(data); io::println(data);
} }
}; };
@@ -15,6 +15,6 @@ typedef ClassWithConstructor {
|ClassWithConstructor| object.construct(4); |ClassWithConstructor| object.construct(4);
object.printData(); object.printData();
|int| a = 8; |int| a = 8;
println(a); io::println(a);
return 0; return 0;
} }

View File

@@ -1,6 +1,6 @@
import io; import io:*;
import mem; import mem:*;
import vector; import vector:*;
typedef AbleToBeDestroyed (Destructable) { typedef AbleToBeDestroyed (Destructable) {
|void| destruct() { |void| destruct() {