progress on generics
							parent
							
								
									8a3920918c
								
							
						
					
					
						commit
						d641f713de
					
				|  | @ -740,6 +740,10 @@ TypeTag *MakeTypeTag(Node *node) | ||||||
|                               ->functionSignature.type); |                               ->functionSignature.type); | ||||||
|         break; |         break; | ||||||
| 
 | 
 | ||||||
|  |     case AllocExpression: | ||||||
|  |         tag = MakeTypeTag(node->allocExpression.type); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|     default: |     default: | ||||||
|         fprintf( |         fprintf( | ||||||
|             stderr, |             stderr, | ||||||
|  |  | ||||||
							
								
								
									
										526
									
								
								src/codegen.c
								
								
								
								
							
							
						
						
									
										526
									
								
								src/codegen.c
								
								
								
								
							|  | @ -23,6 +23,12 @@ typedef struct LocalVariable | ||||||
|     LLVMValueRef value; |     LLVMValueRef value; | ||||||
| } LocalVariable; | } LocalVariable; | ||||||
| 
 | 
 | ||||||
|  | typedef struct LocalGenericType | ||||||
|  | { | ||||||
|  |     char *name; | ||||||
|  |     LLVMTypeRef type; | ||||||
|  | } LocalGenericType; | ||||||
|  | 
 | ||||||
