]> git.mdlowis.com Git - proto/obnc.git/commitdiff
added some type generation code for llvm ir
authorMichael D. Lowis <mike.lowis@gentex.com>
Thu, 10 Feb 2022 21:50:07 +0000 (16:50 -0500)
committerMichael D. Lowis <mike.lowis@gentex.com>
Thu, 10 Feb 2022 21:50:07 +0000 (16:50 -0500)
cerise/backend/ssa/codegen.c
cerise/inc/cerise.h
cerise/tests/Module.m

index fc09ae9f377e80d7b034bfd59a39f5f13ae7e65c..571eaf6f8d506f89d4126a6c35a76d631cfab8bb 100644 (file)
@@ -26,14 +26,77 @@ Type StringType = {
     .size = -1
 };
 
+static char* strmcat(char* first, ...) {
+    va_list args;
+    /* calculate the length of the final string */
+    size_t len = strlen(first);
+    va_start(args, first);
+    for (char* s = NULL; (s = va_arg(args, char*));)
+        len += strlen(s);
+    va_end(args);
+    /* allocate the final string and copy the args into it */
+    char *str  = malloc(len+1), *curr = str;
+    while (first && *first) *(curr++) = *(first++);
+    va_start(args, first);
+    for (char* s = NULL; (s = va_arg(args, char*));)
+        while (s && *s) *(curr++) = *(s++);
+    va_end(args);
+    /* null terminate and return */
+    *curr = '\0';
+    return str;
+}
+
+void declare_record_type(Type* type)
+{
+    if (!type->name)
+    {
+        /* print the field typedefs if needed */
+        for (Field* f = type->fields; f; f = f->next)
+        {
+            if (f->type->form == FORM_RECORD)
+            {
+                declare_record_type(f->type);
+            }
+        }
+
+        /* ok print the top level typedef */
+        int len = snprintf(NULL, 0, "%%struct.%p", (void*)type);
+        type->name = calloc(1, len+1);
+        (void)snprintf(type->name, len+1, "%%struct.%p", (void*)type);
+
+        printf("%s = type { ", type->name);
+        for (Field* f = type->fields; f; f = f->next)
+        {
+            emit_type(f->type);
+            if (f->next)
+            {
+                printf(", ");
+            }
+        }
+        printf(" }\n");
+    }
+}
+
+
 void emit_type(Type* type)
 {
     switch (type->form)
     {
-        case FORM_BOOL: printf("@Bool"); break;
-        case FORM_INT:  printf("@Int"); break;
-        case FORM_REAL: printf("@Real"); break;
-        case FORM_VOID: printf("@Void"); break;
+        case FORM_BOOL:   printf("%%Bool");   break;
+        case FORM_INT:    printf("%%Int");    break;
+        case FORM_REAL:   printf("%%Real");   break;
+        case FORM_VOID:   printf("%%Void");   break;
+        case FORM_STRING: printf("%%String"); break;
+
+        case FORM_ARRAY:
+            printf("[]");
+            break;
+
+        case FORM_RECORD:
+            printf("%%%s", type->name);
+            break;
+
+        case FORM_PROC:
         default:
             printf("????");
             break;
@@ -42,10 +105,12 @@ void emit_type(Type* type)
 
 void codegen_init(Parser* p)
 {
-    printf("@Bool = type i1\n");
-    printf("@Int = type i64\n");
-    printf("@Real = type double\n");
-    printf("@Void = type void\n");
+    (void)p;
+    printf("%%Bool = type i1\n");
+    printf("%%Int = type i64\n");
+    printf("%%Real = type double\n");
+    printf("%%Void = type void\n");
+    printf("%%String = type { i64, i8* }\n");
 }
 
 void codegen_symbol(Parser* p, Symbol* sym)
@@ -61,6 +126,10 @@ void codegen_symbol(Parser* p, Symbol* sym)
     }
     else if (sym->class == SYM_TYPE)
     {
+        if (sym->type->form == FORM_RECORD)
+        {
+            declare_record_type(sym->type);
+        }
         printf("%c%s = type \n", (sym->global ? '@' : '%'), sym->name);
     }
     else if (sym->class == SYM_PROC)
index 0e9d625994986e188b933463d423a829b864fabf..4d664bc3d0d8a096104d6dbb3fc7a75272ed1f55 100644 (file)
@@ -90,10 +90,15 @@ typedef struct Field {
 
 typedef struct Type {
     enum {
-        FORM_BOOL, FORM_INT, FORM_REAL, FORM_ARRAY, FORM_STRING,
-        FORM_RECORD, FORM_PROC, FORM_VOID,
+        /* base types */
+        FORM_BOOL, FORM_INT, FORM_REAL, FORM_VOID,
+
+        /* aggregate types */
+        FORM_ARRAY, FORM_RECORD, FORM_STRING, FORM_PROC,
+
         FORM_COUNT
     } form;
+    char* name;
     struct Field* fields;
     struct Type* base;
     int size;
index 53c6946f90ceb7976f1abce078b9f7bdc191cc7b..61aa3c6d47868be26ccceec2110389077f884784 100644 (file)
@@ -40,6 +40,7 @@ var
   f : TypeD
   g : array 5 of Int
   h : TypeF
+  i : TypeA
 
 #procedure Foo*(e : Int, z : Int, q1 : TypeD, q2 : array 5 of Int) : Int
 #  const FOO = 2
@@ -70,6 +71,8 @@ begin
 end
 
 begin
+  i = 42;
+  b = i;
   b = 1;
   if c == b then
     b = b - 1;