]> git.mdlowis.com Git - proto/obnc.git/commitdiff
record field access is working now
authorMichael D. Lowis <mike@mdlowis.com>
Sun, 2 Oct 2022 00:36:45 +0000 (20:36 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Sun, 2 Oct 2022 00:36:45 +0000 (20:36 -0400)
cerise/backend/ssa/codegen.c
cerise/inc/cerise.h
cerise/src/ssa.c
cerise/tests/Module.m

index e8cc367bb0fab20d50c17bd3328f094b74d675c1..6fa249175ecb290b8ab50f2d6c29b88b3c8e2d34 100644 (file)
@@ -182,6 +182,8 @@ static void topsort(Bitset* set, SsaBlock** sorted, SsaBlock* block)
 static void print_ident(Parser* p, SsaVar* var)
 {
     Symbol* s = symbol_getbyid(p, var->symid);
+    assert(s);
+    assert(s->name);
     char* name = (s->name[0] == '$' ? "" : s->name);
     if ((s->global || s->class == SYM_PROC) && (s->class != SYM_TYPE))
     {
@@ -325,6 +327,30 @@ void print_op(Parser* p, SsaNode* expr)
                 print_oparg(p, expr->right);
                 puts("");
             }
+            else if (expr->code == '.')
+            {
+                printf("    ");
+                print_ident(p, &(SSA_VAR(expr)));
+                printf(" = getelementptr ");
+                emit_type(SSA_LTYPE(expr));
+                printf(", ");
+                emit_type(SSA_LTYPE(expr));
+                printf("* ");
+                print_ident(p, &(SSA_LVAR(expr)));
+                printf(", i64 0");
+                int num = 0;
+                char* fname = ssa_asstring(expr->right);
+                struct Field* field = SSA_LTYPE(expr)->fields;
+                for (; field; field = field->next, num++)
+                {
+                    if (!strcmp(fname, field->name))
+                    {
+                        break;
+                    }
+                }
+                printf(", i32 %d", num);
+                puts("");
+            }
             else
             {
                 assert(!"not implemented");
index 797146d9d003f53928fc773e73061d76f8114f8c..62ac170d95e495c6975dc494611b47cbd57bb932 100644 (file)
@@ -125,6 +125,7 @@ typedef union {
     SsaVar var;
     SsaConst val;
     struct SsaBlock* block;
+    char* str;
 } SsaValue;
 
 //typedef struct SsaNode {
@@ -300,6 +301,7 @@ bool bitset_has(Bitset* set, size_t val);
 bool ssa_asbool(SsaNode* node);
 long long ssa_asint(SsaNode* node);
 double ssa_asreal(SsaNode* node);
+char* ssa_asstring(SsaNode* node);
 
 void ssa_join(Parser* p);
 void ssa_reset_vars(Parser* p);
@@ -308,6 +310,7 @@ SsaNode* ssa_ident(Parser* p, long long index);
 SsaNode* ssa_bool(Parser* p, bool val);
 SsaNode* ssa_int(Parser* p, long long val);
 SsaNode* ssa_real(Parser* p, double val);
+SsaNode* ssa_string(Parser* p, char* val);
 SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right);
 
 SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value);
index a5a298042c07c2a71ee35e5a4249305b450bf247..2e3ef55b4f39c90e8f6025c59a4ebf2feba05312 100644 (file)
@@ -26,6 +26,12 @@ double ssa_asreal(SsaNode* node)
     return (SSA_VAL(node).f);
 }
 
+char* ssa_asstring(SsaNode* node)
+{
+    assert(node->code == STRING);
+    return (SSA_VAL(node).s);
+}
+
 /*
     * store backup values for var versions, restore at the end of block
     * popping a join node processes phis as stores propagating phis to outer join nodes
@@ -172,6 +178,15 @@ SsaNode* ssa_real(Parser* p, double val)
     return node;
 }
 
+SsaNode* ssa_string(Parser* p, char* val)
+{
+    (void)p;
+    SsaNode* node = ssa_node(STRING, MODE_CONST);
+    node->type = &StringType;
+    SSA_VAL(node).s = val;
+    return node;
+}
+
 SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right)
 {
     return (right != NULL)
@@ -182,7 +197,7 @@ SsaNode* ssa_op(Parser* p, int op, SsaNode* left, SsaNode* right)
 SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value)
 {
     value = load(p, value);
-    if (dest->mode == MODE_MEMORY && dest->code == '[')
+    if (dest->mode == MODE_MEMORY && (dest->code == '[' || dest->code == '.'))
     {
         dest = load(p, dest);
     }
@@ -204,27 +219,36 @@ SsaNode* ssa_store(Parser* p, SsaNode* dest, SsaNode* value)
 
 SsaNode* ssa_fieldref(Parser* p, SsaNode* record, char* fname)
 {
-#if 1
-    (void)p, (void)record, (void)fname;
-    assert(!"record field references unimplemented");
-    return NULL;
-#else
-    if (record->mode == MODE_MEMORY && record->code == '[')
+    if (record->mode == MODE_MEMORY && (record->code == '[' || record->code == '.'))
     {
         record = load(p, record);
     }
-    index = load(p, index);
-    SsaNode* node = ssa_node('[', MODE_MEMORY);
-    node->type = array->type->base;
-    node->left = array;
-    node->right = index;
+
+    /* make sure the referenced field exists */
+    struct Field* field = record->type->fields;
+    for (; field; field = field->next)
+    {
+        if (!strcmp(fname, field->name))
+        {
+            break;
+        }
+    }
+    if (!field)
+    {
+        error(p, "record has no field named '%s'", fname);
+    }
+
+    /* now create and return the node */
+    SsaNode* node = ssa_node('.', MODE_MEMORY);
+    node->type = field->type;
+    node->left = record;
+    node->right = ssa_string(p, fname);
     return node;
-#endif
 }
 
 SsaNode* ssa_index(Parser* p, SsaNode* array, SsaNode* index)
 {
-    if (array->mode == MODE_MEMORY && array->code == '[')
+    if (array->mode == MODE_MEMORY && (array->code == '[' || array->code == '.'))
     {
         array = load(p, array);
     }
@@ -530,7 +554,7 @@ static SsaNode* load(Parser* p, SsaNode* node)
 static SsaNode* loadmem(Parser* p, SsaNode* node)
 {
     node = load(p, node);
-    if (node->mode == MODE_MEMORY && node->code == '[')
+    if (node->mode == MODE_MEMORY && (node->code == '[' || node->code == '.'))
     {
         SsaNode* load_op = ssa_node(LOAD, MODE_MEMORY);
         load_op->left = node;
index 0c8f2607c69e0761e67f2c4ab0e6d52778ac8ee2..3cd964f79f3932e313ab26016b05000379246e13 100644 (file)
@@ -172,12 +172,13 @@ end
 
 procedure TestRecordAccess()
 begin
-#    vRec2.a = vRec2.a + vRec2.a;
+    vRec2.a = vRec2.a + vRec2.a;
+#    vInt = vRec2.a;  # TODO: This is broken!
 end
 
 procedure TestNestedRecordAccess()
 begin
-#    vRec2.a.b = vRec2.a.b + vRec2.a.b;
+    vRec1.b.c = vRec1.b.c + vRec1.b.c; # TODO: This is broken!
 end
 
 #begin