| typedef struct FunctionArgument | typedef struct FunctionArgument | ||||||
| { | { | ||||||
|     char *name; |     char *name; | ||||||
|  | @ -33,6 +39,9 @@ typedef struct ScopeFrame | ||||||
| { | { | ||||||
|     LocalVariable *localVariables; |     LocalVariable *localVariables; | ||||||
|     uint32_t localVariableCount; |     uint32_t localVariableCount; | ||||||
|  | 
 | ||||||
|  |     LocalGenericType *genericTypes; | ||||||
|  |     uint32_t genericTypeCount; | ||||||
| } ScopeFrame; | } ScopeFrame; | ||||||
| 
 | 
 | ||||||
| typedef struct Scope | typedef struct Scope | ||||||
|  | @ -75,6 +84,8 @@ typedef struct MonomorphizedGenericFunctionHashArray | ||||||
| 
 | 
 | ||||||
| typedef struct StructTypeGenericFunction | typedef struct StructTypeGenericFunction | ||||||
| { | { | ||||||
|  |     char *parentStructName; | ||||||
|  |     LLVMTypeRef parentStructPointerType; | ||||||
|     char *name; |     char *name; | ||||||
|     Node *functionDeclarationNode; |     Node *functionDeclarationNode; | ||||||
|     uint8_t isStatic; |     uint8_t isStatic; | ||||||
|  | @ -100,6 +111,18 @@ typedef struct StructTypeDeclaration | ||||||
| StructTypeDeclaration *structTypeDeclarations; | StructTypeDeclaration *structTypeDeclarations; | ||||||
| uint32_t structTypeDeclarationCount; | uint32_t structTypeDeclarationCount; | ||||||
| 
 | 
 | ||||||
|  | /* FUNCTION FORWARD DECLARATIONS */ | ||||||
|  | static LLVMBasicBlockRef CompileStatement( | ||||||
|  |     LLVMModuleRef module, | ||||||
|  |     LLVMBuilderRef builder, | ||||||
|  |     LLVMValueRef function, | ||||||
|  |     Node *statement); | ||||||
|  | 
 | ||||||
|  | static LLVMValueRef CompileExpression( | ||||||
|  |     LLVMModuleRef module, | ||||||
|  |     LLVMBuilderRef builder, | ||||||
|  |     Node *expression); | ||||||
|  | 
 | ||||||
| static Scope *CreateScope() | static Scope *CreateScope() | ||||||
| { | { | ||||||
|     Scope *scope = malloc(sizeof(Scope)); |     Scope *scope = malloc(sizeof(Scope)); | ||||||
|  | @ -107,6 +130,8 @@ static Scope *CreateScope() | ||||||
|     scope->scopeStack = malloc(sizeof(ScopeFrame)); |     scope->scopeStack = malloc(sizeof(ScopeFrame)); | ||||||
|     scope->scopeStack[0].localVariableCount = 0; |     scope->scopeStack[0].localVariableCount = 0; | ||||||
|     scope->scopeStack[0].localVariables = NULL; |     scope->scopeStack[0].localVariables = NULL; | ||||||
|  |     scope->scopeStack[0].genericTypeCount = 0; | ||||||
|  |     scope->scopeStack[0].genericTypes = NULL; | ||||||
|     scope->scopeStackCount = 1; |     scope->scopeStackCount = 1; | ||||||
| 
 | 
 | ||||||
|     return scope; |     return scope; | ||||||
|  | @ -120,6 +145,8 @@ static void PushScopeFrame(Scope *scope) | ||||||
|         sizeof(ScopeFrame) * (scope->scopeStackCount + 1)); |         sizeof(ScopeFrame) * (scope->scopeStackCount + 1)); | ||||||
|     scope->scopeStack[index].localVariableCount = 0; |     scope->scopeStack[index].localVariableCount = 0; | ||||||
|     scope->scopeStack[index].localVariables = NULL; |     scope->scopeStack[index].localVariables = NULL; | ||||||
|  |     scope->scopeStack[index].genericTypeCount = 0; | ||||||
|  |     scope->scopeStack[index].genericTypes = NULL; | ||||||
| 
 | 
 | ||||||
|     scope->scopeStackCount += 1; |     scope->scopeStackCount += 1; | ||||||
| } | } | ||||||
|  | @ -138,31 +165,21 @@ static void PopScopeFrame(Scope *scope) | ||||||
|         free(scope->scopeStack[index].localVariables); |         free(scope->scopeStack[index].localVariables); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (scope->scopeStack[index].genericTypes != NULL) | ||||||
|  |     { | ||||||
|  |         for (i = 0; i < scope->scopeStack[index].genericTypeCount; i += 1) | ||||||
|  |         { | ||||||
|  |             free(scope->scopeStack[index].genericTypes[i].name); | ||||||
|  |         } | ||||||
|  |         free(scope->scopeStack[index].localVariables); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     scope->scopeStackCount -= 1; |     scope->scopeStackCount -= 1; | ||||||
| 
 | 
 | ||||||
|     scope->scopeStack = |     scope->scopeStack = | ||||||
|         realloc(scope->scopeStack, sizeof(ScopeFrame) * scope->scopeStackCount); |         realloc(scope->scopeStack, sizeof(ScopeFrame) * scope->scopeStackCount); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void AddLocalVariable( |  | ||||||
|     Scope *scope, |  | ||||||
|     LLVMValueRef pointer, /* can be NULL */ |  | ||||||
|     LLVMValueRef value,   /* can be NULL */ |  | ||||||
|     char *name) |  | ||||||
| { |  | ||||||
|     ScopeFrame *scopeFrame = &scope->scopeStack[scope->scopeStackCount - 1]; |  | ||||||
|     uint32_t index = scopeFrame->localVariableCount; |  | ||||||
| 
 |  | ||||||
|     scopeFrame->localVariables = realloc( |  | ||||||
|         scopeFrame->localVariables, |  | ||||||
|         sizeof(LocalVariable) * (scopeFrame->localVariableCount + 1)); |  | ||||||
|     scopeFrame->localVariables[index].name = strdup(name); |  | ||||||
|     scopeFrame->localVariables[index].pointer = pointer; |  | ||||||
|     scopeFrame->localVariables[index].value = value; |  | ||||||
| 
 |  | ||||||
|     scopeFrame->localVariableCount += 1; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static LLVMTypeRef WraithTypeToLLVMType(PrimitiveType type) | static LLVMTypeRef WraithTypeToLLVMType(PrimitiveType type) | ||||||
| { | { | ||||||
|     switch (type) |     switch (type) | ||||||
|  | @ -184,6 +201,120 @@ static LLVMTypeRef WraithTypeToLLVMType(PrimitiveType type) | ||||||
|     return NULL; |     return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static LLVMTypeRef LookupCustomType(char *name) | ||||||
|  | { | ||||||
|  |     int32_t i, j; | ||||||
|  | 
 | ||||||
|  |     for (i = scope->scopeStackCount - 1; i >= 0; i -= 1) | ||||||
|  |     { | ||||||
|  |         for (j = 0; j < scope->scopeStack[i].genericTypeCount; j += 1) | ||||||
|  |         { | ||||||
|  |             if (strcmp(scope->scopeStack[i].genericTypes[j].name, name) == 0) | ||||||
|  |             { | ||||||
|  |                 return scope->scopeStack[i].genericTypes[j].type; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < structTypeDeclarationCount; i += 1) | ||||||
|  |     { | ||||||
|  |         if (strcmp(structTypeDeclarations[i].name, name) == 0) | ||||||
|  |         { | ||||||
|  |             return structTypeDeclarations[i].structType; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fprintf(stderr, "Could not find struct type!\n"); | ||||||
|  |     return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static LLVMTypeRef ResolveType(TypeTag *typeTag) | ||||||
|  | { | ||||||
|  |     if (typeTag->type == Primitive) | ||||||
|  |     { | ||||||
|  |         return WraithTypeToLLVMType(typeTag->value.primitiveType); | ||||||
|  |     } | ||||||
|  |     else if (typeTag->type == Custom) | ||||||
|  |     { | ||||||
|  |         return LookupCustomType(typeTag->value.customType); | ||||||
|  |     } | ||||||
|  |     else if (typeTag->type == Reference) | ||||||
|  |     { | ||||||
|  |         return LLVMPointerType(ResolveType(typeTag->value.referenceType), 0); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         fprintf(stderr, "Unknown type node!\n"); | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void AddLocalVariable( | ||||||
|  |     Scope *scope, | ||||||
|  |     LLVMValueRef pointer, /* can be NULL */ | ||||||
|  |     LLVMValueRef value,   /* can be NULL */ | ||||||
|  |     char *name) | ||||||
|  | { | ||||||
|  |     ScopeFrame *scopeFrame = &scope->scopeStack[scope->scopeStackCount - 1]; | ||||||
|  |     uint32_t index = scopeFrame->localVariableCount; | ||||||
|  | 
 | ||||||
|  |     scopeFrame->localVariables = realloc( | ||||||
|  |         scopeFrame->localVariables, | ||||||
|  |         sizeof(LocalVariable) * (scopeFrame->localVariableCount + 1)); | ||||||
|  |     scopeFrame->localVariables[index].name = strdup(name); | ||||||
|  |     scopeFrame->localVariables[index].pointer = pointer; | ||||||
|  |     scopeFrame->localVariables[index].value = value; | ||||||
|  | 
 | ||||||
|  |     scopeFrame->localVariableCount += 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void AddGenericVariable(Scope *scope, TypeTag *typeTag, char *name) | ||||||
|  | { | ||||||
|  |     ScopeFrame *scopeFrame = &scope->scopeStack[scope->scopeStackCount - 1]; | ||||||
|  |     uint32_t index = scopeFrame->genericTypeCount; | ||||||
|  | 
 | ||||||
|  |     scopeFrame->genericTypes = realloc( | ||||||
|  |         scopeFrame->genericTypes, | ||||||
|  |         sizeof(LocalGenericType) * (scopeFrame->genericTypeCount + 1)); | ||||||
|  |     scopeFrame->genericTypes[index].name = strdup(name); | ||||||
|  |     scopeFrame->genericTypes[index].type = ResolveType(typeTag); | ||||||
|  | 
 | ||||||
|  |     scopeFrame->genericTypeCount += 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void AddStructVariablesToScope( | ||||||
|  |     LLVMBuilderRef builder, | ||||||
|  |     LLVMValueRef structPointer) | ||||||
|  | { | ||||||
|  |     uint32_t i, j; | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < structTypeDeclarationCount; i += 1) | ||||||
|  |     { | ||||||
|  |         if (structTypeDeclarations[i].structPointerType == | ||||||
|  |             LLVMTypeOf(structPointer)) | ||||||
|  |         { | ||||||
|  |             for (j = 0; j < structTypeDeclarations[i].fieldCount; j += 1) | ||||||
|  |             { | ||||||
|  |                 char *ptrName = | ||||||
|  |                     strdup(structTypeDeclarations[i].fields[j].name); | ||||||
|  |                 strcat(ptrName, "_ptr"); | ||||||
|  |                 LLVMValueRef elementPointer = LLVMBuildStructGEP( | ||||||
|  |                     builder, | ||||||
|  |                     structPointer, | ||||||
|  |                     structTypeDeclarations[i].fields[j].index, | ||||||
|  |                     ptrName); | ||||||
|  |                 free(ptrName); | ||||||
|  | 
 | ||||||
|  |                 AddLocalVariable( | ||||||
|  |                     scope, | ||||||
|  |                     elementPointer, | ||||||
|  |                     NULL, | ||||||
|  |                     structTypeDeclarations[i].fields[j].name); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static LLVMTypeRef FindStructType(char *name) | static LLVMTypeRef FindStructType(char *name) | ||||||
| { | { | ||||||
|     uint32_t i; |     uint32_t i; | ||||||
|  | @ -355,6 +486,7 @@ static void DeclareGenericStructFunction( | ||||||
|     LLVMTypeRef wStructPointerType, |     LLVMTypeRef wStructPointerType, | ||||||
|     Node *functionDeclarationNode, |     Node *functionDeclarationNode, | ||||||
|     uint8_t isStatic, |     uint8_t isStatic, | ||||||
|  |     char *parentStructName, | ||||||
|     char *name) |     char *name) | ||||||
| { | { | ||||||
|     uint32_t i, j, index; |     uint32_t i, j, index; | ||||||
|  | @ -364,8 +496,15 @@ static void DeclareGenericStructFunction( | ||||||
|         if (structTypeDeclarations[i].structPointerType == wStructPointerType) |         if (structTypeDeclarations[i].structPointerType == wStructPointerType) | ||||||
|         { |         { | ||||||
|             index = structTypeDeclarations[i].genericFunctionCount; |             index = structTypeDeclarations[i].genericFunctionCount; | ||||||
|  |             structTypeDeclarations[i].genericFunctions = realloc( | ||||||
|  |                 structTypeDeclarations[i].genericFunctions, | ||||||
|  |                 sizeof(StructTypeGenericFunction) * | ||||||
|  |                     (structTypeDeclarations[i].genericFunctionCount + 1)); | ||||||
|             structTypeDeclarations[i].genericFunctions[index].name = |             structTypeDeclarations[i].genericFunctions[index].name = | ||||||
|                 strdup(name); |                 strdup(name); | ||||||
|  |             structTypeDeclarations[i].genericFunctions[index].parentStructName = | ||||||
|  |                 parentStructName; | ||||||
|  |             structTypeDeclarations[i].structPointerType = wStructPointerType; | ||||||
|             structTypeDeclarations[i] |             structTypeDeclarations[i] | ||||||
|                 .genericFunctions[index] |                 .genericFunctions[index] | ||||||
|                 .functionDeclarationNode = functionDeclarationNode; |                 .functionDeclarationNode = functionDeclarationNode; | ||||||
|  | @ -391,46 +530,6 @@ static void DeclareGenericStructFunction( | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMTypeRef LookupCustomType(char *name) |  | ||||||
| { |  | ||||||
|     uint32_t i; |  | ||||||
| 
 |  | ||||||
|     for (i = 0; i < structTypeDeclarationCount; i += 1) |  | ||||||
|     { |  | ||||||
|         if (strcmp(structTypeDeclarations[i].name, name) == 0) |  | ||||||
|         { |  | ||||||
|             return structTypeDeclarations[i].structType; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fprintf(stderr, "Could not find struct type!\n"); |  | ||||||
|     return NULL; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static LLVMTypeRef ResolveType(Node *typeNode) |  | ||||||
| { |  | ||||||
|     if (IsPrimitiveType(typeNode)) |  | ||||||
|     { |  | ||||||
|         return WraithTypeToLLVMType( |  | ||||||
|             typeNode->type.typeNode->primitiveType.type); |  | ||||||
|     } |  | ||||||
|     else if (typeNode->type.typeNode->syntaxKind == CustomTypeNode) |  | ||||||
|     { |  | ||||||
|         return LookupCustomType(typeNode->type.typeNode->customType.name); |  | ||||||
|     } |  | ||||||
|     else if (typeNode->type.typeNode->syntaxKind == ReferenceTypeNode) |  | ||||||
|     { |  | ||||||
|         return LLVMPointerType( |  | ||||||
|             ResolveType(typeNode->type.typeNode->referenceType.type), |  | ||||||
|             0); |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         fprintf(stderr, "Unknown type node!\n"); |  | ||||||
|         return NULL; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline uint64_t HashTypeTags(TypeTag **tags, uint32_t count) | static inline uint64_t HashTypeTags(TypeTag **tags, uint32_t count) | ||||||
| { | { | ||||||
|     const uint64_t HASH_FACTOR = 97; |     const uint64_t HASH_FACTOR = 97; | ||||||
|  | @ -445,7 +544,159 @@ static inline uint64_t HashTypeTags(TypeTag **tags, uint32_t count) | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static StructTypeFunction CompileGenericFunction( | ||||||
|  |     LLVMModuleRef module, | ||||||
|  |     char *parentStructName, | ||||||
|  |     LLVMTypeRef wStructPointerType, | ||||||
|  |     TypeTag **genericArgumentTypes, | ||||||
|  |     uint32_t genericArgumentTypeCount, | ||||||
|  |     Node *functionDeclaration) | ||||||
|  | { | ||||||
|  |     uint32_t i; | ||||||
|  |     uint8_t hasReturn = 0; | ||||||
|  |     uint8_t isStatic = 0; | ||||||
|  |     Node *functionSignature = | ||||||
|  |         functionDeclaration->functionDeclaration.functionSignature; | ||||||
|  |     Node *functionBody = functionDeclaration->functionDeclaration.functionBody; | ||||||
|  |     uint32_t argumentCount = functionSignature->functionSignature.arguments | ||||||
|  |                                  ->functionSignatureArguments.count; | ||||||
|  |     LLVMTypeRef paramTypes[argumentCount + 1]; | ||||||
|  |     uint32_t paramIndex = 0; | ||||||
|  | 
 | ||||||
|  |     PushScopeFrame(scope); | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < genericArgumentTypeCount; i += 1) | ||||||
|  |     { | ||||||
|  |         AddGenericVariable( | ||||||
|  |             scope, | ||||||
|  |             genericArgumentTypes[i], | ||||||
|  |             functionDeclaration->functionDeclaration.functionSignature | ||||||
|  |                 ->functionSignature.genericArguments->genericArguments | ||||||
|  |                 .arguments[i] | ||||||
|  |                 ->genericArgument.identifier->identifier.name); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (functionSignature->functionSignature.modifiers->functionModifiers | ||||||
|  |             .count > 0) | ||||||
|  |     { | ||||||
|  |         for (i = 0; i < functionSignature->functionSignature.modifiers | ||||||
|  |                             ->functionModifiers.count; | ||||||
|  |              i += 1) | ||||||
|  |         { | ||||||
|  |             if (functionSignature->functionSignature.modifiers | ||||||
|  |                     ->functionModifiers.sequence[i] | ||||||
|  |                     ->syntaxKind == StaticModifier) | ||||||
|  |             { | ||||||
|  |                 isStatic = 1; | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     char *functionName = strdup(parentStructName); | ||||||
|  |     strcat(functionName, "_"); | ||||||
|  |     strcat( | ||||||
|  |         functionName, | ||||||
|  |         functionSignature->functionSignature.identifier->identifier.name); | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < genericArgumentTypeCount; i += 1) | ||||||
|  |     { | ||||||
|  |         strcat(functionName, TypeTagToString(genericArgumentTypes[i])); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (!isStatic) | ||||||
|  |     { | ||||||
|  |         paramTypes[paramIndex] = wStructPointerType; | ||||||
|  |         paramIndex += 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < functionSignature->functionSignature.arguments | ||||||
|  |                         ->functionSignatureArguments.count; | ||||||
|  |          i += 1) | ||||||
|  |     { | ||||||
|  |         paramTypes[paramIndex] = | ||||||
|  |             ResolveType(functionSignature->functionSignature.arguments | ||||||
|  |                             ->functionSignatureArguments.sequence[i] | ||||||
|  |                             ->declaration.identifier->typeTag); | ||||||
|  |         paramIndex += 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     LLVMTypeRef returnType = | ||||||
|  |         ResolveType(functionSignature->functionSignature.identifier->typeTag); | ||||||
|  |     LLVMTypeRef functionType = | ||||||
|  |         LLVMFunctionType(returnType, paramTypes, paramIndex, 0); | ||||||
|  | 
 | ||||||
|  |     LLVMValueRef function = LLVMAddFunction(module, functionName, functionType); | ||||||
|  | 
 | ||||||
|  |     LLVMBasicBlockRef entry = LLVMAppendBasicBlock(function, "entry"); | ||||||
|  |     LLVMBuilderRef builder = LLVMCreateBuilder(); | ||||||
|  |     LLVMPositionBuilderAtEnd(builder, entry); | ||||||
|  | 
 | ||||||
|  |     if (!isStatic) | ||||||
|  |     { | ||||||
|  |         LLVMValueRef wStructPointer = LLVMGetParam(function, 0); | ||||||
|  |         AddStructVariablesToScope(builder, wStructPointer); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < functionSignature->functionSignature.arguments | ||||||
|  |                         ->functionSignatureArguments.count; | ||||||
|  |          i += 1) | ||||||
|  |     { | ||||||
|  |         char *ptrName = strdup(functionSignature->functionSignature.arguments | ||||||
|  |                                    ->functionSignatureArguments.sequence[i] | ||||||
|  |                                    ->declaration.identifier->identifier.name); | ||||||
|  |         strcat(ptrName, "_ptr"); | ||||||
|  |         LLVMValueRef argument = LLVMGetParam(function, i + !isStatic); | ||||||
|  |         LLVMValueRef argumentCopy = | ||||||
|  |             LLVMBuildAlloca(builder, LLVMTypeOf(argument), ptrName); | ||||||
|  |         LLVMBuildStore(builder, argument, argumentCopy); | ||||||
|  |         free(ptrName); | ||||||
|  |         AddLocalVariable( | ||||||
|  |             scope, | ||||||
|  |             argumentCopy, | ||||||
|  |             NULL, | ||||||
|  |             functionSignature->functionSignature.arguments | ||||||
|  |                 ->functionSignatureArguments.sequence[i] | ||||||
|  |                 ->declaration.identifier->identifier.name); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < functionBody->statementSequence.count; i += 1) | ||||||
|  |     { | ||||||
|  |         CompileStatement( | ||||||
|  |             module, | ||||||
|  |             builder, | ||||||
|  |             function, | ||||||
|  |             functionBody->statementSequence.sequence[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     hasReturn = | ||||||
|  |         LLVMGetBasicBlockTerminator(LLVMGetLastBasicBlock(function)) != NULL; | ||||||
|  | 
 | ||||||
|  |     if (LLVMGetTypeKind(returnType) == LLVMVoidTypeKind && !hasReturn) | ||||||
|  |     { | ||||||
|  |         LLVMBuildRetVoid(builder); | ||||||
|  |     } | ||||||
|  |     else if (LLVMGetTypeKind(returnType) != LLVMVoidTypeKind && !hasReturn) | ||||||
|  |     { | ||||||
|  |         fprintf(stderr, "Return statement not provided!"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     LLVMDisposeBuilder(builder); | ||||||
|  |     PopScopeFrame(scope); | ||||||
|  |     free(functionName); | ||||||
|  | 
 | ||||||
|  |     StructTypeFunction structTypeFunction; | ||||||
|  |     structTypeFunction.name = strdup( | ||||||
|  |         functionSignature->functionSignature.identifier->identifier.name); | ||||||
|  |     structTypeFunction.function = function; | ||||||
|  |     structTypeFunction.returnType = returnType; | ||||||
|  |     structTypeFunction.isStatic = isStatic; | ||||||
|  | 
 | ||||||
|  |     return structTypeFunction; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static LLVMValueRef LookupGenericFunction( | static LLVMValueRef LookupGenericFunction( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     StructTypeGenericFunction *genericFunction, |     StructTypeGenericFunction *genericFunction, | ||||||
|     TypeTag **genericArgumentTypes, |     TypeTag **genericArgumentTypes, | ||||||
|     uint32_t genericArgumentTypeCount, |     uint32_t genericArgumentTypeCount, | ||||||
|  | @ -484,17 +735,41 @@ static LLVMValueRef LookupGenericFunction( | ||||||
| 
 | 
 | ||||||
|     if (hashEntry == NULL) |     if (hashEntry == NULL) | ||||||
|     { |     { | ||||||
|  |         StructTypeFunction function = CompileGenericFunction( | ||||||
|  |             module, | ||||||
|  |             genericFunction->parentStructName, | ||||||
|  |             genericFunction->parentStructPointerType, | ||||||
|  |             genericArgumentTypes, | ||||||
|  |             genericArgumentTypeCount, | ||||||
|  |             genericFunction->functionDeclarationNode); | ||||||
| 
 | 
 | ||||||
|         /* TODO: compile */ |         /* TODO: add to hash */ | ||||||
|  |         hashArray->elements = realloc( | ||||||
|  |             hashArray->elements, | ||||||
|  |             sizeof(MonomorphizedGenericFunctionHashEntry) * | ||||||
|  |                 (hashArray->count + 1)); | ||||||
|  |         hashArray->elements[hashArray->count].key = typeHash; | ||||||
|  |         hashArray->elements[hashArray->count].types = | ||||||
|  |             malloc(sizeof(TypeTag *) * genericArgumentTypeCount); | ||||||
|  |         hashArray->elements[hashArray->count].typeCount = | ||||||
|  |             genericArgumentTypeCount; | ||||||
|  |         hashArray->elements[hashArray->count].function = function; | ||||||
|  |         for (i = 0; i < genericArgumentTypeCount; i += 1) | ||||||
|  |         { | ||||||
|  |             hashArray->elements[hashArray->count].types[i] = | ||||||
|  |                 genericArgumentTypes[i]; | ||||||
|  |         } | ||||||
|  |         hashArray->count += 1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     *pReturnType = hashEntry->function.returnType; |     *pReturnType = hashEntry->function.returnType; | ||||||
|     *pStatic = hashEntry->function.isStatic; |     *pStatic = genericFunction->isStatic; | ||||||
| 
 | 
 | ||||||
|     return hashEntry->function.function; |     return hashEntry->function.function; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMValueRef LookupFunctionByType( | static LLVMValueRef LookupFunctionByType( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMTypeRef structType, |     LLVMTypeRef structType, | ||||||
|     char *name, |     char *name, | ||||||
|     TypeTag **genericArgumentTypes, |     TypeTag **genericArgumentTypes, | ||||||
|  | @ -528,6 +803,7 @@ static LLVMValueRef LookupFunctionByType( | ||||||
|                         name) == 0) |                         name) == 0) | ||||||
|                 { |                 { | ||||||
|                     return LookupGenericFunction( |                     return LookupGenericFunction( | ||||||
|  |                         module, | ||||||
|                         &structTypeDeclarations[i].genericFunctions[j], |                         &structTypeDeclarations[i].genericFunctions[j], | ||||||
|                         genericArgumentTypes, |                         genericArgumentTypes, | ||||||
|                         genericArgumentTypeCount, |                         genericArgumentTypeCount, | ||||||
|  | @ -543,6 +819,7 @@ static LLVMValueRef LookupFunctionByType( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMValueRef LookupFunctionByPointerType( | static LLVMValueRef LookupFunctionByPointerType( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMTypeRef structPointerType, |     LLVMTypeRef structPointerType, | ||||||
|     char *name, |     char *name, | ||||||
|     TypeTag **genericArgumentTypes, |     TypeTag **genericArgumentTypes, | ||||||
|  | @ -576,6 +853,7 @@ static LLVMValueRef LookupFunctionByPointerType( | ||||||
|                         name) == 0) |                         name) == 0) | ||||||
|                 { |                 { | ||||||
|                     return LookupGenericFunction( |                     return LookupGenericFunction( | ||||||
|  |                         module, | ||||||
|                         &structTypeDeclarations[i].genericFunctions[j], |                         &structTypeDeclarations[i].genericFunctions[j], | ||||||
|                         genericArgumentTypes, |                         genericArgumentTypes, | ||||||
|                         genericArgumentTypeCount, |                         genericArgumentTypeCount, | ||||||
|  | @ -591,6 +869,7 @@ static LLVMValueRef LookupFunctionByPointerType( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMValueRef LookupFunctionByInstance( | static LLVMValueRef LookupFunctionByInstance( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMValueRef structPointer, |     LLVMValueRef structPointer, | ||||||
|     char *name, |     char *name, | ||||||
|     TypeTag **genericArgumentTypes, |     TypeTag **genericArgumentTypes, | ||||||
|  | @ -599,6 +878,7 @@ static LLVMValueRef LookupFunctionByInstance( | ||||||
|     uint8_t *pStatic) |     uint8_t *pStatic) | ||||||
| { | { | ||||||
|     return LookupFunctionByPointerType( |     return LookupFunctionByPointerType( | ||||||
|  |         module, | ||||||
|         LLVMTypeOf(structPointer), |         LLVMTypeOf(structPointer), | ||||||
|         name, |         name, | ||||||
|         genericArgumentTypes, |         genericArgumentTypes, | ||||||
|  | @ -607,41 +887,6 @@ static LLVMValueRef LookupFunctionByInstance( | ||||||
|         pStatic); |         pStatic); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void AddStructVariablesToScope( |  | ||||||
|     LLVMBuilderRef builder, |  | ||||||
|     LLVMValueRef structPointer) |  | ||||||
| { |  | ||||||
|     uint32_t i, j; |  | ||||||
| 
 |  | ||||||
|     for (i = 0; i < structTypeDeclarationCount; i += 1) |  | ||||||
|     { |  | ||||||
|         if (structTypeDeclarations[i].structPointerType == |  | ||||||
|             LLVMTypeOf(structPointer)) |  | ||||||
|         { |  | ||||||
|             for (j = 0; j < structTypeDeclarations[i].fieldCount; j += 1) |  | ||||||
|             { |  | ||||||
|                 char *ptrName = |  | ||||||
|                     strdup(structTypeDeclarations[i].fields[j].name); |  | ||||||
|                 strcat(ptrName, "_ptr"); |  | ||||||
|                 LLVMValueRef elementPointer = LLVMBuildStructGEP( |  | ||||||
|                     builder, |  | ||||||
|                     structPointer, |  | ||||||
|                     structTypeDeclarations[i].fields[j].index, |  | ||||||
|                     ptrName); |  | ||||||
|                 free(ptrName); |  | ||||||
| 
 |  | ||||||
|                 AddLocalVariable( |  | ||||||
|                     scope, |  | ||||||
|                     elementPointer, |  | ||||||
|                     NULL, |  | ||||||
|                     structTypeDeclarations[i].fields[j].name); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static LLVMValueRef CompileExpression(LLVMBuilderRef builder, Node *expression); |  | ||||||
| 
 |  | ||||||
| static LLVMValueRef CompileNumber(Node *numberExpression) | static LLVMValueRef CompileNumber(Node *numberExpression) | ||||||
| { | { | ||||||
|     return LLVMConstInt(LLVMInt64Type(), numberExpression->number.value, 0); |     return LLVMConstInt(LLVMInt64Type(), numberExpression->number.value, 0); | ||||||
|  | @ -658,13 +903,19 @@ static LLVMValueRef CompileString( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMValueRef CompileBinaryExpression( | static LLVMValueRef CompileBinaryExpression( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMBuilderRef builder, |     LLVMBuilderRef builder, | ||||||
|     Node *binaryExpression) |     Node *binaryExpression) | ||||||
| { | { | ||||||
|     LLVMValueRef left = |     LLVMValueRef left = CompileExpression( | ||||||
|         CompileExpression(builder, binaryExpression->binaryExpression.left); |         module, | ||||||
|     LLVMValueRef right = |         builder, | ||||||
|         CompileExpression(builder, binaryExpression->binaryExpression.right); |         binaryExpression->binaryExpression.left); | ||||||
|  | 
 | ||||||
|  |     LLVMValueRef right = CompileExpression( | ||||||
|  |         module, | ||||||
|  |         builder, | ||||||
|  |         binaryExpression->binaryExpression.right); | ||||||
| 
 | 
 | ||||||
|     switch (binaryExpression->binaryExpression.operator) |     switch (binaryExpression->binaryExpression.operator) | ||||||
|     { |     { | ||||||
|  | @ -709,6 +960,7 @@ static LLVMValueRef CompileBinaryExpression( | ||||||
| 
 | 
 | ||||||
| /* FIXME THIS IS ALL BROKEN */ | /* FIXME THIS IS ALL BROKEN */ | ||||||
| static LLVMValueRef CompileFunctionCallExpression( | static LLVMValueRef CompileFunctionCallExpression( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMBuilderRef builder, |     LLVMBuilderRef builder, | ||||||
|     Node *functionCallExpression) |     Node *functionCallExpression) | ||||||
| { | { | ||||||
|  | @ -728,6 +980,7 @@ static LLVMValueRef CompileFunctionCallExpression( | ||||||
|     LLVMTypeRef functionReturnType; |     LLVMTypeRef functionReturnType; | ||||||
|     char *returnName = ""; |     char *returnName = ""; | ||||||
| 
 | 
 | ||||||
|  |     /* FIXME: this is completely wrong and not how we get generic args */ | ||||||
|     for (i = 0; i < functionCallExpression->functionCallExpression |     for (i = 0; i < functionCallExpression->functionCallExpression | ||||||
|                         .argumentSequence->functionArgumentSequence.count; |                         .argumentSequence->functionArgumentSequence.count; | ||||||
|          i += 1) |          i += 1) | ||||||
|  | @ -739,7 +992,7 @@ static LLVMValueRef CompileFunctionCallExpression( | ||||||
|             genericArgumentTypes[genericArgumentCount] = |             genericArgumentTypes[genericArgumentCount] = | ||||||
|                 functionCallExpression->functionCallExpression.argumentSequence |                 functionCallExpression->functionCallExpression.argumentSequence | ||||||
|                     ->functionArgumentSequence.sequence[i] |                     ->functionArgumentSequence.sequence[i] | ||||||
|                     ->typeTag; |                     ->declaration.identifier->typeTag; | ||||||
| 
 | 
 | ||||||
|             genericArgumentCount += 1; |             genericArgumentCount += 1; | ||||||
|         } |         } | ||||||
|  | @ -757,6 +1010,7 @@ static LLVMValueRef CompileFunctionCallExpression( | ||||||
|         if (typeReference != NULL) |         if (typeReference != NULL) | ||||||
|         { |         { | ||||||
|             function = LookupFunctionByType( |             function = LookupFunctionByType( | ||||||
|  |                 module, | ||||||
|                 typeReference, |                 typeReference, | ||||||
|                 functionCallExpression->functionCallExpression.identifier |                 functionCallExpression->functionCallExpression.identifier | ||||||
|                     ->accessExpression.accessor->identifier.name, |                     ->accessExpression.accessor->identifier.name, | ||||||
|  | @ -771,6 +1025,7 @@ static LLVMValueRef CompileFunctionCallExpression( | ||||||
|                 functionCallExpression->functionCallExpression.identifier |                 functionCallExpression->functionCallExpression.identifier | ||||||
|                     ->accessExpression.accessee->identifier.name); |                     ->accessExpression.accessee->identifier.name); | ||||||
|             function = LookupFunctionByInstance( |             function = LookupFunctionByInstance( | ||||||
|  |                 module, | ||||||
|                 structInstance, |                 structInstance, | ||||||
|                 functionCallExpression->functionCallExpression.identifier |                 functionCallExpression->functionCallExpression.identifier | ||||||
|                     ->accessExpression.accessor->identifier.name, |                     ->accessExpression.accessor->identifier.name, | ||||||
|  | @ -797,6 +1052,7 @@ static LLVMValueRef CompileFunctionCallExpression( | ||||||
|          i += 1) |          i += 1) | ||||||
|     { |     { | ||||||
|         args[argumentCount] = CompileExpression( |         args[argumentCount] = CompileExpression( | ||||||
|  |             module, | ||||||
|             builder, |             builder, | ||||||
|             functionCallExpression->functionCallExpression.argumentSequence |             functionCallExpression->functionCallExpression.argumentSequence | ||||||
|                 ->functionArgumentSequence.sequence[i]); |                 ->functionArgumentSequence.sequence[i]); | ||||||
|  | @ -843,11 +1099,14 @@ static LLVMValueRef CompileAllocExpression( | ||||||
|     LLVMBuilderRef builder, |     LLVMBuilderRef builder, | ||||||
|     Node *allocExpression) |     Node *allocExpression) | ||||||
| { | { | ||||||
|     LLVMTypeRef type = ResolveType(allocExpression->allocExpression.type); |     LLVMTypeRef type = ResolveType(allocExpression->typeTag); | ||||||
|     return LLVMBuildMalloc(builder, type, "allocation"); |     return LLVMBuildMalloc(builder, type, "allocation"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMValueRef CompileExpression(LLVMBuilderRef builder, Node *expression) | static LLVMValueRef CompileExpression( | ||||||
|  |     LLVMModuleRef module, | ||||||
|  |     LLVMBuilderRef builder, | ||||||
|  |     Node *expression) | ||||||
| { | { | ||||||
|     switch (expression->syntaxKind) |     switch (expression->syntaxKind) | ||||||
|     { |     { | ||||||
|  | @ -858,10 +1117,10 @@ static LLVMValueRef CompileExpression(LLVMBuilderRef builder, Node *expression) | ||||||
|         return CompileAllocExpression(builder, expression); |         return CompileAllocExpression(builder, expression); | ||||||
| 
 | 
 | ||||||
|     case BinaryExpression: |     case BinaryExpression: | ||||||
|         return CompileBinaryExpression(builder, expression); |         return CompileBinaryExpression(module, builder, expression); | ||||||
| 
 | 
 | ||||||
|     case FunctionCallExpression: |     case FunctionCallExpression: | ||||||
|         return CompileFunctionCallExpression(builder, expression); |         return CompileFunctionCallExpression(module, builder, expression); | ||||||
| 
 | 
 | ||||||
|     case Identifier: |     case Identifier: | ||||||
|         return FindVariableValue(builder, expression->identifier.name); |         return FindVariableValue(builder, expression->identifier.name); | ||||||
|  | @ -877,17 +1136,14 @@ static LLVMValueRef CompileExpression(LLVMBuilderRef builder, Node *expression) | ||||||
|     return NULL; |     return NULL; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMBasicBlockRef CompileStatement( |  | ||||||
|     LLVMBuilderRef builder, |  | ||||||
|     LLVMValueRef function, |  | ||||||
|     Node *statement); |  | ||||||
| 
 |  | ||||||
| static LLVMBasicBlockRef CompileReturn( | static LLVMBasicBlockRef CompileReturn( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMBuilderRef builder, |     LLVMBuilderRef builder, | ||||||
|     LLVMValueRef function, |     LLVMValueRef function, | ||||||
|     Node *returnStatemement) |     Node *returnStatemement) | ||||||
| { | { | ||||||
|     LLVMValueRef expression = CompileExpression( |     LLVMValueRef expression = CompileExpression( | ||||||
|  |         module, | ||||||
|         builder, |         builder, | ||||||
|         returnStatemement->returnStatement.expression); |         returnStatemement->returnStatement.expression); | ||||||
|     LLVMBuildRet(builder, expression); |     LLVMBuildRet(builder, expression); | ||||||
|  | @ -916,7 +1172,7 @@ static LLVMValueRef CompileFunctionVariableDeclaration( | ||||||
| 
 | 
 | ||||||
|     variable = LLVMBuildAlloca( |     variable = LLVMBuildAlloca( | ||||||
|         builder, |         builder, | ||||||
|         ResolveType(variableDeclaration->declaration.type), |         ResolveType(variableDeclaration->declaration.identifier->typeTag), | ||||||
|         ptrName); |         ptrName); | ||||||
| 
 | 
 | ||||||
|     free(ptrName); |     free(ptrName); | ||||||
|  | @ -927,11 +1183,13 @@ static LLVMValueRef CompileFunctionVariableDeclaration( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMBasicBlockRef CompileAssignment( | static LLVMBasicBlockRef CompileAssignment( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMBuilderRef builder, |     LLVMBuilderRef builder, | ||||||
|     LLVMValueRef function, |     LLVMValueRef function, | ||||||
|     Node *assignmentStatement) |     Node *assignmentStatement) | ||||||
| { | { | ||||||
|     LLVMValueRef result = CompileExpression( |     LLVMValueRef result = CompileExpression( | ||||||
|  |         module, | ||||||
|         builder, |         builder, | ||||||
|         assignmentStatement->assignmentStatement.right); |         assignmentStatement->assignmentStatement.right); | ||||||
|     LLVMValueRef identifier; |     LLVMValueRef identifier; | ||||||
|  | @ -969,13 +1227,14 @@ static LLVMBasicBlockRef CompileAssignment( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMBasicBlockRef CompileIfStatement( | static LLVMBasicBlockRef CompileIfStatement( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMBuilderRef builder, |     LLVMBuilderRef builder, | ||||||
|     LLVMValueRef function, |     LLVMValueRef function, | ||||||
|     Node *ifStatement) |     Node *ifStatement) | ||||||
| { | { | ||||||
|     uint32_t i; |     uint32_t i; | ||||||
|     LLVMValueRef conditional = |     LLVMValueRef conditional = | ||||||
|         CompileExpression(builder, ifStatement->ifStatement.expression); |         CompileExpression(module, builder, ifStatement->ifStatement.expression); | ||||||
| 
 | 
 | ||||||
|     LLVMBasicBlockRef block = LLVMAppendBasicBlock(function, "ifBlock"); |     LLVMBasicBlockRef block = LLVMAppendBasicBlock(function, "ifBlock"); | ||||||
|     LLVMBasicBlockRef afterCond = LLVMAppendBasicBlock(function, "afterCond"); |     LLVMBasicBlockRef afterCond = LLVMAppendBasicBlock(function, "afterCond"); | ||||||
|  | @ -990,6 +1249,7 @@ static LLVMBasicBlockRef CompileIfStatement( | ||||||
|          i += 1) |          i += 1) | ||||||
|     { |     { | ||||||
|         CompileStatement( |         CompileStatement( | ||||||
|  |             module, | ||||||
|             builder, |             builder, | ||||||
|             function, |             function, | ||||||
|             ifStatement->ifStatement.statementSequence->statementSequence |             ifStatement->ifStatement.statementSequence->statementSequence | ||||||
|  | @ -1003,12 +1263,14 @@ static LLVMBasicBlockRef CompileIfStatement( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMBasicBlockRef CompileIfElseStatement( | static LLVMBasicBlockRef CompileIfElseStatement( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMBuilderRef builder, |     LLVMBuilderRef builder, | ||||||
|     LLVMValueRef function, |     LLVMValueRef function, | ||||||
|     Node *ifElseStatement) |     Node *ifElseStatement) | ||||||
| { | { | ||||||
|     uint32_t i; |     uint32_t i; | ||||||
|     LLVMValueRef conditional = CompileExpression( |     LLVMValueRef conditional = CompileExpression( | ||||||
|  |         module, | ||||||
|         builder, |         builder, | ||||||
|         ifElseStatement->ifElseStatement.ifStatement->ifStatement.expression); |         ifElseStatement->ifElseStatement.ifStatement->ifStatement.expression); | ||||||
| 
 | 
 | ||||||
|  | @ -1025,6 +1287,7 @@ static LLVMBasicBlockRef CompileIfElseStatement( | ||||||
|          i += 1) |          i += 1) | ||||||
|     { |     { | ||||||
|         CompileStatement( |         CompileStatement( | ||||||
|  |             module, | ||||||
|             builder, |             builder, | ||||||
|             function, |             function, | ||||||
|             ifElseStatement->ifElseStatement.ifStatement->ifStatement |             ifElseStatement->ifElseStatement.ifStatement->ifStatement | ||||||
|  | @ -1043,6 +1306,7 @@ static LLVMBasicBlockRef CompileIfElseStatement( | ||||||
|              i += 1) |              i += 1) | ||||||
|         { |         { | ||||||
|             CompileStatement( |             CompileStatement( | ||||||
|  |                 module, | ||||||
|                 builder, |                 builder, | ||||||
|                 function, |                 function, | ||||||
|                 ifElseStatement->ifElseStatement.elseStatement |                 ifElseStatement->ifElseStatement.elseStatement | ||||||
|  | @ -1052,6 +1316,7 @@ static LLVMBasicBlockRef CompileIfElseStatement( | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|         CompileStatement( |         CompileStatement( | ||||||
|  |             module, | ||||||
|             builder, |             builder, | ||||||
|             function, |             function, | ||||||
|             ifElseStatement->ifElseStatement.elseStatement); |             ifElseStatement->ifElseStatement.elseStatement); | ||||||
|  | @ -1064,6 +1329,7 @@ static LLVMBasicBlockRef CompileIfElseStatement( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMBasicBlockRef CompileForLoopStatement( | static LLVMBasicBlockRef CompileForLoopStatement( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMBuilderRef builder, |     LLVMBuilderRef builder, | ||||||
|     LLVMValueRef function, |     LLVMValueRef function, | ||||||
|     Node *forLoopStatement) |     Node *forLoopStatement) | ||||||
|  | @ -1076,8 +1342,8 @@ static LLVMBasicBlockRef CompileForLoopStatement( | ||||||
|         LLVMAppendBasicBlock(function, "afterLoop"); |         LLVMAppendBasicBlock(function, "afterLoop"); | ||||||
|     char *iteratorVariableName = forLoopStatement->forLoop.declaration |     char *iteratorVariableName = forLoopStatement->forLoop.declaration | ||||||
|                                      ->declaration.identifier->identifier.name; |                                      ->declaration.identifier->identifier.name; | ||||||
|     LLVMTypeRef iteratorVariableType = |     LLVMTypeRef iteratorVariableType = ResolveType( | ||||||
|         ResolveType(forLoopStatement->forLoop.declaration->declaration.type); |         forLoopStatement->forLoop.declaration->declaration.identifier->typeTag); | ||||||
| 
 | 
 | ||||||
|     PushScopeFrame(scope); |     PushScopeFrame(scope); | ||||||
| 
 | 
 | ||||||
|  | @ -1123,6 +1389,7 @@ static LLVMBasicBlockRef CompileForLoopStatement( | ||||||
|          i += 1) |          i += 1) | ||||||
|     { |     { | ||||||
|         lastBlock = CompileStatement( |         lastBlock = CompileStatement( | ||||||
|  |             module, | ||||||
|             builder, |             builder, | ||||||
|             function, |             function, | ||||||
|             forLoopStatement->forLoop.statementSequence->statementSequence |             forLoopStatement->forLoop.statementSequence->statementSequence | ||||||
|  | @ -1151,6 +1418,7 @@ static LLVMBasicBlockRef CompileForLoopStatement( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static LLVMBasicBlockRef CompileStatement( | static LLVMBasicBlockRef CompileStatement( | ||||||
|  |     LLVMModuleRef module, | ||||||
|     LLVMBuilderRef builder, |     LLVMBuilderRef builder, | ||||||
|     LLVMValueRef function, |     LLVMValueRef function, | ||||||
|     Node *statement) |     Node *statement) | ||||||
|  | @ -1158,27 +1426,27 @@ static LLVMBasicBlockRef CompileStatement( | ||||||
|     switch (statement->syntaxKind) |     switch (statement->syntaxKind) | ||||||
|     { |     { | ||||||
|     case Assignment: |     case Assignment: | ||||||
|         return CompileAssignment(builder, function, statement); |         return CompileAssignment(module, builder, function, statement); | ||||||
| 
 | 
 | ||||||
|     case Declaration: |     case Declaration: | ||||||
|         CompileFunctionVariableDeclaration(builder, function, statement); |         CompileFunctionVariableDeclaration(builder, function, statement); | ||||||
|         return LLVMGetLastBasicBlock(function); |         return LLVMGetLastBasicBlock(function); | ||||||
| 
 | 
 | ||||||
|     case ForLoop: |     case ForLoop: | ||||||
|         return CompileForLoopStatement(builder, function, statement); |         return CompileForLoopStatement(module, builder, function, statement); | ||||||
| 
 | 
 | ||||||
|     case FunctionCallExpression: |     case FunctionCallExpression: | ||||||
|         CompileFunctionCallExpression(builder, statement); |         CompileFunctionCallExpression(module, builder, statement); | ||||||
|         return LLVMGetLastBasicBlock(function); |         return LLVMGetLastBasicBlock(function); | ||||||
| 
 | 
 | ||||||
|     case IfStatement: |     case IfStatement: | ||||||
|         return CompileIfStatement(builder, function, statement); |         return CompileIfStatement(module, builder, function, statement); | ||||||
| 
 | 
 | ||||||
|     case IfElseStatement: |     case IfElseStatement: | ||||||
|         return CompileIfElseStatement(builder, function, statement); |         return CompileIfElseStatement(module, builder, function, statement); | ||||||
| 
 | 
 | ||||||
|     case Return: |     case Return: | ||||||
|         return CompileReturn(builder, function, statement); |         return CompileReturn(module, builder, function, statement); | ||||||
| 
 | 
 | ||||||
|     case ReturnVoid: |     case ReturnVoid: | ||||||
|         return CompileReturnVoid(builder, function); |         return CompileReturnVoid(builder, function); | ||||||
|  | @ -1192,8 +1460,6 @@ static void CompileFunction( | ||||||
|     LLVMModuleRef module, |     LLVMModuleRef module, | ||||||
|     char *parentStructName, |     char *parentStructName, | ||||||
|     LLVMTypeRef wStructPointerType, |     LLVMTypeRef wStructPointerType, | ||||||
|     Node **fieldDeclarations, |  | ||||||
|     uint32_t fieldDeclarationCount, |  | ||||||
|     Node *functionDeclaration) |     Node *functionDeclaration) | ||||||
| { | { | ||||||
|     uint32_t i; |     uint32_t i; | ||||||
|  | @ -1248,12 +1514,12 @@ static void CompileFunction( | ||||||
|             paramTypes[paramIndex] = |             paramTypes[paramIndex] = | ||||||
|                 ResolveType(functionSignature->functionSignature.arguments |                 ResolveType(functionSignature->functionSignature.arguments | ||||||
|                                 ->functionSignatureArguments.sequence[i] |                                 ->functionSignatureArguments.sequence[i] | ||||||
|                                 ->declaration.type); |                                 ->declaration.identifier->typeTag); | ||||||
|             paramIndex += 1; |             paramIndex += 1; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         LLVMTypeRef returnType = |         LLVMTypeRef returnType = ResolveType( | ||||||
|             ResolveType(functionSignature->functionSignature.type); |             functionSignature->functionSignature.identifier->typeTag); | ||||||
|         LLVMTypeRef functionType = |         LLVMTypeRef functionType = | ||||||
|             LLVMFunctionType(returnType, paramTypes, paramIndex, 0); |             LLVMFunctionType(returnType, paramTypes, paramIndex, 0); | ||||||
| 
 | 
 | ||||||
|  | @ -1303,6 +1569,7 @@ static void CompileFunction( | ||||||
|         for (i = 0; i < functionBody->statementSequence.count; i += 1) |         for (i = 0; i < functionBody->statementSequence.count; i += 1) | ||||||
|         { |         { | ||||||
|             CompileStatement( |             CompileStatement( | ||||||
|  |                 module, | ||||||
|                 builder, |                 builder, | ||||||
|                 function, |                 function, | ||||||
|                 functionBody->statementSequence.sequence[i]); |                 functionBody->statementSequence.sequence[i]); | ||||||
|  | @ -1330,7 +1597,8 @@ static void CompileFunction( | ||||||
|             wStructPointerType, |             wStructPointerType, | ||||||
|             functionDeclaration, |             functionDeclaration, | ||||||
|             isStatic, |             isStatic, | ||||||
|             functionName); |             parentStructName, | ||||||
|  |             functionSignature->functionSignature.identifier->identifier.name); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     free(functionName); |     free(functionName); | ||||||
|  | @ -1367,8 +1635,8 @@ static void CompileStruct( | ||||||
|         switch (currentDeclarationNode->syntaxKind) |         switch (currentDeclarationNode->syntaxKind) | ||||||
|         { |         { | ||||||
|         case Declaration: /* this is badly named */ |         case Declaration: /* this is badly named */ | ||||||
|             types[fieldCount] = |             types[fieldCount] = ResolveType( | ||||||
|                 ResolveType(currentDeclarationNode->declaration.type); |                 currentDeclarationNode->declaration.identifier->typeTag); | ||||||
|             fieldDeclarations[fieldCount] = currentDeclarationNode; |             fieldDeclarations[fieldCount] = currentDeclarationNode; | ||||||
|             fieldCount += 1; |             fieldCount += 1; | ||||||
|             break; |             break; | ||||||
|  | @ -1396,8 +1664,6 @@ static void CompileStruct( | ||||||
|                 module, |                 module, | ||||||
|                 structName, |                 structName, | ||||||
|                 wStructPointerType, |                 wStructPointerType, | ||||||
|                 fieldDeclarations, |  | ||||||
|                 fieldCount, |  | ||||||
|                 currentDeclarationNode); |                 currentDeclarationNode); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -59,9 +59,7 @@ IdNode *MakeIdTree(Node *astNode, IdNode *parent) | ||||||
|         return NULL; |         return NULL; | ||||||
| 
 | 
 | ||||||
|     case AllocExpression: |     case AllocExpression: | ||||||
|         AddChildToNode( |         astNode->typeTag = MakeTypeTag(astNode); | ||||||
|             parent, |  | ||||||
|             MakeIdTree(astNode->allocExpression.type, parent)); |  | ||||||
|         return NULL; |         return NULL; | ||||||
| 
 | 
 | ||||||
|     case Assignment: |     case Assignment: | ||||||
|  | @ -154,6 +152,7 @@ IdNode *MakeIdTree(Node *astNode, IdNode *parent) | ||||||
|         idNode->typeTag = mainNode->typeTag; |         idNode->typeTag = mainNode->typeTag; | ||||||
|         MakeIdTree(sigNode->functionSignature.arguments, mainNode); |         MakeIdTree(sigNode->functionSignature.arguments, mainNode); | ||||||
|         MakeIdTree(astNode->functionDeclaration.functionBody, mainNode); |         MakeIdTree(astNode->functionDeclaration.functionBody, mainNode); | ||||||
|  |         MakeIdTree(sigNode->functionSignature.genericArguments, mainNode); | ||||||
|         break; |         break; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -167,6 +166,23 @@ IdNode *MakeIdTree(Node *astNode, IdNode *parent) | ||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     case GenericArgument: | ||||||
|  |     { | ||||||
|  |         char *name = astNode->genericArgument.identifier->identifier.name; | ||||||
|  |         mainNode = MakeIdNode(GenericType, name, parent); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     case GenericArguments: | ||||||
|  |     { | ||||||
|  |         for (i = 0; i < astNode->genericArguments.count; i += 1) | ||||||
|  |         { | ||||||
|  |             Node *argNode = astNode->genericArguments.arguments[i]; | ||||||
|  |             AddChildToNode(parent, MakeIdTree(argNode, parent)); | ||||||
|  |         } | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     case Identifier: |     case Identifier: | ||||||
|     { |     { | ||||||
|         char *name = astNode->identifier.name; |         char *name = astNode->identifier.name; | ||||||
|  | @ -302,6 +318,12 @@ void PrintIdNode(IdNode *node) | ||||||
|     case Variable: |     case Variable: | ||||||
|         printf("%s : %s\n", node->name, TypeTagToString(node->typeTag)); |         printf("%s : %s\n", node->name, TypeTagToString(node->typeTag)); | ||||||
|         break; |         break; | ||||||
|  |     case GenericType: | ||||||
|  |         printf("Generic type: %s\n", node->name); | ||||||
|  |         break; | ||||||
|  |     case Alloc: | ||||||
|  |         printf("Alloc: %s\n", TypeTagToString(node->typeTag)); | ||||||
|  |         break; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -17,7 +17,9 @@ typedef enum NodeType | ||||||
|     OrderedScope, |     OrderedScope, | ||||||
|     Struct, |     Struct, | ||||||
|     Function, |     Function, | ||||||
|     Variable |     Variable, | ||||||
|  |     GenericType, | ||||||
|  |     Alloc | ||||||
| } NodeType; | } NodeType; | ||||||
| 
 | 
 | ||||||
| typedef struct IdNode | typedef struct IdNode | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ uint64_t str_hash(char *str) | ||||||
|     uint64_t hash = 5381; |     uint64_t hash = 5381; | ||||||
|     size_t c; |     size_t c; | ||||||
| 
 | 
 | ||||||
|     while (c = *str++) |     while ((c = *str++)) | ||||||
|     { |     { | ||||||
|         hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ |         hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ | ||||||
|     } |     } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue