]> git.sur5r.net Git - cc65/commitdiff
New syntax for symbols
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 24 Jul 2005 21:09:23 +0000 (21:09 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 24 Jul 2005 21:09:23 +0000 (21:09 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@3546 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ld65/config.c
src/ld65/scanner.h

index 6762ac0da245609e73f364d7dbd023589c94d298..098633323111351eaeed30c4a90a8945afbae2d3 100644 (file)
@@ -1326,8 +1326,8 @@ static void ParseFeatures (void)
        switch (FeatureTok) {
 
            case CFGTOK_CONDES:
-               ParseConDes ();
-               break;
+               ParseConDes ();
+               break;
 
             case CFGTOK_STARTADDRESS:
                 ParseStartAddress ();
@@ -1335,7 +1335,7 @@ static void ParseFeatures (void)
 
 
            default:
-               Error ("Unexpected feature token");
+               Error ("Unexpected feature token");
        }
 
        /* Skip the semicolon */
@@ -1351,24 +1351,111 @@ static void ParseFeatures (void)
 static void ParseSymbols (void)
 /* Parse a symbols section */
 {
+    static const IdentTok Attributes[] = {
+               {   "VALUE",    CFGTOK_VALUE    },
+        {   "WEAK",     CFGTOK_WEAK     },
+    };
+
     while (CfgTok == CFGTOK_IDENT) {
 
-       long Val;
+       long Val = 0L;
+        int  Weak;
 
        /* Remember the name */
        unsigned Name = GetStringId (CfgSVal);
        CfgNextTok ();
 
-       /* Allow an optional assignment */
-       CfgOptionalAssign ();
+        /* Support both, old and new syntax here. New syntax is a colon
+         * followed by an attribute list, old syntax is an optional equal
+         * sign plus a value.
+         */
+        if (CfgTok != CFGTOK_COLON) {
 
-       /* Make sure the next token is an integer, read and skip it */
-       CfgAssureInt ();
-       Val = CfgIVal;
-       CfgNextTok ();
+            /* Old syntax */
+
+            /* Allow an optional assignment */
+            CfgOptionalAssign ();
+
+            /* Make sure the next token is an integer, read and skip it */
+            CfgAssureInt ();
+            Val = CfgIVal;
+            CfgNextTok ();
+
+            /* Generate an export with the given value */
+            CreateConstExport (Name, Val);
+
+        } else {
+
+            /* Bitmask to remember the attributes we got already */
+            enum {
+                atNone         = 0x0000,
+                atValue         = 0x0001,
+                atWeak          = 0x0002
+            };
+            unsigned AttrFlags = atNone;
+
+
+            /* New syntax - skip the colon */
+            CfgNextTok ();
+
+            /* Parse the attributes */
+            while (1) {
+
+                /* Map the identifier to a token */
+                cfgtok_t AttrTok;
+                CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
+                AttrTok = CfgTok;
+
+                /* An optional assignment follows */
+                CfgNextTok ();
+                CfgOptionalAssign ();
 
-       /* Generate an export with the given value */
-       CreateConstExport (Name, Val);
+                /* Check which attribute was given */
+                switch (AttrTok) {
+
+                    case CFGTOK_VALUE:
+                        /* Don't allow this twice */
+                        FlagAttr (&AttrFlags, atValue, "VALUE");
+                        /* We expect a number */
+                        CfgAssureInt ();
+                        /* Remember the value for later */
+                        Val = CfgIVal;
+                        break;
+
+                    case CFGTOK_WEAK:
+                        /* Don't allow this twice */
+                        FlagAttr (&AttrFlags, atWeak, "WEAK");
+                        CfgBoolToken ();
+                        Weak = (CfgTok == CFGTOK_TRUE);
+                        break;
+
+                    default:
+                        FAIL ("Unexpected attribute token");
+
+                }
+
+                /* Skip the attribute value */
+                CfgNextTok ();
+
+                /* Semicolon ends the decl, otherwise accept an optional comma */
+                if (CfgTok == CFGTOK_SEMI) {
+                    break;
+                } else if (CfgTok == CFGTOK_COMMA) {
+                    CfgNextTok ();
+                }
+            }
+
+            /* Check if we have all mandatory attributes */
+            AttrCheck (AttrFlags, atValue, "VALUE");
+
+            /* Weak is optional, the default are non weak symbols */
+            if ((AttrFlags & atWeak) == 0) {
+                Weak = 0;
+            }
+
+            /* Generate an export with the given value */
+            CreateConstExport (Name, Val);
+        }
 
        /* Skip the semicolon */
        CfgConsumeSemi ();
index e7a943257ea692c21b30ad1853139f391d636e31..9f2efa4d8e28dc4dc5574fc28fcf54780091ed8d 100644 (file)
@@ -110,6 +110,9 @@ typedef enum {
     CFGTOK_CONDES,
     CFGTOK_STARTADDRESS,
 
+    CFGTOK_VALUE,
+    CFGTOK_WEAK,
+
     CFGTOK_SEGMENT,
     CFGTOK_LABEL,
     CFGTOK_COUNT,