]> git.mdlowis.com Git - proto/obnc.git/commitdiff
fully implemented first pass at array indexing with range checks
authorMichael D. Lowis <mike.lowis@gentex.com>
Tue, 11 May 2021 18:03:47 +0000 (14:03 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Tue, 11 May 2021 18:03:47 +0000 (14:03 -0400)
cerise/backend/c99/codegen.c
cerise/backend/x86_64/codegen.c
cerise/inc/cerise.h
cerise/src/dump.c [new file with mode: 0644]
cerise/src/grammar.c
cerise/tests/Module.m

index 89adf8cab6f73edfa1b95edf63a6f8e05c21a7f1..9a1f73812382059a2322790893961042c199f64c 100644 (file)
@@ -47,7 +47,7 @@ static char* Operators[] = {
 //    [IS]   = ???
 };
 
-static declare_var(Parser* p, Symbol* sym, int isref)
+static void declare_var(Parser* p, Symbol* sym, int isref)
 {
     char name[8192];
     if (sym->global)
@@ -83,15 +83,12 @@ 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;
 }
@@ -120,16 +117,21 @@ static void load_var(Parser* p, Item* item)
                     (isref ? '&' : ' '), p->name, item->imm.s);
                 break;
 
-            case ITEM_REG:
-                /* nothing to do */
-                break;
-
             default:
                 assert(!"bad load_var()");
         }
     }
 }
 
+static char* temp(Item* a)
+{
+    char name[32];
+    snprintf(name, sizeof(name), "(%c_T%d)",
+        (a->mode == ITEM_INDEX ? '*' : ' '),
+        a->reg);
+    return strdup(name);
+}
+
 /* Operator Handling
  *****************************************************************************/
 static void binary_op(Parser* p, int op, Item* a, Item* b)
@@ -137,7 +139,7 @@ static void binary_op(Parser* p, int op, Item* a, Item* b)
     char* oper = Operators[op];
     assert(oper);
     int dest_reg = declare_temp(p, a->type, 0);
-    printf(" = _T%d %s _T%d;\n", a->reg, oper, b->reg);
+    printf(" = %s %s %s;\n", temp(a), oper, temp(b));
     a->reg = dest_reg;
 }
 
@@ -146,7 +148,7 @@ static void unary_op(Parser* p, int op, Item* a)
     char* oper = Operators[op];
     assert(oper);
     int dest_reg = declare_temp(p, a->type, 0);
-    printf(" = %s _T%d;\n", oper, a->reg);
+    printf(" = %s %s;\n", oper, temp(a));
     a->reg = dest_reg;
 }
 
@@ -257,15 +259,13 @@ 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);
     if (a->mode == ITEM_MVAR && b->reg == 0)
     {
         printf("    %s_%s = %lld;\n", p->name, a->imm.s, b->imm.i);
     }
     else if (a->mode == ITEM_MVAR)
     {
-        printf("    %s_%s = _T%d;\n", p->name, a->imm.s, b->reg);
+        printf("    %s_%s = %s;\n", p->name, a->imm.s, temp(b));
     }
     else if (a->mode == ITEM_VAR && b->reg == 0)
     {
@@ -273,12 +273,12 @@ void codegen_store(Parser* p, Item* a, Item* b)
     }
     else if (a->mode == ITEM_VAR)
     {
-        printf("    %s = _T%d;\n", a->imm.s, b->reg);
+        printf("    %s = %s;\n", a->imm.s, temp(b));
     }
     else if (a->mode == ITEM_INDEX)
     {
         load_var(p, b);
-        printf("    _T%d = _T%d;\n", a->reg, b->reg);
+        printf("    %s = %s;\n", temp(a), temp(b));
     }
     else
     {
@@ -289,7 +289,7 @@ void codegen_store(Parser* p, Item* a, Item* b)
 void codegen_if(Parser* p, Item* item)
 {
     load_var(p, item);
-    printf("    if (_T%d) {\n", item->reg);
+    printf("    if (%s) {\n", temp(item));
 }
 
 void codegen_else(Parser* p, Item* item)
@@ -320,7 +320,7 @@ void codegen_call(Parser* p, Item* item, Item* args)
     printf(" = %s(", item->imm.s);
     while (args)
     {
-        printf("_T%d", args->reg);
+        printf("%s", temp(args));
         if (args->next)
         {
             printf(", ");
@@ -333,17 +333,23 @@ void codegen_call(Parser* p, Item* item, Item* args)
 
 void codegen_setarg(Parser* p, Item* item, bool firstarg)
 {
+    (void)firstarg;
     load_var(p, item);
 }
 
 void codegen_return(Parser* p, Item* item)
 {
     load_var(p, item);
-    printf("    return _T%d;\n", item->reg);
+    printf("    return %s;\n", temp(item));
 }
 
 void codegen_index(Parser* p, Item* array, Item* index)
 {
+    /* load  array and index if not already */
+    load_var(p, index);
+    load_var(p, array);
+
+    /* perform range checking */
     if (index->mode == ITEM_CONST)
     {
         if (index->type->form != FORM_INT)
@@ -359,12 +365,15 @@ void codegen_index(Parser* p, Item* array, Item* index)
             error(p, "negative array index");
         }
     }
+    else
+    {
+        printf("    __CHECK_RANGE(%s < %d);\n", temp(index), array->type->size);
+    }
 
-    load_var(p, index);
-    load_var(p, array);
+    /* emit the operation */
     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);
+    printf(" = &%s[%s];\n", temp(array), temp(index));
     array->reg = dest_reg;
 }
index 651f515aabcb125a5f4008f693678205635ad745..db4efabdb2d0cbcfa53f696fd56635601da4c0dd 100644 (file)
@@ -202,7 +202,9 @@ static void load_var(Parser* p, Item* item)
             next_reg(p);
             break;
 
+        case ITEM_INDEX:
         case ITEM_REG:
+        default:
             /* nothing to do */
             break;
     }
