nitron

commit 5d7eee43f60cccf96a0b9c13e8194b58b0ea8bfd

Author: mesyeti <mesyeti@mesyeti.uk>

fix function pointers

 basic/source/frontend/c89.c | 6 +++++-
 basic/source/semanticAnalysis.c | 30 ++++++++++++++++++++++++------


diff --git a/basic/source/frontend/c89.c b/basic/source/frontend/c89.c
index d6f56b0bc5ae5b3139122537822a936fb06c21d9..b6f8241ece46e2b7b2e5693fa703fd3be7e81623 100644
--- a/basic/source/frontend/c89.c
+++ b/basic/source/frontend/c89.c
@@ -214,6 +214,9 @@ 				
 				if ((var->type.ptr == 0) && (var->type.array == 0) && (type->type == TYPE_FUNC)) {
 					func = true;
 				}
+				if (!type->func.name) {
+					func = false;
+				}
 			}
 
 			if (func) {
@@ -489,7 +492,7 @@ 	for (size_t i = 0; i < state.scopeSize[0]; ++ i) {
 		Var*  var     = &state.scopes[0][i];
 		Type* varType = State_GetTypeFromUsed(var->type);
 
-		if ((varType->type == TYPE_FUNC) && !var->type.ptr) continue;
+		if ((varType->type == TYPE_FUNC) && varType->func.name) continue;
 
 		if (var->isStatic) {
 			fprintf(out, "static ");
@@ -514,6 +517,7 @@
 		if ((var->type.ptr > 0) || (var->type.array > 0) || (varType->type != TYPE_FUNC)) {
 			continue;
 		}
+		if (!varType->func.name) continue;
 
 		Function* func = &varType->func;
 




diff --git a/basic/source/semanticAnalysis.c b/basic/source/semanticAnalysis.c
index 27fc2a736a3eccaade7def989320d48b5612458a..9efabd2fb2d98d781cb045fb12a6bd1bf4f3d41e 100644
--- a/basic/source/semanticAnalysis.c
+++ b/basic/source/semanticAnalysis.c
@@ -107,6 +107,8 @@ static bool AssignCompatible(UsedType left, UsedType right) {
 	Type* leftType  = State_GetTypeFromUsed(left);
 	Type* rightType = State_GetTypeFromUsed(right);
 
+	if ((leftType->type == TYPE_FUNC) && leftType->name) ++ left.ptr;
+
 	if ((left.ptr != right.ptr) || (leftType->type != rightType->type)) {
 		return false;
 	}
@@ -334,8 +336,8 @@ 	Type* leftType  = State_GetTypeFromUsed(left);
 	Type* rightType = State_GetTypeFromUsed(right);
 
 	if (
-		((left.ptr == 0)  && (leftType->type != TYPE_PRIM)) ||
-		((right.ptr == 0) && (rightType->type != TYPE_PRIM))
+		((left.ptr == 0)  && (leftType->type != TYPE_PRIM) && (leftType->type != TYPE_FUNC)) ||
+		((right.ptr == 0) && (rightType->type != TYPE_PRIM) && (leftType->type != TYPE_FUNC))
 	) {
 		PrintError(node->i.err, "You can only use primitive types in binary expressions");
 	}
@@ -490,12 +492,20 @@
 	exit(1);
 }
 
-static Function DecToFunc(FuncDec dec) {
+static Function DecToFunc(ErrorInfo err, FuncDec dec) {
 	Function func;
 	func.sub = dec.ret == NULL;
 
 	if (!func.sub) {
 		func.ret = SemanticAnalysis_NodeAsUsedType(dec.ret);
+
+		if (!func.ret.ptr) {
+			Type* retType = State_GetTypeFromUsed(func.ret);
+
+			if ((retType->type != TYPE_PRIM) && (retType->type != TYPE_FUNC)) {
+				PrintError(err, "Can only return primitive types or pointers");
+			}
+		}
 	}
 
 	func.paramsLen = dec.paramsNum;
@@ -506,6 +516,14 @@ 		func.params[i].type = SemanticAnalysis_NodeAsUsedType(
 			dec.params[i].type
 		);
 		func.params[i].name = dec.params[i].name;
+
+		if (!func.params[i].type.ptr) {
+			Type* paramType = State_GetTypeFromUsed(func.params[i].type);
+
+			if ((paramType->type != TYPE_PRIM) && (paramType->type != TYPE_FUNC)) {
+				PrintError(err, "Can only use primitive types or pointers for parameters");
+			}
+		}
 	}
 
 	func.name = dec.name? NewString(dec.name) : NULL;
@@ -593,7 +611,7 @@ 			if (inFunc) {
 				PrintError(node->i.err, "Nested function definitions are not allowed");
 			}
 
-			Function func = DecToFunc(node->funcDef.dec);
+			Function func = DecToFunc(node->i.err, node->funcDef.dec);
 
  			// create type for this function
  			Type type;
@@ -659,7 +677,7 @@ 			if (inFunc) {
 				PrintError(node->i.err, "Nested function definitions are not allowed");
 			}
 
-			Function func = DecToFunc(node->external.dec);
+			Function func = DecToFunc(node->i.err, node->external.dec);
 
  			// create type for this function
  			Type type;
@@ -725,7 +743,7 @@ 			if (node->typeDef.func) {
 				newType.type    = TYPE_FUNC;
 				newType.name    = NewString(node->typeDef.name);
 				newType.private = external && node->typeDef.private;
-				newType.func    = DecToFunc(node->typeDef.type.dec);
+				newType.func    = DecToFunc(node->i.err, node->typeDef.type.dec);
 			}
 			else {
 				const char* fromName = node->typeDef.type.node->ident.name;