]> git.mdlowis.com Git - proto/obnc.git/commitdiff
added array temporaries but assignment is still busted
authormike lowis <mike@mdlowis.com>
Tue, 11 May 2021 03:00:49 +0000 (23:00 -0400)
committermike lowis <mike@mdlowis.com>
Tue, 11 May 2021 03:00:49 +0000 (23:00 -0400)
cerise/backend/c99/codegen.c
cerise/inc/cerise.h
cerise/src/grammar.c
cerise/tests/Module.m

index 56553f9b156cbe292019775c4185f3fbb1fc6cb7..89adf8cab6f73edfa1b95edf63a6f8e05c21a7f1 100644 (file)
@@ -22,7 +22,7 @@ Type StringType = {
     .size = -1
 };
 
-static char* TypeNames[] = {
+static char* TypeNames[FORM_COUNT] = {
     [FORM_BOOL]   = "bool",
     [FORM_INT]    = "long",
     [FORM_REAL]   = "double",
@@ -47,32 +47,86 @@ static char* Operators[] = {
 //    [IS]   = ???
 };
 
+static declare_var(Parser* p, Symbol* sym, int isref)
+{
+    char name[8192];
+    if (sym->global)
+    {
+        printf("%s", (sym->export ? "" : "static "));
+        snprintf(name, sizeof(name), "%s_%s", p->name, sym->name);
+     }
+    else
+    {
+        printf("    ");
+        snprintf(name, sizeof(name), "(%c%s)",
+            (char)(isref ? '*' : ' '), sym->name);
+    }
+
+    if (sym->type->form == FORM_ARRAY)
+    {
+        Type* type = sym->type;
+        for (; type->form == FORM_ARRAY; type = type->base);
+        printf("%s %s", TypeNames[type->form], name);
+        for (type = sym->type; type->form == FORM_ARRAY; type = type->base)
+        {
+            printf("[%d]", type->size);
+        }
+    }
+    else
+    {
+        printf("%s %s", TypeNames[sym->type->form], name);
+    }
+}
+
+static int declare_temp(Parser* p, Type* type, int isref)
+{
+    char name[32];
+    int reg = p->curr_reg;
+    snprintf(name, sizeof(name), "_T%d", reg);
+//    puts("TEMP");
+    Symbol sym = {
+        .class = SYM_VAR,
+        .name = name,
+        .type = type,
+    };
+    declare_var(p, &sym, isref);
+//    puts("END");
+
+    p->curr_reg++;
+    return reg;
+}
+
 static void load_var(Parser* p, Item* item)
 {
-    (void)p;
-    switch (item->mode)
+    if (!item->reg)
     {
-        case ITEM_CONST:
-            /* TODO: range check the constant */
-            printf("    const %s _T%d = %lld;\n",
-                TypeNames[item->type->form], p->curr_reg, item->imm.i);
-            item->reg = p->curr_reg;
-            p->curr_reg++;
-
-        case ITEM_VAR:
-            break;
-
-        case ITEM_MVAR:
-            /* TODO: range check the constant */
-            printf("    const %s _T%d = %s_%s;\n",
-                TypeNames[item->type->form], p->curr_reg, p->name, item->imm.s);
-            item->reg = p->curr_reg;
-            p->curr_reg++;
-            break;
-
-        case ITEM_REG:
-            /* nothing to do */
-            break;
+        int isref = (item->type->form == FORM_ARRAY);
+        switch (item->mode)
+        {
+            case ITEM_CONST:
+                /* TODO: range check the constant */
+                item->reg = declare_temp(p, item->type, 0);
+                printf(" = %lld;\n", item->imm.i);
+                break;
+
+            case ITEM_VAR:
+                item->reg = declare_temp(p, item->type, isref);
+                printf(" = %c%s;\n", (isref ? '&' : ' '), item->imm.s);
+                break;
+
+            case ITEM_MVAR:
+                item->reg = declare_temp(p, item->type, isref);
+                printf(" = %c%s_%s;\n",
+                    (isref ? '&' : ' '), p->name, item->imm.s);
+                break;
+
+            case ITEM_REG:
+                /* nothing to do */
+                break;
+
+            default:
+                assert(!"bad load_var()");
+        }
     }
 }
 
@@ -80,24 +134,20 @@ static void load_var(Parser* p, Item* item)
  *****************************************************************************/
 static void binary_op(Parser* p, int op, Item* a, Item* b)
 {
-    char* type = TypeNames[a->type->form];
     char* oper = Operators[op];
-    assert(type && oper);
-    printf("    const %s _T%d = _T%d %s _T%d;\n",
-        type, p->curr_reg, a->reg, oper, b->reg);
-    a->reg = p->curr_reg;
-    p->curr_reg++;
+    assert(oper);
+    int dest_reg = declare_temp(p, a->type, 0);
+    printf(" = _T%d %s _T%d;\n", a->reg, oper, b->reg);
+    a->reg = dest_reg;
 }
 
 static void unary_op(Parser* p, int op, Item* a)
 {
-    char* type = TypeNames[a->type->form];
     char* oper = Operators[op];
-    assert(type && oper);
-    printf("    const %s _T%d = %s _T%d;\n",
-        type, p->curr_reg, oper, a->reg);
-    a->reg = p->curr_reg;
-    p->curr_reg++;
+    assert(oper);
+    int dest_reg = declare_temp(p, a->type, 0);
+    printf(" = %s _T%d;\n", oper, a->reg);
+    a->reg = dest_reg;
 }
 
 /* Public Interface
@@ -133,15 +183,8 @@ void codegen_imports(Parser* p)
 
 void codegen_var(Parser* p, Symbol* sym)
 {
-    if (sym->global)
-    {
-        printf("%s%s %s_%s;\n",
-            (sym->export ? "" : "static "), TypeNames[sym->type->form], p->name, sym->name);
-    }
-    else
-    {
-        printf("    %s %s;\n", TypeNames[sym->type->form], sym->name);
-    }
+    declare_var(p, sym, 0);
+    puts(";");
 }
 
 void codegen_main(Parser* p)
@@ -214,30 +257,29 @@ void codegen_binop(Parser* p, int op, Item* a, Item* b)
 
 void codegen_store(Parser* p, Item* a, Item* b)
 {
-    item_dump(a);
-    item_dump(b);
+//    item_dump(a);
+//    item_dump(b);
     if (a->mode == ITEM_MVAR && b->reg == 0)
     {
-//        if (a->offset)
-//        {
-//            printf("    (%s*)\n",
-//                TypeNames[a->type->form]
-//
-//            );
-//        }
         printf("    %s_%s = %lld;\n", p->name, a->imm.s, b->imm.i);
     }
     else if (a->mode == ITEM_MVAR)
     {
-//        if (a->offset)
-//        {
-//            printf("    (%s*)\n",
-//                TypeNames[a->type->form]
-//
-//            );
-//        }
         printf("    %s_%s = _T%d;\n", p->name, a->imm.s, b->reg);
     }
+    else if (a->mode == ITEM_VAR && b->reg == 0)
+    {
+        printf("    %s = %lld;\n", a->imm.s, b->imm.i);
+    }
+    else if (a->mode == ITEM_VAR)
+    {
+        printf("    %s = _T%d;\n", a->imm.s, b->reg);
+    }
+    else if (a->mode == ITEM_INDEX)
+    {
+        load_var(p, b);
+        printf("    _T%d = _T%d;\n", a->reg, b->reg);
+    }
     else
     {
         assert(!"bad store op");
@@ -274,7 +316,8 @@ void codegen_prepcall(Parser* p, Item* item)
 
 void codegen_call(Parser* p, Item* item, Item* args)
 {
-    printf("    const long _T%d = %s(", p->curr_reg, item->imm.s);
+    int dest_reg = declare_temp(p, item->type, 0);
+    printf(" = %s(", item->imm.s);
     while (args)
     {
         printf("_T%d", args->reg);
@@ -284,8 +327,7 @@ void codegen_call(Parser* p, Item* item, Item* args)
         }
         args = args->next;
     }
-    item->reg = p->curr_reg;
-    p->curr_reg++;
+    item->reg = dest_reg;
     printf(");\n");
 }
 
@@ -296,16 +338,12 @@ void codegen_setarg(Parser* p, Item* item, bool firstarg)
 
 void codegen_return(Parser* p, Item* item)
 {
-    if (item)
-    {
-        load_var(p, item);
-        printf("    return _T%d;\n", item->reg);
-    }
+    load_var(p, item);
+    printf("    return _T%d;\n", item->reg);
 }
 
 void codegen_index(Parser* p, Item* array, Item* index)
 {
-//    codegen_binop(p, '*', index, base);
     if (index->mode == ITEM_CONST)
     {
         if (index->type->form != FORM_INT)
@@ -320,7 +358,13 @@ void codegen_index(Parser* p, Item* array, Item* index)
         {
             error(p, "negative array index");
         }
-
-        array->offset = index->imm.i;
     }
+
+    load_var(p, index);
+    load_var(p, array);
+    array->type = array->type->base;
+    array->mode = ITEM_INDEX;
+    int dest_reg = declare_temp(p, array->type, 1);
+    printf(" = _T%d[_T%d]\;\n", array->reg, index->reg);
+    array->reg = dest_reg;
 }
index 26c1a923a083a83ac85c4aac1be4181e7dcbd95e..f7215658e2fda0aee3b7bc3685f13b8a275ab253 100644 (file)
@@ -79,7 +79,8 @@ typedef struct LexFile {
 
 typedef struct Type {
     enum {
-        FORM_BOOL, FORM_INT, FORM_REAL, FORM_ARRAY, FORM_STRING
+        FORM_BOOL, FORM_INT, FORM_REAL, FORM_ARRAY, FORM_STRING,
+        FORM_COUNT
     } form;
     struct Type* base;
     int size;
@@ -115,7 +116,7 @@ typedef struct Module {
 typedef struct Item {
     struct Item* next;
     enum {
-        ITEM_CONST, ITEM_VAR, ITEM_MVAR, ITEM_REG
+        ITEM_CONST, ITEM_VAR, ITEM_MVAR, ITEM_REG, ITEM_INDEX
     } mode;
     Symbol* sym;
     Type* type;
index 347be3572282c93fc1e465863584b40cbbc9c6f3..a5bb9f002608dd978c07c9c86b40e2da41f3f0c1 100644 (file)
@@ -106,39 +106,46 @@ RULE(designator)
 {
     qualident(p, item);
     /* selector */
-    switch ((int)peek(p)->type)
+    for (int done = 0; !done;)
     {
-//        case '.':
-//            expect(p, IDENT);
-//            break;
-
-        case '[':
+        switch ((int)peek(p)->type)
         {
-            Item index = {0};
-            expect(p, '[');
-            expression(p, &index);
-            if (item->type->form == FORM_ARRAY)
-            {
-                codegen_index(p, item, &index);
-                item->type = item->type->base;
-            }
-            else
+    //        case '.':
+    //            expect(p, IDENT);
+    //            break;
+
+            case '[':
             {
-                error(p, "attempting to index non-array value");
+                Item index = {0};
+                expect(p, '[');
+                expression(p, &index);
+                printf("%d\n", item->type->form );
+                if (item->type->form == FORM_ARRAY)
+                {
+                    codegen_index(p, item, &index);
+                    item->type = item->type->base;
+                }
+                else
+                {
+                    error(p, "attempting to index non-array value");
+                }
+                expect(p, ']');
+                break;
             }
-            expect(p, ']');
-            break;
-        }
 
-//
-//        case '^':
-//            expect(p, '^');
-//            break;
-//
-//        case '(':
-//            qualident(p);
-//            expect(p, ')');
-//            break;
+    //        case '^':
+    //            expect(p, '^');
+    //            break;
+
+    //        case '(':
+    //            qualident(p);
+    //            expect(p, ')');
+    //            break;
+
+            default:
+                done = 1;
+                break;
+        }
     }
 }
 
