<commit_before>#include "TestBase.h"

#ifndef _DEBUG
	#define FAILURE_TEST
#endif

#ifdef FAILURE_TEST

const char	*testDivZeroInt = 
"// Division by zero handling\r\n\
int a = 5, b = 0;\r\n\
return a/b;";
TEST_RUNTIME_FAIL("Division by zero handling 1", testDivZeroInt, "ERROR: integer division by zero");

const char	*testDivZeroLong = 
"// Division by zero handling\r\n\
long a = 5, b = 0;\r\n\
return a / b;";
TEST_RUNTIME_FAIL("Division by zero handling 2", testDivZeroLong, "ERROR: integer division by zero");

const char	*testModZeroInt = 
"// Division by zero handling\r\n\
int a = 5, b = 0;\r\n\
return a % b;";
TEST_RUNTIME_FAIL("Modulus division by zero handling 1", testModZeroInt, "ERROR: integer division by zero");

const char	*testModZeroLong = 
"// Division by zero handling\r\n\
long a = 5, b = 0;\r\n\
return a % b;";
TEST_RUNTIME_FAIL("Modulus division by zero handling 2", testModZeroLong, "ERROR: integer division by zero");

const char	*testFuncNoReturn = 
"// Function with no return handling\r\n\
int test(){ 1; } // temporary\r\n\
return test();";
TEST_RUNTIME_FAIL("Function with no return handling", testFuncNoReturn, "ERROR: function didn't return a value");

const char	*testBounds1 = 
"// Array out of bound check \r\n\
int[4] n;\r\n\
int i = 4;\r\n\
n[i] = 3;\r\n\
return 1;";
TEST_RUNTIME_FAIL("Array out of bounds error check 1", testBounds1, "ERROR: array index out of bounds");

const char	*testBounds2 = 
"// Array out of bound check 2\r\n\
int[4] n;\r\n\
int[] nn = n;\r\n\
int i = 4;\r\n\
nn[i] = 3;\r\n\
return 1;";
TEST_RUNTIME_FAIL("Array out of bounds error check 2", testBounds2, "ERROR: array index out of bounds");

const char	*testBounds3 = 
"// Array out of bound check 3\r\n\
auto x0 = { 1, 2 };\r\n\
auto x1 = { 1, 2, 3 };\r\n\
auto x2 = { 1, 2, 3, 4 };\r\n\
int[3][] x;\r\n\
x[0] = x0;\r\n\
x[1] = x1;\r\n\
x[2] = x2;\r\n\
int[][] xr = x;\r\n\
return xr[1][3];";
TEST_RUNTIME_FAIL("Array out of bounds error check 3", testBounds3, "ERROR: array index out of bounds");

const char	*testInvalidFuncPtr = 
"int ref(int) a;\r\n\
return a(5);";
TEST_RUNTIME_FAIL("Invalid function pointer check", testInvalidFuncPtr, "ERROR: invalid function pointer");

const char	*testAutoReferenceMismatch =
"int a = 17;\r\n\
auto ref d = &a;\r\n\
double ref ll = d;\r\n\
return *ll;";
TEST_RUNTIME_FAIL("Auto reference type mismatch", testAutoReferenceMismatch, "ERROR: cannot convert from int ref to double ref");

const char	*testFunctionIsNotACoroutine = "for(i in auto(){return 1;}){}";
TEST_RUNTIME_FAIL("Iteration overa a function that is not a coroutine", testFunctionIsNotACoroutine, "ERROR: function is not a coroutine");

const char	*testTypeDoesntImplementMethod =
"class Foo{ int i; }\r\n\
void Foo:test(){ assert(i); }\r\n\
Foo test; test.i = 5;\r\n\
auto ref[2] objs;\r\n\
objs[0] = &test;\r\n\
objs[1] = &test.i;\r\n\
for(i in objs)\r\n\
	i.test();\r\n\
return 0;";
TEST_RUNTIME_FAIL("Type doesn't implement method on auto ref function call", testTypeDoesntImplementMethod, "ERROR: type 'int' doesn't implement method 'int::test' of type 'void ref()'");

const char	*testAutoArrayConversionFail = "int x = 12; auto[] arr = x; return 0;";
TEST_RUNTIME_FAIL("Array to auto[] type conversion fail", testAutoArrayConversionFail, "ERROR: cannot convert from 'int' to 'auto[]'");

