proper scoping for ADTs, I think
This commit is contained in:
@@ -57,7 +57,8 @@ std::string CGenerator::getID() {
|
|||||||
std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
|
std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
|
||||||
auto data = from->getData();
|
auto data = from->getData();
|
||||||
auto children = from->getChildren();
|
auto children = from->getChildren();
|
||||||
std::string structString, enumString, functionString;
|
//std::string structString, enumString, functionString;
|
||||||
|
std::string structString, enumString;
|
||||||
std::string enumName = "__enum_dummy_" + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())+"__");
|
std::string enumName = "__enum_dummy_" + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName())+"__");
|
||||||
enumString = "enum " + enumName + " {\n";
|
enumString = "enum " + enumName + " {\n";
|
||||||
structString = "struct __struct_dummy_";
|
structString = "struct __struct_dummy_";
|
||||||
@@ -79,48 +80,7 @@ std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
|
|||||||
} else {
|
} else {
|
||||||
structString += tabs() + generate(child, nullptr).oneString() + "\n";
|
structString += tabs() + generate(child, nullptr).oneString() + "\n";
|
||||||
}
|
}
|
||||||
enumString += tabs() + generate(child, nullptr).oneString() + (data.type == adt_def ? ",\n" : "\n");
|
enumString += tabs() + data.symbol.getName() + "__" + 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--;
|
tabLevel--;
|
||||||
@@ -133,7 +93,7 @@ std::string CGenerator::generateTypeStruct(NodeTree<ASTData>* from) {
|
|||||||
}
|
}
|
||||||
enumString += "};\n";
|
enumString += "};\n";
|
||||||
if (data.type == adt_def)
|
if (data.type == adt_def)
|
||||||
return enumString + structString + functionString;
|
return enumString + structString;
|
||||||
return structString;
|
return structString;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,16 +298,57 @@ std::pair<std::string, std::string> CGenerator::generateTranslationUnit(std::str
|
|||||||
break;
|
break;
|
||||||
case adt_def:
|
case adt_def:
|
||||||
{
|
{
|
||||||
//type
|
for (auto child : decChildren) {
|
||||||
//don't even need to do this anymore, it's all earlier
|
if (child->getName() == "function") {
|
||||||
//plainTypedefs += "/* adt " + declarationData.symbol.getName() + " */\n";
|
std::string orig_fun_name = child->getDataRef()->symbol.getName();
|
||||||
//plainTypedefs += "typedef struct __struct_dummy_" +
|
std::string fun_name = "fun_" + declarationData.symbol.getName() + "__" + CifyName(orig_fun_name);
|
||||||
//prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())+ "__") + " " +
|
std::string first_param;
|
||||||
//prefixIfNeeded(scopePrefix(declaration), CifyName(declarationData.symbol.getName())) + ";\n";
|
if (orig_fun_name == "operator==" || orig_fun_name == "operator!=") {
|
||||||
//// skip the name of the thing
|
//fun_name = "fun_" + declarationData.symbol.getName() + "__" + CifyName(orig_fun_name);
|
||||||
//for (int j = 1; j < decChildren.size(); j++) {
|
first_param = ValueTypeToCType(child->getDataRef()->valueType->parameterTypes[0]->withIncreasedIndirectionPtr(), "this") + ", ";
|
||||||
//std::cout << decChildren[j]->getName() << std::endl;
|
} else {
|
||||||
//}
|
//fun_name = "fun_" + orig_fun_name;
|
||||||
|
}
|
||||||
|
bool has_param = child->getDataRef()->valueType->parameterTypes.size();
|
||||||
|
std::string first_part = "\n" + ValueTypeToCType(child->getDataRef()->valueType->returnType, fun_name) + "(" + first_param +
|
||||||
|
(has_param ? ValueTypeToCType(child->getDataRef()->valueType->parameterTypes[0], "in") : "") + ")";
|
||||||
|
functionPrototypes += first_part + "; /*adt func*/\n";
|
||||||
|
functionDefinitions += first_part + "{ /*adt func*/\n";
|
||||||
|
if (orig_fun_name == "operator==") {
|
||||||
|
functionDefinitions += " /* equality woop woop */\n";
|
||||||
|
functionDefinitions += " if (this->flag != in.flag) return false;\n";
|
||||||
|
|
||||||
|
for (auto child : decChildren) {
|
||||||
|
if (child->getName() != "function" && child->getDataRef()->valueType->typeDefinition != declaration) {
|
||||||
|
std::string option_name = child->getDataRef()->symbol.getName();
|
||||||
|
functionDefinitions += " if (this->flag == " + declarationData.symbol.getName() + "__" + option_name + ") {\n";
|
||||||
|
NodeTree<ASTData>* method = nullptr;
|
||||||
|
if (method = getMethod(child->getDataRef()->valueType, "operator==", std::vector<Type>{*child->getDataRef()->valueType})) {
|
||||||
|
functionDefinitions += " return " + generateMethodIfExists(child->getDataRef()->valueType, "operator==",
|
||||||
|
"&this->" + option_name + ", " + (method->getDataRef()->valueType->parameterTypes[0]->is_reference ? "&" : "") + "in." + option_name,
|
||||||
|
std::vector<Type>{*child->getDataRef()->valueType}) + ";\n}\n";
|
||||||
|
} else {
|
||||||
|
functionDefinitions += " return this->" + option_name + " == in." + option_name + ";\n}\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
functionDefinitions += " return true;\n";
|
||||||
|
} else if (orig_fun_name == "operator!=") {
|
||||||
|
functionDefinitions += " /* inequality woop woop */\n";
|
||||||
|
functionDefinitions += " return !fun_" + declarationData.symbol.getName() + "__" + CifyName("operator==") + "(this, in);\n";
|
||||||
|
} else {
|
||||||
|
// ok, is a constructor function
|
||||||
|
functionDefinitions += " /* constructor woop woop */\n";
|
||||||
|
functionDefinitions += " " + declarationData.symbol.getName() + " toRet;\n";
|
||||||
|
functionDefinitions += " toRet.flag = " + declarationData.symbol.getName() + "__" + orig_fun_name + ";\n";
|
||||||
|
if (has_param)
|
||||||
|
functionDefinitions += " toRet." + orig_fun_name + " = in;\n";
|
||||||
|
functionDefinitions += " return toRet;\n";
|
||||||
|
}
|
||||||
|
functionDefinitions += "}\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -440,10 +441,11 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
// this is for using functions as values
|
// this is for using functions as values
|
||||||
if (justFuncName) {
|
if (justFuncName) {
|
||||||
std::string funcName;
|
std::string funcName;
|
||||||
if (data.symbol.getName() != "main")
|
if (data.symbol.getName() != "main") {
|
||||||
funcName += function_header + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName() + nameDecoration));
|
funcName += function_header + prefixIfNeeded(scopePrefix(from), CifyName(data.symbol.getName() + nameDecoration));
|
||||||
else
|
} else {
|
||||||
funcName += CifyName(data.symbol.getName() + nameDecoration);
|
funcName += CifyName(data.symbol.getName() + nameDecoration);
|
||||||
|
}
|
||||||
if (from->getDataRef()->closedVariables.size()) {
|
if (from->getDataRef()->closedVariables.size()) {
|
||||||
std::string tmpStruct = "closureStruct" + getID();
|
std::string tmpStruct = "closureStruct" + getID();
|
||||||
output.preValue += closureStructType(data.closedVariables) + " " + tmpStruct + " = {";
|
output.preValue += closureStructType(data.closedVariables) + " " + tmpStruct + " = {";
|
||||||
@@ -535,8 +537,9 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
for (auto case_stmt : slice(children, 1, -1)) {
|
for (auto case_stmt : slice(children, 1, -1)) {
|
||||||
auto case_children = case_stmt->getChildren();
|
auto case_children = case_stmt->getChildren();
|
||||||
std::string option = generate(case_children[0], enclosingObject, false, enclosingFunction).oneString();
|
std::string option = generate(case_children[0], enclosingObject, false, enclosingFunction).oneString();
|
||||||
|
std::string parentName = case_children[0]->getDataRef()->scope["~enclosing_scope"][0]->getDataRef()->symbol.getName();
|
||||||
output += "/* case " + option + " if " + thingToMatch.value + " */\n";
|
output += "/* case " + option + " if " + thingToMatch.value + " */\n";
|
||||||
output += tabs() + "if (" + thingToMatch.value + ".flag == " + option + ") {\n";
|
output += tabs() + "if (" + thingToMatch.value + ".flag == " + parentName + "__" + option + ") {\n";
|
||||||
tabLevel++;
|
tabLevel++;
|
||||||
if (case_children.size() > 2) {
|
if (case_children.size() > 2) {
|
||||||
output += tabs() + ValueTypeToCType(case_children[1]->getData().valueType, generate(case_children[1], enclosingObject, false, enclosingFunction).oneString())
|
output += tabs() + ValueTypeToCType(case_children[1]->getData().valueType, generate(case_children[1], enclosingObject, false, enclosingFunction).oneString())
|
||||||
@@ -866,7 +869,14 @@ CCodeTriple CGenerator::generate(NodeTree<ASTData>* from, NodeTree<ASTData>* enc
|
|||||||
output += CifyName(name + nameDecoration) + "(";
|
output += CifyName(name + nameDecoration) + "(";
|
||||||
output += std::string(addClosedOver ? "(*closed_variables->this)" : "this") + (children.size() > 1 ? "," : "");
|
output += std::string(addClosedOver ? "(*closed_variables->this)" : "this") + (children.size() > 1 ? "," : "");
|
||||||
} else {
|
} else {
|
||||||
output += function_header + prefixIfNeeded(scopePrefix(children[0]), CifyName(name + nameDecoration)) + "(";
|
// ha, I think this is the normal function call one. Had a little trouble finding it
|
||||||
|
// darned if we don't have to special case ADT psudo-constructors
|
||||||
|
auto possibleParentADTVector = children[0]->getDataRef()->scope["~enclosing_scope"];
|
||||||
|
NodeTree<ASTData>* possibleParentADT = possibleParentADTVector.size() ? possibleParentADTVector[0] : nullptr;
|
||||||
|
std::string adtAdditional = "";
|
||||||
|
if (possibleParentADT && possibleParentADT->getDataRef()->type == adt_def)
|
||||||
|
adtAdditional = possibleParentADT->getDataRef()->symbol.getName() + "__";
|
||||||
|
output += function_header + prefixIfNeeded(scopePrefix(children[0]), CifyName(adtAdditional + name + nameDecoration)) + "(";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1045,7 +1055,7 @@ std::string CGenerator::generateMethodIfExists(Type* type, std::string method, s
|
|||||||
std::string nameDecoration;
|
std::string nameDecoration;
|
||||||
for (Type *paramType : methodDef->getDataRef()->valueType->parameterTypes)
|
for (Type *paramType : methodDef->getDataRef()->valueType->parameterTypes)
|
||||||
nameDecoration += "_" + ValueTypeToCTypeDecoration(paramType);
|
nameDecoration += "_" + ValueTypeToCTypeDecoration(paramType);
|
||||||
return function_header + prefixIfNeeded(scopePrefix(typeDefinition), CifyName(typeDefinition->getDataRef()->symbol.getName())) + "__" + method + nameDecoration + "(" + parameter + ");\n";
|
return function_header + prefixIfNeeded(scopePrefix(typeDefinition), CifyName(typeDefinition->getDataRef()->symbol.getName())) + "__" + CifyName(method) + nameDecoration + "(" + parameter + ");\n";
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,41 @@ adt maybe_int {
|
|||||||
an_int: int
|
an_int: int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun TestObj(num: int): TestObj {
|
||||||
|
print("gonna makke object in function ")
|
||||||
|
println(num)
|
||||||
|
var toRet.construct(num): TestObj
|
||||||
|
return toRet
|
||||||
|
}
|
||||||
|
obj TestObj (Object) {
|
||||||
|
var obj_num: int
|
||||||
|
fun construct(num:int): *TestObj {
|
||||||
|
obj_num = num
|
||||||
|
print("constructed object ")
|
||||||
|
println(obj_num)
|
||||||
|
}
|
||||||
|
fun copy_construct(old: *TestObj) {
|
||||||
|
obj_num = old->obj_num + 100
|
||||||
|
print("copy constructed object ")
|
||||||
|
print(obj_num)
|
||||||
|
print(" from ")
|
||||||
|
println(old->obj_num)
|
||||||
|
}
|
||||||
|
fun destruct() {
|
||||||
|
print("destructed object ")
|
||||||
|
println(obj_num)
|
||||||
|
}
|
||||||
|
fun operator==(other: ref TestObj): bool {
|
||||||
|
return obj_num == other.obj_num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
adt maybe_object {
|
||||||
|
no_obj,
|
||||||
|
an_obj: TestObj,
|
||||||
|
an_int: int
|
||||||
|
}
|
||||||
|
|
||||||
fun handle_possibility(it: maybe_int) {
|
fun handle_possibility(it: maybe_int) {
|
||||||
if (it == maybe_int::no_int()) {
|
if (it == maybe_int::no_int()) {
|
||||||
println("no int")
|
println("no int")
|
||||||
@@ -68,6 +103,42 @@ fun main():int {
|
|||||||
maybe_int::an_int(the_int) println("matched an int incorrectly!")
|
maybe_int::an_int(the_int) println("matched an int incorrectly!")
|
||||||
maybe_int::no_int() println("matched no int correctly!")
|
maybe_int::no_int() println("matched no int correctly!")
|
||||||
}
|
}
|
||||||
|
var obj_item = maybe_object::no_obj()
|
||||||
|
match (obj_item) {
|
||||||
|
maybe_object::no_obj() println("matched no_obj correctly")
|
||||||
|
maybe_object::an_obj(obj_instance) {
|
||||||
|
print("matched an_obj incorrectly ")
|
||||||
|
println(obj_instance.obj_num)
|
||||||
|
}
|
||||||
|
maybe_object::an_int(int_thiny) {
|
||||||
|
print("matched an_intj incorrectly ")
|
||||||
|
println(int_thiny)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obj_item = maybe_object::an_obj(TestObj(100))
|
||||||
|
match (obj_item) {
|
||||||
|
maybe_object::no_obj() println("matched no_obj incorrectly")
|
||||||
|
maybe_object::an_obj(obj_instance) {
|
||||||
|
print("matched an_obj correctly ")
|
||||||
|
println(obj_instance.obj_num)
|
||||||
|
}
|
||||||
|
maybe_object::an_int(int_thiny) {
|
||||||
|
print("matched an_intj incorrectly ")
|
||||||
|
println(int_thiny)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obj_item = maybe_object::an_int(1337)
|
||||||
|
match (obj_item) {
|
||||||
|
maybe_object::no_obj() println("matched no_obj incorrectly")
|
||||||
|
maybe_object::an_obj(obj_instance) {
|
||||||
|
print("matched an_obj incorrectly ")
|
||||||
|
println(obj_instance.obj_num)
|
||||||
|
}
|
||||||
|
maybe_object::an_int(int_thiny) {
|
||||||
|
print("matched an_int correctly ")
|
||||||
|
println(int_thiny)
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,7 +119,8 @@ fun main():int {
|
|||||||
|
|
||||||
var parse.construct(a): parser
|
var parse.construct(a): parser
|
||||||
/*var result = parse.parse_input(string("a"), string("fun name"))*/
|
/*var result = parse.parse_input(string("a"), string("fun name"))*/
|
||||||
var result = parse.parse_input(read_file(string("to_parse.krak")), string("fun name"))
|
var result = parse.parse_input(read_file(string("test_adt.krak")), string("fun name"))
|
||||||
|
/*var result = parse.parse_input(read_file(string("to_parse.krak")), string("fun name"))*/
|
||||||
/*var result = parse.parse_input(string("inport a;"), string("fun name"))*/
|
/*var result = parse.parse_input(string("inport a;"), string("fun name"))*/
|
||||||
/*var result = parse.parse_input(string("fun main():int { return 0; }"), string("fun name"))*/
|
/*var result = parse.parse_input(string("fun main():int { return 0; }"), string("fun name"))*/
|
||||||
/*var result = parse.parse_input(string("ad"), string("fun name"))*/
|
/*var result = parse.parse_input(string("ad"), string("fun name"))*/
|
||||||
|
|||||||
Reference in New Issue
Block a user