@@ -424,7 +431,7 @@ RULE(var_decl)
         int nsyms = 0;
         Symbol* first = NULL;
         Symbol* sym = NULL;
-        Symbol* type = NULL;
+//        Symbol* type = NULL;
         char* name = NULL;
         bool export = false;
 
@@ -439,14 +446,17 @@ RULE(var_decl)
         }
         while (accept(p, ','));
 
+        Item base_type = {0};
         expect(p, ':');
-        name = expect_text(p, IDENT);
-        type = symbol_get(p, SYM_TYPE, name);
+        type(p, &base_type);
+
+//        name = expect_text(p, IDENT);
+//        type = symbol_get(p, SYM_TYPE, name);
 
         /* apply the type to the newly created symbols */
         for (int i = 0; i < nsyms; i++)
         {
-            first->type = type->type;
+            first->type = base_type.type;
             codegen_var(p, first);
             sym = first->next;
         }
index d7d932861396ba52885421242b144b40701b5623..77ba511edd55f97d481ab17ce2fa6862400f872c 100644 (file)
@@ -21,20 +21,23 @@ var
   b : Int
   c : Int
   d : Real
-  e : TypeB
+  e : array 5 of array 10 of Int
 
 procedure Foo*(e : Int, z : Int) : Int
   const FOO = 2
   type foo = Int
-  var z : Int
+  var
+    z : Int
+    q : array 5 of array 10 of Int
 
 #  procedure Bar() : Int
 #  begin
 #  end
 
 begin
-#  c = b * b;
-  return c;
+  c = 1;
+  z = 2;
+  return z;
 end
 
 begin
@@ -104,5 +107,6 @@ begin
 #  c = Foo(1,2);
 #  e[0] = 1;
 #  Foo(1,2);
-  e[0] = 1;
+  e[2][1] = 1;
+#  e[b] = 1;
 end