index f7215658e2fda0aee3b7bc3685f13b8a275ab253..f1b76e89afe21bda23a54ff235c8b9c7951efc5e 100644 (file)
@@ -136,27 +136,6 @@ typedef struct {
     int level;
 } Parser;
 
-static inline void item_dump(Item* a)
-{
-    printf("// Item M:%d R:%d ", a->mode, a->reg);
-    if (a->mode == ITEM_MVAR)
-    {
-        printf(" %s", a->imm.s);
-    }
-    else
-    {
-        if (a->type->form == FORM_INT)
-        {
-            printf("%lld", a->imm.i);
-        }
-        else if (a->type->form == FORM_REAL)
-        {
-            printf("%f", a->imm.f);
-        }
-    }
-    puts("");
-}
-
 // src/stdlib.c
 void fatal(char* estr);
 void* emalloc(size_t size);
@@ -203,6 +182,11 @@ int items_const(Item* a, Item* b);
 void const_binop(int op, Item* a, Item* b);
 void const_unop(Parser* p, int op, Item* a);
 
+// src/dump.c
+void dump_item(Item* a);
+void dump_symbol(Symbol* a);
+void dump_type(Type* a);
+
 /* Backend Code Generation
  *****************************************************************************/
 extern Type BoolType, IntType, RealType, StringType;
diff --git a/cerise/src/dump.c b/cerise/src/dump.c
new file mode 100644 (file)
index 0000000..e0399a6
--- /dev/null
@@ -0,0 +1,63 @@
+#include <cerise.h>
+
+void dump_item(Item* a)
+{
+    printf("// Item M:%d R:%d ", a->mode, a->reg);
+    if (a->mode == ITEM_MVAR)
+    {
+        printf(" %s", a->imm.s);
+    }
+    else
+    {
+        if (a->type->form == FORM_INT)
+        {
+            printf("%lld", a->imm.i);
+        }
+        else if (a->type->form == FORM_REAL)
+        {
+            printf("%f", a->imm.f);
+        }
+    }
+    puts("");
+}
+
+void dump_symbol(Symbol* a)
+{
+    (void)a;
+}
+
+void dump_type(Type* a)
+{
+    printf("// Type: ");
+    for (; a; a = a->base)
+    {
+        switch (a->form)
+        {
+            case FORM_BOOL:
+                printf("Bool");
+                break;
+
+            case FORM_INT:
+                printf("Int");
+                break;
+
+            case FORM_REAL:
+                printf("Real");
+                break;
+
+            case FORM_ARRAY:
+                printf("array %d of ", a->size);
+                break;
+
+            case FORM_STRING:
+                printf("String");
+                break;
+
+            default:
+                printf("?");
+                break;
+        }
+    }
+    puts("");
+}
+
index a5bb9f002608dd978c07c9c86b40e2da41f3f0c1..2bbdf9b4bad5e6a06c6a1d78c95bd9c28ccc2b38 100644 (file)
@@ -119,11 +119,10 @@ RULE(designator)
                 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;
+//                    item->type = item->type->base;
                 }
                 else
                 {
@@ -720,8 +719,8 @@ static void parse_init(char* fname, char* string)
 
 static void parse_rule(void (*rule)(Parser*, Item*), Item* item, char* string)
 {
-    puts("");
-    printf("%s\n", string);
+//    puts("");
+//    printf("%s\n", string);
     parse_init("test_input", string);
     rule(&Ctx, (item ? item : &(Item){0}));
 }
index 77ba511edd55f97d481ab17ce2fa6862400f872c..7e69119cc31291030fcfc9c5b196de63ad7c9f49 100644 (file)
@@ -107,6 +107,10 @@ begin
 #  c = Foo(1,2);
 #  e[0] = 1;
 #  Foo(1,2);
-  e[2][1] = 1;
+#  e[2][1] = 1 +  e[2][1];
 #  e[b] = 1;
+    e[1][2] = 1;
+    c = e[1][c];
 end
+
+# _T5 _T10
\ No newline at end of file