917 lines
19 KiB
C
917 lines
19 KiB
C
|
|
|
||
|
|
#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;
|
||
|
|
|
||
|
|
}
|