const char	*testAutoArrayOutOfBounds = "auto str = \"Hello\"; auto[] arr = str; return char(arr[-1]) - 'l';";
TEST_RUNTIME_FAIL("auto[] type underflow", testAutoArrayOutOfBounds, "ERROR: array index out of bounds");

const char	*testAutoArrayOutOfBounds2 = "auto str = \"Hello\"; auto[] arr = str; return char(arr[7]) - 'l';";
TEST_RUNTIME_FAIL("auto[] type overflow 2", testAutoArrayOutOfBounds2, "ERROR: array index out of bounds");

const char	*testAutoArrayConversionFail2 = "auto str = \"Hello\"; auto[] arr = str; int str2 = arr; return 0;";
TEST_RUNTIME_FAIL("auto[] type conversion mismatch 1", testAutoArrayConversionFail2, "ERROR: cannot convert from 'auto[]' to 'int'");

const char	*testAutoArrayConversionFail3 = "auto str = \"Hello\"; auto[] arr = str; char[7] str2 = arr; return 0;";
TEST_RUNTIME_FAIL("auto[] type conversion mismatch 2", testAutoArrayConversionFail3, "ERROR: cannot convert from 'auto[]' (actual type 'char[6]') to 'char[7]'");

const char	*testAutoArrayConversionFail4 = "auto str = \"Hello\"; auto[] arr = str; int[] str2 = arr; return 0;";
TEST_RUNTIME_FAIL("auto[] type conversion mismatch 3", testAutoArrayConversionFail4, "ERROR: cannot convert from 'auto[]' (actual type 'char[6]') to 'int[]'");

const char	*testInvalidPointer = 
"class Test{ int a, b; }\r\n\
Test ref x;\r\n\
return x.b;";
TEST_RUNTIME_FAIL("Invalid pointer check", testInvalidPointer, "ERROR: null pointer access");

void RecallerTransition(int x)
{
	nullcRunFunction("inside", x);
}

LOAD_MODULE_BIND(func_testX, "func.testX", "void recall(int x);")
{
	nullcBindModuleFunction("func.testX", (void(*)())RecallerTransition, "recall", 0);
}
const char	*testCallStackWhenVariousTransitions =
"import func.testX;\r\n\
void inside(int x)\r\n\
{\r\n\
	assert(x);\r\n\
	recall(x-1);\r\n\
}\r\n\
recall(2);\r\n\
return 0;";
const char *error = "Assertion failed\r\n\
Call stack:\r\n\
global scope (at recall(2);)\r\n\
inside (at recall(x-1);)\r\n\
 param 0: int x (at base+0 size 4)\r\n\
inside (at recall(x-1);)\r\n\
 param 0: int x (at base+0 size 4)\r\n\
inside (at assert(x);)\r\n\
 param 0: int x (at base+0 size 4)\r\n";
struct Test_testMultipleTransiotions : TestQueue
{
	virtual void Run()
	{
		if(Tests::messageVerbose)
			printf("Call stack when there are various transitions between NULLC and C\r\n");
		for(int t = 0; t < TEST_COUNT; t++)
		{
			testsCount[t]++;
			nullcSetExecutor(testTarget[t]);
			nullres good = nullcBuild(testCallStackWhenVariousTransitions);
			if(!good)
			{
				if(!Tests::messageVerbose)
					printf("Call stack when there are various transitions between NULLC and C\r\n");
				printf("Compilation failed: %s\r\n", nullcGetLastError());
				break;
			}
			good = nullcRun();
			if(!good)
			{
				if(strcmp(error, nullcGetLastError()) != 0)
				{
					if(!Tests::messageVerbose)
						printf("Call stack when there are various transitions between NULLC and C\r\n");
					printf("%s failed but for wrong reason:\r\n    %s\r\nexpected:\r\n    %s\r\n", testTarget[t] == NULLC_VM ? "VM " : "X86", nullcGetLastError(), error);
				}else{
					testsPassed[t]++;
				}
			}else{
				if(!Tests::messageVerbose)
					printf("Call stack when there are various transitions between NULLC and C\r\n");
				printf("Test should have failed.\r\n");
			}<commit_msg>Fixed call stack with multiple C<->NULLC transitions test<commit_after>#include "TestBase.h"

#ifndef _DEBUG
	#define FAILURE_TEST
#endif

#ifdef FAILURE_TEST

const char	*testDivZeroInt = 
"// Division by zero handling\r\n\
int a = 5, b = 0;\r\n\
return a/b;";
TEST_RUNTIME_FAIL("Division by zero handling 1", testDivZeroInt, "ERROR: integer division by zero");

const char	*testDivZeroLong = 
"// Division by zero handling\r\n\
long a = 5, b = 0;\r\n\
return a / b;";
TEST_RUNTIME_FAIL("Division by zero handling 2", testDivZeroLong, "ERROR: integer division by zero");

const char	*testModZeroInt = 
"// Division by zero handling\r\n\
int a = 5, b = 0;\r\n\
return a % b;";
TEST_RUNTIME_FAIL("Modulus division by zero handling 1", testModZeroInt, "ERROR: integer division by zero");

const char	*testModZeroLong = 
"// Division by zero handling\r\n\
long a = 5, b = 0;\r\n\
return a % b;";
TEST_RUNTIME_FAIL("Modulus division by zero handling 2", testModZeroLong, "ERROR: integer division by zero");

const char	*testFuncNoReturn = 
"// Function with no return handling\r\n\
int test(){ 1; } // temporary\r\n\
return test();";
TEST_RUNTIME_FAIL("Function with no return handling", testFuncNoReturn, "ERROR: function didn't return a value");

const char	*testBounds1 = 
"// Array out of bound check \r\n\
int[4] n;\r\n\
int i = 4;\r\n\
n[i] = 3;\r\n\
return 1;";
TEST_RUNTIME_FAIL("Array out of bounds error check 1", testBounds1, "ERROR: array index out of bounds");

const char	*testBounds2 = 
"// Array out of bound check 2\r\n\
int[4] n;\r\n\
int[] nn = n;\r\n\
int i = 4;\r\n\
nn[i] = 3;\r\n\
return 1;";
TEST_RUNTIME_FAIL("Array out of bounds error check 2", testBounds2, "ERROR: array index out of bounds");

const char	*testBounds3 = 
"// Array out of bound check 3\r\n\
auto x0 = { 1, 2 };\r\n\
auto x1 = { 1, 2, 3 };\r\n\
auto x2 = { 1, 2, 3, 4 };\r\n\
int[3][] x;\r\n\
x[0] = x0;\r\n\
x[1] = x1;\r\n\
x[2] = x2;\r\n\
int[][] xr = x;\r\n\
return xr[1][3];";
TEST_RUNTIME_FAIL("Array out of bounds error check 3", testBounds3, "ERROR: array index out of bounds");

const char	*testInvalidFuncPtr = 
"int ref(int) a;\r\n\
return a(5);";
TEST_RUNTIME_FAIL("Invalid function pointer check", testInvalidFuncPtr, "ERROR: invalid function pointer");

const char	*testAutoReferenceMismatch =
"int a = 17;\r\n\
auto ref d = &a;\r\n\
double ref ll = d;\r\n\
return *ll;";
TEST_RUNTIME_FAIL("Auto reference type mismatch", testAutoReferenceMismatch, "ERROR: cannot convert from int ref to double ref");

const char	*testFunctionIsNotACoroutine = "for(i in auto(){return 1;}){}";
TEST_RUNTIME_FAIL("Iteration overa a function that is not a coroutine", testFunctionIsNotACoroutine, "ERROR: function is not a coroutine");

const char	*testTypeDoesntImplementMethod =
"class Foo{ int i; }\r\n\
void Foo:test(){ assert(i); }\r\n\
Foo test; test.i = 5;\r\n\
auto ref[2] objs;\r\n\
objs[0] = &test;\r\n\
objs[1] = &test.i;\r\n\
for(i in objs)\r\n\
	i.test();\r\n\
return 0;";
TEST_RUNTIME_FAIL("Type doesn't implement method on auto ref function call", testTypeDoesntImplementMethod, "ERROR: type 'int' doesn't implement method 'int::test' of type 'void ref()'");

const char	*testAutoArrayConversionFail = "int x = 12; auto[] arr = x; return 0;";
TEST_RUNTIME_FAIL("Array to auto[] type conversion fail", testAutoArrayConversionFail, "ERROR: cannot convert from 'int' to 'auto[]'");

const char	*testAutoArrayOutOfBounds = "auto str = \"Hello\"; auto[] arr = str; return char(arr[-1]) - 'l';";
TEST_RUNTIME_FAIL("auto[] type underflow", testAutoArrayOutOfBounds, "ERROR: array index out of bounds");

const char	*testAutoArrayOutOfBounds2 = "auto str = \"Hello\"; auto[] arr = str; return char(arr[7]) - 'l';";
TEST_RUNTIME_FAIL("auto[] type overflow 2", testAutoArrayOutOfBounds2, "ERROR: array index out of bounds");

const char	*testAutoArrayConversionFail2 = "auto str = \"Hello\"; auto[] arr = str; int str2 = arr; return 0;";
TEST_RUNTIME_FAIL("auto[] type conversion mismatch 1", testAutoArrayConversionFail2, "ERROR: cannot convert from 'auto[]' to 'int'");

const char	*testAutoArrayConversionFail3 = "auto str = \"Hello\"; auto[] arr = str; char[7] str2 = arr; return 0;";
TEST_RUNTIME_FAIL("auto[] type conversion mismatch 2", testAutoArrayConversionFail3, "ERROR: cannot convert from 'auto[]' (actual type 'char[6]') to 'char[7]'");

const char	*testAutoArrayConversionFail4 = "auto str = \"Hello\"; auto[] arr = str; int[] str2 = arr; return 0;";
TEST_RUNTIME_FAIL("auto[] type conversion mismatch 3", testAutoArrayConversionFail4, "ERROR: cannot convert from 'auto[]' (actual type 'char[6]') to 'int[]'");

const char	*testInvalidPointer = 
"class Test{ int a, b; }\r\n\
Test ref x;\r\n\
return x.b;";
TEST_RUNTIME_FAIL("Invalid pointer check", testInvalidPointer, "ERROR: null pointer access");

void RecallerTransition(int x)
{
	nullcRunFunction("inside", x);
}

LOAD_MODULE_BIND(func_testX, "func.testX", "void recall(int x);")
{
	nullcBindModuleFunction("func.testX", (void(*)())RecallerTransition, "recall", 0);
}
const char	*testCallStackWhenVariousTransitions =
"import func.testX;\r\n\
void inside(int x)\r\n\
{\r\n\
	assert(x);\r\n\
	recall(x-1);\r\n\
}\r\n\
recall(2);\r\n\
return 0;";
const char *error = "Assertion failed\r\n\
Call stack:\r\n\
global scope (at recall(2);)\r\n\
inside (at recall(x-1);)\r\n\
 param 0: int x (at base+0 size 4)\r\n\
inside (at recall(x-1);)\r\n\
 param 0: int x (at base+0 size 4)\r\n\
inside (at assert(x);)\r\n\
 param 0: int x (at base+0 size 4)\r\n";
struct Test_testMultipleTransiotions : TestQueue
{
	virtual void Run()
	{
		if(Tests::messageVerbose)
			printf("Call stack when there are various transitions between NULLC and C\r\n");
		for(int t = 0; t < TEST_COUNT; t++)
		{
			if(!Tests::testExecutor[t])
				continue;
			testsCount[t]++;
			nullcSetExecutor(testTarget[t]);
			nullres good = nullcBuild(testCallStackWhenVariousTransitions);
			if(!good)
			{
				if(!Tests::messageVerbose)
					printf("Call stack when there are various transitions between NULLC and C\r\n");
				printf("Compilation failed: %s\r\n", nullcGetLastError());
				break;
			}
			good = nullcRun();
			if(!good)
			{
				if(strcmp(error, nullcGetLastError()) != 0)
				{
					if(!Tests::messageVerbose)
						printf("Call stack when there are various transitions between NULLC and C\r\n");
					printf("%s failed but for wrong reason:\r\n    %s\r\nexpected:\r\n    %s\r\n", testTarget[t] == NULLC_VM ? "VM " : "X86", nullcGetLastError(), error);
				}else{
					testsPassed[t]++;
				}
			}else{
				if(!Tests::messageVerbose)
					printf("Call stack when there are various transitions between NULLC and C\r\n");
				printf("Test should have failed.\r\n");
			}
{'fraction_non_alphanumeric': 0.1622981599699587, 'fraction_numerical': 0.016372512204280886, 'mean_word_length': 4.373688458434221, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3069774', 'n_tokens_mistral': 5106, 'n_tokens_neox': 4791, 'n_words': 1481}