Merge branch 'master' of https://github.com/Limvot/kraken
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,6 +5,7 @@ build-ninja
|
||||
stats
|
||||
*.swp
|
||||
*.swm
|
||||
*.swn
|
||||
*.swo
|
||||
*.png
|
||||
*krakout*
|
||||
@@ -16,3 +17,4 @@ callgrind*
|
||||
*.comp_bac
|
||||
bintest.bin
|
||||
*.dot
|
||||
.stfolder
|
||||
|
||||
@@ -16,9 +16,9 @@ class Type;
|
||||
|
||||
enum ASTType {undef, translation_unit, interpreter_directive, import, identifier, type_def, adt_def,
|
||||
function, code_block, typed_parameter, expression, boolean_expression, statement,
|
||||
if_statement, while_loop, for_loop, return_statement, break_statement, continue_statement, defer_statement,
|
||||
assignment_statement, declaration_statement, if_comp, simple_passthrough, passthrough_params,
|
||||
in_passthrough_params, out_passthrough_params, opt_string, param_assign, function_call, value};
|
||||
if_statement, match_statement, case_statement, while_loop, for_loop, return_statement, break_statement,
|
||||
continue_statement, defer_statement, assignment_statement, declaration_statement, if_comp, simple_passthrough,
|
||||
passthrough_params, in_passthrough_params, out_passthrough_params, opt_string, param_assign, function_call, value};
|
||||
|
||||
class ASTData {
|
||||
public:
|
||||
|
||||
@@ -28,6 +28,7 @@ class CGenerator {
|
||||
~CGenerator();
|
||||
void generateCompSet(std::map<std::string, NodeTree<ASTData>*> ASTs, std::string outputName);
|
||||
std::string generateTypeStruct(NodeTree<ASTData>* from);
|
||||
bool isUnderNodeWithType(NodeTree<ASTData>* from, ASTType type);
|
||||
bool isUnderTranslationUnit(NodeTree<ASTData>* from, NodeTree<ASTData>* typeDefinition);
|
||||
NodeTree<ASTData>* highestScope(NodeTree<ASTData>* node);
|
||||
std::pair<std::string, std::string> generateTranslationUnit(std::string name, std::map<std::string, NodeTree<ASTData>*> ASTs);
|
||||
@@ -40,6 +41,8 @@ class CGenerator {
|
||||
std::string ValueTypeToCTypeThingHelper(Type *type, std::string ptrStr, ClosureTypeSpecialType closureSpecial);
|
||||
static std::string CifyName(std::string name);
|
||||
static std::string scopePrefix(NodeTree<ASTData>* from);
|
||||
std::string simpleComplexName(std::string simpleName, std::string complexName);
|
||||
std::string prefixIfNeeded(std::string prefix, std::string name);
|
||||
std::string generateObjectMethod(NodeTree<ASTData>* enclosingObject, NodeTree<ASTData>* from, std::string *functionPrototype);
|
||||
NodeTree<ASTData>* getMethodsObjectType(NodeTree<ASTData>* scope, std::string functionName);
|
||||
NodeTree<ASTData>* getMethod(Type* type, std::string method, std::vector<Type> types);
|
||||
@@ -56,6 +59,8 @@ class CGenerator {
|
||||
std::string linkerString;
|
||||
std::string functionTypedefString;
|
||||
std::string functionTypedefStringPre;
|
||||
std::set<std::string> usedNameSet;
|
||||
std::map<std::string, std::string> simpleComplexNameMap;
|
||||
std::map<Type, triple<std::string, std::string, std::string>> functionTypedefMap;
|
||||
std::map<std::set<NodeTree<ASTData>*>, std::string> closureStructMap;
|
||||
std::vector<std::vector<NodeTree<ASTData>*>> distructDoubleStack;
|
||||
|
||||
@@ -41,6 +41,7 @@ class Type {
|
||||
void decreaseIndirection();
|
||||
void modifyIndirection(int mod);
|
||||
Type withIncreasedIndirection();
|
||||
Type *withIncreasedIndirectionPtr();
|
||||
Type withDecreasedIndirection();
|
||||
|
||||
Type* withoutReference();
|
||||
|
||||
@@ -16,6 +16,7 @@ template_param_list = template_param_list WS "," WS template_param | template_pa
|
||||
template_param = identifier WS traits | identifier ;
|
||||
|
||||
import = "import" WS identifier line_end | "import" WS identifier WS ":" WS "\*" line_end | "import" WS identifier WS ":" WS identifier_list line_end ;
|
||||
identifier_list = identifier | identifier WS "," WS identifier_list ;
|
||||
|
||||
# all for optional semicolons
|
||||
line_break = "
|
||||
@@ -57,7 +58,6 @@ triple_quoted_string = "\"\"\"((\"\"(`|1|2|3|4|5|6|7|8|9|0|-|=| |q|w|e|r|t|y|u|i
|
||||
|
||||
#identifier = alpha_alphanumeric ;
|
||||
identifier = augmented_alpha_alphanumeric ;
|
||||
identifier_list = identifier | identifier WS "," WS identifier_list ;
|
||||
scope_op = ":" ":" ;
|
||||
scoped_identifier = scoped_identifier WS scope_op WS identifier | identifier ;
|
||||
|
||||
@@ -89,10 +89,16 @@ traits = "\(" WS trait_list WS "\)" ;
|
||||
trait_list = trait_list WS "," WS scoped_identifier | scoped_identifier ;
|
||||
|
||||
adt_nonterm = "adt" ;
|
||||
adt_def = adt_nonterm WS identifier WS "{" WS identifier_list WS "}" ;
|
||||
adt_def = adt_nonterm WS identifier WS "{" WS adt_option_list WS "}" ;
|
||||
adt_option_list = adt_option | adt_option WS "," WS adt_option_list ;
|
||||
adt_option = identifier | identifier WS dec_type ;
|
||||
|
||||
if_statement = "if" WS "\(" WS boolean_expression WS "\)" WS statement | "if" WS "\(" WS boolean_expression WS "\)" WS statement WS "else" WS statement ;
|
||||
|
||||
match_statement = "match" WS "\(" WS boolean_expression WS "\)" WS "{" WS case_statement_list WS "}" ;
|
||||
case_statement_list = case_statement WS case_statement_list | case_statement ;
|
||||
case_statement = scoped_identifier WS "\(" WS identifier WS "\)" WS statement | scoped_identifier WS "\(" WS "\)" WS statement ;
|
||||
|
||||
while_loop = "while" WS boolean_expression WS statement ;
|
||||
|
||||
for_loop = "for" WS "\(" WS statement WS boolean_expression line_end WS statement WS "\)" WS statement ;
|
||||
@@ -102,7 +108,7 @@ return_statement = "return" | "return" WS boolean_expression ;
|
||||
code_block = "{" WS statement_list WS "}" | "{" WS "}" ;
|
||||
|
||||
statement_list = statement_list WS statement | statement ;
|
||||
statement = if_statement | while_loop | for_loop | return_statement line_end | boolean_expression line_end | assignment_statement line_end | declaration_statement line_end | code_block | if_comp | simple_passthrough | break_statement | continue_statement | defer_statement ;
|
||||
statement = if_statement | match_statement | while_loop | for_loop | return_statement line_end | boolean_expression line_end | assignment_statement line_end | declaration_statement line_end | code_block | if_comp | simple_passthrough | break_statement | continue_statement | defer_statement ;
|
||||
break_statement = "break" ;
|
||||
continue_statement = "continue" ;
|
||||
defer_statement = "defer" WS statement ;
|
||||
|
||||
@@ -98,13 +98,13 @@ NodeTree<ASTData>* ASTTransformation::firstPass(std::string fileName, NodeTree<S
|
||||
}
|
||||
|
||||
} else if (i->getDataRef()->getName() == "adt_def") {
|
||||
std::string name = concatSymbolTree(i->getChildren()[0]);
|
||||
std::string name = concatSymbolTree(getNode("identifier", i));
|
||||
NodeTree<ASTData>* adt_dec = addToScope("~enclosing_scope", translationUnit, new NodeTree<ASTData>("adt_def", ASTData(adt_def, Symbol(name, true, name))));
|
||||
addToScope(name, adt_dec, translationUnit);
|
||||
translationUnit->addChild(adt_dec);
|
||||
adt_dec->getDataRef()->valueType = new Type(adt_dec);
|
||||
} else if (i->getDataRef()->getName() == "if_comp") {
|
||||
std::cout << "IF COMP" << std::endl;
|
||||
//std::cout << "IF COMP" << std::endl;
|
||||
NodeTree<ASTData>* newNode = addToScope("~enclosing_scope", translationUnit, new NodeTree<ASTData>(i->getDataRef()->getName(), ASTData(if_comp)));
|
||||
newNode->addChild(addToScope("~enclosing_scope", newNode, new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(concatSymbolTree(i->getChildren()[0]),true)))));
|
||||
std::set<int> skipChildren;
|
||||
@@ -193,16 +193,50 @@ void ASTTransformation::secondPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
|
||||
//Do the inside of classes here
|
||||
secondPassDoClassInsides(typeDef, typedefChildren, std::map<std::string, Type*>());
|
||||
} else if (i->getDataRef()->getName() == "adt_def") {
|
||||
std::string name = concatSymbolTree(i->getChildren()[0]);
|
||||
std::cout << "ADT DEF" << std::endl;
|
||||
std::cout << "there are " << getNodes("adt_option", i).size() << " adt_options" << std::endl;
|
||||
std::string name = concatSymbolTree(getNode("identifier", i));
|
||||
NodeTree<ASTData>* adtDef = ast->getDataRef()->scope[name][0]; //No overloaded types (besides uninstantiated templates, which can have multiple versions based on types or specilizations)
|
||||
for (NodeTree<Symbol>* j : i->getChildren()) {
|
||||
if (j->getDataRef()->getName() == "identifier") {
|
||||
std::string ident_name = concatSymbolTree(j);
|
||||
|
||||
// Let's make an equality function prototype
|
||||
Type *thisADTType = adtDef->getDataRef()->valueType;
|
||||
NodeTree<ASTData>* equalityFunc = new NodeTree<ASTData>("function", ASTData(function, Symbol("operator==", true), new Type(std::vector<Type*>{thisADTType}, new Type(boolean))));
|
||||
adtDef->addChild(equalityFunc);
|
||||
addToScope("operator==", equalityFunc, adtDef);
|
||||
addToScope("~enclosing_scope", adtDef, equalityFunc);
|
||||
|
||||
NodeTree<ASTData>* inequalityFunc = new NodeTree<ASTData>("function", ASTData(function, Symbol("operator!=", true), new Type(std::vector<Type*>{thisADTType}, new Type(boolean))));
|
||||
adtDef->addChild(inequalityFunc);
|
||||
addToScope("operator!=", inequalityFunc, adtDef);
|
||||
addToScope("~enclosing_scope", adtDef, inequalityFunc);
|
||||
|
||||
for (NodeTree<Symbol>* j : getNodes("adt_option", i)) {
|
||||
std::string ident_name = concatSymbolTree(getNode("identifier", j));
|
||||
std::cout << "add ing " << ident_name << " to " << name << " for ADT" << std::endl;
|
||||
NodeTree<ASTData>* enum_variant_identifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(ident_name, true), adtDef->getDataRef()->valueType));
|
||||
NodeTree<ASTData>* enum_variant_identifier;
|
||||
NodeTree<Symbol>* possibleType = getNode("type", j);
|
||||
NodeTree<ASTData>* enum_variant_function = nullptr;
|
||||
if (possibleType) {
|
||||
Type* actual_type = typeFromTypeNode(possibleType, adtDef, std::map<std::string, Type*>());
|
||||
enum_variant_identifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(ident_name, true), actual_type));
|
||||
|
||||
// also make a function prototype for a function that returns an instance of this type. If we don't contain a type, it's just the literal
|
||||
//enum_variant_function = new NodeTree<ASTData>("function", ASTData(function, Symbol("fun_"+ident_name, true), new Type(std::vector<Type*>{actual_type}, adtDef->getDataRef()->valueType)));
|
||||
enum_variant_function = new NodeTree<ASTData>("function", ASTData(function, Symbol(ident_name, true), new Type(std::vector<Type*>{actual_type}, thisADTType)));
|
||||
} else {
|
||||
enum_variant_identifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(ident_name, true), adtDef->getDataRef()->valueType));
|
||||
// now a function in both cases...
|
||||
enum_variant_function = new NodeTree<ASTData>("function", ASTData(function, Symbol(ident_name, true), new Type(std::vector<Type*>(), thisADTType)));
|
||||
}
|
||||
adtDef->addChild(enum_variant_identifier);
|
||||
addToScope(ident_name, enum_variant_identifier, adtDef);
|
||||
addToScope("~enclosing_scope", adtDef, enum_variant_identifier);
|
||||
// this comes second so it is added to the enclosing scope second so that the function is found last on identifer lookup so we can still access members that are not functions
|
||||
// as their names alias each other
|
||||
if (enum_variant_function) {
|
||||
adtDef->addChild(enum_variant_function);
|
||||
addToScope(ident_name, enum_variant_function, adtDef);
|
||||
addToScope("~enclosing_scope", adtDef, enum_variant_function);
|
||||
}
|
||||
}
|
||||
} else if (i->getDataRef()->getName() == "function") {
|
||||
@@ -252,7 +286,7 @@ NodeTree<ASTData>* ASTTransformation::secondPassFunction(NodeTree<Symbol>* from,
|
||||
else //has traits
|
||||
yetToBeInstantiatedTemplateTypes[concatSymbolTree(i->getChildren()[0])] = new Type(template_type_type, parseTraits(i->getChildren()[1])); //This may have to be combined with templateTypeReplacements if we do templated member functions inside of templated classes
|
||||
}
|
||||
std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
|
||||
//std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
|
||||
return functionDef;
|
||||
}
|
||||
functionName = concatSymbolTree(children[0]);
|
||||
@@ -326,13 +360,13 @@ bool ASTTransformation::fourthPass(NodeTree<ASTData>* ast, NodeTree<Symbol>* par
|
||||
if (i.second[0]->getDataRef()->type == type_def && i.second[0]->getDataRef()->valueType->templateTypeReplacement.size()
|
||||
&& !i.second[0]->getDataRef()->valueType->templateInstantiated) {
|
||||
classTemplates.push_back(i.second[0]);
|
||||
std::cout << "Saving " << i.second[0]->getDataRef()->toString() << " to instantiate." << std::endl;
|
||||
//std::cout << "Saving " << i.second[0]->getDataRef()->toString() << " to instantiate." << std::endl;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
for (auto i : classTemplates) {
|
||||
Type* classTemplateType = i->getDataRef()->valueType;
|
||||
std::cout << "Instantiating template " << i->getDataRef()->toString() << std::endl;
|
||||
//std::cout << "Instantiating template " << i->getDataRef()->toString() << std::endl;
|
||||
for (NodeTree<Symbol>* j : classTemplateType->templateDefinition->getChildren())
|
||||
if (j->getDataRef()->getName() == "function" && j->getChildren()[1]->getDataRef()->getName() != "template_dec")
|
||||
thirdPassFunction(j, searchScopeForFunctionDef(i, j, classTemplateType->templateTypeReplacement), classTemplateType->templateTypeReplacement); //do member method
|
||||
@@ -348,16 +382,16 @@ NodeTree<ASTData>* ASTTransformation::searchScopeForFunctionDef(NodeTree<ASTData
|
||||
std::vector<Type> types;
|
||||
std::vector<NodeTree<Symbol>*> children = parseTree->getChildren();
|
||||
//Skipping the initial return type and identifier as well as the final code block
|
||||
std::cout << "\n Searching scope for function def, function is: " << concatSymbolTree(children[0]) << ", children size is " << children.size() << std::endl;
|
||||
//std::cout << "\n Searching scope for function def, function is: " << concatSymbolTree(children[0]) << ", children size is " << children.size() << std::endl;
|
||||
for (auto param: getNodes("typed_parameter", children)) { //Skip over commas
|
||||
std::cout << "Making type for lookup ||" << concatSymbolTree(param) << "||" << std::endl;
|
||||
//std::cout << "Making type for lookup ||" << concatSymbolTree(param) << "||" << std::endl;
|
||||
Type type = *typeFromTypeNode(param->getChildren().back(), scope, templateTypeReplacements);
|
||||
std::cout << "Type made: " << type.toString() << std::endl;
|
||||
//std::cout << "Type made: " << type.toString() << std::endl;
|
||||
types.push_back(type);
|
||||
}
|
||||
std::cout << "About to search scope about " << concatSymbolTree(children[0]) << std::endl;
|
||||
//std::cout << "About to search scope about " << concatSymbolTree(children[0]) << std::endl;
|
||||
NodeTree<ASTData>* result = functionLookup(scope, functionName, types);
|
||||
std::cout << "Done searching scope about " << concatSymbolTree(children[0]) << std::endl;
|
||||
//std::cout << "Done searching scope about " << concatSymbolTree(children[0]) << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -384,7 +418,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
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;
|
||||
//std::cout << "Looking up: " << lookupName << std::endl;
|
||||
if (limitToFunction) {
|
||||
newNode = functionLookup(scope, lookupName, types);
|
||||
if (newNode == NULL) {
|
||||
@@ -438,7 +472,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
} else if (name == "type_def") {
|
||||
//If it is an alisis of a type
|
||||
std::string typeAlias;
|
||||
std::cout << "The scope here at type_def is " << scope->getDataRef()->toString() << std::endl;
|
||||
//std::cout << "The scope here at type_def is " << scope->getDataRef()->toString() << std::endl;
|
||||
if (children[1]->getData().getName() == "type") {
|
||||
typeAlias = concatSymbolTree(children[0]);
|
||||
newNode = scope->getDataRef()->scope[typeAlias][0]; //The node for this type_def has already been made by translation_unit.
|
||||
@@ -451,7 +485,7 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
Type* objectType = NULL;
|
||||
if (children[1]->getData().getName() == "template_dec") {
|
||||
typeAlias = concatSymbolTree(children[0]);
|
||||
std::cout << "Template Type!"<<std::endl;
|
||||
//std::cout << "Template Type!"<<std::endl;
|
||||
newNode = scope->getDataRef()->scope[typeAlias][0]; //The node for this type_def has already been made by translation_unit.
|
||||
//This is done so that types that reference each other can be declared in any order
|
||||
// std::cout << "typeAlias is " << typeAlias << " and newNode is " << newNode << std::endl;
|
||||
@@ -491,13 +525,13 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
yetToBeInstantiatedTemplateTypes[concatSymbolTree(i)] = new Type(template_type_type); //This may have to be combined with templateTypeReplacements if we do templated member functions inside of templated classes
|
||||
|
||||
auto transChildren = transformChildren(slice(children,3,-2), std::set<int>(), newNode, types, limitToFunction, yetToBeInstantiatedTemplateTypes);
|
||||
std::cout << "Template function " << functionName << " has these parameters: ";
|
||||
for (auto i : transChildren)
|
||||
std::cout << "||" << i->getDataRef()->toString() << "|| ";
|
||||
std::cout << "??||" << std::endl;
|
||||
//std::cout << "Template function " << functionName << " has these parameters: ";
|
||||
//for (auto i : transChildren)
|
||||
//std::cout << "||" << i->getDataRef()->toString() << "|| ";
|
||||
//std::cout << "??||" << std::endl;
|
||||
newNode->addChildren(transChildren);
|
||||
|
||||
std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
|
||||
//std::cout << "Finished Non-Instantiated Template function " << functionName << std::endl;
|
||||
return newNode;
|
||||
}
|
||||
if (name == "lambda")
|
||||
@@ -518,13 +552,13 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
newNode->addChildren(parameters);
|
||||
// update type with actual type
|
||||
newNode->getDataRef()->valueType = new Type(mapNodesToTypePointers(parameters), newNode->getDataRef()->valueType);
|
||||
auto statement = transform(getNode("statement", children), scope, types, limitToFunction, templateTypeReplacements);
|
||||
auto statement = transform(getNode("statement", children), scope, types, false, templateTypeReplacements); // definitly do not limit this statement to functions
|
||||
if (name == "lambda")
|
||||
newNode->getDataRef()->closedVariables = findVariablesToClose(newNode, statement, scope);
|
||||
for (auto i : newNode->getDataRef()->closedVariables)
|
||||
std::cout << "OK, CLOSED: " << i->getDataRef()->toString() << std::endl;
|
||||
//for (auto i : newNode->getDataRef()->closedVariables)
|
||||
//std::cout << "OK, CLOSED: " << i->getDataRef()->toString() << std::endl;
|
||||
newNode->addChild(statement);
|
||||
std::cout << "finished function" << functionName << std::endl;
|
||||
//std::cout << "finished function" << functionName << std::endl;
|
||||
return newNode;
|
||||
|
||||
} else if (name == "code_block") {
|
||||
@@ -534,12 +568,12 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
} else if (name == "typed_parameter") {
|
||||
//newNode = transform(children[1]); //Transform to get the identifier
|
||||
std::string parameterName = concatSymbolTree(children[0]);
|
||||
std::cout << "Doing typed parameter " << parameterName << std::endl;
|
||||
//std::cout << "Doing typed parameter " << parameterName << std::endl;
|
||||
//std::string typeString = concatSymbolTree(children[0]);//Get the type (left child) and set our new identifer to be that type
|
||||
newNode = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(parameterName, true), typeFromTypeNode(children[2], scope, templateTypeReplacements)));
|
||||
addToScope(parameterName, newNode, scope);
|
||||
addToScope("~enclosing_scope", scope, newNode);
|
||||
std::cout << "Done doing typed_parameter " << parameterName << std::endl;
|
||||
//std::cout << "Done doing typed_parameter " << parameterName << std::endl;
|
||||
return newNode;
|
||||
} else if (name == "boolean_expression" || name == "and_boolean_expression" || name == "bool_exp") {
|
||||
//If this is an actual part of an expression, not just a premoted term
|
||||
@@ -564,10 +598,10 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
} else if (name == "expression" || name == "shiftand" || name == "term" || name == "unarad" || name == "access_operation") {
|
||||
//If this is an actual part of an expression, not just a premoted child
|
||||
if (children.size() > 2) {
|
||||
NodeTree<ASTData>* lhs = transform(children[0], scope, std::vector<Type>(),limitToFunction, templateTypeReplacements); //LHS does not inherit types
|
||||
NodeTree<ASTData>* lhs = transform(children[0], scope, std::vector<Type>(),false, templateTypeReplacements); //LHS does not inherit types, or limittofunction
|
||||
NodeTree<ASTData>* rhs;
|
||||
if (name == "access_operation") {
|
||||
std::cout << "lhs is: " << lhs->getDataRef()->toString() << std::endl;
|
||||
//std::cout << "lhs is: " << lhs->getDataRef()->toString() << std::endl;
|
||||
rhs = transform(children[2], lhs->getDataRef()->valueType->typeDefinition, types, limitToFunction, templateTypeReplacements); //If an access operation, then the right side will be in the lhs's type's scope
|
||||
// this might be a template member function, so do like below would do, but make it our rhs
|
||||
if (rhs == nullptr)
|
||||
@@ -610,11 +644,11 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
else
|
||||
funcName = concatSymbolTree(children[1]), param = transform(children[0], scope, types, limitToFunction, templateTypeReplacements);
|
||||
|
||||
std::cout << "\t\t\t funcName= " << funcName << " param: " << param->getDataRef()->symbol.getName() << std::endl;
|
||||
//std::cout << "\t\t\t funcName= " << funcName << " param: " << param->getDataRef()->symbol.getName() << std::endl;
|
||||
//std::cout << "scope lookup from factor" << std::endl;
|
||||
std::vector<NodeTree<ASTData>*> transformedChildren; transformedChildren.push_back(param);
|
||||
NodeTree<ASTData>* function = doFunction(scope, funcName, transformedChildren, templateTypeReplacements);
|
||||
std::cout << "\t\t\t AFTER dofunction= " << std::endl;
|
||||
//std::cout << "\t\t\t AFTER dofunction= " << std::endl;
|
||||
if (function == NULL) {
|
||||
std::cerr << "scope lookup error! Could not find " << funcName << " in factor " << std::endl;
|
||||
throw "LOOKUP ERROR: " + funcName;
|
||||
@@ -628,6 +662,30 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
newNode = new NodeTree<ASTData>(name, ASTData(statement));
|
||||
} else if (name == "if_statement") {
|
||||
newNode = new NodeTree<ASTData>(name, ASTData(if_statement));
|
||||
} else if (name == "match_statement") {
|
||||
newNode = new NodeTree<ASTData>(name, ASTData(match_statement));
|
||||
} else if (name == "case_statement") {
|
||||
newNode = new NodeTree<ASTData>(name, ASTData(case_statement));
|
||||
std::string adtOptionStr = concatSymbolTree(getNodes("scoped_identifier", children)[0]);
|
||||
auto optionDefPoss = scopeLookup(scope, adtOptionStr);
|
||||
auto optionDef = optionDefPoss[0];
|
||||
//auto adtDef = optionDef->getDataRef()->scope["~enclosing_scope"][0];
|
||||
|
||||
addToScope("~enclosing_scope", scope, newNode);
|
||||
newNode->addChild(optionDef);
|
||||
|
||||
// we have a destructure
|
||||
auto newIdentifierSymbolNodes = getNodes("identifier", children);
|
||||
if (newIdentifierSymbolNodes.size()) {
|
||||
std::string newIdentifierStr = concatSymbolTree(newIdentifierSymbolNodes[0]);
|
||||
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), optionDef->getDataRef()->valueType));
|
||||
addToScope(newIdentifierStr, newIdentifier, newNode);
|
||||
addToScope("~enclosing_scope", newNode, newIdentifier);
|
||||
newNode->addChild(newIdentifier);
|
||||
}
|
||||
|
||||
newNode->addChild(transform(getNode("statement",children), newNode, types, limitToFunction, templateTypeReplacements));
|
||||
return newNode;
|
||||
} else if (name == "while_loop") {
|
||||
newNode = new NodeTree<ASTData>(name, ASTData(while_loop));
|
||||
} else if (name == "for_loop") {
|
||||
@@ -688,10 +746,10 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
NodeTree<Symbol>* typeSyntaxNode = getNode("type", children);
|
||||
Type* identifierType = typeSyntaxNode ? typeFromTypeNode(typeSyntaxNode, scope, templateTypeReplacements) : nullptr;
|
||||
|
||||
if (identifierType)
|
||||
std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
|
||||
else
|
||||
std::cout << "Declaring an identifier " << newIdentifierStr << " with type to be type-inferenced " << std::endl;
|
||||
//if (identifierType)
|
||||
//std::cout << "Declaring an identifier " << newIdentifierStr << " to be of type " << identifierType->toString() << std::endl;
|
||||
//else
|
||||
//std::cout << "Declaring an identifier " << newIdentifierStr << " with type to be type-inferenced " << std::endl;
|
||||
|
||||
if (children.size() > 1 && concatSymbolTree(children[1]) == ".") {
|
||||
NodeTree<ASTData>* newIdentifier = new NodeTree<ASTData>("identifier", ASTData(identifier, Symbol(newIdentifierStr, true), identifierType));
|
||||
@@ -771,15 +829,15 @@ NodeTree<ASTData>* ASTTransformation::transform(NodeTree<Symbol>* from, NodeTree
|
||||
|
||||
skipChildren.insert(0);
|
||||
std::vector<NodeTree<ASTData>*> transformedChildren = transformChildren(children, skipChildren, scope, types, limitToFunction, templateTypeReplacements);
|
||||
std::cout << "scope lookup from function_call: " << functionCallName << std::endl;
|
||||
for (auto i : children)
|
||||
std::cout << i << " : " << i->getName() << " : " << i->getDataRef()->getName() << std::endl;
|
||||
//std::cout << "scope lookup from function_call: " << functionCallName << std::endl;
|
||||
//for (auto i : children)
|
||||
//std::cout << i << " : " << i->getName() << " : " << i->getDataRef()->getName() << std::endl;
|
||||
|
||||
NodeTree<ASTData>* function = transform(children[0], scope, mapNodesToTypes(transformedChildren), true, templateTypeReplacements);
|
||||
std::cout << "The thing: " << function << " : " << function->getName() << std::endl;
|
||||
for (auto i : function->getChildren())
|
||||
std::cout << i->getName() << " ";
|
||||
std::cout << std::endl;
|
||||
//std::cout << "The thing: " << function << " : " << function->getName() << std::endl;
|
||||
//for (auto i : function->getChildren())
|
||||
//std::cout << i->getName() << " ";
|
||||
//std::cout << std::endl;
|
||||
newNode->addChild(function);
|
||||
// note that we now get the return type from the function call's type
|
||||
newNode->getDataRef()->valueType = function->getDataRef()->valueType->returnType;
|
||||
@@ -865,11 +923,11 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
|
||||
auto LLElementIterator = languageLevelOperators.find(lookup);
|
||||
NodeTree<ASTData>* newNode;
|
||||
if (LLElementIterator != languageLevelOperators.end()) {
|
||||
std::cout << "Checking for early method level operator overload" << std::endl;
|
||||
//std::cout << "Checking for early method level operator overload" << std::endl;
|
||||
std::string lookupOp = "operator" + lookup;
|
||||
for (auto i : nodes)
|
||||
std::cout << i->getDataRef()->toString() << " ";
|
||||
std::cout << std::endl;
|
||||
//for (auto i : nodes)
|
||||
//std::cout << i->getDataRef()->toString() << " ";
|
||||
//std::cout << std::endl;
|
||||
NodeTree<ASTData>* operatorMethod = NULL;
|
||||
|
||||
// make sure this isn't a pointer, also. Silly vector<string> bug
|
||||
@@ -881,7 +939,7 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
|
||||
}
|
||||
if (operatorMethod) {
|
||||
//Ok, so we construct
|
||||
std::cout << "Early method level operator was found" << std::endl;
|
||||
//std::cout << "Early method level operator was found" << std::endl;
|
||||
//return operatorMethod;
|
||||
NodeTree<ASTData>* newNode = new NodeTree<ASTData>(lookupOp, ASTData(function_call, Symbol(lookupOp, true)));
|
||||
NodeTree<ASTData>* dotFunctionCall = new NodeTree<ASTData>(".", ASTData(function_call, Symbol(".", true), operatorMethod->getDataRef()->valueType));
|
||||
@@ -896,32 +954,32 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
|
||||
newNode->getDataRef()->valueType = operatorMethod->getDataRef()->valueType->returnType;
|
||||
return newNode;
|
||||
}
|
||||
std::cout << "Early method level operator was NOT found" << std::endl;
|
||||
//std::cout << "Early method level operator was NOT found" << std::endl;
|
||||
if (lookup == "[]=") {
|
||||
std::cout << "as the operator was []= we're returning nullptr now and gonna let our above handle it as seperate ones" << std::endl;
|
||||
//std::cout << "as the operator was []= we're returning nullptr now and gonna let our above handle it as seperate ones" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
newNode = new NodeTree<ASTData>(lookup, ASTData(function_call, Symbol(lookup, true)));
|
||||
NodeTree<ASTData>* function = functionLookup(scope, lookup, mapNodesToTypes(nodes));
|
||||
std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
|
||||
//std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
|
||||
newNode->addChild(function);
|
||||
std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
|
||||
//std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
|
||||
newNode->addChildren(nodes);
|
||||
std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
|
||||
std::cout << "nodes " << nodes.size() << std::endl;
|
||||
//std::cout << "Num of newNode children " << newNode->getChildren().size() << std::endl;
|
||||
//std::cout << "nodes " << nodes.size() << std::endl;
|
||||
|
||||
//Specially handle dereference and address of to assign the correct type
|
||||
//We need some significant other type corrections here, maybe to the point of being their own function. (int + float, etc.)
|
||||
std::cout << "the passed in nodes" << std::endl;
|
||||
for (auto i : nodes)
|
||||
std::cout << i->getDataRef()->toString() << " ";
|
||||
std::cout<<std::endl;
|
||||
//std::cout << "the passed in nodes" << std::endl;
|
||||
//for (auto i : nodes)
|
||||
//std::cout << i->getDataRef()->toString() << " ";
|
||||
//std::cout<<std::endl;
|
||||
|
||||
|
||||
std::vector<Type> oldTypes = mapNodesToTypes(nodes);
|
||||
std::cout << "the oldtypes size" << oldTypes.size() << std::endl;
|
||||
//std::cout << "the oldtypes size" << oldTypes.size() << std::endl;
|
||||
if ((nodes.size() != 2 && lookup == "*") || lookup == "&" || lookup == "[]") {
|
||||
Type* newType = oldTypes[0].clone();
|
||||
if (lookup == "*" || lookup == "[]")
|
||||
@@ -929,9 +987,9 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
|
||||
else
|
||||
newType->increaseIndirection();
|
||||
|
||||
newNode->getDataRef()->valueType = newType, std::cout << "Operator " + lookup << " is altering indirection from " << oldTypes[0].toString() << " to " << newType->toString() << std::endl;
|
||||
newNode->getDataRef()->valueType = newType; //, std::cout << "Operator " + lookup << " is altering indirection from " << oldTypes[0].toString() << " to " << newType->toString() << std::endl;
|
||||
} else {
|
||||
std::cout << "Some other ||" << lookup << "||" << std::endl;
|
||||
//std::cout << "Some other ||" << lookup << "||" << std::endl;
|
||||
if (function->getDataRef()->valueType)
|
||||
newNode->getDataRef()->valueType = function->getDataRef()->valueType->returnType;
|
||||
}
|
||||
@@ -940,7 +998,7 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
|
||||
// It's important that it's the last parameter, the rhs if it has one
|
||||
// because of the . operator, etc
|
||||
if (newNode->getDataRef()->valueType == NULL) {
|
||||
std::cout << "The value type from doFunction was null! (for " << lookup << ")" << std::endl;
|
||||
//std::cout << "The value type from doFunction was null! (for " << lookup << ")" << std::endl;
|
||||
Type* newType = nullptr;
|
||||
if (lookup == "->")
|
||||
newType = oldTypes.back().clone();
|
||||
@@ -954,7 +1012,7 @@ NodeTree<ASTData>* ASTTransformation::doFunction(NodeTree<ASTData>* scope, std::
|
||||
//newType = oldTypes.back().clone();
|
||||
|
||||
newNode->getDataRef()->valueType = newType;
|
||||
std::cout << "function call to " << lookup << " - " << newNode->getName() << " is now " << newNode->getDataRef()->valueType << std::endl;
|
||||
//std::cout << "function call to " << lookup << " - " << newNode->getName() << " is now " << newNode->getDataRef()->valueType << std::endl;
|
||||
}
|
||||
return newNode;
|
||||
}
|
||||
@@ -1019,7 +1077,7 @@ NodeTree<ASTData>* ASTTransformation::functionLookup(NodeTree<ASTData>* scope, s
|
||||
//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()) {
|
||||
std::cout << "found it at language level as reserved word." << std::endl;
|
||||
//std::cout << "found it at language level as reserved word." << std::endl;
|
||||
return LLElementIterator->second[0];
|
||||
}
|
||||
//We search the languageLevelOperators to see if it's an operator. If so, we modifiy the lookup with a preceding "operator"
|
||||
@@ -1033,20 +1091,22 @@ NodeTree<ASTData>* ASTTransformation::functionLookup(NodeTree<ASTData>* scope, s
|
||||
if (possibleMatches.size()) {
|
||||
for (auto i : possibleMatches) {
|
||||
//We're not looking for types
|
||||
if (i->getDataRef()->type == type_def || i->getDataRef()->type == adt_def)
|
||||
//if (i->getDataRef()->type == type_def || i->getDataRef()->type == adt_def)
|
||||
// actually, lets make it we're only looking for things with type function
|
||||
if (i->getDataRef()->valueType->baseType != function_type)
|
||||
continue;
|
||||
Type* functionType = i->getDataRef()->valueType;
|
||||
|
||||
int numTypes = functionType->parameterTypes.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 << functionType->parameterTypes[j]->toString() << " ";
|
||||
std::cout << std::endl;
|
||||
//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 << functionType->parameterTypes[j]->toString() << " ";
|
||||
//std::cout << std::endl;
|
||||
continue;
|
||||
}
|
||||
bool typesMatch = true;
|
||||
@@ -1060,8 +1120,8 @@ NodeTree<ASTData>* ASTTransformation::functionLookup(NodeTree<ASTData>* scope, s
|
||||
// we use test_equality so that we can pass in a false to not care about references
|
||||
if (!types[j].test_equality(*tmpType, false)) {
|
||||
typesMatch = false;
|
||||
std::cout << "Types do not match between two " << lookup << " " << types[j].toString();
|
||||
std::cout << " vs " << tmpType->toString() << std::endl;
|
||||
//std::cout << "Types do not match between two " << lookup << " " << types[j].toString();
|
||||
//std::cout << " vs " << tmpType->toString() << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1070,11 +1130,11 @@ NodeTree<ASTData>* ASTTransformation::functionLookup(NodeTree<ASTData>* scope, s
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "could not find " << lookup << " in standard scopes, checking for operator" << std::endl;
|
||||
//std::cout << "could not find " << lookup << " in standard scopes, checking for operator" << std::endl;
|
||||
//Note that we don't check for types. At some point we should, as we don't know how to add objects/structs without overloaded operators, etc
|
||||
//Also, we've already searched for the element because this is also how we keep track of operator overloading
|
||||
if (LLElementIterator != languageLevelOperators.end()) {
|
||||
std::cout << "found it at language level as operator." << std::endl;
|
||||
//std::cout << "found it at language level as operator." << std::endl;
|
||||
return LLElementIterator->second[0];
|
||||
}
|
||||
std::cout << "Did not find, returning NULL" << std::endl;
|
||||
@@ -1086,7 +1146,7 @@ NodeTree<ASTData>* ASTTransformation::templateClassLookup(NodeTree<ASTData>* sco
|
||||
std::set<NodeTree<ASTData>*> mostFittingTemplates;
|
||||
int bestNumTraitsSatisfied = -1;
|
||||
auto possibleMatches = scopeLookup(scope, lookup);
|
||||
std::cout << "Template Class instantiation has " << possibleMatches.size() << " possible matches." << std::endl;
|
||||
//std::cout << "Template Class instantiation has " << possibleMatches.size() << " possible matches." << std::endl;
|
||||
for (auto i : possibleMatches) {
|
||||
if (i->getDataRef()->type != type_def)
|
||||
continue;
|
||||
@@ -1104,20 +1164,20 @@ NodeTree<ASTData>* ASTTransformation::templateClassLookup(NodeTree<ASTData>* sco
|
||||
// error out if not subset, or if we're a pointer but should have traits
|
||||
if (!subset(j.second, templateInstantiationTypes[typeIndex]->traits) || (templateInstantiationTypes[typeIndex]->getIndirection() && j.second.size())) {
|
||||
traitsEqual = false;
|
||||
std::cout << "Traits not subset for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
|
||||
//std::cout << "Traits not subset for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
|
||||
//std::cout << baseType << " " << indirection << " " << typeDefinition << " " << templateDefinition << " " << traits << ;
|
||||
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << " vs ";
|
||||
std::copy(templateInstantiationTypes[typeIndex]->traits.begin(), templateInstantiationTypes[typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
//std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
//std::cout << " vs ";
|
||||
//std::copy(templateInstantiationTypes[typeIndex]->traits.begin(), templateInstantiationTypes[typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
//std::cout << std::endl;
|
||||
break;
|
||||
} else {
|
||||
std::cout << "Traits ARE subset for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
|
||||
//std::cout << "Traits ARE subset for " << j.first << " and " << templateInstantiationTypes[typeIndex]->toString() << ": ";
|
||||
//std::cout << baseType << " " << indirection << " " << typeDefinition << " " << templateDefinition << " " << traits << ;
|
||||
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << " vs ";
|
||||
std::copy(templateInstantiationTypes[typeIndex]->traits.begin(), templateInstantiationTypes[typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
//std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
//std::cout << " vs ";
|
||||
//std::copy(templateInstantiationTypes[typeIndex]->traits.begin(), templateInstantiationTypes[typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
//std::cout << std::endl;
|
||||
}
|
||||
currentTraitsSatisfied += j.second.size();
|
||||
typeIndex++;
|
||||
@@ -1128,12 +1188,12 @@ NodeTree<ASTData>* ASTTransformation::templateClassLookup(NodeTree<ASTData>* sco
|
||||
//See if this is a better match than the current best
|
||||
if (currentTraitsSatisfied > bestNumTraitsSatisfied) {
|
||||
mostFittingTemplates.clear();
|
||||
std::cout << "Class satisfying " << currentTraitsSatisfied << " beats previous " << bestNumTraitsSatisfied << std::endl;
|
||||
//std::cout << "Class satisfying " << currentTraitsSatisfied << " beats previous " << bestNumTraitsSatisfied << std::endl;
|
||||
bestNumTraitsSatisfied = currentTraitsSatisfied;
|
||||
} else if (currentTraitsSatisfied < bestNumTraitsSatisfied)
|
||||
continue;
|
||||
mostFittingTemplates.insert(i);
|
||||
std::cout << "Current class fits, satisfying " << currentTraitsSatisfied << " traits" << std::endl;
|
||||
//std::cout << "Current class fits, satisfying " << currentTraitsSatisfied << " traits" << std::endl;
|
||||
}
|
||||
if (!mostFittingTemplates.size()) {
|
||||
std::cout << "No template classes fit for " << lookup << "!" << std::endl;
|
||||
@@ -1221,8 +1281,8 @@ void ASTTransformation::unifyType(NodeTree<Symbol> *syntaxType, Type type, std::
|
||||
std::vector<NodeTree<Symbol>*> uninTypeInstTypes = getNodes("type", getNode("template_inst", children));
|
||||
std::vector<NodeTree<Symbol>*> typeInstTypes = getNodes("template_param", getNode("template_dec", typeTemplateDefinition->getChildren()));
|
||||
for (int i = 0; i < uninTypeInstTypes.size(); i++) {
|
||||
std::cout << concatSymbolTree(uninTypeInstTypes[i]) << " : " << origionalType->toString() << " : " << concatSymbolTree(typeInstTypes[i]) << std::endl;
|
||||
std::cout << "which is " << origionalType->templateTypeReplacement[concatSymbolTree(typeInstTypes[i])]->toString() << std::endl;
|
||||
//std::cout << concatSymbolTree(uninTypeInstTypes[i]) << " : " << origionalType->toString() << " : " << concatSymbolTree(typeInstTypes[i]) << std::endl;
|
||||
//std::cout << "which is " << origionalType->templateTypeReplacement[concatSymbolTree(typeInstTypes[i])]->toString() << std::endl;
|
||||
//std::cout << "which is " << *origionalType->templateTypeReplacement[concatSymbolTree(typeInstTypes[i])] << std::endl;
|
||||
unifyType(uninTypeInstTypes[i], *origionalType->templateTypeReplacement[concatSymbolTree(typeInstTypes[i])], templateTypeMap, typeMap);
|
||||
}
|
||||
@@ -1259,10 +1319,10 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
|
||||
for (auto i : possibleMatches) {
|
||||
if (i->getDataRef()->type != function)
|
||||
continue;
|
||||
std::cout << "Possibility " << index++ << std::endl;
|
||||
//std::cout << "Possibility " << index++ << std::endl;
|
||||
NodeTree<Symbol>* templateSyntaxTree = i->getDataRef()->valueType->templateDefinition;
|
||||
if (!templateSyntaxTree) {
|
||||
std::cout << "Not a template, skipping" << std::endl;
|
||||
//std::cout << "Not a template, skipping" << std::endl;
|
||||
continue;
|
||||
}
|
||||
// We have the type map here because we might want to augment it with the typeMap from
|
||||
@@ -1271,15 +1331,15 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
|
||||
// If template instantiation was explicit, use those types. Otherwise, unify to find them
|
||||
if (templateInstantiationTypes->size()) {
|
||||
templateInstantiationTypesPerFunction[i] = *templateInstantiationTypes;
|
||||
std::cout << "passed in types" << std::endl;
|
||||
//std::cout << "passed in types" << std::endl;
|
||||
}else{
|
||||
unifyTemplateFunction(i, types, &templateInstantiationTypesPerFunction[i], typeMap);
|
||||
std::cout << "unified types" << std::endl;
|
||||
//std::cout << "unified types" << std::endl;
|
||||
}
|
||||
std::cout << "TYPES ARE: ";
|
||||
for (Type *a : templateInstantiationTypesPerFunction[i])
|
||||
std::cout << a->toString() << " : ";
|
||||
std::cout << std::endl;
|
||||
//std::cout << "TYPES ARE: ";
|
||||
//for (Type *a : templateInstantiationTypesPerFunction[i])
|
||||
//std::cout << a->toString() << " : ";
|
||||
//std::cout << std::endl;
|
||||
auto nameTraitsPairs = makeTemplateNameTraitPairs(templateSyntaxTree->getChildren()[1]);
|
||||
//Check if sizes match between the placeholder and actual template types
|
||||
if (nameTraitsPairs.size() != templateInstantiationTypesPerFunction[i].size())
|
||||
@@ -1292,18 +1352,18 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
|
||||
// error out if not subset, or if we're a pointer but should have traits
|
||||
if (!subset(j.second, templateInstantiationTypesPerFunction[i][typeIndex]->traits) || (templateInstantiationTypesPerFunction[i][typeIndex]->getIndirection() && j.second.size())) {
|
||||
traitsEqual = false;
|
||||
std::cout << "Traits not a subset for " << j.first << " and " << templateInstantiationTypesPerFunction[i][typeIndex]->toString() << ": |";
|
||||
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << "| vs |";
|
||||
std::copy(templateInstantiationTypesPerFunction[i][typeIndex]->traits.begin(), templateInstantiationTypesPerFunction[i][typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << "|" << std::endl;
|
||||
//std::cout << "Traits not a subset for " << j.first << " and " << templateInstantiationTypesPerFunction[i][typeIndex]->toString() << ": |";
|
||||
//std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
//std::cout << "| vs |";
|
||||
//std::copy(templateInstantiationTypesPerFunction[i][typeIndex]->traits.begin(), templateInstantiationTypesPerFunction[i][typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
//std::cout << "|" << std::endl;
|
||||
break;
|
||||
} else {
|
||||
std::cout << "Traits ARE a subset for " << j.first << " and " << templateInstantiationTypesPerFunction[i][typeIndex]->toString() << ": ";
|
||||
std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << " vs ";
|
||||
std::copy(templateInstantiationTypesPerFunction[i][typeIndex]->traits.begin(), templateInstantiationTypesPerFunction[i][typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
//std::cout << "Traits ARE a subset for " << j.first << " and " << templateInstantiationTypesPerFunction[i][typeIndex]->toString() << ": ";
|
||||
//std::copy(j.second.begin(), j.second.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
//std::cout << " vs ";
|
||||
//std::copy(templateInstantiationTypesPerFunction[i][typeIndex]->traits.begin(), templateInstantiationTypesPerFunction[i][typeIndex]->traits.end(), std::ostream_iterator<std::string>(std::cout, " "));
|
||||
//std::cout << std::endl;
|
||||
}
|
||||
//As we go, build up the typeMap for when we transform the parameters for parameter checking
|
||||
typeMap[j.first] = templateInstantiationTypesPerFunction[i][typeIndex];
|
||||
@@ -1322,11 +1382,11 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
|
||||
bool parameterTypesMatch = true;
|
||||
for (int j = 0; j < functionParameters.size(); j++) {
|
||||
auto paramType = typeFromTypeNode(functionParameters[j]->getChildren()[2], scope, typeMap);
|
||||
std::cout << "Template param type: " << paramType->toString() << " : Needed Type: " << types[j].toString() << std::endl;
|
||||
//std::cout << "Template param type: " << paramType->toString() << " : Needed Type: " << types[j].toString() << std::endl;
|
||||
// use test_equality so we can pass false and not care about references
|
||||
if (!paramType->test_equality(types[j], false)) {
|
||||
parameterTypesMatch = false;
|
||||
std::cout << "Not equal template param: " << paramType->toString() << " : Needed Type actual param: " << types[j].toString() << std::endl;
|
||||
//std::cout << "Not equal template param: " << paramType->toString() << " : Needed Type actual param: " << types[j].toString() << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1335,12 +1395,12 @@ NodeTree<ASTData>* ASTTransformation::templateFunctionLookup(NodeTree<ASTData>*
|
||||
//See if this is a better match than the current best
|
||||
if (currentTraitsSatisfied > bestNumTraitsSatisfied) {
|
||||
mostFittingTemplates.clear();
|
||||
std::cout << "Function satisfying " << currentTraitsSatisfied << " beats previous " << bestNumTraitsSatisfied << std::endl;
|
||||
//std::cout << "Function satisfying " << currentTraitsSatisfied << " beats previous " << bestNumTraitsSatisfied << std::endl;
|
||||
bestNumTraitsSatisfied = currentTraitsSatisfied;
|
||||
} else if (currentTraitsSatisfied < bestNumTraitsSatisfied)
|
||||
continue;
|
||||
mostFittingTemplates.insert(i);
|
||||
std::cout << "Current function fits, satisfying " << currentTraitsSatisfied << " traits" << std::endl;
|
||||
//std::cout << "Current function fits, satisfying " << currentTraitsSatisfied << " traits" << std::endl;
|
||||
}
|
||||
if (!mostFittingTemplates.size()) {
|
||||
std::cout << "No template functions fit for " << lookup << "(";
|
||||
@@ -1383,17 +1443,12 @@ std::map<std::string, Type*> ASTTransformation::makeTemplateFunctionTypeMap(Node
|
||||
std::cout << typePairs.size() << " " << types.size() << std::endl;
|
||||
for (auto i : typePairs) {
|
||||
typeMap[i.first] = types[typeIndex];
|
||||
std::cout << "Mapping " << i.first << " to " << types[typeIndex]->toString() << std::endl;
|
||||
//std::cout << "Mapping " << i.first << " to " << types[typeIndex]->toString() << std::endl;
|
||||
typeIndex++;
|
||||
}
|
||||
return typeMap;
|
||||
}
|
||||
|
||||
// We need recursion protection
|
||||
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules) {
|
||||
return scopeLookup(scope, lookup, includeModules, std::set<NodeTree<ASTData>*>());
|
||||
}
|
||||
|
||||
NodeTree<ASTData>* ASTTransformation::generateThis(NodeTree<ASTData>* scope) {
|
||||
// if we're looking for this, traverse up until we find the declaration of this object and assign it's type to this
|
||||
NodeTree<ASTData>* trans;
|
||||
@@ -1410,9 +1465,14 @@ NodeTree<ASTData>* ASTTransformation::generateThis(NodeTree<ASTData>* scope) {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
// We need recursion protection
|
||||
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules) {
|
||||
return scopeLookup(scope, lookup, includeModules, std::set<NodeTree<ASTData>*>());
|
||||
}
|
||||
|
||||
std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>* scope, std::string lookup, bool includeModules, std::set<NodeTree<ASTData>*> visited) {
|
||||
std::cout << "Scp]|[e looking up " << lookup << std::endl;
|
||||
std::cout << "current: " << scope->getDataRef()->toString() << std::endl;
|
||||
//std::cout << "Scp]|[e looking up " << lookup << std::endl;
|
||||
//std::cout << "current: " << scope->getDataRef()->toString() << std::endl;
|
||||
//for (auto i : scope->getDataRef()->scope)
|
||||
//std::cout << "\t" << i.first << std::endl;
|
||||
//std::cout << i.first << " : " << i.second->toString() << std::endl;
|
||||
@@ -1423,7 +1483,7 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
|
||||
//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()) {
|
||||
std::cout << "found it at language level as reserved word." << std::endl;
|
||||
//std::cout << "found it at language level as reserved word." << std::endl;
|
||||
NodeTree<ASTData>* identifier = LLElementIterator->second[0];
|
||||
if (lookup == "this") {
|
||||
identifier = generateThis(scope);
|
||||
@@ -1437,9 +1497,9 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
|
||||
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;
|
||||
//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;
|
||||
//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());
|
||||
}
|
||||
@@ -1452,7 +1512,7 @@ std::vector<NodeTree<ASTData>*> ASTTransformation::scopeLookup(NodeTree<ASTData>
|
||||
for (auto i : possibleMatches->second)
|
||||
if (includeModules || i->getName() != "translation_unit")
|
||||
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.
|
||||
// If it doesn't we should be at the top of a translation unit, and we should check the scope of import statements.
|
||||
@@ -1551,24 +1611,24 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
||||
//So either this is an uninstatiated template class type, or this is literally a template type T, and we should get it from our
|
||||
//templateTypeReplacements map. We try this first
|
||||
if (templateTypeReplacements.find(edited) != templateTypeReplacements.end()) {
|
||||
std::cout << "Template type! (" << edited << ")" << std::endl;
|
||||
//std::cout << "Template type! (" << edited << ")" << std::endl;
|
||||
Type* templateTypeReplacement = templateTypeReplacements[edited]->clone();
|
||||
templateTypeReplacement->modifyIndirection(indirection);
|
||||
templateTypeReplacement->is_reference = is_reference;
|
||||
return templateTypeReplacement;
|
||||
}
|
||||
std::cout << edited << " was not found in templateTypeReplacements" << std::endl;
|
||||
std::cout << "templateTypeReplacements consists of : ";
|
||||
for (auto i : templateTypeReplacements)
|
||||
std::cout << i.first << " ";
|
||||
std::cout << std::endl;
|
||||
//std::cout << edited << " was not found in templateTypeReplacements" << std::endl;
|
||||
//std::cout << "templateTypeReplacements consists of : ";
|
||||
//for (auto i : templateTypeReplacements)
|
||||
//std::cout << i.first << " ";
|
||||
//std::cout << std::endl;
|
||||
|
||||
std::cout << possibleMatches.size() << " " << typeNode->getChildren().size() << std::endl;
|
||||
if (typeNode->getChildren().size() > 1)
|
||||
std::cout << typeNode->getChildren()[1]->getDataRef()->getName() << std::endl;
|
||||
//std::cout << possibleMatches.size() << " " << typeNode->getChildren().size() << std::endl;
|
||||
//if (typeNode->getChildren().size() > 1)
|
||||
//std::cout << typeNode->getChildren()[1]->getDataRef()->getName() << std::endl;
|
||||
//If not, we better instantiate it and then add it to the highest (not current) scope
|
||||
if (possibleMatches.size() == 0 && typeNode->getChildren().size() > 1 && typeNode->getChildren()[1]->getData().getName() == "template_inst") {
|
||||
std::cout << "Template type: " << edited << " not yet instantiated" << std::endl;
|
||||
//std::cout << "Template type: " << edited << " not yet instantiated" << std::endl;
|
||||
|
||||
//We pull out the replacement types first so that we can choose the correct possibly overloaded template
|
||||
std::vector<NodeTree<Symbol>*> templateParamInstantiationNodes = slice(typeNode->getChildren()[1]->getChildren(), 1, -2, 2); //same
|
||||
@@ -1598,9 +1658,9 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
||||
if (possibleMatches.size()) {
|
||||
typeDefinition = possibleMatches[0];
|
||||
traits = typeDefinition->getDataRef()->valueType->traits;
|
||||
std::cout << "Found already instantiated template of " << templateLookupName << " at second check" << std::endl;
|
||||
//std::cout << "Found already instantiated template of " << templateLookupName << " at second check" << std::endl;
|
||||
} else {
|
||||
std::cout << "Did not find already instantiated template of " << templateLookupName << " at second check" << std::endl;
|
||||
//std::cout << "Did not find already instantiated template of " << templateLookupName << " at second check" << std::endl;
|
||||
//Look up this template's plain definition. It's type has the syntax tree that we need to parse
|
||||
NodeTree<ASTData>* templateDefinition = templateClassLookup(scope, concatSymbolTree(typeNode->getChildren()[0]), templateParamInstantiationTypes);
|
||||
|
||||
@@ -1626,9 +1686,9 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
||||
|
||||
// Actually, let's just put it in the scope of the origional template, which should work just fine under the new scoping rules and will ACTUALLY prevent multiple instantiation.
|
||||
// At least, hopefully it will if we also check it's scope for it. Which I think it should be anyway. Yeah, I think it should work.
|
||||
std::cout << "Adding to template top scope and template's origional scope with fullyInstantiatedName " << fullyInstantiatedName << std::endl;
|
||||
//std::cout << "Adding to template top scope and template's origional scope with fullyInstantiatedName " << fullyInstantiatedName << std::endl;
|
||||
auto templateTopScope = getUpperTranslationUnit(templateDefinition);
|
||||
std::cout << "UPPER TRANS for " << fullyInstantiatedName << " " << templateTopScope->getDataRef()->toString() << std::endl;
|
||||
//std::cout << "UPPER TRANS for " << fullyInstantiatedName << " " << templateTopScope->getDataRef()->toString() << std::endl;
|
||||
templateTopScope->getDataRef()->scope[fullyInstantiatedName].push_back(typeDefinition);
|
||||
templateTopScope->addChild(typeDefinition); // Add this object the the highest scope's
|
||||
|
||||
@@ -1647,22 +1707,22 @@ Type* ASTTransformation::typeFromTypeNode(NodeTree<Symbol>* typeNode, NodeTree<A
|
||||
// deferred method allowing us to correctly instantiate multiple levels of mututally recursive definitions.
|
||||
selfType->templateDefinition = templateSyntaxTree; //We're going to still need this when we finish instantiating
|
||||
selfType->templateTypeReplacement = newTemplateTypeReplacement; //Save the types for use when this is fully instantiated in pass 4
|
||||
for (auto daPair : selfType->templateTypeReplacement) {
|
||||
std::cout << " BREAK HERE " << daPair.first << " : " << daPair.second->toString() << std::endl;
|
||||
if (daPair.second == NULL)
|
||||
std::cout << " BREAK HERE " << std::endl;
|
||||
}
|
||||
//for (auto daPair : selfType->templateTypeReplacement) {
|
||||
//std::cout << " BREAK HERE " << daPair.first << " : " << daPair.second->toString() << std::endl;
|
||||
//if (daPair.second == NULL)
|
||||
//std::cout << " BREAK HERE " << std::endl;
|
||||
//}
|
||||
secondPassDoClassInsides(typeDefinition, templateSyntaxTree->getChildren(), newTemplateTypeReplacement); //Use these types when instantiating data members
|
||||
}
|
||||
} else if (possibleMatches.size() == 0) {
|
||||
std::cout << "Could not find type " << edited << ", returning NULL" << std::endl;
|
||||
return NULL;
|
||||
} else {
|
||||
std::cout << "Type: " << edited << " already instantiated with " << typeDefinition << ", will be " << Type(baseType, typeDefinition, indirection, is_reference, traits).toString() << std::endl;
|
||||
//std::cout << "Type: " << edited << " already instantiated with " << typeDefinition << ", will be " << Type(baseType, typeDefinition, indirection, is_reference, traits).toString() << std::endl;
|
||||
}
|
||||
}
|
||||
Type* toReturn = new Type(baseType, typeDefinition, indirection, is_reference, traits);
|
||||
std::cout << "Returning type " << toReturn->toString() << std::endl;
|
||||
//std::cout << "Returning type " << toReturn->toString() << std::endl;
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@@ -1683,7 +1743,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
|
||||
}
|
||||
NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::string functionName, std::vector<NodeTree<Symbol>*> children, NodeTree<ASTData>* scope, std::vector<Type> types, std::map<std::string, Type*> templateTypeReplacements) {
|
||||
//First look to see if we can find this already instantiated
|
||||
std::cout << "\n\nFinding or instantiating templated function\n\n" << std::endl;
|
||||
//std::cout << "\n\nFinding or instantiating templated function\n\n" << std::endl;
|
||||
if (children.size())
|
||||
functionName = concatSymbolTree(children[0]);
|
||||
std::string fullyInstantiatedName;
|
||||
@@ -1720,27 +1780,27 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
|
||||
instTypeString += (instTypeString == "" ? instType->toString() : "," + instType->toString());
|
||||
templateActualTypes.push_back(instType);
|
||||
}
|
||||
std::cout << "Size: " << templateParamInstantiationNodes.size() << std::endl;
|
||||
//std::cout << "Size: " << templateParamInstantiationNodes.size() << std::endl;
|
||||
}
|
||||
fullyInstantiatedName = functionName + "<" + instTypeString + ">";
|
||||
std::cout << "Looking for " << fullyInstantiatedName << std::endl;
|
||||
std::cout << "Types are : ";
|
||||
for (auto i : types)
|
||||
std::cout << " " << i.toString();
|
||||
std::cout << std::endl;
|
||||
//std::cout << "Looking for " << fullyInstantiatedName << std::endl;
|
||||
//std::cout << "Types are : ";
|
||||
//for (auto i : types)
|
||||
//std::cout << " " << i.toString();
|
||||
//std::cout << std::endl;
|
||||
|
||||
NodeTree<ASTData>* instantiatedFunction = functionLookup(scope, fullyInstantiatedName, types);
|
||||
//If it already exists, return it
|
||||
if (instantiatedFunction) {
|
||||
std::cout << fullyInstantiatedName << " already exists! Returning" << std::endl;
|
||||
//std::cout << fullyInstantiatedName << " already exists! Returning" << std::endl;
|
||||
return instantiatedFunction;
|
||||
} else {
|
||||
instantiatedFunction = functionLookup(topScope, fullyInstantiatedName, types);
|
||||
if (instantiatedFunction) {
|
||||
std::cout << fullyInstantiatedName << "already exists! Found in TopScope" << std::endl;
|
||||
//std::cout << fullyInstantiatedName << "already exists! Found in TopScope" << std::endl;
|
||||
return instantiatedFunction;
|
||||
}
|
||||
std::cout << fullyInstantiatedName << " does NOT exist" << std::endl;
|
||||
//std::cout << fullyInstantiatedName << " does NOT exist" << std::endl;
|
||||
}
|
||||
|
||||
//Otherwise, we're going to instantiate it
|
||||
@@ -1751,7 +1811,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
|
||||
if (!templateDefinition)
|
||||
templateDefinition = templateFunctionLookup(scope, functionName, &templateActualTypes, types, scopeTypeMap);
|
||||
if (templateDefinition == NULL) {
|
||||
std::cout << functionName << " search turned up null, returing null" << std::endl;
|
||||
//std::cout << functionName << " search turned up null, returing null" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
scopelessFullyInstantiatedName = templateDefinition->getDataRef()->symbol.getName() + "<" + instTypeString + ">";
|
||||
@@ -1761,9 +1821,9 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
|
||||
std::map<std::string, Type*> newTemplateTypeReplacement = makeTemplateFunctionTypeMap(templateSyntaxTree->getChildren()[1], templateActualTypes, scopeTypeMap);
|
||||
|
||||
std::vector<NodeTree<Symbol>*> templateChildren = templateSyntaxTree->getChildren();
|
||||
for (int i = 0; i < templateChildren.size(); i++)
|
||||
std::cout << ", " << i << " : " << templateChildren[i]->getDataRef()->getName();
|
||||
std::cout << std::endl;
|
||||
//for (int i = 0; i < templateChildren.size(); i++)
|
||||
//std::cout << ", " << i << " : " << templateChildren[i]->getDataRef()->getName();
|
||||
//std::cout << std::endl;
|
||||
|
||||
// return type should be looked up in template's scope
|
||||
auto returnTypeNode = getNode("type", getNode("typed_return", templateChildren)); // if null, the typed_return had no children and we're supposed to automatically do a void type
|
||||
@@ -1773,7 +1833,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
|
||||
addToScope(scopelessFullyInstantiatedName, instantiatedFunction, templateDefinition->getDataRef()->scope["~enclosing_scope"][0]);
|
||||
templateDefinition->getDataRef()->scope["~enclosing_scope"][0]->addChild(instantiatedFunction); // Add this object the the highest scope's
|
||||
|
||||
std::cout << "About to do children of " << functionName << " to " << fullyInstantiatedName << std::endl;
|
||||
//std::cout << "About to do children of " << functionName << " to " << fullyInstantiatedName << std::endl;
|
||||
|
||||
std::set<int> skipChildren;
|
||||
auto parameters = transformChildren(getNodes("typed_parameter", templateSyntaxTree->getChildren()), skipChildren, instantiatedFunction, std::vector<Type>(), false, newTemplateTypeReplacement);
|
||||
@@ -1782,7 +1842,7 @@ NodeTree<ASTData>* ASTTransformation::findOrInstantiateFunctionTemplate(std::str
|
||||
instantiatedFunction->getDataRef()->valueType = new Type(mapNodesToTypePointers(parameters), instantiatedFunction->getDataRef()->valueType);
|
||||
instantiatedFunction->addChild(transform(getNode("statement", templateSyntaxTree->getChildren()), instantiatedFunction, std::vector<Type>(), false, newTemplateTypeReplacement));
|
||||
|
||||
std::cout << "Fully Instantiated function " << functionName << " to " << fullyInstantiatedName << std::endl;
|
||||
//std::cout << "Fully Instantiated function " << functionName << " to " << fullyInstantiatedName << std::endl;
|
||||
return instantiatedFunction;
|
||||
}
|
||||
|
||||
@@ -1796,7 +1856,7 @@ NodeTree<ASTData>* ASTTransformation::addToScope(std::string name, NodeTree<ASTD
|
||||
std::vector<Type*> mapNodesToTypePointers(std::vector<NodeTree<ASTData>*> nodes) {
|
||||
std::vector<Type*> types;
|
||||
for (auto i : nodes) {
|
||||
std::cout << i->getDataRef()->toString() << std::endl;
|
||||
//std::cout << i->getDataRef()->toString() << std::endl;
|
||||
types.push_back((i->getDataRef()->valueType));
|
||||
}
|
||||
return types;
|
||||
@@ -1806,7 +1866,7 @@ std::vector<Type*> mapNodesToTypePointers(std::vector<NodeTree<ASTData>*> nodes)
|
||||
std::vector<Type> mapNodesToTypes(std::vector<NodeTree<ASTData>*> nodes) {
|
||||
std::vector<Type> types;
|
||||
for (auto i : nodes) {
|
||||
std::cout << i->getDataRef()->toString() << std::endl;
|
||||
//std::cout << i->getDataRef()->toString() << std::endl;
|
||||
types.push_back(*(i->getDataRef()->valueType));
|
||||
}
|
||||
return types;
|
||||
|
||||
@@ -17,19 +17,22 @@ void CGenerator::generateCompSet(std::map<std::string, NodeTree<ASTData>*> ASTs,
|
||||
std::cout << "\n\n =====GENERATE PASS===== \n\n" << std::endl;
|
||||
std::cout << "\n\nGenerate pass for: " << outputName << std::endl;
|
||||
buildString += outputName + ".c ";
|
||||
std::ofstream outputCFile, outputHFile;
|
||||
//std::ofstream outputCFile, outputHFile;
|
||||
std::ofstream outputCFile;
|
||||
outputCFile.open(outputName + "/" + outputName + ".c");
|
||||
outputHFile.open(outputName + "/" + outputName + ".h");
|
||||
if (outputCFile.is_open() || outputHFile.is_open()) {
|
||||
//outputHFile.open(outputName + "/" + outputName + ".h");
|
||||
//if (outputCFile.is_open() || outputHFile.is_open()) {
|
||||
if (outputCFile.is_open()) {
|
||||
// Prequel common to all files
|
||||
auto chPair = generateTranslationUnit(outputName, ASTs);
|
||||
outputHFile << "#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n" << chPair.first;
|
||||
outputCFile << "#include \"" + outputName + ".h\"\n\n" << chPair.second;
|
||||
//outputHFile << "#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n" << chPair.first;
|
||||
//outputCFile << "#include \"" + outputName + ".h\"\n\n" << chPair.second;
|
||||
outputCFile << "#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n" << chPair.first << "\n\n// C FILE BEGIN\n\n" << chPair.second;
|
||||
} else {
|
||||
std::cerr << "Cannot open file " << outputName << ".c/h" << std::endl;
|
||||
}
|
||||
outputCFile.close();
|
||||
outputHFile.close();
|
||||
//outputHFile.close();
|
||||
|
||||
buildString += linkerString;
|
||||
buildString += "-o " + outputName;
|
||||
@@ -54,21 +57,84 @@ std::string CGenerator::getID() {
|
||||
std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
|
||||
auto data = from->getData();
|
||||
auto children = from->getChildren();
|
||||
std::string objectString;
|
||||
if (data.type == type_def)
|
||||
objectString = "struct __struct_dummy_";
|
||||
else if (data.type == adt_def)
|
||||
objectString = "enum __adt_dummy_";
|
||||
objectString += scopePrefix(from) + CifyName(data.symbol.getName()) + "__ {\n";
|
||||
std::string structString, enumString, functionString;
|
||||
std::string enumName = "__enum_dummy_" + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())+"__");
|
||||
enumString = "enum " + enumName + " {\n";
|
||||
structString = "struct __struct_dummy_";
|
||||
structString += prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())+"__") + " {\n";
|
||||
if (data.type == adt_def) {
|
||||
structString = "typedef " + structString + " enum " + enumName + " flag;\n union { \n";
|
||||
tabLevel++;
|
||||
for (int i = (data.type == adt_def ? 1 : 0); i < children.size(); i++) {
|
||||
}
|
||||
tabLevel++;
|
||||
|
||||
for (auto child : children) {
|
||||
//std::cout << children[i]->getName() << std::endl;
|
||||
if (children[i]->getName() != "function")
|
||||
objectString += tabs() + generate(children[i], nullptr).oneString() + (data.type == adt_def ? ",\n" : "\n");
|
||||
if (child->getName() != "function") {
|
||||
if (data.type == adt_def) {
|
||||
// if this is not a plain no-data adt member (so if it is a primitive or doesn't have a reference back to)
|
||||
// wait a sec, this is easier
|
||||
if ( child->getDataRef()->valueType->typeDefinition != from)
|
||||
structString += tabs() + ValueTypeToCType(child->getDataRef()->valueType, child->getDataRef()->symbol.getName()) + "; /* adt data member */\n";
|
||||
} else {
|
||||
structString += tabs() + generate(child, nullptr).oneString() + "\n";
|
||||
}
|
||||
enumString += tabs() + generate(child, nullptr).oneString() + (data.type == adt_def ? ",\n" : "\n");
|
||||
} else {
|
||||
if (data.type == adt_def) {
|
||||
std::string orig_fun_name = child->getDataRef()->symbol.getName();
|
||||
std::string fun_name;
|
||||
std::string first_param;
|
||||
if (orig_fun_name == "operator==" || orig_fun_name == "operator!=") {
|
||||
fun_name = "fun_" + data.symbol.getName() + "__" + CifyName(orig_fun_name);
|
||||
first_param = ValueTypeToCType(child->getDataRef()->valueType->parameterTypes[0]->withIncreasedIndirectionPtr(), "this") + ", ";
|
||||
} else {
|
||||
fun_name = "fun_" + orig_fun_name;
|
||||
}
|
||||
bool has_param = child->getDataRef()->valueType->parameterTypes.size();
|
||||
functionString += "\n" + ValueTypeToCType(child->getDataRef()->valueType->returnType, fun_name) + "(" + first_param +
|
||||
(has_param ? ValueTypeToCType(child->getDataRef()->valueType->parameterTypes[0], "in") : "") + ") { /*adt func*/\n";
|
||||
if (orig_fun_name == "operator==") {
|
||||
functionString += " /* equality woop woop */\n";
|
||||
functionString += " if (this->flag != in.flag) return false;\n";
|
||||
|
||||
for (auto child : children) {
|
||||
if (child->getName() != "function" && child->getDataRef()->valueType->typeDefinition != from) {
|
||||
std::string option_name = child->getDataRef()->symbol.getName();
|
||||
functionString += " if (this->flag == " + option_name + ")\n";
|
||||
functionString += " return this->" + option_name + " == in." + option_name + ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
functionString += " return true;\n";
|
||||
} else if (orig_fun_name == "operator!=") {
|
||||
functionString += " /* inequality woop woop */\n";
|
||||
functionString += " return !fun_" + data.symbol.getName() + "__" + CifyName("operator==") + "(this, in);\n";
|
||||
} else {
|
||||
// ok, is a constructor function
|
||||
functionString += " /* constructor woop woop */\n";
|
||||
functionString += " " + data.symbol.getName() + " toRet;\n";
|
||||
functionString += " toRet.flag = " + orig_fun_name + ";\n";
|
||||
if (has_param)
|
||||
functionString += " toRet." + orig_fun_name + " = in;\n";
|
||||
functionString += " return toRet;\n";
|
||||
}
|
||||
functionString += "}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
tabLevel--;
|
||||
objectString += "};";
|
||||
return objectString;
|
||||
if (data.type == adt_def) {
|
||||
//structString += "} data; /*end union*/ \n";
|
||||
tabLevel--;
|
||||
structString += " }; /*end union*/\n} " + CifyName(data.symbol.getName()) + "; /* end struct */";
|
||||
} else {
|
||||
structString += "};";
|
||||
}
|
||||
enumString += "};\n";
|
||||
if (data.type == adt_def)
|
||||
return enumString + structString + functionString;
|
||||
return structString;
|
||||
}
|
||||
|
||||
// This method recurseivly generates all aliases of some definition
|
||||
@@ -82,8 +148,8 @@ std::string CGenerator::generateAliasChains(std::map<std::string, NodeTree<ASTDa
|
||||
&& declarationData->valueType->typeDefinition != declaration
|
||||
&& declarationData->valueType->typeDefinition == definition) {
|
||||
output += "typedef " +
|
||||
scopePrefix(definition) + CifyName(definition->getDataRef()->symbol.getName()) + " " +
|
||||
scopePrefix(declaration) + CifyName(declarationData->symbol.getName()) + ";\n";
|
||||
prefixIfNeeded(scopePrefix(definition), CifyName(definition->getDataRef()->symbol.getName())) + " " +
|
||||
prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData->symbol.getName())) + ";\n";
|
||||
// Recursively add the ones that depend on this one
|
||||
output += generateAliasChains(ASTs, declaration);
|
||||
}
|
||||
@@ -93,6 +159,17 @@ std::string CGenerator::generateAliasChains(std::map<std::string, NodeTree<ASTDa
|
||||
return output;
|
||||
}
|
||||
|
||||
bool CGenerator::isUnderNodeWithType(NodeTree<ASTData>* from, ASTType type) {
|
||||
auto scope = from->getDataRef()->scope;
|
||||
auto upper = scope.find("~enclosing_scope");
|
||||
if (upper != scope.end()) {
|
||||
if (upper->second[0]->getDataRef()->type == type)
|
||||
return true;
|
||||
return isUnderNodeWithType(upper->second[0], type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CGenerator::isUnderTranslationUnit(NodeTree<ASTData>* from, NodeTree<ASTData>* node) {
|
||||
auto scope = from->getDataRef()->scope;
|
||||
for (auto i : scope)
|
||||
@@ -195,7 +272,7 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
||||
{
|
||||
auto parent = declaration->getDataRef()->scope["~enclosing_scope"][0];
|
||||
if (parent->getChildren().size() == 1)
|
||||
variableDeclarations += ValueTypeToCType(declarationData.valueType, scopePrefix(declaration) + declarationData.symbol.getName()) + "; /*identifier*/\n";
|
||||
variableDeclarations += ValueTypeToCType(declarationData.valueType, prefixIfNeeded(scopePrefix(declaration), declarationData.symbol.getName())) + "; /*identifier*/\n";
|
||||
else
|
||||
variableDeclarations += ValueTypeToCType(declarationData.valueType, generate(parent->getChildren()[0], nullptr, true, nullptr).oneString()) + " = " + generate(parent->getChildren()[1], nullptr, true, nullptr).oneString() + ";";
|
||||
variableExternDeclarations += "extern " + ValueTypeToCType(declarationData.valueType, declarationData.symbol.getName()) + "; /*extern identifier*/\n";
|
||||
@@ -217,12 +294,11 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
||||
parameters += ValueTypeToCType(decChildren[j]->getData().valueType, generate(decChildren[j], nullptr).oneString());
|
||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(decChildren[j]->getData().valueType);
|
||||
}
|
||||
functionPrototypes += "\n" + ValueTypeToCType(declarationData.valueType->returnType, ((declarationData.symbol.getName() == "main") ? "" : function_header + scopePrefix(declaration)) +
|
||||
CifyName(declarationData.symbol.getName() + nameDecoration)) +
|
||||
"(" + parameters + "); /*func*/\n";
|
||||
std::string funName = (declarationData.symbol.getName() == "main") ? "main" :
|
||||
function_header + prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName() + nameDecoration));
|
||||
functionPrototypes += "\n" + ValueTypeToCType(declarationData.valueType->returnType, funName) + "(" + parameters + "); /*func*/\n";
|
||||
// generate function
|
||||
std::cout << "Generating " << scopePrefix(declaration) +
|
||||
CifyName(declarationData.symbol.getName()) << std::endl;
|
||||
//std::cout << "Generating " << prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())) << std::endl;
|
||||
functionDefinitions += generate(declaration, nullptr).oneString();
|
||||
}
|
||||
}
|
||||
@@ -238,18 +314,17 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
||||
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,
|
||||
scopePrefix(declaration) +
|
||||
CifyName(declarationData.symbol.getName())) + ";\n";
|
||||
prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName()))) + ";\n";
|
||||
plainTypedefs += generateAliasChains(ASTs, declaration);
|
||||
} else {
|
||||
plainTypedefs += "typedef struct __struct_dummy_" +
|
||||
scopePrefix(declaration) + CifyName(declarationData.symbol.getName()) + "__ " +
|
||||
scopePrefix(declaration) + CifyName(declarationData.symbol.getName()) + ";\n";
|
||||
prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName()) + "__") + " " +
|
||||
prefixIfNeeded(scopePrefix(declaration), 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;
|
||||
//std::cout << decChildren[j]->getName() << std::endl;
|
||||
if (decChildren[j]->getName() == "function"
|
||||
&& decChildren[j]->getDataRef()->valueType->baseType != template_type) //If object method and not template
|
||||
objectFunctionDefinitions += generateObjectMethod(declaration, decChildren[j], &functionPrototypes) + "\n";
|
||||
@@ -264,19 +339,15 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
||||
case adt_def:
|
||||
{
|
||||
//type
|
||||
plainTypedefs += "/* adt " + declarationData.symbol.getName() + " */\n";
|
||||
//plainTypedefs += "typedef struct __adt_dummy_" +
|
||||
plainTypedefs += "typedef enum __adt_dummy_" +
|
||||
scopePrefix(declaration) + CifyName(declarationData.symbol.getName()) + "__ " +
|
||||
scopePrefix(declaration) + CifyName(declarationData.symbol.getName()) + ";\n";
|
||||
// We use a seperate string for this because we only include it if this is the file we're defined in
|
||||
std::string enumString = "/* Enum Definition for " + declarationData.symbol.getName() + " */\n";
|
||||
// skip the name of the thing
|
||||
for (int j = 1; j < decChildren.size(); j++) {
|
||||
std::cout << decChildren[j]->getName() << std::endl;
|
||||
if (decChildren[j]->getName() == "identifier") //If object method and not template
|
||||
enumString += "an_option \n";
|
||||
}
|
||||
//don't even need to do this anymore, it's all earlier
|
||||
//plainTypedefs += "/* adt " + declarationData.symbol.getName() + " */\n";
|
||||
//plainTypedefs += "typedef struct __struct_dummy_" +
|
||||
//prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())+ "__") + " " +
|
||||
//prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())) + ";\n";
|
||||
//// skip the name of the thing
|
||||
//for (int j = 1; j < decChildren.size(); j++) {
|
||||
//std::cout << decChildren[j]->getName() << std::endl;
|
||||
//}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -320,7 +391,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
// first, get declaring function, if it exists
|
||||
if (enclosingFunction) {
|
||||
if (enclosingFunction->getDataRef()->closedVariables.size()) {
|
||||
std::cout << "WHOH IS A CLOSER" << std::endl;
|
||||
//std::cout << "WHOH IS A CLOSER" << std::endl;
|
||||
if (enclosingFunction->getDataRef()->closedVariables.find(from) != enclosingFunction->getDataRef()->closedVariables.end()) {
|
||||
preName += "(*closed_variables->";
|
||||
postName += ")";
|
||||
@@ -344,8 +415,8 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
preName += "(*";
|
||||
postName += ")";
|
||||
}
|
||||
// we're scope prefixing EVERYTHING
|
||||
return preName + scopePrefix(from) + CifyName(data.symbol.getName()) + postName; //Cifying does nothing if not an operator overload
|
||||
// we're scope prefixing EVERYTHING, but only if needed
|
||||
return preName + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())) + postName; //Cifying does nothing if not an operator overload
|
||||
}
|
||||
case function:
|
||||
{
|
||||
@@ -370,7 +441,8 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
if (justFuncName) {
|
||||
std::string funcName;
|
||||
if (data.symbol.getName() != "main")
|
||||
funcName += function_header + scopePrefix(from);
|
||||
funcName += function_header + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName() + nameDecoration));
|
||||
else
|
||||
funcName += CifyName(data.symbol.getName() + nameDecoration);
|
||||
if (from->getDataRef()->closedVariables.size()) {
|
||||
std::string tmpStruct = "closureStruct" + getID();
|
||||
@@ -384,7 +456,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
std::string preName;
|
||||
if (enclosingObject && enclosingObject->getDataRef()->scope.find(varName) != enclosingObject->getDataRef()->scope.end())
|
||||
preName += "this->";
|
||||
varName = (varName == "this") ? varName : scopePrefix(var) + varName;
|
||||
varName = (varName == "this") ? varName : prefixIfNeeded(scopePrefix(var), varName);
|
||||
// so that we can close over things that have been closed over by an enclosing closure
|
||||
output.preValue += "." + varName + " = &/*woo*/" + generate(var, enclosingObject, justFuncName, enclosingFunction).oneString() + "/*woo*/";
|
||||
//output.preValue += "." + varName + " = &" + preName + varName;
|
||||
@@ -396,8 +468,9 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
}
|
||||
} else {
|
||||
// Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock
|
||||
output = "\n" + ValueTypeToCType(data.valueType->returnType, ((data.symbol.getName() == "main") ? "" : function_header + scopePrefix(from)) +
|
||||
CifyName(data.symbol.getName() + nameDecoration)) + "(" + parameters + ") {\n" + generate(children[children.size()-1], enclosingObject, justFuncName, from).oneString();
|
||||
std::string funName = (data.symbol.getName() == "main") ? "main" : function_header + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName() + nameDecoration));
|
||||
output = "\n" + ValueTypeToCType(data.valueType->returnType, funName) + "(" + parameters + ") {\n" +
|
||||
generate(children[children.size()-1], enclosingObject, justFuncName, from).oneString();
|
||||
output += emitDestructors(reverse(distructDoubleStack.back()), enclosingObject);
|
||||
output += "}\n";
|
||||
}
|
||||
@@ -453,6 +526,35 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
if (children.size() > 2)
|
||||
output += " else { " + generate(children[2], enclosingObject, justFuncName, enclosingFunction).oneString() + " }";
|
||||
return output;
|
||||
case match_statement:
|
||||
{
|
||||
output += "/* match_statement */\n";
|
||||
CCodeTriple thingToMatch = generate(children[0], enclosingObject, false, enclosingFunction);
|
||||
output.preValue += thingToMatch.preValue;
|
||||
output.postValue += thingToMatch.postValue;
|
||||
for (auto case_stmt : slice(children, 1, -1)) {
|
||||
auto case_children = case_stmt->getChildren();
|
||||
std::string option = generate(case_children[0], enclosingObject, false, enclosingFunction).oneString();
|
||||
output += "/* case " + option + " if " + thingToMatch.value + " */\n";
|
||||
output += tabs() + "if (" + thingToMatch.value + ".flag == " + option + ") {\n";
|
||||
tabLevel++;
|
||||
if (case_children.size() > 2) {
|
||||
output += tabs() + ValueTypeToCType(case_children[1]->getData().valueType, generate(case_children[1], enclosingObject, false, enclosingFunction).oneString())
|
||||
+ " = " + thingToMatch.value + "." + option + ";\n";
|
||||
output += generate(case_children[2], enclosingObject, false, enclosingFunction).oneString();
|
||||
} else {
|
||||
output += generate(case_children[1], enclosingObject, false, enclosingFunction).oneString();
|
||||
}
|
||||
tabLevel--;
|
||||
output += "}\n";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
break;
|
||||
case case_statement:
|
||||
output += "/* case_statement */";
|
||||
throw "case statement isn't actually used, but is generated in match";
|
||||
break;
|
||||
case while_loop:
|
||||
{
|
||||
// we push on a new vector to hold while stuff that might need a destructor call
|
||||
@@ -615,6 +717,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
return CCodeTriple("");
|
||||
case simple_passthrough:
|
||||
{
|
||||
std::string pre_end_dec, end_assign;
|
||||
// Stuff is bit more interesting now! XXX
|
||||
std::string pre_passthrough, post_passthrough;
|
||||
// Handle input/output parameters
|
||||
@@ -623,17 +726,27 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
for (auto in_or_out : optParamAssignLists) {
|
||||
for (auto assign : in_or_out->getChildren()) {
|
||||
auto assignChildren = assign->getChildren();
|
||||
if (in_or_out->getDataRef()->type == in_passthrough_params)
|
||||
if (in_or_out->getDataRef()->type == in_passthrough_params) {
|
||||
std::string currentName = generate(assignChildren[0], enclosingObject, enclosingFunction).oneString();
|
||||
std::string toName;
|
||||
if (assignChildren.size() == 2)
|
||||
pre_passthrough += ValueTypeToCType(assignChildren[0]->getDataRef()->valueType, assignChildren[1]->getDataRef()->symbol.getName()) + " = " + generate(assignChildren[0], enclosingObject, enclosingFunction).oneString() + ";\n";
|
||||
toName = assignChildren[1]->getDataRef()->symbol.getName();
|
||||
else
|
||||
pre_passthrough += ValueTypeToCType(assignChildren[0]->getDataRef()->valueType, assignChildren[0]->getDataRef()->symbol.getName()) + " = " + generate(assignChildren[0], enclosingObject, enclosingFunction).oneString() + ";\n";
|
||||
else if (in_or_out->getDataRef()->type == out_passthrough_params)
|
||||
toName = assignChildren[0]->getDataRef()->symbol.getName();
|
||||
if (currentName != toName)
|
||||
pre_passthrough += ValueTypeToCType(assignChildren[0]->getDataRef()->valueType, toName) + " = " + currentName + ";\n";
|
||||
} else if (in_or_out->getDataRef()->type == out_passthrough_params) {
|
||||
std::string currentName = generate(assignChildren[0], enclosingObject, justFuncName, enclosingFunction).oneString();
|
||||
std::string toName;
|
||||
if (assignChildren.size() == 2)
|
||||
post_passthrough += generate(assignChildren[0], enclosingObject, justFuncName, enclosingFunction).oneString() + " = " + assignChildren[1]->getDataRef()->symbol.getName() + ";\n";
|
||||
else
|
||||
post_passthrough += generate(assignChildren[0], enclosingObject, justFuncName, enclosingFunction).oneString() + " = " + assignChildren[0]->getDataRef()->symbol.getName() + ";\n";
|
||||
toName = assignChildren[1]->getDataRef()->symbol.getName();
|
||||
else
|
||||
toName += assignChildren[0]->getDataRef()->symbol.getName();
|
||||
std::string trans_dec_name = currentName + "_end_assign";
|
||||
pre_end_dec += ValueTypeToCType(assignChildren[0]->getDataRef()->valueType, trans_dec_name) + ";\n";
|
||||
post_passthrough += trans_dec_name + " = " + toName + ";\n";
|
||||
end_assign += currentName + " = " + trans_dec_name + ";\n";
|
||||
} else
|
||||
linkerString += " " + strSlice(generate(in_or_out, enclosingObject, justFuncName, enclosingFunction).oneString(), 1, -2) + " ";
|
||||
}
|
||||
}
|
||||
@@ -641,8 +754,11 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
// The actual passthrough string is the last child now, as we might
|
||||
// have passthrough_params be the first child
|
||||
// we don't generate, as that will escape the returns and we don't want that. We'll just grab the string
|
||||
//return pre_passthrough + strSlice(generate(children.back(, enclosingFunction), enclosingObject, justFuncName).oneString(), 3, -4) + post_passthrough;
|
||||
return pre_passthrough + strSlice(children.back()->getDataRef()->symbol.getName(), 3, -4) + post_passthrough;
|
||||
// we don't want the scope stuff if we're at top level for an include, etc....
|
||||
if (isUnderNodeWithType(from,function))
|
||||
return pre_end_dec + "{" + pre_passthrough + strSlice(children.back()->getDataRef()->symbol.getName(), 3, -4) + post_passthrough + "}\n" + end_assign;
|
||||
else
|
||||
return strSlice(children.back()->getDataRef()->symbol.getName(), 3, -4);
|
||||
}
|
||||
case function_call:
|
||||
{
|
||||
@@ -704,7 +820,7 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
for (int i = 0; i < (functionDefChildren.size() > 0 ? functionDefChildren.size()-1 : 0); i++)
|
||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(functionDefChildren[i]->getData().valueType);
|
||||
// Note that we only add scoping to the object, as this specifies our member function too
|
||||
/*HERE*/ return function_header + scopePrefix(unaliasedTypeDef) + CifyName(unaliasedTypeDef->getDataRef()->symbol.getName()) +"__" +
|
||||
/*HERE*/ return function_header + prefixIfNeeded(scopePrefix(unaliasedTypeDef), CifyName(unaliasedTypeDef->getDataRef()->symbol.getName())) +"__" +
|
||||
CifyName(functionName + nameDecoration) + "(" + (name == "." ? "&" : "") + generate(children[1], enclosingObject, true, enclosingFunction) + ",";
|
||||
//The comma lets the upper function call know we already started the param list
|
||||
//Note that we got here from a function call. We just pass up this special case and let them finish with the perentheses
|
||||
@@ -746,11 +862,11 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
||||
//Check to see if we're inside of an object and this is a method call
|
||||
bool isSelfObjectMethod = enclosingObject && contains(enclosingObject->getChildren(), children[0]);
|
||||
if (isSelfObjectMethod) {
|
||||
output += function_header + scopePrefix(children[0]) + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__";
|
||||
output += function_header + prefixIfNeeded(scopePrefix(children[0]), CifyName(enclosingObject->getDataRef()->symbol.getName())) +"__";
|
||||
output += CifyName(name + nameDecoration) + "(";
|
||||
output += std::string(addClosedOver ? "(*closed_variables->this)" : "this") + (children.size() > 1 ? "," : "");
|
||||
} else {
|
||||
output += function_header + scopePrefix(children[0]) + CifyName(name + nameDecoration) + "(";
|
||||
output += function_header + prefixIfNeeded(scopePrefix(children[0]), CifyName(name + nameDecoration)) + "(";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -877,8 +993,9 @@ std::string CGenerator::generateObjectMethod(NodeTree<ASTData>* enclosingObject,
|
||||
|
||||
distructDoubleStack.back().push_back(children[i]);
|
||||
}
|
||||
std::string functionSignature = "\n" + ValueTypeToCType(data.valueType->returnType, function_header + scopePrefix(from) + CifyName(enclosingObject->getDataRef()->symbol.getName()) +"__"
|
||||
+ CifyName(data.symbol.getName()) + nameDecoration) + "(" + ValueTypeToCType(&enclosingObjectType, "this") + parameters + ")";
|
||||
std::string functionSignature = "\n" + ValueTypeToCType(data.valueType->returnType, function_header +
|
||||
prefixIfNeeded(scopePrefix(from), CifyName(enclosingObject->getDataRef()->symbol.getName())) + "__" +
|
||||
CifyName(data.symbol.getName()) + nameDecoration) + "(" + ValueTypeToCType(&enclosingObjectType, "this") + parameters + ")";
|
||||
*functionPrototype += functionSignature + ";\n";
|
||||
// Note that we always wrap out child in {}, as we now allow one statement functions without a codeblock
|
||||
//
|
||||
@@ -928,7 +1045,7 @@ std::string CGenerator::generateMethodIfExists(Type* type, std::string method, s
|
||||
std::string nameDecoration;
|
||||
for (Type *paramType : methodDef->getDataRef()->valueType->parameterTypes)
|
||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(paramType);
|
||||
return function_header + scopePrefix(typeDefinition) + CifyName(typeDefinition->getDataRef()->symbol.getName()) + "__" + method + nameDecoration + "(" + parameter + ");\n";
|
||||
return function_header + prefixIfNeeded(scopePrefix(typeDefinition), CifyName(typeDefinition->getDataRef()->symbol.getName())) + "__" + method + nameDecoration + "(" + parameter + ");\n";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
@@ -952,7 +1069,7 @@ std::string CGenerator::closureStructType(std::set<NodeTree<ASTData>*> closedVar
|
||||
// will actually change the underlying function's type. We cheat and just add a *
|
||||
//auto tmp = var->getDataRef()->valueType->withIncreasedIndirection();
|
||||
std::string varName = var->getDataRef()->symbol.getName();
|
||||
varName = (varName == "this") ? varName : scopePrefix(var) + varName;
|
||||
varName = (varName == "this") ? varName : prefixIfNeeded(scopePrefix(var), varName);
|
||||
typedefString += ValueTypeToCType(var->getDataRef()->valueType->withoutReference(), "*"+varName) + ";";
|
||||
}
|
||||
std::string structName = "closureStructType" + getID();
|
||||
@@ -970,7 +1087,7 @@ std::string CGenerator::ValueTypeToCTypeThingHelper(Type *type, std::string decl
|
||||
switch (type->baseType) {
|
||||
case none:
|
||||
if (type->typeDefinition)
|
||||
return_type = scopePrefix(type->typeDefinition) + CifyName(type->typeDefinition->getDataRef()->symbol.getName());
|
||||
return_type = prefixIfNeeded(scopePrefix(type->typeDefinition), CifyName(type->typeDefinition->getDataRef()->symbol.getName()));
|
||||
else
|
||||
return_type = "none";
|
||||
break;
|
||||
@@ -1128,4 +1245,20 @@ std::string CGenerator::scopePrefix(NodeTree<ASTData>* from) {
|
||||
// that parent object will get scoped. When we add a package system, we'll have to then add their scoping here
|
||||
return scopePrefix(from->getDataRef()->scope["~enclosing_scope"][0]);
|
||||
}
|
||||
std::string CGenerator::prefixIfNeeded(std::string prefix, std::string name) {
|
||||
return simpleComplexName(name, prefix + name);
|
||||
}
|
||||
std::string CGenerator::simpleComplexName(std::string simpleName, std::string complexName) {
|
||||
auto already = simpleComplexNameMap.find(complexName);
|
||||
if (already != simpleComplexNameMap.end())
|
||||
return already->second;
|
||||
if (usedNameSet.find(simpleName) == usedNameSet.end()) {
|
||||
usedNameSet.insert(simpleName);
|
||||
simpleComplexNameMap[complexName] = simpleName;
|
||||
return simpleName;
|
||||
}
|
||||
usedNameSet.insert(complexName);
|
||||
simpleComplexNameMap[complexName] = complexName;
|
||||
return complexName;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,12 +45,14 @@ Importer::Importer(Parser* parserIn, std::vector<std::string> includePaths, std:
|
||||
removeSymbols.push_back(Symbol("adt_nonterm", false));
|
||||
removeSymbols.push_back(Symbol("template", true));
|
||||
removeSymbols.push_back(Symbol("\\|", true));
|
||||
//collapseSymbols.push_back(Symbol("scoped_identifier", false));
|
||||
//removeSymbols.push_back(Symbol("match", true));
|
||||
collapseSymbols.push_back(Symbol("case_statement_list", false));
|
||||
collapseSymbols.push_back(Symbol("opt_param_assign_list", false));
|
||||
collapseSymbols.push_back(Symbol("param_assign_list", false));
|
||||
collapseSymbols.push_back(Symbol("opt_typed_parameter_list", false));
|
||||
collapseSymbols.push_back(Symbol("opt_parameter_list", false));
|
||||
collapseSymbols.push_back(Symbol("identifier_list", false));
|
||||
collapseSymbols.push_back(Symbol("adt_option_list", false));
|
||||
collapseSymbols.push_back(Symbol("statement_list", false));
|
||||
collapseSymbols.push_back(Symbol("parameter_list", false));
|
||||
collapseSymbols.push_back(Symbol("typed_parameter_list", false));
|
||||
|
||||
@@ -199,7 +199,7 @@ std::string Type::toString(bool showTraits) {
|
||||
if (is_reference)
|
||||
typeString = "ref " + typeString;
|
||||
for (int i = 0; i < indirection; i++)
|
||||
typeString = "*" + typeString;
|
||||
typeString += "*";
|
||||
if (indirection < 0)
|
||||
typeString += "negative indirection: " + intToString(indirection);
|
||||
if (traits.size() && showTraits) {
|
||||
@@ -240,6 +240,11 @@ Type Type::withIncreasedIndirection() {
|
||||
newOne->increaseIndirection();
|
||||
return *newOne;
|
||||
}
|
||||
Type *Type::withIncreasedIndirectionPtr() {
|
||||
Type *newOne = clone();
|
||||
newOne->increaseIndirection();
|
||||
return newOne;
|
||||
}
|
||||
Type Type::withDecreasedIndirection() {
|
||||
Type *newOne = clone();
|
||||
newOne->decreaseIndirection();
|
||||
|
||||
@@ -512,14 +512,24 @@ obj action {
|
||||
return act == other.act && state_or_rule == other.state_or_rule && rule_position == other.rule_position
|
||||
}
|
||||
fun print() {
|
||||
if (act == action_type::push)
|
||||
match (act) {
|
||||
action_type::push()
|
||||
io::print("push ")
|
||||
else if (act == action_type::reduce)
|
||||
action_type::reduce()
|
||||
io::print("reduce ")
|
||||
else if (act == action_type::accept)
|
||||
action_type::accept()
|
||||
io::print("accept ")
|
||||
else if (act == action_type::reject)
|
||||
action_type::reject()
|
||||
io::print("reject ")
|
||||
}
|
||||
/*if (act == action_type::push)*/
|
||||
/*io::print("push ")*/
|
||||
/*else if (act == action_type::reduce)*/
|
||||
/*io::print("reduce ")*/
|
||||
/*else if (act == action_type::accept)*/
|
||||
/*io::print("accept ")*/
|
||||
/*else if (act == action_type::reject)*/
|
||||
/*io::print("reject ")*/
|
||||
io::print(state_or_rule)
|
||||
io::print(" ")
|
||||
io::print(rule_position)
|
||||
@@ -566,25 +576,25 @@ obj table (Object, Serializable) {
|
||||
expand_to(from_state)
|
||||
var cleaned_symbol = clean_symbol(on_symbol)
|
||||
if (items[from_state].contains_key(cleaned_symbol))
|
||||
items[from_state][cleaned_symbol].addEnd(action(action_type::push, to_state))
|
||||
items[from_state][cleaned_symbol].addEnd(action(action_type::push(), to_state))
|
||||
else
|
||||
items[from_state].set(cleaned_symbol, vector::vector(action(action_type::push, to_state)))
|
||||
items[from_state].set(cleaned_symbol, vector::vector(action(action_type::push(), to_state)))
|
||||
}
|
||||
fun add_reduce(from_state: int, on_symbol: ref symbol::symbol, by_rule_no: int, rule_position: int) {
|
||||
expand_to(from_state)
|
||||
var cleaned_symbol = clean_symbol(on_symbol)
|
||||
if (items[from_state].contains_key(cleaned_symbol))
|
||||
items[from_state][cleaned_symbol].addEnd(action(action_type::reduce, by_rule_no, rule_position))
|
||||
items[from_state][cleaned_symbol].addEnd(action(action_type::reduce(), by_rule_no, rule_position))
|
||||
else
|
||||
items[from_state].set(cleaned_symbol, vector::vector(action(action_type::reduce, by_rule_no, rule_position)))
|
||||
items[from_state].set(cleaned_symbol, vector::vector(action(action_type::reduce(), by_rule_no, rule_position)))
|
||||
}
|
||||
fun add_accept(from_state: int, on_symbol: ref symbol::symbol) {
|
||||
expand_to(from_state)
|
||||
var cleaned_symbol = clean_symbol(on_symbol)
|
||||
if (items[from_state].contains_key(cleaned_symbol))
|
||||
items[from_state][cleaned_symbol].addEnd(action(action_type::accept, 0))
|
||||
items[from_state][cleaned_symbol].addEnd(action(action_type::accept(), 0))
|
||||
else
|
||||
items[from_state].set(cleaned_symbol, vector::vector(action(action_type::accept, 0)))
|
||||
items[from_state].set(cleaned_symbol, vector::vector(action(action_type::accept(), 0)))
|
||||
}
|
||||
fun get(state: int, on_symbol: symbol::symbol): vector::vector<action> {
|
||||
var cleaned_symbol = clean_symbol(on_symbol)
|
||||
@@ -593,17 +603,17 @@ obj table (Object, Serializable) {
|
||||
fun get_shift(state: int, on_symbol: symbol::symbol): action {
|
||||
var actions = get(state, on_symbol)
|
||||
for (var i = 0; i < actions.size; i++;)
|
||||
if (actions[i].act == action_type::push)
|
||||
if (actions[i].act == action_type::push())
|
||||
return actions[i]
|
||||
io::println("tried to get a shift when none existed")
|
||||
io::print("for state ")
|
||||
io::print(state)
|
||||
io::print(" and symbol ")
|
||||
io::println(on_symbol.to_string())
|
||||
return action(action_type::invalid,-1)
|
||||
return action(action_type::invalid(),-1)
|
||||
}
|
||||
fun get_reduces(state: int, on_symbol: symbol::symbol): vector::vector<action> {
|
||||
return get(state, on_symbol).filter(fun(act: action):bool { return act.act == action_type::reduce; })
|
||||
return get(state, on_symbol).filter(fun(act: action):bool { return act.act == action_type::reduce(); })
|
||||
}
|
||||
fun print_string() {
|
||||
/*return string::string("woo a table of size: ") + items.size*/
|
||||
|
||||
@@ -131,7 +131,7 @@ fun read_file_binary(path: string::string): vector::vector<char> {
|
||||
|
||||
__if_comp__ __C__ {
|
||||
simple_passthrough(data = data::) """
|
||||
free(data)
|
||||
free(data);
|
||||
"""
|
||||
}
|
||||
return toRet
|
||||
|
||||
@@ -63,7 +63,7 @@ obj parser (Object) {
|
||||
// if the zero state contains any reductions for state 0 and eof, then
|
||||
// it must be reducing to the goal state
|
||||
println("checking the bidness")
|
||||
if (inputStr == "" && gram.parse_table.get(0, eof_symbol()).contains(action(action_type::reduce, 0))) {
|
||||
if (inputStr == "" && gram.parse_table.get(0, eof_symbol()).contains(action(action_type::reduce(), 0))) {
|
||||
println("Accept on no input for ")
|
||||
println(name)
|
||||
return new<tree<symbol>>()->construct(null_symbol())
|
||||
@@ -92,11 +92,11 @@ obj parser (Object) {
|
||||
gram.parse_table.get(0, input[0]).for_each(fun(act: action) {
|
||||
println("for each action")
|
||||
act.print()
|
||||
if (act.act == action_type::push)
|
||||
if (act.act == action_type::push())
|
||||
to_shift.push(make_pair(v0, act.state_or_rule))
|
||||
/*else if (act.act == reduce && fully_reduces_to_null(gram.rules[act.state_or_rule])) {*/
|
||||
else if (act.act == action_type::reduce && act.rule_position == 0) {
|
||||
print("act == reduce && == 0 Adding reduction from state: ")
|
||||
else if (act.act == action_type::reduce() && act.rule_position == 0) {
|
||||
print("act == reduce() && == 0 Adding reduction from state: ")
|
||||
println(v0->data)
|
||||
to_reduce.push(reduction(v0, gram.rules[act.state_or_rule].lhs, 0, null_symbol_tree, null_symbol_tree))
|
||||
}
|
||||
@@ -197,7 +197,7 @@ obj parser (Object) {
|
||||
gram.parse_table.get(shift_to, input[i]).for_each(fun(act: action) {
|
||||
var reduce_rule = gram.rules[act.state_or_rule]
|
||||
/*if (act.act == reduce && !fully_reduces_to_null(reduce_rule)) {*/
|
||||
if (act.act == action_type::reduce && act.rule_position != 0) {
|
||||
if (act.act == action_type::reduce() && act.rule_position != 0) {
|
||||
to_reduce.push(reduction(curr_reached, reduce_rule.lhs,
|
||||
act.rule_position,
|
||||
get_nullable_parts(reduce_rule),
|
||||
@@ -213,7 +213,7 @@ obj parser (Object) {
|
||||
gss.add_to_frontier(i, shift_to_node)
|
||||
gss.add_edge(shift_to_node, curr_reached, new_label)
|
||||
gram.parse_table.get(shift_to, input[i]).for_each(fun(act: action) {
|
||||
if (act.act == action_type::push) {
|
||||
if (act.act == action_type::push()) {
|
||||
to_shift.push(make_pair(shift_to_node, act.state_or_rule))
|
||||
} else {
|
||||
var action_rule = gram.rules[act.state_or_rule]
|
||||
@@ -278,7 +278,7 @@ obj parser (Object) {
|
||||
println("post add edger")
|
||||
gram.parse_table.get(shift.second, input[i+1]).for_each(fun(action: action) {
|
||||
println("looking at an action")
|
||||
if (action.act == action_type::push) {
|
||||
if (action.act == action_type::push()) {
|
||||
println("is push")
|
||||
next_shifts.push(make_pair(shift_to_node, action.state_or_rule))
|
||||
} else {
|
||||
|
||||
@@ -33,7 +33,7 @@ obj regexState (Object) {
|
||||
fun destruct():void {
|
||||
next_states.destruct()
|
||||
}
|
||||
fun match(input: char): vector::vector<*regexState> {
|
||||
fun match_char(input: char): vector::vector<*regexState> {
|
||||
return next_states.filter(fun(it:*regexState):bool { return it->character == input; })
|
||||
}
|
||||
fun is_end():bool {
|
||||
@@ -190,8 +190,8 @@ obj regex (Object, Serializable) {
|
||||
return longest
|
||||
if (next.any_true(fun(state: *regexState):bool { return state->is_end(); }))
|
||||
longest = i
|
||||
//next = next.flatten_map<*regexState>(fun(state: *regexState): vector::vector<*regexState> { return state->match(to_match[i]); })
|
||||
next = next.flatten_map(fun(state: *regexState): vector::vector<*regexState> { return state->match(to_match[i]); })
|
||||
//next = next.flatten_map<*regexState>(fun(state: *regexState): vector::vector<*regexState> { return state->match_char(to_match[i]); })
|
||||
next = next.flatten_map(fun(state: *regexState): vector::vector<*regexState> { return state->match_char(to_match[i]); })
|
||||
}
|
||||
if (next.any_true(fun(state: *regexState):bool { return state->is_end(); }))
|
||||
return to_match.length()
|
||||
|
||||
@@ -5,16 +5,69 @@ adt options {
|
||||
option1
|
||||
}
|
||||
|
||||
adt maybe_int {
|
||||
no_int,
|
||||
an_int: int
|
||||
}
|
||||
|
||||
fun handle_possibility(it: maybe_int) {
|
||||
if (it == maybe_int::no_int()) {
|
||||
println("no int")
|
||||
}
|
||||
/*if (it == maybe_int::an_int) {*/
|
||||
else {
|
||||
print("an int: ")
|
||||
println(it.an_int)
|
||||
}
|
||||
}
|
||||
|
||||
fun give_maybe(give_it: bool): maybe_int {
|
||||
if (give_it)
|
||||
return maybe_int::an_int(7)
|
||||
return maybe_int::no_int()
|
||||
}
|
||||
|
||||
fun can_pass(it: options): options {
|
||||
return options::option1
|
||||
return it
|
||||
}
|
||||
|
||||
fun main():int {
|
||||
var it: options = can_pass(options::option0)
|
||||
if (it == options::option0)
|
||||
var it: options = can_pass(options::option0())
|
||||
if (it == options::option0()) {
|
||||
println("nope")
|
||||
if (it == options::option1)
|
||||
}
|
||||
if (it == options::option1()) {
|
||||
println("option1")
|
||||
}
|
||||
|
||||
var possibility = give_maybe(false)
|
||||
handle_possibility(possibility)
|
||||
possibility = give_maybe(true)
|
||||
handle_possibility(possibility)
|
||||
if ( maybe_int::an_int(7) == maybe_int::an_int(7) )
|
||||
println("equality true works!")
|
||||
else
|
||||
println("equality true fails!")
|
||||
|
||||
if ( maybe_int::an_int(7) != maybe_int::an_int(8) )
|
||||
println("equality false works!")
|
||||
else
|
||||
println("equality false fails!")
|
||||
|
||||
match (maybe_int::an_int(11)) {
|
||||
maybe_int::an_int(the_int) {
|
||||
print("matched an int:")
|
||||
print(the_int)
|
||||
println(" correctly!")
|
||||
}
|
||||
maybe_int::no_int() {
|
||||
println("matched no int incorrectly!")
|
||||
}
|
||||
}
|
||||
match (maybe_int::no_int()) {
|
||||
maybe_int::an_int(the_int) println("matched an int incorrectly!")
|
||||
maybe_int::no_int() println("matched no int correctly!")
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user