Initial commit
This commit is contained in:
916
source/class.c
Normal file
916
source/class.c
Normal file
@@ -0,0 +1,916 @@
|
||||
|
||||
#include "class.h"
|
||||
|
||||
|
||||
struct class * class_new() {
|
||||
|
||||
struct class * classInstance = malloc( sizeof( struct class ) );
|
||||
|
||||
return classInstance;
|
||||
|
||||
}
|
||||
|
||||
void class_reIndexLineNumbers( struct class * baseClass ) {
|
||||
|
||||
int maxLineNumber = 0;
|
||||
|
||||
struct array * methods = baseClass->methods;
|
||||
|
||||
int methodsCount = array_length( methods );
|
||||
|
||||
for (int i = 0; i < methodsCount; ++i)
|
||||
{
|
||||
struct method * methodInstance = array_get( methods, i );
|
||||
|
||||
if( methodInstance->lineNumber > maxLineNumber ) {
|
||||
|
||||
maxLineNumber = methodInstance->lineNumber;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
maxLineNumber += 12;
|
||||
|
||||
for (int i = 0; i < methodsCount; ++i)
|
||||
{
|
||||
struct method * methodInstance = array_get( methods, i );
|
||||
|
||||
|
||||
if( methodInstance->lineNumber == -1 ) {
|
||||
|
||||
methodInstance->lineNumber = maxLineNumber;
|
||||
|
||||
maxLineNumber += text_findNumberOfLineBreaks( methodInstance->body );
|
||||
|
||||
maxLineNumber += 6;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void class_updateThisArgument( struct array * arguments, char * baseClassName ) {
|
||||
|
||||
struct text * newThisArgument = text_new( "" );
|
||||
|
||||
text_append( newThisArgument, "struct " );
|
||||
|
||||
text_append( newThisArgument, baseClassName );
|
||||
|
||||
text_append( newThisArgument, " * this" );
|
||||
|
||||
array_set( arguments, 0, newThisArgument->value );
|
||||
|
||||
//printf("update this argument: %s %s\n ", firstArgument, methodName);
|
||||
|
||||
}
|
||||
|
||||
int class_getMethodIndexByName( struct class * classInstance, char * methodName ) {
|
||||
|
||||
struct array * methods = classInstance->methods;
|
||||
|
||||
int count = array_length( methods );
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
|
||||
struct method * currentMethod = array_get( methods, i );
|
||||
|
||||
if( strcmp( currentMethod->methodName, methodName ) == 0 ) {
|
||||
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void addMethodsToBaseClass( struct class * baseClass, struct class * extendedClass ) {
|
||||
|
||||
struct array * methods = extendedClass->methods;
|
||||
|
||||
int methodsCount = array_length( methods );
|
||||
|
||||
for (int i = 0; i < methodsCount; ++i)
|
||||
{
|
||||
struct method * methodInstance = array_get( methods, i );
|
||||
|
||||
struct method * methodCopy = malloc( sizeof( struct method ) );
|
||||
|
||||
methodCopy->methodName = methodInstance->methodName;
|
||||
|
||||
methodCopy->body = methodInstance->body;
|
||||
|
||||
methodCopy->returnType = methodInstance->returnType;
|
||||
|
||||
methodCopy->lineNumber = -1;
|
||||
|
||||
methodCopy->arguments = methodInstance->arguments;
|
||||
|
||||
|
||||
int methodIndex = class_getMethodIndexByName( baseClass, methodInstance->methodName );
|
||||
|
||||
if( methodIndex == -1 ) {
|
||||
|
||||
class_updateThisArgument( methodCopy->arguments, baseClass->className );
|
||||
|
||||
array_add( baseClass->methods, methodCopy );
|
||||
|
||||
} else {
|
||||
|
||||
class_updateThisArgument( methodCopy->arguments, baseClass->className );
|
||||
|
||||
//array_set( baseClass->methods, methodIndex, methodCopy );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void addPropertiesToBaseClass( struct class * baseClass, struct class * extendedClass ) {
|
||||
|
||||
struct array * properties = extendedClass->properties;
|
||||
|
||||
int propertyCount = array_length( properties );
|
||||
|
||||
|
||||
for (int i = 0; i < propertyCount; ++i)
|
||||
{
|
||||
|
||||
struct property * propertyInstance = array_get( properties, i );
|
||||
|
||||
int propertyIndex = class_getPropertyIndexByName( baseClass, propertyInstance->propertyName );
|
||||
|
||||
if( propertyIndex == -1 ) {
|
||||
|
||||
array_add( baseClass->properties, propertyInstance );
|
||||
|
||||
} else {
|
||||
|
||||
array_set( baseClass->properties, propertyIndex, propertyInstance );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//printf("processCurrent extend: %s \n\n", extendedClass->className );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void class_extendClass( struct class * baseClass ) {
|
||||
|
||||
if( baseClass->hasExtended == 1 ) {
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
struct array * extends = baseClass->extends;
|
||||
|
||||
int extendCount = array_length( extends );
|
||||
|
||||
|
||||
//printf("extend: %s %i \n\n\n\n\n", baseClass->className, extendCount );
|
||||
|
||||
|
||||
for ( int i = 0; i < extendCount; ++i )
|
||||
{
|
||||
|
||||
|
||||
|
||||
char * extendName = text_removeWhiteSpaces( array_get( extends, i ) );
|
||||
|
||||
|
||||
struct class * extendedClass = application_getClassByClassName( allClasses, extendName );
|
||||
|
||||
|
||||
if( extendedClass == NULL ) {
|
||||
|
||||
printf("\n\n\n\n ERROR: Class '%s' tries to extend class '%s', Class '%s' does not exist. \n\n\n\n", baseClass->className, extendName, extendName);
|
||||
|
||||
exit( 0 );
|
||||
|
||||
}
|
||||
|
||||
if( extendedClass->hasExtended == -1 ) {
|
||||
|
||||
class_extendClass( extendedClass );
|
||||
|
||||
}
|
||||
/*
|
||||
addPropertiesToBaseClass( baseClass, extendedClass );
|
||||
|
||||
addMethodsToBaseClass( baseClass, extendedClass );
|
||||
*/
|
||||
}
|
||||
|
||||
class_reIndexLineNumbers( baseClass );
|
||||
|
||||
baseClass->hasExtended = 1;
|
||||
|
||||
}
|
||||
|
||||
int class_findClassByClassNameExists( array * classesArray, char * name ) {
|
||||
|
||||
int count = array_length( classesArray );
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
struct class * currentClass = array_get( classesArray, i );
|
||||
|
||||
//printf(" %s\n",currentClass->className );
|
||||
|
||||
if ( strcmp( currentClass->className, name ) == 0 ) {
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void class_extractMethod( lexer * currentLexer,
|
||||
char * source,
|
||||
int i,
|
||||
struct class * classInstance,
|
||||
struct array * classesArray,
|
||||
struct array * functions ) {
|
||||
|
||||
|
||||
double key = lexer_getKey( currentLexer, i );
|
||||
|
||||
array * validPreviousTokens = array_new();
|
||||
|
||||
array_add( validPreviousTokens, "{");
|
||||
|
||||
array_add( validPreviousTokens, "}");
|
||||
|
||||
array_add( validPreviousTokens, ";");
|
||||
|
||||
|
||||
int previousKey = lexer_findPreviouseTokenIndex( currentLexer, i, validPreviousTokens ) + 1;
|
||||
|
||||
struct method * methodInstance = malloc( sizeof( struct method ) );
|
||||
|
||||
methodInstance->isSetter = false;
|
||||
|
||||
methodInstance->isGetter = false;
|
||||
|
||||
method_extractMethodNameAndReturnType( previousKey, key, source, methodInstance );
|
||||
|
||||
// &(int){ 0 } create inline pointer
|
||||
methodInstance->bodyOriginal = class_extractBodyFromSource( currentLexer, i, source, 0 );
|
||||
|
||||
methodInstance->variables = method_extractArguments( currentLexer, key, source, i, classInstance, methodInstance, classesArray );
|
||||
|
||||
methodInstance->lineNumber = text_countLineBreaks( source, (int) key );
|
||||
|
||||
|
||||
array_add( classInstance->methods, methodInstance );
|
||||
|
||||
}
|
||||
|
||||
char * class_extractBodyFromSource( lexer * currentLexer, int i, char * source, int bodyCloseIndex ) {
|
||||
|
||||
int bodyOpenIndex = lexer_findNextTokenIndex( currentLexer, i, "{" );
|
||||
|
||||
int bodyOpenKey = lexer_findNextToken( currentLexer, i, "{" );
|
||||
|
||||
bodyCloseIndex = lexer_findBodyCloseIndex( currentLexer, bodyOpenIndex );
|
||||
|
||||
int bodyCloseKey = lexer_getKey( currentLexer, bodyCloseIndex );
|
||||
|
||||
|
||||
char * bodySource = text_slice( source, bodyOpenKey + 1, bodyCloseKey - 1 );
|
||||
|
||||
return bodySource;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void class_extractProperty( lexer * currentLexer, int key, int i, char * source, struct class * classInstance ) {
|
||||
|
||||
char * previousToken = lexer_getToken( currentLexer, i - 1 );
|
||||
|
||||
int hasValue = -1;
|
||||
|
||||
char * propertyValue = "";
|
||||
|
||||
char * propertySource = "";
|
||||
|
||||
struct property * propertyInstance = malloc( sizeof( struct property ) );
|
||||
|
||||
propertyInstance->propertyName = NULL;
|
||||
|
||||
propertyInstance->type = "default";
|
||||
|
||||
// todo this can be done more effectively
|
||||
//printf("previousToken: %s\n", previousToken);
|
||||
|
||||
|
||||
int shift = 0;
|
||||
|
||||
|
||||
if ( strcmp( previousToken, "=" ) == 0 || strcmp( previousToken, "\"" ) == 0 ) {
|
||||
|
||||
|
||||
|
||||
int IsTokenKey = lexer_findPreviousTokenIndex( currentLexer, i, "=" );
|
||||
|
||||
int IsKey = lexer_getKey( currentLexer, IsTokenKey );
|
||||
|
||||
int keyBeforeIS = lexer_getKey( currentLexer, IsTokenKey - 1 );
|
||||
|
||||
propertyValue = text_slice( source, IsKey + 1, key - 1 );
|
||||
|
||||
propertySource = text_removeWhiteSpaces( text_slice( source, keyBeforeIS + 1, IsKey - 1 ) );
|
||||
|
||||
hasValue = 1;
|
||||
|
||||
} else if ( strcmp( previousToken, ")" ) == 0 ) {
|
||||
|
||||
|
||||
shift = 3;
|
||||
|
||||
int IsTokenKey = lexer_findPreviousTokenIndex( currentLexer, i, "=" );
|
||||
|
||||
int previousSemicolon = lexer_findPreviousTokenIndex( currentLexer, i, ";" );
|
||||
|
||||
|
||||
if( previousSemicolon > IsTokenKey ) {
|
||||
|
||||
printf("\n\n\n This is an function. \n\n\n\n\n\n\n");
|
||||
|
||||
int afterPreviousSemicolon = lexer_getKey( currentLexer, previousSemicolon );
|
||||
|
||||
int openArgumentKey = lexer_findNextToken( currentLexer, previousSemicolon, "(" );
|
||||
|
||||
int closeArgumentKey = lexer_findNextToken( currentLexer, previousSemicolon, ")" );
|
||||
|
||||
|
||||
char * propertyName = text_removeWhiteSpaces( text_slice( source, openArgumentKey + 1 , closeArgumentKey - 1 ) ) ;
|
||||
|
||||
struct array * propertyNameParts = text_split( propertyName, " \t" );
|
||||
|
||||
|
||||
propertyInstance->propertyName = property_extractPropertyName( propertyNameParts );
|
||||
|
||||
|
||||
printf(" function name '%s' %i %i %i \n\n",propertyInstance->propertyName, openArgumentKey, closeArgumentKey, afterPreviousSemicolon);
|
||||
|
||||
propertySource = text_removeWhiteSpaces( text_slice( source, (int)afterPreviousSemicolon + 1, key-1 ) );
|
||||
|
||||
|
||||
hasValue = 0;
|
||||
|
||||
|
||||
//propertyInstance->propertyName = "customName";
|
||||
|
||||
propertyInstance->type = "function";
|
||||
|
||||
printf("A\n\n\n");
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
int IsKey = lexer_getKey( currentLexer, IsTokenKey );
|
||||
|
||||
int keyBeforeIS = lexer_getKey( currentLexer, IsTokenKey - 1 );
|
||||
|
||||
|
||||
propertyValue = text_slice( source, IsKey + 1, key - 1 );
|
||||
|
||||
propertySource = text_removeWhiteSpaces( text_slice( source, keyBeforeIS + 1, IsKey - 1 ) );
|
||||
|
||||
hasValue = 1;
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
int previousKey = lexer_getKey( currentLexer, i - 1 );
|
||||
|
||||
propertySource = text_slice( source, previousKey + 1, key - 1 );
|
||||
|
||||
|
||||
shift = 0;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
char * beforeShiftToken = lexer_getToken( currentLexer, i - 1 - shift );
|
||||
|
||||
|
||||
if( strcmp( beforeShiftToken, ">" ) == 0 ) {
|
||||
|
||||
int templateOpenKey = lexer_getKey( currentLexer, i - 2 - shift );
|
||||
|
||||
int templateCloseKey = lexer_getKey( currentLexer, i - 1 - shift );
|
||||
|
||||
int afterCloseKey = lexer_getKey( currentLexer, i - shift );
|
||||
|
||||
char * templateArgument = text_slice( source, templateOpenKey + 1, templateCloseKey - 1 );
|
||||
|
||||
int beforeClassName = lexer_getKey( currentLexer, i - 3 - shift );
|
||||
|
||||
char * className = text_removeWhiteSpaces( text_slice( source, beforeClassName + 1 , templateOpenKey - 1 ) ) ;
|
||||
|
||||
char * afterTemplate = text_slice( source, templateCloseKey + 1, afterCloseKey - 1 );
|
||||
|
||||
|
||||
char * classNameWithoutStruct = className;
|
||||
|
||||
struct array * nameParts = text_split( className, " \t" );
|
||||
|
||||
if( array_length( nameParts ) > 1 ) {
|
||||
|
||||
char * firstPart = array_get( nameParts, 0 );
|
||||
|
||||
if( strcmp( firstPart, "struct" ) == NULL ) {
|
||||
|
||||
|
||||
classNameWithoutStruct = array_get( nameParts, 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct class * classInstance = application_getClassByClassName( allClasses, classNameWithoutStruct );
|
||||
|
||||
if( classInstance == NULL ) {
|
||||
|
||||
printf("Error: class with template not found: %s \n\n\n\n\n", classNameWithoutStruct );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
if( !classInstance->usesTemplate ) {
|
||||
|
||||
printf("Error: This class does not have an template: %s \n\n", classInstance->className );
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
template_addArgumentValue( classInstance, templateArgument );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct text * templateClassName = text_new( "" );
|
||||
|
||||
templateArgument = text_replaceAll( templateArgument, "*", "_pointer" );
|
||||
|
||||
templateArgument = text_removeAllWhiteSpaces( templateArgument );
|
||||
|
||||
|
||||
text_append( templateClassName, className );
|
||||
|
||||
text_append( templateClassName, "_" );
|
||||
|
||||
text_append( templateClassName, templateArgument );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct text * newPropertySource = text_new( "" );
|
||||
|
||||
|
||||
text_append( newPropertySource, templateClassName->value );
|
||||
|
||||
text_append( newPropertySource, afterTemplate );
|
||||
|
||||
|
||||
propertySource = newPropertySource->value;
|
||||
|
||||
|
||||
if( hasValue == 1 ) {
|
||||
|
||||
|
||||
|
||||
|
||||
char * needle = "\\b"; // "\\bTT\\b"
|
||||
|
||||
needle = text_concatenate( needle, className );
|
||||
|
||||
needle = text_concatenate( needle, "\\b" );
|
||||
|
||||
propertyValue = text_regexReplaceAll( propertyValue, needle, className, templateClassName->value );
|
||||
|
||||
}
|
||||
|
||||
|
||||
//printf(" templateArgument: %s %s\n\n", className, templateArgument);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
char * trimmedPropertySource = text_removeWhiteSpaces( propertySource );
|
||||
|
||||
//printf(" trimmedPropertySource: %s\n", propertySource);
|
||||
|
||||
struct array * propertyParts = text_split( trimmedPropertySource, " \t" );
|
||||
|
||||
int propertyPartsLength = array_length( propertyParts );
|
||||
|
||||
|
||||
|
||||
propertyInstance->isPointer = variable_isPointer( propertyParts );
|
||||
|
||||
propertyInstance->hasValue = hasValue;
|
||||
|
||||
propertyInstance->decleration = property_extractPropertyDeclaration( propertyParts, propertyInstance );
|
||||
|
||||
if( hasValue == 1 ) {
|
||||
|
||||
//printf(" propertyValue: %s\n", propertyValue);
|
||||
|
||||
propertyInstance->value = property_composePropertyValue( propertyValue, propertyInstance );
|
||||
|
||||
}
|
||||
|
||||
//printf("propertyName: %s\n\n\n", propertyInstance->propertyName);
|
||||
|
||||
if( propertyInstance->propertyName == NULL ) {
|
||||
|
||||
propertyInstance->propertyName = property_extractPropertyName( propertyParts );
|
||||
|
||||
}
|
||||
|
||||
|
||||
propertyInstance->declerationParts = propertyParts;
|
||||
|
||||
|
||||
array_add( classInstance->properties, (void*) propertyInstance );
|
||||
|
||||
|
||||
|
||||
//printf("decleration: %s\n\n\n", propertyInstance->decleration);
|
||||
|
||||
}
|
||||
|
||||
int class_getPropertyIndexByName( struct class * classInstance, char * propertyName ) {
|
||||
|
||||
struct array * properties = classInstance->properties;
|
||||
|
||||
int propertyCount = array_length( properties );
|
||||
|
||||
for (int i = 0; i < propertyCount; ++i)
|
||||
{
|
||||
|
||||
struct property * propertyInstance = array_get( properties, i );
|
||||
|
||||
if( strcmp( propertyInstance->propertyName, propertyName ) == 0 ) {
|
||||
|
||||
return i;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct property * class_getPropertyByName( struct class * classInstance, char * propertyName ) {
|
||||
|
||||
struct array * properties = classInstance->properties;
|
||||
|
||||
int propertyCount = array_length( properties );
|
||||
|
||||
for (int i = 0; i < propertyCount; ++i)
|
||||
{
|
||||
|
||||
struct property * propertyInstance = array_get( properties, i );
|
||||
|
||||
if( strcmp( propertyInstance->propertyName, propertyName ) == 0 ) {
|
||||
|
||||
return propertyInstance;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
void class_composeHeader( struct class * classInstance, struct text * classHeader, char * filename ) {
|
||||
|
||||
char * className = classInstance->className;
|
||||
|
||||
if( strcmp( className, "char" ) != 0 && strcmp( className, "int" ) != 0 && strcmp( className, "void" ) != 0 ) {
|
||||
|
||||
class_composeStruct( classInstance, classHeader );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void class_composeTypedefStruct( struct class * classInstance, struct text * classHeader ) {
|
||||
|
||||
char * className = classInstance->className;
|
||||
|
||||
struct array * properties = classInstance->properties;
|
||||
|
||||
int propertyCount = array_length( properties );
|
||||
|
||||
text_append( classHeader, "\n\n" );
|
||||
|
||||
text_append( classHeader, "typedef struct " );
|
||||
|
||||
text_append( classHeader, className );
|
||||
|
||||
text_append( classHeader, " " );
|
||||
|
||||
text_append( classHeader, className );
|
||||
|
||||
text_append( classHeader, ";\n\n" );
|
||||
|
||||
text_append( classHeader, "\n\n" );
|
||||
|
||||
}
|
||||
|
||||
void class_composeStruct( struct class * classInstance, struct text * classHeader ) {
|
||||
|
||||
char * className = classInstance->className;
|
||||
|
||||
struct array * properties = classInstance->properties;
|
||||
|
||||
int propertyCount = array_length( properties );
|
||||
|
||||
|
||||
text_append( classHeader, "typedef struct " );
|
||||
|
||||
text_append( classHeader, className );
|
||||
|
||||
text_append( classHeader, "{\n\n" );
|
||||
|
||||
if( classInstance->hasReflection ) {
|
||||
|
||||
if( strcmp( className, "window" ) != 0 && strcmp( className, "Hints" ) != 0 ) {
|
||||
|
||||
text_append( classHeader, " unsigned short __classIndex;\n\n" );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for ( int i = 0; i < propertyCount; ++i )
|
||||
{
|
||||
|
||||
struct property * currentProperty = array_get( properties, i );
|
||||
|
||||
char * decleration = currentProperty->decleration;
|
||||
|
||||
text_append( classHeader, " " );
|
||||
|
||||
text_append( classHeader, decleration );
|
||||
|
||||
text_append( classHeader, ";\n\n" );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
text_append( classHeader, "\n} " );
|
||||
|
||||
text_append( classHeader, className );
|
||||
|
||||
text_append( classHeader, ";\n\n" );
|
||||
|
||||
}
|
||||
|
||||
void class_composeMethods( struct class * classInstance, struct text * classHeader, struct array * sourceArray ) {
|
||||
|
||||
char * className = classInstance->className;
|
||||
|
||||
struct array * methods = classInstance->methods;
|
||||
|
||||
int length = array_length( methods );
|
||||
|
||||
for (int i = 0; i < length; ++i)
|
||||
{
|
||||
|
||||
struct method * currentMethod = array_get( classInstance->methods, i );
|
||||
|
||||
method_compose( currentMethod, className, sourceArray, classHeader );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int class_classNameIsPrimitive( char * baseClassName ) {
|
||||
|
||||
// dont overload numbers because these are used for pointers
|
||||
char * primitiveTypes[3] = { "int", "long", "size_t" };
|
||||
|
||||
int primitiveTypesCount = 3;
|
||||
|
||||
for (int j = 0; j < primitiveTypesCount; ++j)
|
||||
{
|
||||
|
||||
char * primitiveType = primitiveTypes[j];
|
||||
|
||||
if( strcmp( baseClassName, primitiveType ) == 0 ) {
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
struct property * class_getClassPropertyByPropertyName( struct class * instance, char * propertyName ) {
|
||||
|
||||
struct array * properties = instance->properties;
|
||||
|
||||
int propertyLength = array_length( properties );
|
||||
|
||||
for (int i = 0; i < propertyLength; ++i)
|
||||
{
|
||||
|
||||
struct property * currentProperty = array_get( properties, i );
|
||||
|
||||
char * currentPropertyName = currentProperty->propertyName;
|
||||
|
||||
if( strcmp( currentPropertyName, propertyName ) == 0 ) {
|
||||
|
||||
return currentProperty;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
char * class_getDatatypeFromClassProperty( char * declaration, struct array * variables ) {
|
||||
|
||||
array * parts = text_split( declaration, "->" );
|
||||
|
||||
char * propertyName = array_get( parts, 1 );
|
||||
|
||||
char * variableName = array_get( parts, 0 );
|
||||
|
||||
|
||||
struct variable * variableInstance = variable_getByName( variables, variableName );
|
||||
|
||||
if( variableInstance == NULL ) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
struct class * currentClass = application_getClassByClassName( allClasses, variableInstance->datatype );
|
||||
|
||||
if( currentClass == NULL ) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
struct property * propertyInstance = class_getClassPropertyByPropertyName( currentClass, propertyName );
|
||||
|
||||
if( propertyInstance == NULL ) {
|
||||
|
||||
return "";
|
||||
|
||||
}
|
||||
|
||||
return propertyInstance->datatype;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
char * class_openingDeclarationFromBaseClassName( char * baseClassName, char * currentOperatorSymbol, int leftSideIsPointer ) {
|
||||
|
||||
struct class * baseClass = application_getClassByClassName( allClasses, baseClassName );
|
||||
|
||||
if( baseClass != NULL ) {
|
||||
|
||||
char * openingDeclaration;
|
||||
|
||||
|
||||
char * operatorName = method_getOperatorNameByOperatorSymbol( currentOperatorSymbol );
|
||||
|
||||
struct text * fullOperatorName = text_new( "" );
|
||||
|
||||
text_append( fullOperatorName, "operator_" );
|
||||
|
||||
text_append( fullOperatorName, operatorName );
|
||||
|
||||
//printf("operator name: %s %s %s\n\n", baseClassName, fullOperatorName->value, operatorName);
|
||||
|
||||
struct method * operatorMethod = method_getMethodByMethodName( baseClass, fullOperatorName->value );
|
||||
|
||||
if( operatorMethod != NULL ) {
|
||||
|
||||
return method_composeOperatorOverloadOpeningDeclaration( baseClassName, operatorName, leftSideIsPointer );
|
||||
|
||||
} else {
|
||||
|
||||
// printf(" method not found!\n\n");
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
char * class_getBaseClassNameBySymbol( char * leftSideSymbol, struct array * variables, int * leftSideIsPointer ) {
|
||||
|
||||
if( strcmp( leftSideSymbol, "" ) == 0 ) {
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
if( strcmp( leftSideSymbol, "char") == 0 ) {
|
||||
|
||||
return "char";
|
||||
|
||||
}
|
||||
|
||||
if( strstr( leftSideSymbol, "->" ) != 0 ) {
|
||||
|
||||
return class_getDatatypeFromClassProperty( leftSideSymbol, variables );
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct variable * variableInstance = variable_getByName( variables, leftSideSymbol );
|
||||
|
||||
if( strcmp( variableInstance->datatype, "this_variable_is_missing" ) != 0 ) {
|
||||
|
||||
*leftSideIsPointer = variableInstance->isPointer;
|
||||
|
||||
return variableInstance->datatype;
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct method * methodInstance = method_extractMethodFromSymbol( leftSideSymbol );
|
||||
|
||||
if( methodInstance != NULL ) {
|
||||
|
||||
return tools_removePointerSymbolFromDatatype( methodInstance->returnType, leftSideIsPointer );
|
||||
|
||||
}
|
||||
|
||||
|
||||
char * returntype = function_getReturnTypeBySymbol( leftSideSymbol, leftSideIsPointer );
|
||||
|
||||
if( returntype != NULL ) {
|
||||
|
||||
return returntype;
|
||||
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user