forked from cosmonaut/wraith-lang
				
			structure for system calls
							parent
							
								
									d9b01515eb
								
							
						
					
					
						commit
						506ee9ecad
					
				|  | @ -40,6 +40,7 @@ | ||||||
| ";"                         return SEMICOLON; | ";"                         return SEMICOLON; | ||||||
| ":"                         return COLON; | ":"                         return COLON; | ||||||
| "?"                         return QUESTION; | "?"                         return QUESTION; | ||||||
|  | "@"                         return AT; | ||||||
| "("                         return LEFT_PAREN; | "("                         return LEFT_PAREN; | ||||||
| ")"                         return RIGHT_PAREN; | ")"                         return RIGHT_PAREN; | ||||||
| "["                         return LEFT_BRACKET; | "["                         return LEFT_BRACKET; | ||||||
|  |  | ||||||
|  | @ -54,6 +54,7 @@ extern FILE *yyin; | ||||||
| %token SEMICOLON | %token SEMICOLON | ||||||
| %token COLON | %token COLON | ||||||
| %token QUESTION | %token QUESTION | ||||||
|  | %token AT | ||||||
| %token LEFT_PAREN | %token LEFT_PAREN | ||||||
| %token RIGHT_PAREN | %token RIGHT_PAREN | ||||||
| %token LEFT_BRACE | %token LEFT_BRACE | ||||||
|  | @ -141,6 +142,11 @@ AccessExpression        : Identifier POINT AccessExpression | ||||||
|                             $$ = $1; |                             $$ = $1; | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
|  | SystemCallExpression    : AT Identifier | ||||||
|  |                         { | ||||||
|  |                             $$ = $2; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
| Number                  : NUMBER | Number                  : NUMBER | ||||||
|                         { |                         { | ||||||
|                             $$ = MakeNumberNode(yytext); |                             $$ = MakeNumberNode(yytext); | ||||||
|  | @ -234,6 +240,10 @@ FunctionCallExpression  : AccessExpression LEFT_PAREN Arguments RIGHT_PAREN | ||||||
|                         { |                         { | ||||||
|                             $$ = MakeFunctionCallExpressionNode($1, $3); |                             $$ = MakeFunctionCallExpressionNode($1, $3); | ||||||
|                         } |                         } | ||||||
|  |                         | SystemCallExpression LEFT_PAREN Arguments RIGHT_PAREN | ||||||
|  |                         { | ||||||
|  |                             $$ = MakeSystemCallExpressionNode($1, $3); | ||||||
|  |                         } | ||||||
| 
 | 
 | ||||||
| PartialStatement        : FunctionCallExpression | PartialStatement        : FunctionCallExpression | ||||||
|                         | AssignmentStatement |                         | AssignmentStatement | ||||||
|  |  | ||||||
|  | @ -13,6 +13,8 @@ struct Program { | ||||||
|     static Main(): int { |     static Main(): int { | ||||||
|         x: int = 4; |         x: int = 4; | ||||||
|         y: int = Foo.Func(x); |         y: int = Foo.Func(x); | ||||||
|  |         addr: uint = @malloc(y); | ||||||
|  |         @free(addr); | ||||||
|         return x; |         return x; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								src/ast.c
								
								
								
								
							
							
						
						
									
										13
									
								
								src/ast.c
								
								
								
								
							|  | @ -67,6 +67,8 @@ const char *SyntaxKindString(SyntaxKind syntaxKind) | ||||||
|         return "StringLiteral"; |         return "StringLiteral"; | ||||||
|     case StructDeclaration: |     case StructDeclaration: | ||||||
|         return "StructDeclaration"; |         return "StructDeclaration"; | ||||||
|  |     case SystemCall: | ||||||
|  |         return "SystemCall"; | ||||||
|     case Type: |     case Type: | ||||||
|         return "Type"; |         return "Type"; | ||||||
|     case UnaryExpression: |     case UnaryExpression: | ||||||
|  | @ -426,6 +428,17 @@ Node *MakeFunctionCallExpressionNode( | ||||||
|     return node; |     return node; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | Node *MakeSystemCallExpressionNode( | ||||||
|  |     Node *identifierNode, | ||||||
|  |     Node *argumentSequenceNode) | ||||||
|  | { | ||||||
|  |     Node *node = (Node *)malloc(sizeof(Node)); | ||||||
|  |     node->syntaxKind = SystemCall; | ||||||
|  |     node->systemCall.identifier = identifierNode; | ||||||
|  |     node->systemCall.argumentSequence = argumentSequenceNode; | ||||||
|  |     return node; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Node *MakeAccessExpressionNode(Node *accessee, Node *accessor) | Node *MakeAccessExpressionNode(Node *accessee, Node *accessor) | ||||||
| { | { | ||||||
|     Node *node = (Node *)malloc(sizeof(Node)); |     Node *node = (Node *)malloc(sizeof(Node)); | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								src/ast.h
								
								
								
								
							
							
						
						
									
										10
									
								
								src/ast.h
								
								
								
								
							|  | @ -44,6 +44,7 @@ typedef enum | ||||||
|     StaticModifier, |     StaticModifier, | ||||||
|     StringLiteral, |     StringLiteral, | ||||||
|     StructDeclaration, |     StructDeclaration, | ||||||
|  |     SystemCall, | ||||||
|     Type, |     Type, | ||||||
|     UnaryExpression |     UnaryExpression | ||||||
| } SyntaxKind; | } SyntaxKind; | ||||||
|  | @ -287,6 +288,12 @@ struct Node | ||||||
|             Node *declarationSequence; |             Node *declarationSequence; | ||||||
|         } structDeclaration; |         } structDeclaration; | ||||||
| 
 | 
 | ||||||
|  |         struct | ||||||
|  |         { | ||||||
|  |             Node *identifier; | ||||||
|  |             Node *argumentSequence; | ||||||
|  |         } systemCall; | ||||||
|  | 
 | ||||||
|         struct |         struct | ||||||
|         { |         { | ||||||
|             Node *typeNode; |             Node *typeNode; | ||||||
|  | @ -349,6 +356,9 @@ Node *MakeEmptyFunctionArgumentSequenceNode(); | ||||||
| Node *MakeFunctionCallExpressionNode( | Node *MakeFunctionCallExpressionNode( | ||||||
|     Node *identifierNode, |     Node *identifierNode, | ||||||
|     Node *argumentSequenceNode); |     Node *argumentSequenceNode); | ||||||
|  | Node *MakeSystemCallExpressionNode( | ||||||
|  |     Node *identifierNode, | ||||||
|  |     Node *argumentSequenceNode); | ||||||
| Node *MakeAccessExpressionNode(Node *accessee, Node *accessor); | Node *MakeAccessExpressionNode(Node *accessee, Node *accessor); | ||||||
| Node *MakeAllocNode(Node *typeNode); | Node *MakeAllocNode(Node *typeNode); | ||||||
| Node *MakeIfNode(Node *expressionNode, Node *statementSequenceNode); | Node *MakeIfNode(Node *expressionNode, Node *statementSequenceNode); | ||||||
|  |  | ||||||
							
								
								
									
										113
									
								
								src/codegen.c
								
								
								
								
							
							
						
						
									
										113
									
								
								src/codegen.c
								
								
								
								
							|  | @ -112,6 +112,16 @@ typedef struct StructTypeDeclaration | ||||||
| StructTypeDeclaration *structTypeDeclarations; | StructTypeDeclaration *structTypeDeclarations; | ||||||
| uint32_t structTypeDeclarationCount; | uint32_t structTypeDeclarationCount; | ||||||
| 
 | 
 | ||||||
|  | typedef struct SystemFunction | ||||||
|  | { | ||||||
|  |     char *name; | ||||||
|  |     LLVMTypeRef functionType; | ||||||
|  |     LLVMValueRef function; | ||||||
|  | } SystemFunction; | ||||||
|  | 
 | ||||||
|  | SystemFunction *systemFunctions; | ||||||
|  | uint32_t systemFunctionCount; | ||||||
|  | 
 | ||||||
| /* FUNCTION FORWARD DECLARATIONS */ | /* FUNCTION FORWARD DECLARATIONS */ | ||||||
| static LLVMBasicBlockRef CompileStatement( | static LLVMBasicBlockRef CompileStatement( | ||||||
|     LLVMModuleRef module, |     LLVMModuleRef module, | ||||||
|  | @ -262,6 +272,36 @@ static LLVMTypeRef ResolveType(TypeTag *typeTag) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void AddSystemFunction( | ||||||
|  |     char *name, | ||||||
|  |     LLVMTypeRef functionType, | ||||||
|  |     LLVMValueRef function) | ||||||
|  | { | ||||||
|  |     systemFunctions = realloc( | ||||||
|  |         systemFunctions, | ||||||
|  |         sizeof(SystemFunction) * (systemFunctionCount + 1)); | ||||||
|  |     systemFunctions[systemFunctionCount].name = strdup(name); | ||||||
|  |     systemFunctions[systemFunctionCount].functionType = functionType; | ||||||
|  |     systemFunctions[systemFunctionCount].function = function; | ||||||
|  |     systemFunctionCount += 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static SystemFunction *LookupSystemFunction(char *name) | ||||||
|  | { | ||||||
|  |     uint32_t i; | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < systemFunctionCount; i += 1) | ||||||
|  |     { | ||||||
|  |         if (strcmp(name, systemFunctions[i].name) == 0) | ||||||
|  |         { | ||||||
|  |             return &systemFunctions[i]; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fprintf(stderr, "%s %s %s", "System function", name, "not found!"); | ||||||
|  |     return NULL; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void AddLocalVariable( | static void AddLocalVariable( | ||||||
|     Scope *scope, |     Scope *scope, | ||||||
|     LLVMValueRef pointer, /* can be NULL */ |     LLVMValueRef pointer, /* can be NULL */ | ||||||
|  | @ -1133,6 +1173,51 @@ static LLVMValueRef CompileFunctionCallExpression( | ||||||
|     return LLVMBuildCall(builder, function, args, argumentCount, returnName); |     return LLVMBuildCall(builder, function, args, argumentCount, returnName); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static LLVMValueRef CompileSystemCallExpression( | ||||||
|  |     LLVMModuleRef module, | ||||||
|  |     LLVMBuilderRef builder, | ||||||
|  |     Node *systemCallExpression) | ||||||
|  | { | ||||||
|  |     uint32_t i; | ||||||
|  |     uint32_t argumentCount = systemCallExpression->systemCall.argumentSequence | ||||||
|  |                                  ->functionArgumentSequence.count; | ||||||
|  |     LLVMValueRef args[argumentCount]; | ||||||
|  |     char *returnName = ""; | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < systemCallExpression->systemCall.argumentSequence | ||||||
|  |                         ->functionArgumentSequence.count; | ||||||
|  |          i += 1) | ||||||
|  |     { | ||||||
|  |         args[i] = CompileExpression( | ||||||
|  |             module, | ||||||
|  |             builder, | ||||||
|  |             systemCallExpression->systemCall.argumentSequence | ||||||
|  |                 ->functionArgumentSequence.sequence[i]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     SystemFunction *systemFunction = LookupSystemFunction( | ||||||
|  |         systemCallExpression->systemCall.identifier->identifier.name); | ||||||
|  | 
 | ||||||
|  |     if (systemFunction == NULL) | ||||||
|  |     { | ||||||
|  |         fprintf(stderr, "System function not found!"); | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (LLVMGetTypeKind(LLVMGetReturnType(systemFunction->functionType)) != | ||||||
|  |         LLVMVoidTypeKind) | ||||||
|  |     { | ||||||
|  |         returnName = "callReturn"; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return LLVMBuildCall( | ||||||
|  |         builder, | ||||||
|  |         systemFunction->function, | ||||||
|  |         args, | ||||||
|  |         argumentCount, | ||||||
|  |         returnName); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static LLVMValueRef CompileAccessExpressionForStore( | static LLVMValueRef CompileAccessExpressionForStore( | ||||||
|     LLVMBuilderRef builder, |     LLVMBuilderRef builder, | ||||||
|     Node *accessExpression) |     Node *accessExpression) | ||||||
|  | @ -1196,6 +1281,9 @@ static LLVMValueRef CompileExpression( | ||||||
| 
 | 
 | ||||||
|     case StringLiteral: |     case StringLiteral: | ||||||
|         return CompileString(builder, expression); |         return CompileString(builder, expression); | ||||||
|  | 
 | ||||||
|  |     case SystemCall: | ||||||
|  |         return CompileSystemCallExpression(module, builder, expression); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fprintf(stderr, "Unknown expression kind!\n"); |     fprintf(stderr, "Unknown expression kind!\n"); | ||||||
|  | @ -1516,6 +1604,10 @@ static LLVMBasicBlockRef CompileStatement( | ||||||
| 
 | 
 | ||||||
|     case ReturnVoid: |     case ReturnVoid: | ||||||
|         return CompileReturnVoid(builder, function); |         return CompileReturnVoid(builder, function); | ||||||
|  | 
 | ||||||
|  |     case SystemCall: | ||||||
|  |         CompileSystemCallExpression(module, builder, statement); | ||||||
|  |         return LLVMGetLastBasicBlock(function); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fprintf(stderr, "Unknown statement kind!\n"); |     fprintf(stderr, "Unknown statement kind!\n"); | ||||||
|  | @ -1812,6 +1904,24 @@ static void RegisterLibraryFunctions( | ||||||
|         LLVMInt8Type(), |         LLVMInt8Type(), | ||||||
|         1, |         1, | ||||||
|         "PrintLine"); |         "PrintLine"); | ||||||
|  | 
 | ||||||
|  |     LLVMTypeRef mallocArg = LLVMInt64Type(); | ||||||
|  |     LLVMTypeRef mallocFunctionType = | ||||||
|  |         LLVMFunctionType(LLVMInt64Type(), &mallocArg, 1, 0); | ||||||
|  |     LLVMValueRef mallocFunction = | ||||||
|  |         LLVMAddFunction(module, "malloc", mallocFunctionType); | ||||||
|  |     LLVMSetLinkage(mallocFunction, LLVMExternalLinkage); | ||||||
|  | 
 | ||||||
|  |     AddSystemFunction("malloc", mallocFunctionType, mallocFunction); | ||||||
|  | 
 | ||||||
|  |     LLVMTypeRef freeArg = LLVMInt64Type(); | ||||||
|  |     LLVMTypeRef freeFunctionType = | ||||||
|  |         LLVMFunctionType(LLVMVoidType(), &freeArg, 1, 0); | ||||||
|  |     LLVMValueRef freeFunction = | ||||||
|  |         LLVMAddFunction(module, "free", freeFunctionType); | ||||||
|  |     LLVMSetLinkage(freeFunction, LLVMExternalLinkage); | ||||||
|  | 
 | ||||||
|  |     AddSystemFunction("free", freeFunctionType, freeFunction); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int Codegen(Node *node, uint32_t optimizationLevel) | int Codegen(Node *node, uint32_t optimizationLevel) | ||||||
|  | @ -1821,6 +1931,9 @@ int Codegen(Node *node, uint32_t optimizationLevel) | ||||||
|     structTypeDeclarations = NULL; |     structTypeDeclarations = NULL; | ||||||
|     structTypeDeclarationCount = 0; |     structTypeDeclarationCount = 0; | ||||||
| 
 | 
 | ||||||
|  |     systemFunctions = NULL; | ||||||
|  |     systemFunctionCount = 0; | ||||||
|  | 
 | ||||||
|     LLVMModuleRef module = LLVMModuleCreateWithName("my_module"); |     LLVMModuleRef module = LLVMModuleCreateWithName("my_module"); | ||||||
|     LLVMContextRef context = LLVMGetGlobalContext(); |     LLVMContextRef context = LLVMGetGlobalContext(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue