[esnacc-dev] [PATCH 3/5] compiler/core/snacc-util: Introduce automatic tag utils

Aaron Conole aconole at bytheb.org
Fri Jul 15 16:07:50 UTC 2016


In order to properly perform automatic tagging, it is required to have a
two-pass system to gather all of the used tags, and then fill the holes
using the new tags.  Not much interop testing is done with gap filling.

Signed-off-by: Aaron Conole <aconole at bytheb.org>
---
 compiler/core/snacc-util.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++
 compiler/core/snacc-util.h |  2 ++
 2 files changed, 73 insertions(+)

diff --git a/compiler/core/snacc-util.c b/compiler/core/snacc-util.c
index 05c456e..fbcf326 100644
--- a/compiler/core/snacc-util.c
+++ b/compiler/core/snacc-util.c
@@ -1625,5 +1625,76 @@ AppendSubtype PARAMS ((s, newSubtype, op),
 
 }  /* AppendSubtype */
 
+static int
+TagCodeFound(AsnList *tags, AsnInt startingTag)
+{
+    Tag *tag;
+    FOR_EACH_LIST_ELMT(tag, tags) {
+        if (tag->code == startingTag)
+            return 1;
+    }
+    return 0;
+}
+
+void
+AutomaticTagNamed PARAMS ((l, all),
+    NamedTypeList *l)
+{
+    AsnList *used_tag;
+    NamedType *e;
+    void *lcurr;
+    AsnInt startingTag = 0;
+
+    if (l == NULL) {
+        fprintf(errFileG, "AutomaticTagNamed - NULL tag list.\n");
+    }
 
+    /* Two passes */
+    used_tag = AsnListNew(sizeof(void*));
+    /* First pass, identify all the tags, and all the elements which
+       need tags */
+    lcurr = l->curr;
+    FOR_EACH_LIST_ELMT(e, l) {
+        if (e->type->tags != NULL) {
+            Tag *t;
+            void *curr = e->type->tags->curr;
+            FOR_EACH_LIST_ELMT(t, e->type->tags) {
+                if (t->tclass == CNTX) {
+                    APPEND(t, used_tag);
+                    break;
+                }
+            }
+            e->type->tags->curr = curr;
+        }
+    }
+    FOR_EACH_LIST_ELMT(e, l) {
+        int found = 0;
+        Tag *t;
+        FOR_EACH_LIST_ELMT(t, e->type->tags) {
+            if (t->tclass == CNTX) {
+                fprintf(errFileG, "CNTX tag exists\n");
+                found = 1;
+            }
+        }
+        if (!found) {
+            Tag *newTag = Malloc(sizeof(Tag));
+            newTag->tclass = CNTX;
+            newTag->form = PRIM;
+            newTag->valueRef = NULL;
+            /* It seems strange to only use context tagging; however, after
+             * some brief interop testing, that seems like the right thing to
+             * do */
+            if (!(e->type->tags))
+                AsnListFree(e->type->tags);
+            e->type->tags = AsnListNew(sizeof(void *));
+            while(TagCodeFound(used_tag, startingTag))
+                startingTag++;
+            newTag->code = startingTag++;
+            newTag->explicit = FALSE;
+            PREPEND(newTag, e->type->tags);
+        }
+    }
+    l->curr = lcurr;
 
+    AsnListFree(used_tag);
+}
diff --git a/compiler/core/snacc-util.h b/compiler/core/snacc-util.h
index fbb98c8..c10b581 100644
--- a/compiler/core/snacc-util.h
+++ b/compiler/core/snacc-util.h
@@ -108,6 +108,8 @@ BasicValue * GetLastNamedNumberValue PROTO ((NamedNumberList *valueList));
 
 void SetupType PROTO ((Type **t, enum BasicTypeChoiceId typeId, unsigned long lineNum));
 
+void AutomaticTagNamed PROTO ((NamedTypeList *l));
+
 void SetupMacroType PROTO ((Type **t, enum MacroTypeChoiceId macroTypeId, unsigned long lineNum));
 
 void SetupValue PROTO ((Value **v, enum BasicValueChoiceId valId, unsigned long lineNum));
-- 
2.5.5




More information about the dev mailing list