Compare commits
	
		
			3 Commits 
		
	
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | a0efcf548d | |
|  | e5e5397e7e | |
|  | a529bb6e4f | 
							
								
								
									
										10
									
								
								example.w
								
								
								
								
							
							
						
						
									
										10
									
								
								example.w
								
								
								
								
							|  | @ -1,6 +1,16 @@ | |||
| interface Increments | ||||
| { | ||||
|     Increment(): void; | ||||
| } | ||||
| 
 | ||||
| struct YourStruct | ||||
| { | ||||
|     yourInt: int; | ||||
| 
 | ||||
|     IncrementOther<T: Increments>(other: T): void | ||||
|     { | ||||
|         other.Increment(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| struct MyStruct | ||||
|  |  | |||
|  | @ -13,6 +13,7 @@ | |||
| "string"                    return STRING; | ||||
| "bool"                      return BOOL; | ||||
| "struct"                    return STRUCT; | ||||
| "interface"                 return INTERFACE; | ||||
| "return"                    return RETURN; | ||||
| "static"                    return STATIC; | ||||
| "Reference"                 return REFERENCE; | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ extern FILE *yyin; | |||
| %token STRING | ||||
| %token BOOL | ||||
| %token STRUCT | ||||
| %token INTERFACE | ||||
| %token RETURN | ||||
| %token STATIC | ||||
| %token REFERENCE | ||||
|  | @ -307,14 +308,40 @@ Body                    : LEFT_BRACE Statements RIGHT_BRACE | |||
|                             $$ = $2; | ||||
|                         } | ||||
| 
 | ||||
| FunctionSignature       : Identifier LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type | ||||
| GenericConstraint       : Identifier COLON Identifier | ||||
|                         { | ||||
|                             $$ = MakeFunctionSignatureNode($1, $6, $3, MakeFunctionModifiersNode(NULL, 0)); | ||||
|                             $$ = MakeGenericConstraintNode($1, $3); | ||||
|                         } | ||||
| 
 | ||||
| GenericConstraints      : GenericConstraint | ||||
|                         { | ||||
|                             $$ = StartGenericConstraintsNode($1); | ||||
|                         } | ||||
|                         | GenericConstraints COMMA GenericConstraint | ||||
|                         { | ||||
|                             $$ = AddGenericConstraint($1, $3); | ||||
|                         } | ||||
|                         ; | ||||
| 
 | ||||
| GenericConstraintClause : LESS_THAN GenericConstraints GREATER_THAN | ||||
|                         { | ||||
|                             $$ = $2; | ||||
|                         } | ||||
|                         | | ||||
|                         { | ||||
|                             $$ = MakeEmptyGenericConstraintsNode(); | ||||
|                         } | ||||
|                         ; | ||||
| 
 | ||||
| /* FIXME: modifiers should be recursive */ | ||||
| FunctionSignature       : Identifier GenericConstraintClause LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type | ||||
|                         { | ||||
|                             $$ = MakeFunctionSignatureNode($1, $7, $4, MakeFunctionModifiersNode(NULL, 0), $2); | ||||
|                         } | ||||
|                         | STATIC Identifier LEFT_PAREN SignatureArguments RIGHT_PAREN COLON Type | ||||
|                         { | ||||
|                             Node *modifier = MakeStaticNode(); | ||||
|                             $$ = MakeFunctionSignatureNode($2, $7, $4, MakeFunctionModifiersNode(&modifier, 1)); | ||||
|                             $$ = MakeFunctionSignatureNode($2, $7, $4, MakeFunctionModifiersNode(&modifier, 1), MakeEmptyGenericConstraintsNode()); | ||||
|                         } | ||||
| 
 | ||||
| FunctionDeclaration     : FunctionSignature Body | ||||
|  | @ -327,6 +354,24 @@ StructDeclaration       : STRUCT Identifier LEFT_BRACE Declarations RIGHT_BRACE | |||
|                             $$ = MakeStructDeclarationNode($2, $4); | ||||
|                         } | ||||
| 
 | ||||
| InterfaceDeclaration    : INTERFACE Identifier LEFT_BRACE InterfaceChildren RIGHT_BRACE | ||||
|                         { | ||||
|                             $$ = MakeInterfaceDeclarationNode($2, $4); | ||||
|                         } | ||||
| 
 | ||||
| InterfaceChild          : FunctionSignature SEMICOLON | ||||
|                         ; | ||||
| 
 | ||||
| InterfaceChildren       : InterfaceChild | ||||
|                         { | ||||
|                             $$ = StartDeclarationSequenceNode($1); | ||||
|                         } | ||||
|                         | InterfaceChildren InterfaceChild | ||||
|                         { | ||||
|                             $$ = AddDeclarationNode($1, $2); | ||||
|                         } | ||||
|                         ; | ||||
| 
 | ||||
| Declaration             : FunctionDeclaration | ||||
|                         | VariableDeclaration SEMICOLON | ||||
|                         ; | ||||
|  | @ -340,7 +385,9 @@ Declarations            : Declaration | |||
|                             $$ = AddDeclarationNode($1, $2); | ||||
|                         } | ||||
| 
 | ||||
