2570 lines
62 KiB
C
2570 lines
62 KiB
C
|
|
|
||
|
|
#include "method.h"
|
||
|
|
|
||
|
|
// todo
|
||
|
|
|
||
|
|
//
|
||
|
|
|
||
|
|
// method_operatorOverload.h
|
||
|
|
|
||
|
|
// method_operator_processOperatorSymbols
|
||
|
|
|
||
|
|
// method_operator_processOperatorSymbol
|
||
|
|
|
||
|
|
//
|
||
|
|
|
||
|
|
|
||
|
|
// method_chaining.h
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int total_libc_function = 293;
|
||
|
|
|
||
|
|
char * libcFunctionNames[293] = {"abort","abs","acos","asctime","asctime_r","asin","assert","atan","atan2","atexit","atof","atoi","atol","bsearch","btowc","calloc","catclose<sup>6</sup>","catgets<sup>6</sup>","catopen<sup>6</sup>","ceil","clearerr","clock","cos","cosh","ctime","ctime64","ctime_r","ctime64_r","difftime","difftime64","div","erf","erfc","exit","exp","fabs","fclose","fdopen<sup>5</sup>","feof","ferror","fflush<sup>1</sup>","fgetc<sup>1</sup>","fgetpos<sup>1</sup>","fgets<sup>1</sup>","fgetwc<sup>6</sup>","fgetws<sup>6</sup>","fileno<sup>5</sup>","floor","fmod","fopen","fprintf","fputc<sup>1</sup>","fputs<sup>1</sup>","fputwc<sup>6</sup>","fputws<sup>6</sup>","fread","free","freopen","frexp","fscanf","fseek<sup>1</sup>","fsetpos<sup>1</sup>","ftell<sup>1</sup>","fwide<sup>6</sup>","fwprintf<sup>6</sup>","fwrite","fwscanf<sup>6</sup>","gamma","getc<sup>1</sup>","getchar<sup>1</sup>","getenv","gets","getwc<sup>6</sup>","getwchar<sup>6</sup>","gmtime","gmtime64","gmtime_r","gmtime64_r","hypot","isalnum","isalpha","isascii<sup>4</sup>","isblank","iscntrl","isdigit","isgraph","islower","isprint","ispunct","isspace","isupper","iswalnum<sup>4</sup>","iswalpha<sup>4</sup>","iswblank<sup>4</sup>","iswcntrl<sup>4</sup>","iswctype<sup>4</sup>","iswdigit<sup>4</sup>","iswgraph<sup>4</sup>","iswlower<sup>4</sup>","iswprint<sup>4</sup>","iswpunct<sup>4</sup>","iswspace<sup>4</sup>","iswupper<sup>4</sup>","iswxdigit<sup>4</sup>","isxdigit<sup>4</sup>","j0","j1","jn","labs","ldexp","ldiv","localeconv","localtime","localtime64","localtime_r","localtime64_r","log","log10","longjmp","malloc","mblen","mbrlen<sup>4</sup>","mbrtowc<sup>4</sup>","mbsinit<sup>4</sup>","mbsrtowcs<sup>4</sup>","mbstowcs","mbtowc","memchr","memcmp","memcpy","memmove","memset","mktime","mktime64","modf","nextafter","nextafterl","nexttoward","nexttowardl","nl_langinfo<sup>4</sup>","perror","pow","printf","putc<sup>1</sup>","putchar<sup>1</sup>","putenv","puts","putwc<sup>6</sup>","putwchar<sup>6</sup>","qsort","quantexpd32","quantexpd64","quantexpd128","quantized32","quantized64","quantized128","samequantumd32","samequantumd64","samequantumd128","raise","rand","rand_r","realloc","regcomp","regerror","regexec","regfree","remove","rename","rewind<sup>1</sup>","scanf","setbuf","setjmp","setlocale","setvbuf","signal","sin","sinh","snprintf","sprintf","sqrt","srand","sscanf","strcasecmp","strcat","strchr","strcmp","strcoll","strcpy","strcspn","strerror","strfmon<sup>4</sup>","strftime","strlen","strncasecmp","strncat","strncmp","strncpy","strpbrk","strptime<sup>4</sup>","strrchr","strspn","strstr","strtod","strtod32","strtod64","strtod128","strtof","strtok","strtok_r","strtol","strtold","strtoul","strxfrm","swprintf","swscanf","system","tan","tanh","time","time64","tmpfile","tmpnam","toascii","tolower","toupper","towctrans","towlower<sup>4</sup>","towupper<sup>4</sup>","ungetc<sup>1</sup>","ungetwc<sup>6</sup>","va_arg","va_copy","va_end","va_start","vfprintf","vfscanf","vfwprintf<sup>6</sup>","vfwscanf","vprintf","vscanf","vsprintf","vsnprintf","vsscanf","vswprintf","vswscanf","vwprintf<sup>6</sup>","vwscanf","wcrtomb<sup>4</sup>","wcscat","wcschr","wcscmp","wcscoll<sup>4</sup>","wcscpy","wcscspn","wcsftime","wcslen","wcslocaleconv","wcsncat","wcsncmp","wcsncpy","wcspbrk","wcsptime","wcsrchr","wcsrtombs<sup>4</sup>","wcsspn","wcsstr","wcstod","wcstod32","wcstod64","wcstod128","wcstof","wcstok","wcstol","wcstold","wcstombs","wcstoul","wcsxfrm<sup>4</sup>","wctob","wctomb","wctrans","wctype<sup>4</sup>","wcwidth","wmemchr","wmemcmp","wmemcpy","wmemmove","wmemset","wprintf<sup>6</sup>","wscanf<sup>6</sup>","y0","y1","yn"};
|
||
|
|
|
||
|
|
char * libcReturnTypes[293] = {"void","int","double","char","char","double","void","double","double","int","double","int","long","void","wint_t","void","int","char","nl_catd","double","void","clock_t","double","double","char","char","char","char","double","double","div_t","double","double","void","double","double","int","FILE","int","int","int","int","int","char","wint_t","wchar_t","int","double","double","FILE","int","int","int","wint_t","int","size_t","void","FILE","double","int","int","int","long","int","int","size_t","int","double","int","int","char","char","wint_t","wint_t","struct","struct","struct","struct","double","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","int","double","double","double","long","double","ldiv_t","struct","struct","struct","struct","struct","double","double","void","void","int","int","int","int","size_t","size_t","int","void","int","void","void","void","time_t","time64_t","double","double","long","double","long","char","void","double","int","int","int","int","int","wint_t","wint_t","void","_Decimal32","_Decimal64","_Decimal128","int","int","int","__bool__","__bool__","__bool__","int","int","int","void","int","size_t","int","void","int","int","void","int","void","int","char","int","void(*signal","double","double","int","int","double","void","int","int","char","char","int","int","char","size_t","char","int","size_t","size_t","int","char","int","char","char","char","char","size_t","char","double","_Decimal32","_Decimal64","_Decimal128","float","char","char","long","long","unsigned","size_t","int","int","int","double","double","time_t","time64_t","FILE","char","int","int","int","wint_t","wint_t","wint_t","int","wint_t","<em>var_type</em>","void","void","void","int","int","int","int","int","int","int","int","int","int","int","int","int","int","wchar_t","wchar_t","int","int","wchar_t","size_t","size_t","size_t","struct","wchar_t","int","wchar_t","wchar_t","wchar_t","wchar_t","size_t","size_t","wchar_t","double","_Decimal32","_Decimal64","_Decimal128","float","wchar_t","long","long","size_t","unsigned","size_t","int","int","wctrans_t","wctype_t","int","wchar_t","int","wchar_t","wchar_t","wchar_t","int","int","double","double","double"};
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
void method_sortLineNumbers( struct array * lineNumbers ) {
|
||
|
|
|
||
|
|
int count = array_length( lineNumbers );
|
||
|
|
|
||
|
|
int i = 0;
|
||
|
|
|
||
|
|
int j = 0;
|
||
|
|
|
||
|
|
void * temp;
|
||
|
|
|
||
|
|
|
||
|
|
for (i = 0; i < (count - 1); ++i)
|
||
|
|
{
|
||
|
|
for (j = 0; j < count - 1 - i; ++j )
|
||
|
|
{
|
||
|
|
struct codeBundle * a = array_get( lineNumbers, j );
|
||
|
|
|
||
|
|
struct codeBundle * b = array_get( lineNumbers, j + 1 );
|
||
|
|
|
||
|
|
if ( a->lineNumber > b->lineNumber )
|
||
|
|
{
|
||
|
|
temp = lineNumbers->items[ j + 1 ];
|
||
|
|
|
||
|
|
lineNumbers->items[ j + 1 ] = lineNumbers->items[ j ];
|
||
|
|
|
||
|
|
lineNumbers->items[ j ] = temp;
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
char * method_getReturnTypeFromDeclerationParts( struct array * methodDeclerationParts, int methodDeclerationCount ) {
|
||
|
|
|
||
|
|
struct text * returnType = text_new( "" );
|
||
|
|
|
||
|
|
//returnType[0] = '\0';
|
||
|
|
|
||
|
|
for (int i = 0; i < methodDeclerationCount - 1; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * returnPart = ( char * ) array_get( methodDeclerationParts, i );
|
||
|
|
|
||
|
|
if( i != 0 ) {
|
||
|
|
|
||
|
|
text_append( returnType, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( strcmp( text_removeWhiteSpaces(returnPart), "*" ) == 0 ) {
|
||
|
|
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//printf(" ------------------------return type: %s\n", returnPart );
|
||
|
|
|
||
|
|
char * temporary = malloc(2);//text_removeWhiteSpaces(returnPart);
|
||
|
|
|
||
|
|
char * cleanedReturnPart = text_removeWhiteSpaces( returnPart );
|
||
|
|
|
||
|
|
if( strlen( cleanedReturnPart ) < 3 ) {
|
||
|
|
|
||
|
|
strcpy( temporary, cleanedReturnPart);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( returnType, cleanedReturnPart );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return returnType->value;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * method_extractTemplate( lexer * currentLexer, int i, char * source ) {
|
||
|
|
|
||
|
|
int closeTypeLexerIndex = lexer_findNextTokenIndex( currentLexer, i, ">" );
|
||
|
|
|
||
|
|
int closeTypeDefinition = lexer_getKey( currentLexer, closeTypeLexerIndex );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
char * className = text_extractWordBeforeKey( source, key );
|
||
|
|
|
||
|
|
int keyBeforeClassName = text_getIndexBeforeWord( source, key - 1 );
|
||
|
|
|
||
|
|
|
||
|
|
struct class * classInstance = application_getClassByClassName( allClasses, className );
|
||
|
|
|
||
|
|
if( classInstance == NULL ) {
|
||
|
|
|
||
|
|
//printf("Error: class with template not found: %s \n\n\n\n\n", className );
|
||
|
|
|
||
|
|
return source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( !classInstance->usesTemplate ) {
|
||
|
|
|
||
|
|
//printf("Error: This class does not have an template: %s \n\n", classInstance->className );
|
||
|
|
|
||
|
|
return source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * templateArguments = text_slice( source, key + 1, closeTypeDefinition - 1 );
|
||
|
|
|
||
|
|
template_addArgumentValue( classInstance, templateArguments );
|
||
|
|
|
||
|
|
char * replaceWith = template_extractTemplateName( classInstance->template, templateArguments );
|
||
|
|
|
||
|
|
|
||
|
|
replaceWith = text_replace( replaceWith, "*", "_pointer" );
|
||
|
|
|
||
|
|
replaceWith = text_regexReplaceAll( replaceWith, "struct ", "struct ", "" );
|
||
|
|
|
||
|
|
replaceWith = text_removeAllWhiteSpaces( replaceWith );
|
||
|
|
|
||
|
|
|
||
|
|
char * newName = text_copy( classInstance->className );
|
||
|
|
|
||
|
|
newName = text_concatenate( newName, "_" );
|
||
|
|
|
||
|
|
newName = text_concatenate( newName, replaceWith );
|
||
|
|
|
||
|
|
source = text_replaceAt( keyBeforeClassName, closeTypeDefinition + 1, source, newName );
|
||
|
|
|
||
|
|
|
||
|
|
return source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * method_extractTemplates( char * source ) {
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, source, "<" );
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, source, ">" );
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
if ( strcmp( token, "<" ) == 0 ) {
|
||
|
|
|
||
|
|
source = method_extractTemplate( currentLexer, i, source );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return source;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void method_extractMethodNameAndReturnType( int previousKey, int key, char * source, struct method * methodInstance ) {
|
||
|
|
|
||
|
|
|
||
|
|
char * methodDecleration = text_removeWhiteSpaces( text_slice( source, previousKey + 1, key - 1 ));
|
||
|
|
|
||
|
|
struct array * methodDeclerationParts = text_split( methodDecleration, " \t" );
|
||
|
|
|
||
|
|
int methodDeclerationCount = array_length( methodDeclerationParts );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
char * returnType = method_getReturnTypeFromDeclerationParts( methodDeclerationParts, methodDeclerationCount );
|
||
|
|
|
||
|
|
char * methodName = text_removeWhiteSpaces( array_get( methodDeclerationParts, methodDeclerationCount - 1 ) );
|
||
|
|
|
||
|
|
int maxOperatorNameLength = 20;
|
||
|
|
|
||
|
|
int methodNameLength = strlen( methodName );
|
||
|
|
|
||
|
|
methodInstance->isOperator = -1;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if( methodNameLength > 7 ) {
|
||
|
|
|
||
|
|
char* methodNameStart = malloc( 8 + 1 );
|
||
|
|
|
||
|
|
strncpy( methodNameStart, methodName, 8 );
|
||
|
|
|
||
|
|
|
||
|
|
if( strcmp( methodNameStart, "operator" ) == 0 ) {
|
||
|
|
|
||
|
|
//char * newMethodName = malloc( strlen( methodName ) + maxOperatorNameLength );
|
||
|
|
|
||
|
|
char * operatorFull = malloc( methodNameLength - 7 );
|
||
|
|
|
||
|
|
strncpy( operatorFull, methodName + 8, methodNameLength );
|
||
|
|
|
||
|
|
char * operator = text_removeWhiteSpaces( operatorFull );
|
||
|
|
|
||
|
|
char * operatorName = method_getOperatorNameByOperatorSymbol( operator );
|
||
|
|
|
||
|
|
|
||
|
|
text * newMethodName = text_new( "" );
|
||
|
|
|
||
|
|
text_append( newMethodName, "operator_" );
|
||
|
|
|
||
|
|
text_append( newMethodName, operatorName );
|
||
|
|
|
||
|
|
methodName = newMethodName->value;
|
||
|
|
|
||
|
|
methodInstance->operator = operator;
|
||
|
|
|
||
|
|
methodInstance->isOperator = 1;
|
||
|
|
|
||
|
|
|
||
|
|
printf(" this is an operator: %s %s %s", methodNameStart, operator, operatorName);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
printf(" %s(){}\n", methodName );
|
||
|
|
|
||
|
|
methodInstance->returnType = text_copy( returnType );
|
||
|
|
|
||
|
|
methodInstance->methodName = methodName;
|
||
|
|
|
||
|
|
if( strcmp( text_removeWhiteSpaces( methodInstance->returnType ), "set" ) == 0 ) {
|
||
|
|
|
||
|
|
|
||
|
|
methodInstance->returnType = "";
|
||
|
|
|
||
|
|
methodInstance->isSetter = true;
|
||
|
|
|
||
|
|
|
||
|
|
struct text * newMethodName = text_new( "" );
|
||
|
|
|
||
|
|
text_append( newMethodName, "setter_" );
|
||
|
|
|
||
|
|
text_append( newMethodName, methodName );
|
||
|
|
|
||
|
|
methodInstance->methodName = text_copy( newMethodName->value );
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//printf("methodName: %s\n\n", methodName);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void method_extractVariablesFromArguments( struct array * arguments, array * classesArray, struct array * variables ) {
|
||
|
|
|
||
|
|
|
||
|
|
int argumentCount = array_length( arguments );
|
||
|
|
|
||
|
|
for ( int j = 0; j < argumentCount; ++j )
|
||
|
|
{
|
||
|
|
char * argumentText = (char *) array_get( arguments, j );
|
||
|
|
|
||
|
|
struct array * argumentParts = text_split( argumentText, " \t" );
|
||
|
|
|
||
|
|
//printf("\n\n ?????????? find out if this is an variable: '%s' \n\n", argumentText);
|
||
|
|
|
||
|
|
variable_getVariablesByArgumentParts( argumentParts, variables, classesArray );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void method_processVariadicMethodArguments( struct class * classInstance, struct method * methodInstance ) {
|
||
|
|
|
||
|
|
/*
|
||
|
|
char * thisExpression = malloc( 3500 );
|
||
|
|
|
||
|
|
strcat( thisExpression, ( char * ) text_copy( classInstance->className ) );
|
||
|
|
|
||
|
|
strcat( thisExpression, " * this" );
|
||
|
|
|
||
|
|
array_unshift( methodInstance->arguments, thisExpression );
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
array * arguments = methodInstance->arguments;
|
||
|
|
|
||
|
|
int count = array_length( arguments );
|
||
|
|
|
||
|
|
float isVariadic = -1;
|
||
|
|
|
||
|
|
for (int i = 0; i < count; ++i)
|
||
|
|
{
|
||
|
|
char * currentArgument = text_removeWhiteSpaces( array_get( arguments, i ) );
|
||
|
|
|
||
|
|
if( strcmp( currentArgument, "..." ) == 0 ) {
|
||
|
|
|
||
|
|
isVariadic = 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( isVariadic == 1 ) {
|
||
|
|
|
||
|
|
array_unshift( methodInstance->arguments, "int datatypes[]" );
|
||
|
|
|
||
|
|
array_unshift( methodInstance->arguments, "int count" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void method_addThisVariableToVariables( struct class * classInstance, array * variables ) {
|
||
|
|
|
||
|
|
struct variable * variableInstance = malloc( sizeof( struct variable ) );
|
||
|
|
|
||
|
|
variableInstance->variableName = "this";
|
||
|
|
|
||
|
|
variableInstance->datatype = classInstance->className;
|
||
|
|
|
||
|
|
//variableInstance->isPointer = 1;
|
||
|
|
|
||
|
|
array_add( variables, variableInstance );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
struct array * method_getArguments_new( lexer * currentLexer, int key, int i, char * source, struct array * variables ) {
|
||
|
|
|
||
|
|
int argumentCloseIndex = 0;
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
int depth = 1;
|
||
|
|
|
||
|
|
for (int j = i + 1; j < count; ++j)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, j );
|
||
|
|
|
||
|
|
if( strcmp( token, "(" ) == 0 ) {
|
||
|
|
|
||
|
|
depth++;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( strcmp( token, ")" ) == 0 ) {
|
||
|
|
|
||
|
|
depth--;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//printf("???????????????? token %s %i \n", token, depth);
|
||
|
|
|
||
|
|
if( depth == 0 ) {
|
||
|
|
|
||
|
|
argumentCloseIndex = lexer_getKey( currentLexer, j );
|
||
|
|
|
||
|
|
break;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * argumentsText = text_removeWhiteSpaces( text_slice( source, key + 1, argumentCloseIndex - 1 ));
|
||
|
|
|
||
|
|
struct array * argumentsArray = text_split( argumentsText, "," );
|
||
|
|
|
||
|
|
int argumentCount = array_length( argumentsArray );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = 0; i < argumentCount; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * currentArgument = array_get( argumentsArray, i );
|
||
|
|
|
||
|
|
struct array * argumentParts = text_split( currentArgument, " \t" );
|
||
|
|
|
||
|
|
//char * datatype = tools_findDatatype( argumentParts );
|
||
|
|
|
||
|
|
|
||
|
|
if( text_contains( currentArgument, "<" ) ) {
|
||
|
|
|
||
|
|
printf("\n\n\n\n This is a template: %s\n\n\n", currentArgument);
|
||
|
|
|
||
|
|
int templateOpenKey = text_text_findFirstCharacterIndexFromIndex( currentArgument, "<", 0 );
|
||
|
|
|
||
|
|
int templateCloseKey = text_text_findFirstCharacterIndexFromIndex( currentArgument, ">", 0 );
|
||
|
|
|
||
|
|
|
||
|
|
char * templateArgument = text_slice( currentArgument, templateOpenKey + 1, templateCloseKey - 1 );
|
||
|
|
|
||
|
|
char * className = text_removeWhiteSpaces( text_slice( currentArgument, 0 , templateOpenKey - 1 ) ) ;
|
||
|
|
|
||
|
|
char * classNameClean = tools_findDatatype( text_split( className, " \t" ) );
|
||
|
|
|
||
|
|
struct array * parts = text_split( currentArgument, " \t" );
|
||
|
|
|
||
|
|
|
||
|
|
char * variableName = array_get( parts, array_length( parts ) - 1 );
|
||
|
|
|
||
|
|
|
||
|
|
struct text * newVariableName = text_new( "" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
templateArgument = text_regexReplaceAll( templateArgument, "struct ", "struct ", "" );
|
||
|
|
|
||
|
|
text_removeSpaces( templateArgument );
|
||
|
|
|
||
|
|
text_append( newVariableName, classNameClean );
|
||
|
|
|
||
|
|
text_append( newVariableName, "_" );
|
||
|
|
|
||
|
|
text_append( newVariableName, templateArgument );
|
||
|
|
|
||
|
|
|
||
|
|
currentArgument = text_replaceAt( 0, templateCloseKey + 1, currentArgument, newVariableName->value );
|
||
|
|
|
||
|
|
printf("\n\n\n\n This is a template: %s\n\n\n", currentArgument);
|
||
|
|
|
||
|
|
printf("\n\n\n\n %i - %i %s %s \n\n\n", templateOpenKey, templateCloseKey, templateArgument, classNameClean );
|
||
|
|
|
||
|
|
array_set( argumentsArray, i, currentArgument );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
struct variable * variableInstance = malloc( sizeof( struct variable ) );
|
||
|
|
|
||
|
|
variableInstance->variableName = variableName;
|
||
|
|
|
||
|
|
variableInstance->datatype = newVariableName->value;
|
||
|
|
|
||
|
|
printf("\n\n\n add argument as variable: variable->variableName %s variableInstance->datatype %s\n\n\n", variableInstance->variableName, variableInstance->datatype);
|
||
|
|
|
||
|
|
variableInstance->isPointer = variable_isPointer( parts );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
array_add( variables, variableInstance );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//printf("argumentsText: %s %i\n", argumentsText, array_length(argumentsArray));
|
||
|
|
|
||
|
|
return argumentsArray;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
void method_addThisVariableToMethodArguments( struct class * classInstance, struct method * methodInstance ) {
|
||
|
|
|
||
|
|
struct text * thisExpression = text_new( "" );
|
||
|
|
|
||
|
|
text_append( thisExpression, classInstance->className );
|
||
|
|
|
||
|
|
text_append( thisExpression, " * this" );
|
||
|
|
|
||
|
|
array_unshift( methodInstance->arguments, thisExpression->value );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
struct array * method_addArgumentsToMethod( struct class * classInstance, struct method * methodInstance, struct array * classesArray, struct array * argumentsArray ) {
|
||
|
|
|
||
|
|
method_extractVariablesFromArguments( methodInstance->arguments, classesArray, methodInstance->variables );
|
||
|
|
|
||
|
|
method_addThisVariableToVariables( classInstance, methodInstance->variables );
|
||
|
|
|
||
|
|
method_processVariadicMethodArguments( classInstance, methodInstance );
|
||
|
|
|
||
|
|
method_addThisVariableToMethodArguments( classInstance, methodInstance );
|
||
|
|
|
||
|
|
return methodInstance->variables;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct array * method_extractArguments( lexer * currentLexer, int key, char * source, int i, struct class * classInstance, struct method * methodInstance, struct array * classesArray ) {
|
||
|
|
|
||
|
|
methodInstance->arguments = array_new();
|
||
|
|
|
||
|
|
methodInstance->variables = array_new();
|
||
|
|
|
||
|
|
methodInstance->arguments = method_getArguments_new( currentLexer, key, i, source, methodInstance->variables );
|
||
|
|
|
||
|
|
methodInstance->isVariadic = method_methodIsVaradic( methodInstance->arguments );
|
||
|
|
|
||
|
|
method_addArgumentsToMethod( classInstance, methodInstance, classesArray, methodInstance->arguments );
|
||
|
|
|
||
|
|
return methodInstance->variables;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int method_checkIfSymbolIsOperator( char * functionName ) {
|
||
|
|
|
||
|
|
array * functionNameParts = text_split( text_copy( functionName ), "_" );
|
||
|
|
|
||
|
|
int partsCount = array_length( functionNameParts );
|
||
|
|
|
||
|
|
if( partsCount > 1 ) {
|
||
|
|
|
||
|
|
char * operatorPart = array_get( functionNameParts, 1 );
|
||
|
|
|
||
|
|
if( strcmp( operatorPart, "operator" ) == 0 ) {
|
||
|
|
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int method_methodIsVaradic( array * arguments ) {
|
||
|
|
|
||
|
|
float isVariadic = -1;
|
||
|
|
|
||
|
|
int count = array_length( arguments );
|
||
|
|
|
||
|
|
for (int i = 0; i < count; ++i)
|
||
|
|
{
|
||
|
|
char * currentArgument = text_removeWhiteSpaces( array_get( arguments, i ) );
|
||
|
|
|
||
|
|
if( strcmp( currentArgument, "..." ) == 0 ) {
|
||
|
|
|
||
|
|
|
||
|
|
isVariadic = 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return isVariadic;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * method_composeOperatorOverloadOpeningDeclaration( char * baseClassName, char * operatorName, int leftSideIsPointer ) {
|
||
|
|
|
||
|
|
struct text * newMethodDecleration = text_new( "" );
|
||
|
|
|
||
|
|
text_append( newMethodDecleration, baseClassName );
|
||
|
|
|
||
|
|
text_append( newMethodDecleration, "_operator_" );
|
||
|
|
|
||
|
|
text_append( newMethodDecleration, operatorName );
|
||
|
|
|
||
|
|
text_append( newMethodDecleration, "( " );
|
||
|
|
|
||
|
|
if( leftSideIsPointer != 1 ) {
|
||
|
|
|
||
|
|
text_append( newMethodDecleration, "&" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return newMethodDecleration->value;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * method_getOperatorNameByOperatorSymbol( char * symbol ) {
|
||
|
|
|
||
|
|
if( strcmp( symbol, "+" ) == 0 ) {
|
||
|
|
|
||
|
|
return "plus";
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( strcmp( symbol, "+=" ) == 0 ) {
|
||
|
|
|
||
|
|
return "add";
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( strcmp( symbol, "==" ) == 0 ) {
|
||
|
|
|
||
|
|
return "compare";
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( strcmp( symbol, "=" ) == 0 ) {
|
||
|
|
|
||
|
|
return "is";
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return symbol;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct method * method_extractMethodFromSymbol( char * functionName ) {
|
||
|
|
|
||
|
|
struct array * nameParts = text_split( text_copy( functionName ), "_" );
|
||
|
|
|
||
|
|
int partsCount = array_length( nameParts );
|
||
|
|
|
||
|
|
char * className = array_get( nameParts, 0 );
|
||
|
|
|
||
|
|
array_delete( nameParts, 0 );
|
||
|
|
|
||
|
|
char * methodName = text_join( nameParts, "_" );
|
||
|
|
|
||
|
|
struct class * classInstance = application_getClassByClassName( allClasses, className );
|
||
|
|
|
||
|
|
if( classInstance != NULL ) {
|
||
|
|
|
||
|
|
return method_getMethodByMethodName( classInstance, methodName );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
return NULL;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// exists
|
||
|
|
int method_findMethodByName( struct class * classInstance, char * methodName ) {
|
||
|
|
|
||
|
|
struct array * methods = classInstance->methods;
|
||
|
|
|
||
|
|
int count = array_length( methods );
|
||
|
|
|
||
|
|
for (int k = 0; k < count; ++k)
|
||
|
|
{
|
||
|
|
struct method * methodInstance = array_get( methods, k );
|
||
|
|
|
||
|
|
if( strcmp( methodInstance->methodName, methodName ) == 0 ) {
|
||
|
|
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct method * method_getMethodByMethodName( struct class * classInstance, char * methodName ) {
|
||
|
|
|
||
|
|
struct array * methods = classInstance->methods;
|
||
|
|
|
||
|
|
int count = array_length( methods );
|
||
|
|
|
||
|
|
struct array * output = array_new();
|
||
|
|
|
||
|
|
for (int i = 0; i < count; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct method * currentMethod = array_get( methods, i );
|
||
|
|
|
||
|
|
//printf(" getMethodByName %s %s\n", currentMethod->methodName, methodName );
|
||
|
|
|
||
|
|
if( strcmp( currentMethod->methodName, methodName ) == 0 ) {
|
||
|
|
|
||
|
|
return currentMethod;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( classInstance->hasExtended == 1 ) {
|
||
|
|
|
||
|
|
return NULL;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct array * extends = classInstance->extends;
|
||
|
|
|
||
|
|
int extendCount = array_length( extends );
|
||
|
|
|
||
|
|
for ( int i = 0; i < extendCount; ++i )
|
||
|
|
{
|
||
|
|
|
||
|
|
char * extendName = text_removeWhiteSpaces( array_get( extends, i ) );
|
||
|
|
|
||
|
|
struct class * extendedClass = application_getClassByClassName( allClasses, extendName );
|
||
|
|
|
||
|
|
struct method * foundMethod = method_getMethodByMethodName( extendedClass, methodName );
|
||
|
|
|
||
|
|
if( foundMethod != NULL ) {
|
||
|
|
|
||
|
|
return foundMethod;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
return NULL;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void method_parseFirstNextMethodInChain( lexer * currentLexer, int i, char * body, int key, struct array * replacements ) {
|
||
|
|
|
||
|
|
int keyAfterMethod = text_extractIndexAfterWord( body, key + 1 );
|
||
|
|
|
||
|
|
if( body[ keyAfterMethod ] == 40 || body[keyAfterMethod + 1] == 40 ){
|
||
|
|
|
||
|
|
void * previousToken = lexer_getToken( currentLexer, i - 1 );
|
||
|
|
|
||
|
|
// ↓
|
||
|
|
// variable->method( "" )->method()
|
||
|
|
if ( strcmp( previousToken, ")" ) == 0 ) {
|
||
|
|
|
||
|
|
int previousKey = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
int keyAfterMethod = text_extractIndexAfterWord( body, key + 1 );
|
||
|
|
|
||
|
|
int argumentOpenIndex = text_text_findFirstCharacterIndexFromIndex( body, "(", keyAfterMethod -1 );
|
||
|
|
|
||
|
|
int argumentCloseIndex = text_findArgumentCloseIndex( body, (int ) keyAfterMethod - 1 );
|
||
|
|
|
||
|
|
char * methodName = text_removeWhiteSpaces( text_slice( body, key + 2, keyAfterMethod - 1 ) );
|
||
|
|
|
||
|
|
// caller current
|
||
|
|
//
|
||
|
|
// caller 'char_concatenate( a, b )->concatenate->( d )'
|
||
|
|
int callerArgumentCloseIndex = tools_findArgumentCloseIndexReverse( body, (int ) previousKey );
|
||
|
|
|
||
|
|
int indexBeforeCaller = text_getIndexBeforeWord( body, callerArgumentCloseIndex );
|
||
|
|
|
||
|
|
char * variableName = text_removeWhiteSpaces( text_slice( body, indexBeforeCaller, previousKey ) );
|
||
|
|
|
||
|
|
char * callerFunctionName = text_removeWhiteSpaces( text_slice( body, indexBeforeCaller, callerArgumentCloseIndex -1 ) );
|
||
|
|
|
||
|
|
struct array * callerFunctionNameParts = text_split( callerFunctionName, "_" );
|
||
|
|
|
||
|
|
if( array_length( callerFunctionNameParts ) == 1 ) {
|
||
|
|
|
||
|
|
// previouse "->something()" is not yet processed
|
||
|
|
//printf("Previous '->something()' is not yet processed");
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * callerClassName = array_get( callerFunctionNameParts, 0 );
|
||
|
|
|
||
|
|
char * callerMethodName = text_removeWhiteSpaces( text_slice( body, indexBeforeCaller + strlen(callerClassName) + 1, callerArgumentCloseIndex - 1 ) );
|
||
|
|
|
||
|
|
struct class * callerClass = application_getClassByClassName( allClasses, callerClassName );
|
||
|
|
|
||
|
|
struct method * callerMethod = method_getMethodByMethodName( callerClass, callerMethodName );
|
||
|
|
|
||
|
|
if( callerMethod == NULL ) {
|
||
|
|
|
||
|
|
//printf("method not found");
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
struct array * returnParts = text_split( callerMethod->returnType, " \t" );
|
||
|
|
|
||
|
|
char * returnDatatype = tools_findDatatype( returnParts );
|
||
|
|
|
||
|
|
if( strcmp( returnDatatype, "void *" ) ) {
|
||
|
|
|
||
|
|
printf( ANSI_COLOR_RED " Error: you are not supposed to use void pointers within method chaining. %s()->%s() \n\n" ANSI_COLOR_RESET, callerMethodName, methodName);
|
||
|
|
|
||
|
|
|
||
|
|
//exit( 0 );
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * partToRemove = text_removeWhiteSpaces( text_slice( body, previousKey, argumentOpenIndex ) );// replace with a ','
|
||
|
|
|
||
|
|
char * argumentsText = text_slice( body, argumentOpenIndex + 1, argumentCloseIndex - 2 );
|
||
|
|
|
||
|
|
|
||
|
|
printf(" Processing chain: %s->%s() : %s %s \n", callerClassName, callerMethodName, callerMethod->returnType, variableName);
|
||
|
|
char * testLastIndex = text_slice( body, (int)previousKey, argumentCloseIndex );
|
||
|
|
|
||
|
|
if( argumentCloseIndex == -1 ) {
|
||
|
|
|
||
|
|
//continue;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// todo check if returnDatatype is a valid class
|
||
|
|
|
||
|
|
if( strlen( text_removeWhiteSpaces( argumentsText ) ) == 0 ) {
|
||
|
|
|
||
|
|
replacement_add( previousKey, argumentOpenIndex + 1, " ", replacements );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
replacement_add( previousKey, argumentOpenIndex + 1, ", ", replacements );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct text * newMethodDecleration = text_new( "" );
|
||
|
|
|
||
|
|
text_append( newMethodDecleration, returnDatatype );
|
||
|
|
|
||
|
|
text_append( newMethodDecleration, "_" );
|
||
|
|
|
||
|
|
text_append( newMethodDecleration, methodName);
|
||
|
|
|
||
|
|
text_append( newMethodDecleration, "(" );
|
||
|
|
|
||
|
|
replacement_add( indexBeforeCaller, indexBeforeCaller, newMethodDecleration->value, replacements );
|
||
|
|
|
||
|
|
/*
|
||
|
|
printf("---------------- newMethodDecleration = %s\n", newMethodDecleration);
|
||
|
|
|
||
|
|
printf("---------------- methodName = %s\n", methodName);
|
||
|
|
|
||
|
|
printf("---------------- argumentsText = %s\n", argumentsText);
|
||
|
|
|
||
|
|
printf("---------------- testLastIndex = %s\n", testLastIndex);
|
||
|
|
|
||
|
|
printf("---------------- partToRemove = %s\n", partToRemove);
|
||
|
|
|
||
|
|
printf("---------------- returnType = %s\n", returnDatatype);
|
||
|
|
|
||
|
|
printf("-------------------------**********argumentCloseIndex: %s %s %s %s \n\n", callerMethodName, callerClassName, callerFunctionName, variableName);
|
||
|
|
*/
|
||
|
|
}
|
||
|
|
|
||
|
|
// class methodName
|
||
|
|
//
|
||
|
|
// char_concatenate
|
||
|
|
// ↓
|
||
|
|
// char_concatenate( " " )->concatenate( " and this end." )
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
char * method_replaceMultiMethods( char * body ) {
|
||
|
|
|
||
|
|
|
||
|
|
array * replacements = array_new();
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "{");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "}");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "(");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ")");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ";");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "=");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "->");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ".");
|
||
|
|
|
||
|
|
|
||
|
|
lexer_add( currentLexer, 0, ";" );
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
|
||
|
|
if ( strcmp( token, "->" ) == 0 ) {
|
||
|
|
|
||
|
|
method_parseFirstNextMethodInChain( currentLexer, i, body, key, replacements );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( token, "." ) == 0 ) {
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
replacement_sort( replacements );
|
||
|
|
|
||
|
|
count = array_length( replacements );
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i){
|
||
|
|
|
||
|
|
struct replacement * a = array_get( replacements, i );
|
||
|
|
|
||
|
|
body = text_replaceAt( a->fromIndex, a->toIndex, body, a->content );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( count > 0 ) {
|
||
|
|
|
||
|
|
body = method_replaceMultiMethods( body );
|
||
|
|
}
|
||
|
|
|
||
|
|
return body;
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void processCallback( int key, int i, char * body, array * variables, array * functions, array * replacements ) {
|
||
|
|
|
||
|
|
int keyAfterMethod = text_extractIndexAfterWord( body, key + 1 );
|
||
|
|
|
||
|
|
if( body[keyAfterMethod] != 40 ) {
|
||
|
|
|
||
|
|
// this is for callbacks this->somecallback
|
||
|
|
int keyAfterMethod = text_extractIndexAfterWord( body, key + 1 );
|
||
|
|
|
||
|
|
int beforeMethodNameKey = text_getIndexBeforeWord( body, key );
|
||
|
|
|
||
|
|
char * variableName = text_removeWhiteSpaces( text_slice( body, beforeMethodNameKey, key -1 ) );
|
||
|
|
|
||
|
|
char * methodName = text_removeWhiteSpaces( text_slice( body, key + 2, (int) keyAfterMethod - 1 ) );
|
||
|
|
|
||
|
|
//char * test = text_removeWhiteSpaces( text_slice( body, beforeMethodNameKey, (int) keyAfterMethod - 1 ) );
|
||
|
|
|
||
|
|
struct variable * variable = variable_getByName( variables, variableName );
|
||
|
|
|
||
|
|
struct class * currentClass = application_getClassByClassName( allClasses, variable->datatype );
|
||
|
|
|
||
|
|
if( currentClass == 0 ) {
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int isMethod = method_findMethodByName( currentClass, methodName );
|
||
|
|
|
||
|
|
//printf("Current class found! ------------------------- %s %s %s %i \n\n", currentClass->className, variableName, methodName, isMethod );
|
||
|
|
// this doesnt work yet -> replace inline callback functions
|
||
|
|
// transform 'sqlite->print' to 'print'
|
||
|
|
// replacement_add( (int) beforeMethodNameKey, (int) keyAfterMethod - 1, methodName, replacements );
|
||
|
|
|
||
|
|
if( isMethod == 1 ) {
|
||
|
|
|
||
|
|
struct method * currentMethod = method_getMethodByMethodName( currentClass, methodName );
|
||
|
|
|
||
|
|
struct text * newName = text_new( "" );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( newName, "callback_" );
|
||
|
|
|
||
|
|
text_append( newName, currentClass->className );
|
||
|
|
|
||
|
|
text_append( newName, "_" );
|
||
|
|
|
||
|
|
text_append( newName, methodName );
|
||
|
|
|
||
|
|
|
||
|
|
int functionExistsCheck = functionExists( functions, newName->value );
|
||
|
|
|
||
|
|
if( functionExistsCheck == -1 ) {
|
||
|
|
|
||
|
|
cloneMethodToFunction( currentMethod, functions, newName->value );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//printf("this is a callback replace '%s' with '%s' \n\n", variableName, currentClass->className);
|
||
|
|
|
||
|
|
replacement_add( (int) beforeMethodNameKey, (int) keyAfterMethod, newName->value, replacements );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void method_parseFirstChainMethodCall( lexer * currentLexer,
|
||
|
|
int i,
|
||
|
|
char * body,
|
||
|
|
int currentKey,
|
||
|
|
char * currentToken,
|
||
|
|
struct array * variables,
|
||
|
|
struct array * replacements,
|
||
|
|
int methodSeparatorLength ) {
|
||
|
|
|
||
|
|
void * nextToken = lexer_getToken( currentLexer, i + 1 );
|
||
|
|
|
||
|
|
void * previousToken = lexer_getToken( currentLexer, i - 1 );
|
||
|
|
|
||
|
|
//printf("this is a method: %s\n", nextToken);
|
||
|
|
|
||
|
|
// ↓
|
||
|
|
// variable->method( "" )->method()
|
||
|
|
if ( strcmp( previousToken, ")" ) == 0 ) {
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( nextToken, "(" ) == 0 ) {
|
||
|
|
|
||
|
|
int nextKey = lexer_getKey( currentLexer, i + 1 );
|
||
|
|
|
||
|
|
char * methodName = text_slice( body, currentKey + methodSeparatorLength, nextKey - 1 );
|
||
|
|
|
||
|
|
char * variableName = text_extractWordBeforeKey( body, currentKey );
|
||
|
|
|
||
|
|
|
||
|
|
struct class * callerClass;
|
||
|
|
|
||
|
|
int isVariadic = -1;
|
||
|
|
|
||
|
|
|
||
|
|
int beforeVariableNameKey;
|
||
|
|
|
||
|
|
char * datatype;
|
||
|
|
|
||
|
|
int isPointer;
|
||
|
|
|
||
|
|
// |
|
||
|
|
// this->something->someMethod();
|
||
|
|
if( variableName[0] == 62 ) {
|
||
|
|
|
||
|
|
int indexBeforeVariableName = text_getIndexBeforeWord( body, currentKey );
|
||
|
|
|
||
|
|
char * baseClassName = text_extractWordBeforeKey( body, indexBeforeVariableName-1 );
|
||
|
|
|
||
|
|
|
||
|
|
beforeVariableNameKey = text_getIndexBeforeWord( body, indexBeforeVariableName-1 );
|
||
|
|
|
||
|
|
char * propertyName = text_slice( body, indexBeforeVariableName + 1, currentKey -1 );
|
||
|
|
|
||
|
|
struct variable * variableInstance = variable_getByName( variables, baseClassName );
|
||
|
|
|
||
|
|
struct class * baseClass = application_getClassByClassName( allClasses, variableInstance->datatype );
|
||
|
|
|
||
|
|
int propertyIndex = class_getPropertyIndexByName( baseClass, propertyName );
|
||
|
|
|
||
|
|
struct property * propertyInstance = array_get( baseClass->properties, propertyIndex );
|
||
|
|
|
||
|
|
//callerClass = propertyInstance->datatype;
|
||
|
|
|
||
|
|
datatype = propertyInstance->datatype;
|
||
|
|
|
||
|
|
isPointer = propertyInstance->isPointer;
|
||
|
|
|
||
|
|
variableName = text_slice( body, beforeVariableNameKey, currentKey -1 );
|
||
|
|
|
||
|
|
|
||
|
|
//printf("get property of class: %s %s %s %s ", variableInstance->datatype, propertyName, propertyInstance->datatype, methodName);
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
beforeVariableNameKey = text_getIndexBeforeWord( body, currentKey );
|
||
|
|
|
||
|
|
|
||
|
|
struct variable * variableInstance = variable_getByName( variables, variableName );
|
||
|
|
|
||
|
|
if( strcmp( variableInstance->datatype, "this_variable_is_missing" ) == 0 ) {
|
||
|
|
|
||
|
|
printf( ANSI_COLOR_RED "Error: Variable with name '%s' is missing, You probably need to include a file containing a class associated with this variable. " ANSI_COLOR_RESET, variableName );
|
||
|
|
|
||
|
|
exit( 0 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( isalpha( variableInstance->datatype[0] ) == 0 ) {
|
||
|
|
|
||
|
|
printf(" this is not a datatype\n\n");
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
isPointer = variableInstance->isPointer;
|
||
|
|
|
||
|
|
datatype = variableInstance->datatype;
|
||
|
|
|
||
|
|
/*
|
||
|
|
|
||
|
|
if ( strcmp( variableName, "test" ) == 0 ) {
|
||
|
|
|
||
|
|
datatype = "vector2";
|
||
|
|
}
|
||
|
|
*/
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
callerClass = application_getClassByClassName( allClasses, datatype );
|
||
|
|
|
||
|
|
if( callerClass == NULL ) {
|
||
|
|
|
||
|
|
printf( ANSI_COLOR_RED "ERROR: " ANSI_COLOR_RESET "Class '%s' not found, Maybe you need to include the file containing this the class '%s'. line number: ?? \n\n", datatype, datatype );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
exit( 0 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct method * callerMethod = method_getMethodByMethodName( callerClass, methodName );
|
||
|
|
|
||
|
|
if( callerMethod == NULL ) {
|
||
|
|
|
||
|
|
printf(ANSI_COLOR_RED "ERROR: " ANSI_COLOR_RESET " Method '%s' not found. Class '%s' does not have an method called '%s'. \n\n", methodName, callerClass->className, methodName );
|
||
|
|
|
||
|
|
struct property * currentProperty = class_getPropertyByName( callerClass, methodName );
|
||
|
|
|
||
|
|
if( currentProperty == NULL ) {
|
||
|
|
|
||
|
|
exit( 0 );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
if( strcmp( currentProperty->type, "function" ) != 0 ) {
|
||
|
|
|
||
|
|
exit( 0 );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
printf("return\n\n\n\n\n");
|
||
|
|
|
||
|
|
// this is an function callback this->somecallback();
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
//struct method * callerMethod = array_get( methods, 0 );
|
||
|
|
|
||
|
|
isVariadic = callerMethod->isVariadic;
|
||
|
|
|
||
|
|
//printf("this method is isVariadic: %s %i %s\n\n", variableInstance->variableName, callerMethod->isVariadic, callerClass->className);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * toReplace = text_slice( body, beforeVariableNameKey, nextKey - 1 );
|
||
|
|
|
||
|
|
struct text * newFunctionDeclaration = text_new( "" );
|
||
|
|
|
||
|
|
//char * newFunctionDeclaration = malloc(1000);
|
||
|
|
|
||
|
|
text_append( newFunctionDeclaration, datatype );
|
||
|
|
|
||
|
|
text_append( newFunctionDeclaration, "_" );
|
||
|
|
|
||
|
|
text_append( newFunctionDeclaration, text_copy( methodName ) );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int openArgumentKey = lexer_findNextToken( currentLexer, i, "(" );
|
||
|
|
|
||
|
|
int closeArgumentKey = lexer_findNextToken( currentLexer, i, ")" );
|
||
|
|
|
||
|
|
char * argumentsText = text_removeWhiteSpaces( text_slice( body, openArgumentKey +1 , closeArgumentKey - 1 ) );
|
||
|
|
|
||
|
|
struct array * argumentsArray = text_splitArguments( argumentsText );
|
||
|
|
|
||
|
|
int argumentCount = array_length( argumentsArray );
|
||
|
|
|
||
|
|
struct text * newFirstArgument = text_new( "" );
|
||
|
|
|
||
|
|
text_append( newFirstArgument, " " );
|
||
|
|
|
||
|
|
if( isPointer == -1 ) {
|
||
|
|
|
||
|
|
text_append( newFirstArgument, "&" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( newFirstArgument, text_copy( variableName ) );
|
||
|
|
|
||
|
|
if( argumentCount > 0 ) {
|
||
|
|
|
||
|
|
text_append( newFirstArgument, ", " );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
text_append( newFirstArgument, " " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( isVariadic == 1 ) {
|
||
|
|
|
||
|
|
//printf("----------------------------------============================================================ this method is variadic. %i \n\n\n\n", isVariadic);
|
||
|
|
|
||
|
|
struct array * argumentDatatypes = argument_getArgumentDatatypes( argumentsArray, variables );
|
||
|
|
|
||
|
|
int argumentDatatypeCount = array_length( argumentDatatypes );
|
||
|
|
|
||
|
|
char * numberOfVariadicArguments = text_fromNumber( argumentDatatypeCount );
|
||
|
|
|
||
|
|
|
||
|
|
text_append( newFirstArgument, numberOfVariadicArguments );
|
||
|
|
|
||
|
|
text_append( newFirstArgument, ", " );
|
||
|
|
|
||
|
|
text_append( newFirstArgument, "(int[" );
|
||
|
|
|
||
|
|
text_append( newFirstArgument, numberOfVariadicArguments );
|
||
|
|
|
||
|
|
text_append( newFirstArgument, "]){ " );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
for (int k = 0; k < argumentDatatypeCount; ++k)
|
||
|
|
{
|
||
|
|
|
||
|
|
uintptr_t datatypeIndex = ( uintptr_t ) array_get( argumentDatatypes, k );
|
||
|
|
|
||
|
|
if( k != 0 ) {
|
||
|
|
|
||
|
|
text_append( newFirstArgument, "," );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( newFirstArgument, text_fromNumber( datatypeIndex ) );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( newFirstArgument, " }" );
|
||
|
|
|
||
|
|
text_append( newFirstArgument, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
replacement_add( beforeVariableNameKey, nextKey, newFunctionDeclaration->value, replacements );
|
||
|
|
|
||
|
|
replacement_add( (int) openArgumentKey+ 1, (int) openArgumentKey + 1, newFirstArgument->value, replacements );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
struct property * method_getArrowRecursive( struct array * arrows, char * datatype ) {
|
||
|
|
|
||
|
|
|
||
|
|
struct class * variableDatatypeClass = application_getClassByClassName( allClasses, datatype );
|
||
|
|
|
||
|
|
struct array * properties = variableDatatypeClass->properties;
|
||
|
|
|
||
|
|
int propertyCount = array_length( properties );
|
||
|
|
|
||
|
|
char * secondVariableName = array_get( arrows, 0 );
|
||
|
|
|
||
|
|
|
||
|
|
array_delete( arrows, 0 );
|
||
|
|
|
||
|
|
for (int j = 0; j < propertyCount; ++j)
|
||
|
|
{
|
||
|
|
|
||
|
|
struct property * currentProperty = array_get( properties, j );
|
||
|
|
|
||
|
|
if ( strcmp( currentProperty->propertyName, secondVariableName ) == NULL )
|
||
|
|
{
|
||
|
|
|
||
|
|
if( array_length( arrows ) > 0 ) {
|
||
|
|
|
||
|
|
return method_getArrowRecursive( arrows, currentProperty->datatype );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
return currentProperty;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//return currentProperty->datatype;
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return NULL;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void method_replaceNewSymbol( lexer * currentLexer,
|
||
|
|
int i,
|
||
|
|
char * body,
|
||
|
|
int currentKey,
|
||
|
|
struct array * variables,
|
||
|
|
struct array * replacements ) {
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int classOpenArgumentKey = lexer_findNextToken( currentLexer, i, "(" );
|
||
|
|
|
||
|
|
int isKey = lexer_findPreviousKeyByToken( currentLexer, i, "=" );
|
||
|
|
|
||
|
|
int previousLineBreak = text_findPreviousLineBreak( body, currentKey );
|
||
|
|
|
||
|
|
char * className = text_removeWhiteSpaces( text_slice( body, currentKey + 3 , classOpenArgumentKey - 1 ) );
|
||
|
|
|
||
|
|
if( isKey > 0 ) {
|
||
|
|
|
||
|
|
isKey--;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * defineText = text_removeWhiteSpaces( text_slice( body, previousLineBreak + 1, isKey ) );
|
||
|
|
|
||
|
|
struct array * defineParts = text_split( defineText, " \t" );
|
||
|
|
|
||
|
|
char * variableName = array_get( defineParts, array_length( defineParts ) - 1 );
|
||
|
|
|
||
|
|
|
||
|
|
char * classDefinition = array_get( defineParts, 0 );
|
||
|
|
|
||
|
|
if( strcmp( classDefinition, "struct" ) == 0 ) {
|
||
|
|
|
||
|
|
classDefinition = array_get( defineParts, 1 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int isPointer = -1;
|
||
|
|
|
||
|
|
|
||
|
|
if( array_length( defineParts ) == 1 ) {
|
||
|
|
|
||
|
|
struct variable * variableInstance = variable_getByName( variables, text_removeWhiteSpaces( defineText ) );
|
||
|
|
|
||
|
|
printf("define text: %s\n", text_removeWhiteSpaces( defineText ));
|
||
|
|
|
||
|
|
if( variableInstance == NULL ) {
|
||
|
|
|
||
|
|
printf("this is not a global variable\n\n");
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
printf(" This is an global variable %s %i\n\n ", variableInstance->variableName, variableInstance->isPointer);
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
isPointer = variableInstance->isPointer;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( array_length( defineParts ) == 1 ) {
|
||
|
|
|
||
|
|
struct array * arrows = text_split( classDefinition, "->" );
|
||
|
|
|
||
|
|
struct array * dotted = text_split( classDefinition, "." );
|
||
|
|
|
||
|
|
|
||
|
|
if( array_length( dotted ) > 1 ) {
|
||
|
|
|
||
|
|
arrows = dotted;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( array_length( arrows ) > 1 ) {
|
||
|
|
|
||
|
|
char * firstVariableName = array_get( arrows, 0 );
|
||
|
|
|
||
|
|
array_delete( arrows, 0 );
|
||
|
|
|
||
|
|
struct variable * firstVariableInstance = variable_getByName( variables, firstVariableName );
|
||
|
|
|
||
|
|
char * variableDatatype = firstVariableInstance->datatype;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
struct property * currentProperty = method_getArrowRecursive( arrows, variableDatatype );
|
||
|
|
|
||
|
|
// arrow instance -> background
|
||
|
|
|
||
|
|
|
||
|
|
int isKey = lexer_findPreviousKeyByToken( currentLexer, i, "=" );
|
||
|
|
|
||
|
|
int endOfDefinition = lexer_findNextTokenIndex( currentLexer, i, ";" );
|
||
|
|
|
||
|
|
int endOfDefinitionKey = lexer_getKey( currentLexer, endOfDefinition ) - 1;
|
||
|
|
|
||
|
|
char * afterIs = text_removeWhiteSpaces( text_slice( body, isKey + 1, (endOfDefinitionKey) ) );
|
||
|
|
|
||
|
|
|
||
|
|
int from = text_indexOff( afterIs, "new", 0);
|
||
|
|
|
||
|
|
int to = text_indexOff( afterIs, "(", 0);
|
||
|
|
|
||
|
|
char * definedDatatype = text_removeWhiteSpaces( text_slice( text_copy(afterIs), from + 3, to -1 ) );
|
||
|
|
|
||
|
|
|
||
|
|
printf("find out between new and ( '%s' %s \n", currentProperty->datatype, definedDatatype);
|
||
|
|
|
||
|
|
if( !currentProperty ) {
|
||
|
|
|
||
|
|
printf(" Setter doesnt have an defined variable of the same name. %s\n", variableDatatype);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
printf("arrow part: %s %s \n\n", firstVariableName, variableDatatype);
|
||
|
|
|
||
|
|
|
||
|
|
classDefinition = currentProperty->datatype;
|
||
|
|
|
||
|
|
isPointer = currentProperty->isPointer;
|
||
|
|
|
||
|
|
|
||
|
|
if( strcmp( definedDatatype, classDefinition ) != NULL ) {
|
||
|
|
|
||
|
|
|
||
|
|
classDefinition = definedDatatype;
|
||
|
|
|
||
|
|
isPointer = -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
struct variable * firstVariableInstance = variable_getByName( variables, classDefinition );
|
||
|
|
|
||
|
|
classDefinition = firstVariableInstance->datatype;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
printf(" find out datatype \n\n\n\n\n");
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
isPointer = variable_isPointer( defineParts );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
className = classDefinition;
|
||
|
|
|
||
|
|
|
||
|
|
char * newFunctionDeclaration = text_copy( classDefinition );
|
||
|
|
|
||
|
|
if( isPointer == -1 ) {
|
||
|
|
|
||
|
|
newFunctionDeclaration = text_concatenate( newFunctionDeclaration, "_new" );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
newFunctionDeclaration = text_concatenate( newFunctionDeclaration, "_newPointer" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
replacement_add( currentKey, classOpenArgumentKey, newFunctionDeclaration, replacements );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
// dont save this as variable: 'somefunction( new classname() )'
|
||
|
|
if( array_length( defineParts ) > 1 && strcmp( defineText, "" ) != 0 ) {
|
||
|
|
|
||
|
|
struct variable * variableInstance = malloc( sizeof( struct variable ) );
|
||
|
|
|
||
|
|
printf("\n\n\n\n Error: %s %s \n\n\n", className, defineText);
|
||
|
|
|
||
|
|
|
||
|
|
//className = text_regexReplaceAll( className, "*", "*", "_");
|
||
|
|
|
||
|
|
variableInstance->variableName = variableName;
|
||
|
|
|
||
|
|
variableInstance->datatype = className;
|
||
|
|
|
||
|
|
variableInstance->isPointer = isPointer;
|
||
|
|
|
||
|
|
array_add( variables, variableInstance );
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
void parsePropertySetter( struct lexer * currentLexer, int i, int key, char * body, array * variables, struct array * replacements, int separatorWidth ) {
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int nextKey = lexer_getKey( currentLexer, i + 1 );
|
||
|
|
|
||
|
|
char * propertyName = text_removeWhiteSpaces( text_slice( body, key + separatorWidth, nextKey - 1 ) );
|
||
|
|
|
||
|
|
|
||
|
|
int endOfDefinition = lexer_findNextTokenIndex( currentLexer, i, ";" );
|
||
|
|
|
||
|
|
int endOfDefinitionKey = lexer_getKey( currentLexer, endOfDefinition ) - 1;
|
||
|
|
|
||
|
|
char * afterIs = text_removeWhiteSpaces( text_slice( body, nextKey + 1, endOfDefinitionKey ) );
|
||
|
|
|
||
|
|
|
||
|
|
char * variableName = text_extractWordBeforeKey( body, key );
|
||
|
|
|
||
|
|
int keyBeforeVariableName = text_getIndexBeforeWord( body, key - 1 );
|
||
|
|
|
||
|
|
|
||
|
|
struct variable * variableInstance = variable_getByName( variables, variableName );
|
||
|
|
|
||
|
|
char * variableType = variableInstance->datatype;
|
||
|
|
|
||
|
|
struct class * classInstance = application_getClassByClassName( allClasses, variableType );
|
||
|
|
|
||
|
|
if( classInstance == NULL ) {
|
||
|
|
|
||
|
|
printf("Error: class with template not found: %s \n\n\n\n\n", variableType );
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
struct text * newMethodName = text_new( "" );
|
||
|
|
|
||
|
|
text_append( newMethodName, "setter_" );
|
||
|
|
|
||
|
|
text_append( newMethodName, propertyName );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
struct method * methodInstance = method_getMethodByMethodName( classInstance, newMethodName->value );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if( methodInstance == NULL ) {
|
||
|
|
|
||
|
|
printf("method not found: %s %s \n", variableType, newMethodName->value);
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if( !methodInstance->isSetter ) {
|
||
|
|
|
||
|
|
return;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
printf(" this is a setter\n\n\n");
|
||
|
|
|
||
|
|
struct text * setterCallback = text_new( "" );
|
||
|
|
|
||
|
|
text_append( setterCallback, variableInstance->datatype );
|
||
|
|
|
||
|
|
text_append( setterCallback, "_setter_" );
|
||
|
|
|
||
|
|
text_append( setterCallback, propertyName );
|
||
|
|
|
||
|
|
text_append( setterCallback, "( " );
|
||
|
|
|
||
|
|
|
||
|
|
if( variableInstance->isPointer == -1 ) {
|
||
|
|
|
||
|
|
text_append( setterCallback, "&" );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( setterCallback, variableName);
|
||
|
|
|
||
|
|
text_append( setterCallback, ", " );
|
||
|
|
|
||
|
|
if( methodInstance->isVariadic == 1 ) {
|
||
|
|
|
||
|
|
int argumentDatatypeCount = 1;
|
||
|
|
|
||
|
|
char * numberOfVariadicArguments = text_fromNumber( argumentDatatypeCount );
|
||
|
|
|
||
|
|
text_append( setterCallback, numberOfVariadicArguments );
|
||
|
|
|
||
|
|
text_append( setterCallback, ", " );
|
||
|
|
|
||
|
|
text_append( setterCallback, "(int[" );
|
||
|
|
|
||
|
|
text_append( setterCallback, numberOfVariadicArguments );
|
||
|
|
|
||
|
|
text_append( setterCallback, "]){ " );
|
||
|
|
|
||
|
|
uintptr_t datatypeIndex = ( uintptr_t ) argument_determineDatatypeOfArgument( afterIs, variables );
|
||
|
|
|
||
|
|
if( text_contains( afterIs, "(" ) ) {
|
||
|
|
|
||
|
|
struct array * functionNameParts = text_split( text_copy( afterIs ), "_" );
|
||
|
|
|
||
|
|
int count = array_length(functionNameParts);
|
||
|
|
|
||
|
|
if( count > 1 ) {
|
||
|
|
|
||
|
|
char * className = array_get( functionNameParts, 0 );
|
||
|
|
|
||
|
|
struct class * classInstance = application_getClassByClassName( allClasses, className );
|
||
|
|
|
||
|
|
datatypeIndex = ( int )classInstance->classIndex;
|
||
|
|
|
||
|
|
printf("getDatatypeof function: %s \n\n", afterIs);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( setterCallback, text_fromNumber( datatypeIndex ) );
|
||
|
|
|
||
|
|
text_append( setterCallback, " }" );
|
||
|
|
|
||
|
|
text_append( setterCallback, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
text_append( setterCallback, afterIs );
|
||
|
|
|
||
|
|
text_append( setterCallback, " );" );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
replacement_add( keyBeforeVariableName, endOfDefinitionKey + 2, setterCallback->value, replacements );
|
||
|
|
|
||
|
|
//printf(" Parse property setter: %s %s %s %s %s \n\n ", variableName, propertyName, variableInstance->datatype, afterIs, setterCallback->value);
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * method_parse( char * body, struct array * variables, array * functions ) {
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
//body = parseAndRemoveTemplateDeclaration( body );
|
||
|
|
|
||
|
|
|
||
|
|
array * replacements = array_new();
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "{");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "}");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "(");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ")");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ";");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "=");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "->");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "\"");
|
||
|
|
|
||
|
|
// \"
|
||
|
|
char * quotesWithinQuotes = malloc(3);
|
||
|
|
|
||
|
|
quotesWithinQuotes[0] = 92;
|
||
|
|
|
||
|
|
quotesWithinQuotes[1] = 34;
|
||
|
|
|
||
|
|
quotesWithinQuotes[2] = 0;
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, quotesWithinQuotes);
|
||
|
|
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ".");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ",");
|
||
|
|
|
||
|
|
lexer_tokenizeRegex( currentLexer, body, "\\snew\\s", "new");
|
||
|
|
|
||
|
|
// operators
|
||
|
|
lexer_tokenize( currentLexer, body, "+");
|
||
|
|
|
||
|
|
|
||
|
|
lexer_add( currentLexer, 0, ";" );
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
|
||
|
|
if ( strcmp( token, "=" ) == 0 ) {
|
||
|
|
|
||
|
|
variable_extractFromDeclaration( currentLexer, key, i, body, variables );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int notWithinQuotes = 1;
|
||
|
|
|
||
|
|
|
||
|
|
for ( int i = 0; i < count; ++i )
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
|
||
|
|
if ( strcmp( token, "\"" ) == 0 ) {
|
||
|
|
|
||
|
|
//int previousCharacter = body[i-1];
|
||
|
|
|
||
|
|
//if( previousCharacter != 92 ) {
|
||
|
|
|
||
|
|
if( notWithinQuotes == 1 ) {
|
||
|
|
|
||
|
|
notWithinQuotes = 0;
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
notWithinQuotes = 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( token, "new" ) == 0 && notWithinQuotes == 1 ) {
|
||
|
|
|
||
|
|
method_replaceNewSymbol( currentLexer, i, body, key, variables, replacements );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( token, "->" ) == 0 ) {
|
||
|
|
|
||
|
|
int keyAfterMethod = text_extractIndexAfterWord( body, key + 1 );
|
||
|
|
|
||
|
|
char * nextToken = lexer_getToken( currentLexer, i + 1 );
|
||
|
|
|
||
|
|
// if character after methodName = a "("
|
||
|
|
// space after method name is not allowed.
|
||
|
|
//body[keyAfterMethod] == 40
|
||
|
|
if( nextToken[0] == 40 ){
|
||
|
|
|
||
|
|
//printf("next token ------------------------------------------- : %i\n\n", (int) ((char *) array_get( tokens, i+1 ))[0]);
|
||
|
|
|
||
|
|
method_parseFirstChainMethodCall( currentLexer, i, body, key, token, variables, replacements, 2 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( token, "." ) == 0 ) {
|
||
|
|
|
||
|
|
method_parseFirstChainMethodCall( currentLexer, i, body, key, token, variables, replacements, 1 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
replacement_sort( replacements );
|
||
|
|
|
||
|
|
|
||
|
|
count = array_length(replacements);
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i){
|
||
|
|
|
||
|
|
struct replacement * a = array_get( replacements, i );
|
||
|
|
|
||
|
|
body = text_replaceAt( a->fromIndex, a->toIndex, body, a->content );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
replacements = array_new();
|
||
|
|
|
||
|
|
currentLexer = lexer_new();
|
||
|
|
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "{");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "}");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "(");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ")");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ";");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "=");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "->");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "\"");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, quotesWithinQuotes);
|
||
|
|
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ".");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ",");
|
||
|
|
|
||
|
|
lexer_tokenizeRegex( currentLexer, body, "\\snew\\s", "new");
|
||
|
|
|
||
|
|
// operators
|
||
|
|
lexer_tokenize( currentLexer, body, "+");
|
||
|
|
|
||
|
|
|
||
|
|
lexer_add( currentLexer, 0, ";" );
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
for ( int i = 0; i < count; ++i )
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
int keyAfterMethod = text_extractIndexAfterWord( body, key + 1 );
|
||
|
|
|
||
|
|
char * nextToken = lexer_getToken( currentLexer, i + 1 );
|
||
|
|
|
||
|
|
if ( strcmp( token, "->" ) == 0 ) {
|
||
|
|
|
||
|
|
if( nextToken[0] == 61 ) {
|
||
|
|
|
||
|
|
parsePropertySetter( currentLexer, i, key, body, variables, replacements, 2 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( token, "." ) == 0 ) {
|
||
|
|
|
||
|
|
if( nextToken[0] == 61 ) {
|
||
|
|
|
||
|
|
parsePropertySetter( currentLexer, i, key, body, variables, replacements, 1 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = 0; i < count; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
|
||
|
|
if ( strcmp( token, "->" ) == 0 ) {
|
||
|
|
|
||
|
|
processCallback( key, i, body, variables, functions, replacements );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
replacement_sort( replacements );
|
||
|
|
|
||
|
|
|
||
|
|
count = array_length(replacements);
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i){
|
||
|
|
|
||
|
|
struct replacement * a = array_get( replacements, i );
|
||
|
|
|
||
|
|
body = text_replaceAt( a->fromIndex, a->toIndex, body, a->content );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
body = method_replaceMultiMethods( body );
|
||
|
|
|
||
|
|
|
||
|
|
body = method_overloadOperators( body, variables );
|
||
|
|
|
||
|
|
return body;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
int method_processOperatorSymbols( char * body,
|
||
|
|
int currentKey,
|
||
|
|
char * currentToken,
|
||
|
|
array * replacements,
|
||
|
|
array * variables ) {
|
||
|
|
|
||
|
|
char * operators[3] = { "+", "==", "+=" };
|
||
|
|
|
||
|
|
int operatorsCount = 3;
|
||
|
|
|
||
|
|
for (int k = 0; k < operatorsCount; ++k)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * operatorSymbol = operators[k];
|
||
|
|
|
||
|
|
int succeeded = method_processOperatorSymbol( operatorSymbol,
|
||
|
|
body,
|
||
|
|
currentKey,
|
||
|
|
currentToken,
|
||
|
|
replacements,
|
||
|
|
variables );
|
||
|
|
if( succeeded == 1 ) {
|
||
|
|
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * method_findLeftSideSymbol( char * body, int currentKey, int symbolLength, int * beforeVariableNameKey, array * variables ) {
|
||
|
|
|
||
|
|
char * leftSideSymbol;
|
||
|
|
|
||
|
|
// Handle left side
|
||
|
|
// leftside are parentheses
|
||
|
|
// ↓
|
||
|
|
// '( ) + ... '
|
||
|
|
int firstCharacterBefore = text_findFirstCharacterReverse( body, currentKey-symbolLength-1 );
|
||
|
|
|
||
|
|
if( firstCharacterBefore == 41 ) {
|
||
|
|
|
||
|
|
int firstCharacterBeforeIndex = text_text_findFirstCharacterIndexbackwards( body, currentKey-symbolLength - 1 );
|
||
|
|
|
||
|
|
// ↓
|
||
|
|
// '( ) + ... '
|
||
|
|
int argumentOpenIndex = tools_findArgumentCloseIndexReverse( body, ( int ) firstCharacterBeforeIndex );
|
||
|
|
|
||
|
|
int characterBeforeParenthesisOpen = text_findFirstCharacterReverse( body, argumentOpenIndex -1 );
|
||
|
|
|
||
|
|
int characterAfterPerenthesisOpen = text_findFirstNextCharacterNotWhiteSpaceNotParenthesis( body, argumentOpenIndex );
|
||
|
|
|
||
|
|
// ↓
|
||
|
|
// 'something( ( " " ) + ... '
|
||
|
|
if( isalpha( characterBeforeParenthesisOpen ) ) {
|
||
|
|
|
||
|
|
int beforeKey = text_getIndexBeforeWord( body, argumentOpenIndex-1 );
|
||
|
|
|
||
|
|
leftSideSymbol = text_removeWhiteSpaces( text_slice( body, beforeKey, argumentOpenIndex-1 ) );
|
||
|
|
|
||
|
|
*beforeVariableNameKey = beforeKey;
|
||
|
|
|
||
|
|
return leftSideSymbol;
|
||
|
|
|
||
|
|
// ↓
|
||
|
|
// '( ( " " ) + ... '
|
||
|
|
} else if( body[ characterAfterPerenthesisOpen ] == 34 ) {
|
||
|
|
|
||
|
|
printf("these are quotes\n\n");
|
||
|
|
|
||
|
|
leftSideSymbol = "char";
|
||
|
|
|
||
|
|
*beforeVariableNameKey = argumentOpenIndex;
|
||
|
|
|
||
|
|
return leftSideSymbol;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
leftSideSymbol = text_removeWhiteSpaces( text_extractWordBeforeKey( body, argumentOpenIndex ) );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
struct array * leftSideSymbolParts = text_split( text_copy( leftSideSymbol ), "_" );
|
||
|
|
|
||
|
|
int partsCount = array_length( leftSideSymbolParts );
|
||
|
|
|
||
|
|
// partsCount = 3
|
||
|
|
// 'vector3_operator_add( ) + ... '
|
||
|
|
if( partsCount > 1 ) {
|
||
|
|
|
||
|
|
*beforeVariableNameKey = text_getIndexBeforeWord( body, argumentOpenIndex );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
|
||
|
|
// →→→→→→→→
|
||
|
|
// ↓ ↓
|
||
|
|
// '( ( ( variable ) ) ) + ... '
|
||
|
|
int firstCharacterIndex = text_seekParenthesesLeftToRight( body, argumentOpenIndex );
|
||
|
|
|
||
|
|
int keyAfterMethod = text_extractIndexAfterWord( body, firstCharacterIndex + 1 ) ;
|
||
|
|
|
||
|
|
|
||
|
|
// '( ( ( variable->property ) ) ) + ... '
|
||
|
|
if( body[ keyAfterMethod ] == 45 && body[ keyAfterMethod + 1 ] == 62 ) {
|
||
|
|
|
||
|
|
int keyAfterProperty = text_extractIndexAfterWord( body, keyAfterMethod + 1 ) ;
|
||
|
|
|
||
|
|
leftSideSymbol = text_removeWhiteSpaces( text_slice( body, firstCharacterIndex, keyAfterProperty ) );
|
||
|
|
|
||
|
|
|
||
|
|
// '( ( ( variable ) ) ) + ... '
|
||
|
|
} else {
|
||
|
|
|
||
|
|
leftSideSymbol = text_removeWhiteSpaces( text_slice( body, firstCharacterIndex, keyAfterMethod - 1 ) );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
*beforeVariableNameKey = argumentOpenIndex;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// ↓
|
||
|
|
// leftSide is not opening parentheses '( ) + '
|
||
|
|
// but ↓
|
||
|
|
// ' someName + somename'
|
||
|
|
} else {
|
||
|
|
|
||
|
|
*beforeVariableNameKey = text_getIndexBeforeWord( body, currentKey );
|
||
|
|
|
||
|
|
int firstCharacterReverse = text_text_findFirstCharacterIndexbackwards( body, currentKey-symbolLength );
|
||
|
|
|
||
|
|
int beforeKey = text_getIndexBeforeWord( body, currentKey-symbolLength );
|
||
|
|
|
||
|
|
// variableName->propertyName
|
||
|
|
if( body[ beforeKey ] == 62 && body[ beforeKey - 1 ] == 45 ) {
|
||
|
|
|
||
|
|
int indexBeforeClassName = text_getIndexBeforeWord( body, beforeKey - 1 );
|
||
|
|
|
||
|
|
*beforeVariableNameKey = indexBeforeClassName;
|
||
|
|
|
||
|
|
leftSideSymbol = text_removeWhiteSpaces( text_slice( body, indexBeforeClassName, currentKey-1 ) );
|
||
|
|
|
||
|
|
|
||
|
|
// "something" + ...
|
||
|
|
} else if( body[ firstCharacterReverse ] == 34 ) {
|
||
|
|
|
||
|
|
leftSideSymbol = "char";
|
||
|
|
|
||
|
|
*beforeVariableNameKey = *beforeVariableNameKey-1;
|
||
|
|
|
||
|
|
//printf(" method 7\n");
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
// printf(" -- this part ");
|
||
|
|
|
||
|
|
|
||
|
|
int indexBeforeClassName = text_getIndexBeforeWord( body, currentKey - symbolLength );
|
||
|
|
|
||
|
|
*beforeVariableNameKey = indexBeforeClassName;
|
||
|
|
|
||
|
|
leftSideSymbol = text_removeWhiteSpaces( text_slice( body, indexBeforeClassName, currentKey-symbolLength ) );
|
||
|
|
/*
|
||
|
|
|
||
|
|
leftSideSymbol = text_removeWhiteSpaces( text_extractWordBeforeKey( body, currentKey - symbolLength - 1 ) );
|
||
|
|
*/
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return leftSideSymbol;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int method_findRightSideEndIndex( char * body, int currentKey, int symbolLength, struct array * variables ) {
|
||
|
|
|
||
|
|
|
||
|
|
int firstNextCharacter = text_findFirstNextCharacterNotWhiteSpace( body, currentKey + symbolLength );
|
||
|
|
|
||
|
|
int keyAfterOperator ;
|
||
|
|
|
||
|
|
// quoted text " sometext "
|
||
|
|
if( body[firstNextCharacter] == 34 ) {
|
||
|
|
|
||
|
|
keyAfterOperator = text_findQuoteCloseIndex( body, firstNextCharacter );
|
||
|
|
|
||
|
|
keyAfterOperator++;
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
keyAfterOperator = text_extractIndexAtWhiteSpace( body, currentKey + symbolLength );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// if " ... + someObject->property "
|
||
|
|
if( body[ keyAfterOperator ] == 45 && body[ keyAfterOperator + 1 ] == 62 ) {
|
||
|
|
|
||
|
|
keyAfterOperator = text_extractIndexAtWhiteSpace( body, keyAfterOperator + 1 );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// ↓
|
||
|
|
// if " ... + some_function_name( ... ) "
|
||
|
|
if( body[ keyAfterOperator ] == 40 ) {
|
||
|
|
|
||
|
|
// find ↓
|
||
|
|
// new key " ... = some_function_name( ... ) "
|
||
|
|
|
||
|
|
// check if rightSideFunction is a valid type
|
||
|
|
|
||
|
|
char * rightSideFunctionName = text_removeWhiteSpaces( text_slice( body, currentKey + symbolLength, keyAfterOperator - 1 ) );
|
||
|
|
|
||
|
|
struct array * functionNameParts = text_split( text_copy( rightSideFunctionName ), "_" );
|
||
|
|
|
||
|
|
int partsCount = array_length( functionNameParts );
|
||
|
|
|
||
|
|
if( partsCount == 1 ) {
|
||
|
|
|
||
|
|
// find function
|
||
|
|
|
||
|
|
//printf(" rightside is an function: %s\n\n\n", rightSideFunctionName);
|
||
|
|
|
||
|
|
for (int i = 0; i < total_libc_function; ++i)
|
||
|
|
{
|
||
|
|
|
||
|
|
char * libcFunctionName = libcFunctionNames[i];
|
||
|
|
|
||
|
|
if ( strcmp( libcFunctionName, rightSideFunctionName ) == 0 )
|
||
|
|
{
|
||
|
|
|
||
|
|
char * returnType = libcReturnTypes[i];
|
||
|
|
|
||
|
|
//printf("function found!! return type is %s\n\n\n", returnType);
|
||
|
|
|
||
|
|
if( class_classNameIsPrimitive( returnType ) == 1 ) {
|
||
|
|
|
||
|
|
//printf(" this is an number %s\n\n", returnType);
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
keyAfterOperator = text_findArgumentCloseIndex( body, keyAfterOperator );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// if the right side is opening parentheses " + ( ) "
|
||
|
|
// (
|
||
|
|
if( body[keyAfterOperator] == 40 ) {
|
||
|
|
|
||
|
|
int argumentOpenIndex = text_text_findFirstCharacterIndexFromIndex( body, "(", currentKey );
|
||
|
|
|
||
|
|
int argumentCloseIndex = text_findArgumentCloseIndex( body, ( int ) argumentOpenIndex );
|
||
|
|
|
||
|
|
keyAfterOperator = argumentCloseIndex;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
char * rightSideSymbol = text_removeWhiteSpaces( text_slice( body, currentKey + symbolLength, keyAfterOperator -1 ) );
|
||
|
|
|
||
|
|
struct variable * rightsideVariable = variable_getByName( variables, rightSideSymbol );
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if( class_classNameIsPrimitive( rightsideVariable->datatype ) == 1 ) {
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
//*rightSideIsPointer = rightsideVariable->isPointer;
|
||
|
|
|
||
|
|
|
||
|
|
return keyAfterOperator;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int method_processOperatorSymbol( char * currentOperatorSymbol,
|
||
|
|
char * body,
|
||
|
|
int currentKey,
|
||
|
|
char * currentToken,
|
||
|
|
array * replacements,
|
||
|
|
array * variables ) {
|
||
|
|
|
||
|
|
int operatorSymbolLength = strlen( currentOperatorSymbol );
|
||
|
|
|
||
|
|
if( body[ currentKey + operatorSymbolLength ] > 48 ) {
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( strcmp( currentToken, currentOperatorSymbol ) != 0 ) {
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int rightSideIsPointer = 1;
|
||
|
|
|
||
|
|
int keyAfterOperator = method_findRightSideEndIndex( body, currentKey, operatorSymbolLength, variables );
|
||
|
|
|
||
|
|
char * rightSideSymbol = text_removeWhiteSpaces( text_slice( body, currentKey + operatorSymbolLength, keyAfterOperator ) );
|
||
|
|
|
||
|
|
|
||
|
|
char * rightSideBaseClass = class_getBaseClassNameBySymbol( rightSideSymbol, variables, &rightSideIsPointer );
|
||
|
|
|
||
|
|
//printf(" RightSideSymbol: %s\n\n RightSideBase: %s %i \n\n", rightSideSymbol, rightSideBaseClass, rightSideIsPointer);
|
||
|
|
|
||
|
|
|
||
|
|
if( keyAfterOperator == -1 ) {
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( operatorSymbolLength == 1 ) {
|
||
|
|
|
||
|
|
if( body[ currentKey + 1 ] == 43 ) {
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
int indexBeforeLeftSideSymbol;
|
||
|
|
|
||
|
|
int leftSideIsPointer = 1;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
char * leftSideSymbol = method_findLeftSideSymbol( body, currentKey, operatorSymbolLength, &indexBeforeLeftSideSymbol, variables );
|
||
|
|
|
||
|
|
char * baseClassName = class_getBaseClassNameBySymbol( leftSideSymbol, variables, &leftSideIsPointer );
|
||
|
|
|
||
|
|
|
||
|
|
//printf(" leftSideSymbol: %-20s baseClassName: %s Operator: %s \n\n\n", leftSideSymbol, baseClassName, currentOperatorSymbol ,text_slice(body, indexBeforeLeftSideSymbol, keyAfterOperator));
|
||
|
|
|
||
|
|
//printf(" leftSide is pointer?? %i\n\n", leftSideIsPointer);
|
||
|
|
|
||
|
|
|
||
|
|
if( baseClassName == NULL ) {
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
if( strcmp( text_copy( baseClassName ) , "char" ) == 0 ) {
|
||
|
|
|
||
|
|
leftSideIsPointer = 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * openingDeclaration = class_openingDeclarationFromBaseClassName( baseClassName, currentOperatorSymbol, leftSideIsPointer );
|
||
|
|
|
||
|
|
//printf(" openingDeclaration: %s \n\n", openingDeclaration);
|
||
|
|
|
||
|
|
if( openingDeclaration != NULL ) {
|
||
|
|
|
||
|
|
replacement_add( indexBeforeLeftSideSymbol, indexBeforeLeftSideSymbol, openingDeclaration, replacements );
|
||
|
|
|
||
|
|
|
||
|
|
if( rightSideIsPointer == 1 ) {
|
||
|
|
|
||
|
|
replacement_add( (int) currentKey, (int) currentKey + operatorSymbolLength, ", ", replacements );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
replacement_add( (int) currentKey, (int) currentKey + operatorSymbolLength, ", &", replacements );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
replacement_add( (int) keyAfterOperator, (int) keyAfterOperator , ")", replacements );
|
||
|
|
|
||
|
|
return 1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return -1;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
char * method_overloadOperators( char * body, struct array * variables ) {
|
||
|
|
|
||
|
|
lexer * currentLexer = lexer_new();
|
||
|
|
|
||
|
|
struct array * depthArray = array_new();
|
||
|
|
|
||
|
|
struct array * depthIndices = array_new();
|
||
|
|
|
||
|
|
struct array * replacements = array_new();
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "{");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "}");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "(");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ")");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ";");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "=");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "->");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, ".");
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "+");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "+=");
|
||
|
|
|
||
|
|
lexer_tokenize( currentLexer, body, "==");
|
||
|
|
|
||
|
|
lexer_add( currentLexer, 0, ";" );
|
||
|
|
|
||
|
|
|
||
|
|
lexer_sortKeys( currentLexer );
|
||
|
|
|
||
|
|
|
||
|
|
int count = lexer_length( currentLexer );
|
||
|
|
|
||
|
|
intptr_t depth = 0;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
for ( intptr_t i = 0; i < count; ++i )
|
||
|
|
{
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, i );
|
||
|
|
|
||
|
|
char * token = lexer_getToken( currentLexer, i );
|
||
|
|
|
||
|
|
if( strcmp( token, "(" ) ) {
|
||
|
|
|
||
|
|
depth--;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( strcmp( token, ")" ) ) {
|
||
|
|
|
||
|
|
depth++;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
array_add( depthArray, ( void * ) depth );
|
||
|
|
|
||
|
|
array_add( depthIndices, ( void * ) i );
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
// replace this with a lexer or something.
|
||
|
|
lexer_sortKeys_separate( depthArray, depthIndices );
|
||
|
|
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i)
|
||
|
|
{
|
||
|
|
|
||
|
|
intptr_t depthIndex = ( intptr_t ) array_get( depthIndices, i );
|
||
|
|
|
||
|
|
int key = lexer_getKey( currentLexer, depthIndex );
|
||
|
|
|
||
|
|
void * token = lexer_getToken( currentLexer, depthIndex );
|
||
|
|
|
||
|
|
int succeeded = method_processOperatorSymbols( body, key, token, replacements, variables );
|
||
|
|
|
||
|
|
if( succeeded == 1 ) {
|
||
|
|
|
||
|
|
break;
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
replacement_sort( replacements );
|
||
|
|
|
||
|
|
count = array_length(replacements);
|
||
|
|
|
||
|
|
for (int i = count - 1; i >= 0; --i){
|
||
|
|
|
||
|
|
struct replacement * a = array_get( replacements, i );
|
||
|
|
|
||
|
|
body = text_replaceAt( a->fromIndex, a->toIndex, body, a->content );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
if( count > 0 ) {
|
||
|
|
|
||
|
|
body = method_overloadOperators( body, variables );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
return body;
|
||
|
|
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
void method_compose( struct method * currentMethod, char * className, struct array * sourceArray, struct text * classHeader ) {
|
||
|
|
|
||
|
|
char * methodName = currentMethod->methodName;
|
||
|
|
|
||
|
|
struct text * methodSource = text_new("");
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
if( strlen( currentMethod->returnType ) == 0 ) {
|
||
|
|
|
||
|
|
text_append( methodSource, "void" );
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
text_append( methodSource, text_removeWhiteSpaces( currentMethod->returnType ) );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( methodSource, " " );
|
||
|
|
|
||
|
|
text_append( methodSource, className );
|
||
|
|
|
||
|
|
text_append( methodSource, "_" );
|
||
|
|
|
||
|
|
text_append( methodSource, methodName );
|
||
|
|
|
||
|
|
text_append( methodSource, "( " );
|
||
|
|
|
||
|
|
|
||
|
|
int argumentsLength = array_length( currentMethod->arguments );
|
||
|
|
|
||
|
|
for (int j = 0; j < argumentsLength; ++j)
|
||
|
|
{
|
||
|
|
char * argumentText = text_copy( array_get( currentMethod->arguments, j ) );
|
||
|
|
|
||
|
|
if( j != 0 ) {
|
||
|
|
|
||
|
|
text_append( methodSource, ", " );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
text_append( methodSource, argumentText );
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
text_append( classHeader, text_copy( methodSource->value ) );
|
||
|
|
|
||
|
|
text_append( classHeader, " );\n\n" );
|
||
|
|
|
||
|
|
|
||
|
|
struct text * finalMethodCode = text_new("");
|
||
|
|
|
||
|
|
text_append( finalMethodCode, text_copy( methodSource->value ) );
|
||
|
|
|
||
|
|
text_append( finalMethodCode, " ) {" );
|
||
|
|
|
||
|
|
text_append( finalMethodCode, text_copy( currentMethod->body ) );
|
||
|
|
|
||
|
|
text_append( finalMethodCode, "}" );
|
||
|
|
|
||
|
|
|
||
|
|
struct codeBundle * code = malloc( sizeof( struct codeBundle ) );
|
||
|
|
|
||
|
|
code->lineNumber = currentMethod->lineNumber;
|
||
|
|
|
||
|
|
code->sourceCode = finalMethodCode->value;
|
||
|
|
|
||
|
|
array_add( sourceArray, code );
|
||
|
|
|
||
|
|
|
||
|
|
text_free( methodSource );
|
||
|
|
|
||
|
|
}
|