]> git.mdlowis.com Git - proto/obnc.git/commitdiff
reworked field addition to records
authormike lowis <mike@mdlowis.com>
Mon, 24 May 2021 02:22:58 +0000 (22:22 -0400)
committermike lowis <mike@mdlowis.com>
Mon, 24 May 2021 02:22:58 +0000 (22:22 -0400)
cerise/src/grammar.c

index c94a57676acb8f5cbd7c97e09a5b98694d46aebf..ec56a0f5c1f90b8604db929e825b0141bd14ba14 100644 (file)
@@ -87,8 +87,6 @@ static void init_item(Item* item, Symbol* sym)
     }
 }
 
-
-
 static long align_item(long offset, long size)
 {
     offset--;
@@ -117,6 +115,36 @@ static long size_of(Type* type)
     return (size * type->size);
 }
 
+Field* add_field(Parser* p, Type* type, char* name, bool export)
+{
+    Field* prev = NULL;
+    Field* curr = type->fields;
+
+    while (curr)
+    {
+        if (curr->name && !strcmp(curr->name, name))
+        {
+            error(p, "multiple definitions of '%s' in record", name);
+        }
+        prev = curr;
+        curr = curr->next;
+    }
+
+    Field* field = calloc(1, sizeof(Field));
+    field->name = name;
+    field->export = export;
+    if (prev)
+    {
+        prev->next = field;
+    }
+    else
+    {
+        type->fields = field;
+    }
+
+    return field;
+}
+
 /* Grammar Definition
  *****************************************************************************/
 static void expression(Parser* p, Item* item);
@@ -378,26 +406,22 @@ RULE(type)
         long offset = 0;
         item->type = calloc(1, sizeof(Type));
         item->type->form = FORM_RECORD;
-        Field **field = &(item->type->fields);
 
         while (peek(p)->type != END)
         {
             /* parse the field name list */
-            int nfields = 0;
             Field* first = NULL;
+            int nfields = 0;
             do
             {
                 char* name = expect_text(p, IDENT);
                 bool export = accept(p, '*');
-                *field = calloc(1, sizeof(Field));
-                (*field)->name = name;
-                (*field)->export = export;
+                Field* f = add_field(p, item->type, name, export);
+                nfields++;
                 if (!first)
                 {
-                    first = *field;
+                    first = f;
                 }
-                field = &((*field)->next);
-                nfields++;
             }
             while (accept(p, ','));