| TopLevelDeclaration     : StructDeclaration; | ||||
| TopLevelDeclaration     : StructDeclaration | ||||
|                         | InterfaceDeclaration | ||||
|                         ; | ||||
| 
 | ||||
| TopLevelDeclarations    : TopLevelDeclaration | ||||
|                         { | ||||
|  |  | |||
							
								
								
									
										58
									
								
								src/ast.c
								
								
								
								
							
							
						
						
									
										58
									
								
								src/ast.c
								
								
								
								
							|  | @ -276,20 +276,59 @@ Node *MakeEmptyFunctionSignatureArgumentsNode() | |||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node* MakeGenericConstraintNode(Node *identifierNode, Node *interfaceNode) | ||||
| { | ||||
|     Node* node = (Node*) malloc(sizeof(Node)); | ||||
|     node->syntaxKind = GenericConstraint; | ||||
|     node->childCount = 2; | ||||
|     node->children = (Node**) malloc(sizeof(Node*) * 2); | ||||
|     node->children[0] = identifierNode; | ||||
|     node->children[1] = interfaceNode; /* can be NULL */ | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node* StartGenericConstraintsNode(Node *genericNode) | ||||
| { | ||||
|     Node* node = (Node*) malloc(sizeof(Node)); | ||||
|     node->syntaxKind = GenericConstraints; | ||||
|     node->childCount = 1; | ||||
|     node->children = (Node**) malloc(sizeof(Node*)); | ||||
|     node->children[0] = genericNode; | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node* AddGenericConstraint(Node *genericsNode, Node *genericNode) | ||||
| { | ||||
|     genericsNode->children = realloc(genericsNode->children, sizeof(Node*) * (genericsNode->childCount + 1)); | ||||
|     genericsNode->children[genericsNode->childCount] = genericNode; | ||||
|     genericsNode->childCount += 1; | ||||
|     return genericsNode; | ||||
| } | ||||
| 
 | ||||
| Node* MakeEmptyGenericConstraintsNode() | ||||
| { | ||||
|     Node* node = (Node*) malloc(sizeof(Node)); | ||||
|     node->syntaxKind = GenericConstraints; | ||||
|     node->childCount = 0; | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node* MakeFunctionSignatureNode( | ||||
|     Node *identifierNode, | ||||
|     Node* typeNode, | ||||
|     Node* arguments, | ||||
|     Node* modifiersNode | ||||
|     Node* modifiersNode, | ||||
|     Node* genericConstraintsNode | ||||
| ) { | ||||
|     Node* node = (Node*) malloc(sizeof(Node)); | ||||
|     node->syntaxKind = FunctionSignature; | ||||
|     node->childCount = 4; | ||||
|     node->childCount = 5; | ||||
|     node->children = (Node**) malloc(sizeof(Node*) * (node->childCount)); | ||||
|     node->children[0] = identifierNode; | ||||
|     node->children[1] = typeNode; | ||||
|     node->children[2] = arguments; | ||||
|     node->children[3] = modifiersNode; | ||||
|     node->children[4] = genericConstraintsNode; | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
|  | @ -319,6 +358,19 @@ Node* MakeStructDeclarationNode( | |||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node* MakeInterfaceDeclarationNode( | ||||
|     Node *identifierNode, | ||||
|     Node *declarationSequenceNode | ||||
| ) { | ||||
|     Node* node = (Node*) malloc(sizeof(Node)); | ||||
|     node->syntaxKind = InterfaceDeclaration; | ||||
|     node->childCount = 2; | ||||
|     node->children = (Node**) malloc(sizeof(Node*) * 2); | ||||
|     node->children[0] = identifierNode; | ||||
|     node->children[1] = declarationSequenceNode; | ||||
|     return node; | ||||
| } | ||||
| 
 | ||||
| Node* StartDeclarationSequenceNode( | ||||
|     Node *declarationNode | ||||
| ) { | ||||
|  | @ -575,7 +627,7 @@ TypeTag* MakeTypeTag(Node *node) { | |||
|             break; | ||||
| 
 | ||||
|         default: | ||||
|             fprintf(stderr,  | ||||
|             fprintf(stderr, | ||||
|                     "wraith: Attempted to call MakeTypeTag on" | ||||
|                     " node with unsupported SyntaxKind: %s\n", | ||||
|                     SyntaxKindString(node->syntaxKind)); | ||||
|  |  | |||
							
								
								
									
										30
									
								
								src/ast.h
								
								
								
								
							
							
						
						
									
										30
									
								
								src/ast.h
								
								
								
								
							|  | @ -22,9 +22,12 @@ typedef enum | |||
|     FunctionModifiers, | ||||
|     FunctionSignature, | ||||
|     FunctionSignatureArguments, | ||||
|     GenericConstraint, | ||||
|     GenericConstraints, | ||||
|     Identifier, | ||||
|     IfStatement, | ||||
|     IfElseStatement, | ||||
|     InterfaceDeclaration, | ||||
|     Number, | ||||
|     PrimitiveTypeNode, | ||||
|     ReferenceTypeNode, | ||||
|  | @ -176,21 +179,36 @@ Node* AddFunctionSignatureArgumentNode( | |||
|     Node *argumentsNode, | ||||
|     Node *argumentNode | ||||
| ); | ||||
| Node *MakeEmptyFunctionSignatureArgumentsNode(); | ||||
| Node* MakeEmptyFunctionSignatureArgumentsNode(); | ||||
| Node* MakeGenericConstraintNode( | ||||
|     Node *identifierNode, | ||||
|     Node *interfaceNode | ||||
| ); | ||||
| Node* StartGenericConstraintsNode(Node *genericNode); | ||||
| Node* AddGenericConstraint( | ||||
|     Node *genericsNode, | ||||
|     Node *genericNode | ||||
| ); | ||||
| Node* MakeEmptyGenericConstraintsNode(); | ||||
| Node* MakeFunctionSignatureNode( | ||||
|     Node *identifierNode, | ||||
|     Node* typeNode, | ||||
|     Node* argumentsNode, | ||||
|     Node* modifiersNode | ||||
|     Node *typeNode, | ||||
|     Node *argumentsNode, | ||||
|     Node *modifiersNode, | ||||
|     Node *genericConstraintsNode | ||||
| ); | ||||
| Node* MakeFunctionDeclarationNode( | ||||
|     Node* functionSignatureNode, | ||||
|     Node* functionBodyNode | ||||
|     Node *functionSignatureNode, | ||||
|     Node *functionBodyNode | ||||
| ); | ||||
| Node* MakeStructDeclarationNode( | ||||
|     Node *identifierNode, | ||||
|     Node *declarationSequenceNode | ||||
| ); | ||||
| Node* MakeInterfaceDeclarationNode( | ||||
|     Node *identifierNode, | ||||
|     Node *declarationSequenceNode | ||||
| ); | ||||
| Node* StartDeclarationSequenceNode( | ||||
|     Node *declarationNode | ||||
| ); | ||||
|  |  | |||
							
								
								
									
										103
									
								
								src/codegen.c
								
								
								
								
							
							
						
						
									
										103
									
								
								src/codegen.c
								
								
								
								
							|  | @ -56,6 +56,24 @@ typedef struct StructTypeFunction | |||
|     uint8_t isStatic; | ||||
| } StructTypeFunction; | ||||
| 
 | ||||
| typedef struct MonomorphizedGenericStructFunction | ||||
| { | ||||
|     TypeTag **typeTags; | ||||
|     LLVMValueRef functionReference; | ||||
| } MonomorphizedGenericStructFunction; | ||||
| 
 | ||||
| typedef struct GenericStructFunction | ||||
| { | ||||
|     char *name; | ||||
|     Node *functionDeclaration; | ||||
| 
 | ||||
|     char **genericTypeNames; | ||||
|     uint32_t genericTypeCount; | ||||
| 
 | ||||
|     MonomorphizedGenericStructFunction *monomorphizedFunctions; | ||||
|     uint32_t monomorphizedFunctionCount; | ||||
| } GenericStructFunction; | ||||
| 
 | ||||
| typedef struct StructTypeDeclaration | ||||
| { | ||||
|     char *name; | ||||
|  | @ -66,6 +84,9 @@ typedef struct StructTypeDeclaration | |||
| 
 | ||||
|     StructTypeFunction *functions; | ||||
|     uint32_t functionCount; | ||||
| 
 | ||||
|     GenericStructFunction *genericFunctions; | ||||
|     uint32_t genericFunctionCount; | ||||
| } StructTypeDeclaration; | ||||
| 
 | ||||
| StructTypeDeclaration *structTypeDeclarations; | ||||
|  | @ -299,6 +320,32 @@ static void DeclareStructFunction( | |||
|     fprintf(stderr, "Could not find struct type for function!\n"); | ||||
| } | ||||
| 
 | ||||
| static void DeclareGenericFunction( | ||||
|     LLVMTypeRef structPointerType, | ||||
|     Node *functionDeclaration | ||||
| ) { | ||||
|     uint32_t i, j, index; | ||||
| 
 | ||||
|     for (i = 0; i < structTypeDeclarationCount; i += 1) | ||||
|     { | ||||
|         if (structTypeDeclarations[i].structPointerType == structPointerType) | ||||
|         { | ||||
|             index = structTypeDeclarations[i].genericFunctionCount; | ||||
|             structTypeDeclarations[i].genericFunctions = realloc(structTypeDeclarations[i].genericFunctions, sizeof(GenericStructFunction) * (structTypeDeclarations[i].genericFunctionCount + 1)); | ||||
|             structTypeDeclarations[i].genericFunctions[index].name = strdup(functionDeclaration->children[0]->children[0]->value.string); | ||||
|             structTypeDeclarations[i].genericFunctions[index].functionDeclaration = functionDeclaration; | ||||
|             structTypeDeclarations[i].genericFunctions[index].genericTypeCount = functionDeclaration->children[0]->children[4]->childCount; | ||||
|             for (j = 0; j < structTypeDeclarations[i].genericFunctions[index].genericTypeCount; j += 1) | ||||
|             { | ||||
|                 structTypeDeclarations[i].genericFunctions[index].genericTypeNames[j] = strdup(functionDeclaration->children[0]->children[4]->children[j]->children[0]->value.string); | ||||
|             } | ||||
|             structTypeDeclarations[i].genericFunctionCount += 1; | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static LLVMTypeRef LookupCustomType(char *name) | ||||
| { | ||||
|     uint32_t i; | ||||
|  | @ -337,6 +384,20 @@ static LLVMTypeRef ResolveType(Node* typeNode) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| static LLVMValueRef LookupGenericFunction( | ||||
|     StructTypeDeclaration *structDeclaration, | ||||
|     GenericStructFunction *genericFunction, | ||||
|     TypeTag **argTypes, | ||||
|     uint32_t argCount | ||||
| ) { | ||||
|     uint32_t i; | ||||
|     for (i = 0; i < argCount; i += 1) | ||||
|     { | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* FIXME: add generics */ | ||||
| static LLVMValueRef LookupFunctionByType( | ||||
|     LLVMTypeRef structType, | ||||
|     char *name, | ||||
|  | @ -369,7 +430,9 @@ static LLVMValueRef LookupFunctionByPointerType( | |||
|     LLVMTypeRef structPointerType, | ||||
|     char *name, | ||||
|     LLVMTypeRef *pReturnType, | ||||
|     uint8_t *pStatic | ||||
|     uint8_t *pStatic, | ||||
|     TypeTag **argTypes, | ||||
|     uint32_t argCount | ||||
| ) { | ||||
|     uint32_t i, j; | ||||
| 
 | ||||
|  | @ -386,6 +449,14 @@ static LLVMValueRef LookupFunctionByPointerType( | |||
|                     return structTypeDeclarations[i].functions[j].function; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             for (j = 0; j < structTypeDeclarations[i].genericFunctionCount; j += 1) | ||||
|             { | ||||
|                 if (strcmp(structTypeDeclarations[i].genericFunctions[j].name, name) == 0) | ||||
|                 { | ||||
|                     return LookupGenericFunction() | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -397,9 +468,10 @@ static LLVMValueRef LookupFunctionByInstance( | |||
|     LLVMValueRef structPointer, | ||||
|     char *name, | ||||
|     LLVMTypeRef *pReturnType, | ||||
|     uint8_t *pStatic | ||||
|     uint8_t *pStatic, | ||||
|     TypeTag **argTypes | ||||
| ) { | ||||
|     return LookupFunctionByPointerType(LLVMTypeOf(structPointer), name, pReturnType, pStatic); | ||||
|     return LookupFunctionByPointerType(LLVMTypeOf(structPointer), name, pReturnType, pStatic, argTypes); | ||||
| } | ||||
| 
 | ||||
| static void AddStructVariablesToScope( | ||||
|  | @ -498,6 +570,7 @@ static LLVMValueRef CompileFunctionCallExpression( | |||
| ) { | ||||
|     uint32_t i; | ||||
|     uint32_t argumentCount = 0; | ||||
|     TypeTag *argTypes[expression->children[1]->childCount + 1]; | ||||
|     LLVMValueRef args[expression->children[1]->childCount + 1]; | ||||
|     LLVMValueRef function; | ||||
|     uint8_t isStatic; | ||||
|  | @ -505,6 +578,11 @@ static LLVMValueRef CompileFunctionCallExpression( | |||
|     LLVMTypeRef functionReturnType; | ||||
|     char *returnName = ""; | ||||
| 
 | ||||
|     for (i = 0; i < expression->children[1]->childCount; i += 1) | ||||
|     { | ||||
|         argTypes[i] = expression->children[1]->children[i]->typeTag; | ||||
|     } | ||||
| 
 | ||||
|     /* FIXME: this needs to be recursive on access chains */ | ||||
|     if (expression->children[0]->syntaxKind == AccessExpression) | ||||
|     { | ||||
|  | @ -524,7 +602,7 @@ static LLVMValueRef CompileFunctionCallExpression( | |||
|         else | ||||
|         { | ||||
|             structInstance = FindVariablePointer(expression->children[0]->children[0]->value.string); | ||||
|             function = LookupFunctionByInstance(structInstance, expression->children[0]->children[1]->value.string, &functionReturnType, &isStatic); | ||||
|             function = LookupFunctionByInstance(structInstance, expression->children[0]->children[1]->value.string, &functionReturnType, &isStatic, argTypes); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|  | @ -872,6 +950,12 @@ static void CompileFunction( | |||
|         paramIndex += 1; | ||||
|     } | ||||
| 
 | ||||
|     if (functionSignature->children[4]->childCount > 0) | ||||
|     { | ||||
|         DeclareGenericFunction(wStructPointerType, functionDeclaration); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     PushScopeFrame(scope); | ||||
| 
 | ||||
|     /* FIXME: should work for non-primitive types */ | ||||
|  | @ -984,6 +1068,11 @@ static void CompileStruct(LLVMModuleRef module, LLVMContextRef context, Node *no | |||
|     PopScopeFrame(scope); | ||||
| } | ||||
| 
 | ||||
| static void CompileInterface(LLVMModuleRef module, LLVMContextRef context, Node *node) | ||||
| { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node) | ||||
| { | ||||
|     uint32_t i; | ||||
|  | @ -994,9 +1083,13 @@ static void Compile(LLVMModuleRef module, LLVMContextRef context, Node *node) | |||
|         { | ||||
|             CompileStruct(module, context, node->children[i]); | ||||
|         } | ||||
|         else if (node->children[i]->syntaxKind == InterfaceDeclaration) | ||||
|         { | ||||
|             CompileInterface(module, context, node->children[i]); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             fprintf(stderr, "top level declarations that are not structs are forbidden!\n"); | ||||
|             fprintf(stderr, "Top-level declarations that are not structs or interfaces are forbidden!\n"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue