G

G Programming Language
git clone http://git.omkov.net/G
Log | Tree | Refs | README | Download

AuthorJakob Wakeling <[email protected]>
Date2022-03-28 09:59:27
Commit6d07b21638d06401c3fd9d67f8e868958cb9443e
Parentd47751def35f23c73f6722584cf0cf4934db9e36

llvm: Reimplement LLVM code generation

Diffstat

M examples/main.g | 2 +-
M src/llvm.c | 60 +++++++++++++++++++++++++++++++++++++-----------------------

2 files changed, 38 insertions, 24 deletions

diff --git a/examples/main.g b/examples/main.g
index c36b90e..a2d30e0 100644
--- a/examples/main.g
+++ b/examples/main.g
@@ -1 +1 @@
-main :: proc() -> s32 { return 1; }
+main :: proc() -> s64 { return 1; }
diff --git a/src/llvm.c b/src/llvm.c
index c788ece..7174a44 100644
--- a/src/llvm.c
+++ b/src/llvm.c
@@ -39,6 +39,8 @@ static inline void llvm_init(void);
 static inline void llvm_free(void);
 static LLVMTypeRef llvm_type(type *t);
 
+#define C (a->c.a) /* AST child shorthand "C[i]" */
+
 /* Generate IR from an AST with LLVM. */
 void llvm(ast *a) {
 	llvm_init();
@@ -90,22 +92,29 @@ static LLVMValueRef llvm_stmt(ast *a) {
 
 /* Generate IR for a compound statement. */
 static LLVMValueRef llvm_stmt_compound(ast *a) {
-	/* TODO actually implement this properly. */
-	if ((a->c.a[0])->k == AK_RETURN) {
-		return llvm_int(a->c.a[0]->c.a[0]);
-	}
-	else { error(1, "llvm_compound else!"); }
+	for (UINT i = 0; i < a->c.al; i += 1) { llvm_stmt(C[i]); }
 
 	return NULL;
 }
 
 /* Generate IR for a declaration statement. */
 static LLVMValueRef llvm_stmt_decl(ast *a) {
-	/* TODO actually implement this properly. */
-	if (a->k == AK_DECL && a->c.a[0]->k == AK_PROC) {
-		return llvm_expr_proc(a->c.a[0]);
+	if (a->k != AK_DECL) { error(2, "_stmt_decl != AK_DECL"); } /* DEBUG */
+	
+	if (C[0]->k == AK_PROC) {
+		/* TODO handle procedure arguments if present */
+		LLVMTypeRef ft = LLVMFunctionType(llvm_type(C[0]->t), NULL, 0, 0);
+		LLVMValueRef f = LLVMAddFunction(llvm_module, a->s, ft);
+		
+		LLVMBasicBlockRef bb = LLVMAppendBasicBlock(f, "entry");
+		LLVMPositionBuilderAtEnd(llvm_builder, bb);
+		
+		llvm_expr_proc(C[0]);
+	}
+	else {
+		LLVMValueRef v = LLVMAddGlobal(llvm_module, llvm_type(C[0]->t), a->s);
+		LLVMSetInitializer(v, llvm_int(C[0]));
 	}
-	else { error(1, "llvm_decl else!"); }
 
 	return NULL;
 }
@@ -117,30 +126,29 @@ static LLVMValueRef llvm_stmt_expr(ast *a) {
 
 /* Generate IR for a return statement. */
 static LLVMValueRef llvm_stmt_return(ast *a) {
-	
+	return LLVMBuildRet(llvm_builder, llvm_expr(C[0]));
 }
 
 /* Generate IR for an if statement. */
-static LLVMValueRef llvm_stmt_if(ast *a) { /* TODO */ }
+static LLVMValueRef llvm_stmt_if(ast *a) {
+	
+}
 
 /* Generate IR for a for statement. */
-static LLVMValueRef llvm_stmt_for(ast *a) { /* TODO */ }
+static LLVMValueRef llvm_stmt_for(ast *a) {
+	
+}
 
 /* Generate IR for an expression. */
 static LLVMValueRef llvm_expr(ast *a) {
-	
+	if (a->k == AK_PROC) { return llvm_expr_proc(a); }
+	if (a->k == AK_INT) { return llvm_int(a); }
+	else { error(2, "_expr unknown kind"); }
 }
 
 /* Generate IR for a procedure. */
 static LLVMValueRef llvm_expr_proc(ast *a) {
-	LLVMTypeRef ft = LLVMFunctionType(llvm_type(a->t), NULL, 0, 0);
-	LLVMValueRef f = LLVMAddFunction(llvm_module, a->p->s, ft);
-	
-	LLVMBasicBlockRef bb = LLVMAppendBasicBlock(f, "entry");
-	LLVMPositionBuilderAtEnd(llvm_builder, bb);
-	
-	LLVMValueRef r = llvm_stmt_compound(a->c.a[0]); if (!r) { return NULL; }
-	LLVMBuildRet(llvm_builder, r); return f;
+	return llvm_stmt_compound(C[0]);
 }
 
 /* Generate IR for an integer. */