diff --git a/src/codegen/codegen.c b/src/codegen/codegen.c index e222712..9173761 100644 --- a/src/codegen/codegen.c +++ b/src/codegen/codegen.c @@ -38,6 +38,31 @@ char* createCodegenError(SolsNode* node, char* what) { return err.str; } +static ResultType(SolsType, charptr) resolveValueType(SolsType* type, SolsScope* scope) { + if (type->identifierType == NULL) { + return Success(SolsType, charptr, *type); + } + + if (type->type != STT_UNKNOWN && + !(type->type == STT_OBJECT && type->children.count == 0)) { + return Success(SolsType, charptr, *type); + } + + SolsVariable* var = findSolsVariable(scope, type->identifierType); + if (var == NULL) { + Estr estr = CREATE_ESTR("Unable to find type "); + APPEND_ESTR(estr, type->identifierType); + return Error(SolsType, charptr, estr.str); + } + + SolsType resolved = var->typeinfo; + if (resolved.type == STT_TEMPLATE) { + resolved.type = STT_OBJECT; + } + + return Success(SolsType, charptr, resolved); +} + ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) { switch (node->type) { case SNT_PUTS: @@ -210,7 +235,7 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) { APPEND_ESTR(estr, node->as.idName); return Error(SolsType, charptr, estr.str); } - return Success(SolsType, charptr, var->typeinfo); + return resolveValueType(&var->typeinfo, scope); } case SNT_LAMBDA: { return Success(SolsType, charptr, node->as.type); @@ -227,7 +252,7 @@ ResultType(SolsType, charptr) getNodeType(SolsNode* node, SolsScope* scope) { APPEND_ESTR(estr, " is not a callable function"); return Error(SolsType, charptr, estr.str); } - return Success(SolsType, charptr, *var->typeinfo.returnType); + return resolveValueType(var->typeinfo.returnType, scope); } case SNT_EXPR_IN_PAREN: { return getNodeType(&node->children.at[node->children.count - 1], scope); @@ -808,7 +833,11 @@ ResultType(GroundProgram, charptr) generateLambdaNode(SolsNode* node, SolsScope* lambdaScope.returnType = *node->as.type.returnType; for (size_t i = 0; i < node->as.type.children.count; i++) { - addVariableToScope(&lambdaScope, node->as.type.children.at[i].name, node->as.type.children.at[i].type); + ResultType(SolsType, charptr) resolvedType = resolveValueType(&node->as.type.children.at[i].type, scope); + if (resolvedType.error) { + return Error(GroundProgram, charptr, resolvedType.as.error); + } + addVariableToScope(&lambdaScope, node->as.type.children.at[i].name, resolvedType.as.success); } // Generate children and add then to this program @@ -875,10 +904,18 @@ ResultType(GroundProgram, charptr) generateDefNode(SolsNode* node, SolsScope* sc SolsScope functionScope = copySolsScope(scope); // Set the scope's return type - functionScope.returnType = *node->as.type.returnType; + ResultType(SolsType, charptr) resolvedReturnType = resolveValueType(node->as.type.returnType, scope); + if (resolvedReturnType.error) { + return Error(GroundProgram, charptr, resolvedReturnType.as.error); + } + functionScope.returnType = resolvedReturnType.as.success; for (size_t i = 0; i < node->as.type.children.count; i++) { - addVariableToScope(&functionScope, node->as.type.children.at[i].name, node->as.type.children.at[i].type); + ResultType(SolsType, charptr) resolvedType = resolveValueType(&node->as.type.children.at[i].type, scope); + if (resolvedType.error) { + return Error(GroundProgram, charptr, resolvedType.as.error); + } + addVariableToScope(&functionScope, node->as.type.children.at[i].name, resolvedType.as.success); } // Generate children and add then to this program @@ -917,7 +954,13 @@ ResultType(GroundProgram, charptr) generateFunctionCallNode(SolsNode* node, Sols if (type.error) { return Error(GroundProgram, charptr, type.as.error); } - if (compareTypes(&type.as.success, &var->typeinfo.children.at[i].type) == false) { + + ResultType(SolsType, charptr) expectedType = resolveValueType(&var->typeinfo.children.at[i].type, scope); + if (expectedType.error) { + return Error(GroundProgram, charptr, expectedType.as.error); + } + + if (compareTypes(&type.as.success, &expectedType.as.success) == false) { return Error(GroundProgram, charptr, "Types incorrect for function call"); } } diff --git a/src/lexer/SolsType.c b/src/lexer/SolsType.c index 5972060..30a9f71 100644 --- a/src/lexer/SolsType.c +++ b/src/lexer/SolsType.c @@ -41,6 +41,72 @@ ResultType(SolsType, charptr) createIdentifiedSolsType(char* in) { })); } +ResultType(SolsType, charptr) copySolsType(SolsType* type) { + SolsType ret = { + .type = type->type, + .identifierType = NULL, + .typeIsKnown = type->typeIsKnown, + .needsGroundStruct = type->needsGroundStruct, + .returnType = NULL, + .children.count = type->children.count, + .children.capacity = type->children.capacity, + .children.at = NULL + }; + + if (type->identifierType != NULL) { + ret.identifierType = malloc(strlen(type->identifierType) + 1); + if (ret.identifierType == NULL) { + return Error(SolsType, charptr, "Couldn't allocate memory (in copySolsType() function)"); + } + strcpy(ret.identifierType, type->identifierType); + } + + if (type->returnType != NULL) { + ResultType(SolsType, charptr) copiedReturn = copySolsType(type->returnType); + if (copiedReturn.error) { + Estr err = CREATE_ESTR(copiedReturn.as.error); + APPEND_ESTR(err, " (in copySolsType() function)"); + return Error(SolsType, charptr, err.str); + } + + ret.returnType = malloc(sizeof(SolsType)); + if (ret.returnType == NULL) { + return Error(SolsType, charptr, "Couldn't allocate memory (in copySolsType() function)"); + } + *ret.returnType = copiedReturn.as.success; + } + + if (type->children.capacity > 0) { + SolsTypeField* ptr = malloc(sizeof(SolsTypeField) * type->children.capacity); + if (ptr == NULL) { + return Error(SolsType, charptr, "Couldn't allocate memory (in copySolsType() function)"); + } + ret.children.at = ptr; + } + + for (size_t i = 0; i < type->children.count; i++) { + ResultType(SolsType, charptr) copied = copySolsType(&type->children.at[i].type); + if (copied.error) { + Estr err = CREATE_ESTR(copied.as.error); + APPEND_ESTR(err, " (in copySolsType() function)"); + return Error(SolsType, charptr, err.str); + } + ret.children.at[i].type = copied.as.success; + + if (type->children.at[i].name == NULL) { + ret.children.at[i].name = NULL; + } else { + ret.children.at[i].name = malloc(strlen(type->children.at[i].name) + 1); + if (ret.children.at[i].name == NULL) { + return Error(SolsType, charptr, "Couldn't allocate memory (in copySolsType() function)"); + } + strcpy(ret.children.at[i].name, type->children.at[i].name); + } + } + + return Success(SolsType, charptr, ret); +} +/* ResultType(SolsType, charptr) copySolsType(SolsType* type) { SolsType ret = { .type = type->type, .children.count = type->children.count, .children.capacity = type->children.capacity}; @@ -75,6 +141,7 @@ ResultType(SolsType, charptr) copySolsType(SolsType* type) { } return Success(SolsType, charptr, ret); } +*/ ResultType(Nothing, charptr) addChildToSolsType(SolsType* type, SolsType child, const char* name) { if (type->children.capacity < type->children.count + 1) { diff --git a/src/main.c b/src/main.c index 1d34b11..49c0d84 100644 --- a/src/main.c +++ b/src/main.c @@ -14,6 +14,8 @@ #endif #include +extern bool groundDisableTypeChecking; + typedef enum SolsAction { SA_PRINT, SA_EXEC, SA_BYTECODE, SA_COMPILE, SA_EXIT, SA_EXITOK } SolsAction; @@ -126,6 +128,8 @@ char* getFileContents(const char* filename) { } int main(int argc, char** argv) { + groundDisableTypeChecking = true; + Args args = parseArgs(argc, argv); if (args.action == SA_EXIT) {