]> git.sur5r.net Git - cc65/blobdiff - src/ca65/struct.c
atari5200: name conio constructor 'initconio'
[cc65] / src / ca65 / struct.c
index 583d6338971f14733257a60a704f85553be1b6ad..5ea7a18ec3b60e73d9f0140caa2231c15e3ba72e 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2003      Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2003-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 /* common */
 #include "addrsize.h"
+#include "scopedefs.h"
 
 /* ca65 */
 #include "condasm.h"
 #include "error.h"
 #include "expr.h"
+#include "macro.h"
 #include "nexttok.h"
 #include "scanner.h"
 #include "sizeof.h"
@@ -50,7 +52,7 @@
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                                   Data                                    */
 /*****************************************************************************/
 
 
@@ -63,7 +65,7 @@ enum {
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
@@ -74,10 +76,10 @@ static long Member (long AllocSize)
     long Multiplicator;
 
     /* A multiplicator may follow */
-    if (Tok != TOK_SEP) {
+    if (CurTok.Tok != TOK_SEP) {
         Multiplicator = ConstExpression ();
         if (Multiplicator <= 0) {
-            Error ("Range error");
+            ErrorSkip ("Range error");
             Multiplicator = 1;
         }
         AllocSize *= Multiplicator;
@@ -85,7 +87,7 @@ static long Member (long AllocSize)
 
     /* Check the size for a reasonable value */
     if (AllocSize >= 0x10000) {
-        Error ("Range error");
+        ErrorSkip ("Range error");
     }
 
     /* Return the size */
@@ -100,13 +102,13 @@ static long DoStructInternal (long Offs, unsigned Type)
     long Size = 0;
 
     /* Outside of other structs, we need a name. Inside another struct or
-     * union, the struct may be anonymous, in which case no new lexical level
-     * is started.
-     */
-    int Anon = (Tok != TOK_IDENT);
+    ** union, the struct may be anonymous, in which case no new lexical level
+    ** is started.
+    */
+    int Anon = (CurTok.Tok != TOK_IDENT);
     if (!Anon) {
         /* Enter a new scope, then skip the name */
-        SymEnterLevel (SVal, ST_STRUCT, ADDR_SIZE_ABS);
+        SymEnterLevel (&CurTok.SVal, SCOPE_STRUCT, ADDR_SIZE_ABS, 0);
         NextTok ();
         /* Start at zero offset in the new scope */
         Offs = 0;
@@ -116,16 +118,35 @@ static long DoStructInternal (long Offs, unsigned Type)
     ConsumeSep ();
 
     /* Read until end of struct */
-    while (Tok != TOK_ENDSTRUCT && Tok != TOK_ENDUNION && Tok != TOK_EOF) {
+    while (CurTok.Tok != TOK_ENDSTRUCT &&
+           CurTok.Tok != TOK_ENDUNION  &&
+           CurTok.Tok != TOK_EOF) {
 
         long      MemberSize;
         SymTable* Struct;
+        SymEntry* Sym;
+
+        /* Allow empty and comment lines */
+        if (CurTok.Tok == TOK_SEP) {
+            NextTok ();
+            continue;
+        }
 
         /* The format is "[identifier] storage-allocator [, multiplicator]" */
-        SymEntry* Sym = 0;
-        if (Tok == TOK_IDENT) {
+        Sym = 0;
+        if (CurTok.Tok == TOK_IDENT) {
+
+            /* Beware: An identifier may also be a macro, in which case we have
+            ** to start over.
+            */
+            Macro* M = FindMacro (&CurTok.SVal);
+            if (M) {
+                MacExpandStart (M);
+                continue;
+            }
+
             /* We have an identifier, generate a symbol */
-            Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
+            Sym = SymFind (CurrentScope, &CurTok.SVal, SYM_ALLOC_NEW);
 
             /* Assign the symbol the offset of the current member */
             SymDef (Sym, GenLiteralExpr (Offs), ADDR_SIZE_DEFAULT, SF_NONE);
@@ -136,7 +157,7 @@ static long DoStructInternal (long Offs, unsigned Type)
 
         /* Read storage allocators */
         MemberSize = 0;                 /* In case of errors, use zero */
-        switch (Tok) {
+        switch (CurTok.Tok) {
 
             case TOK_BYTE:
                 NextTok ();
@@ -161,8 +182,9 @@ static long DoStructInternal (long Offs, unsigned Type)
                 break;
 
             case TOK_RES:
-                if (Tok == TOK_SEP) {
-                    Error ("Size is missing");
+                NextTok ();
+                if (CurTok.Tok == TOK_SEP) {
+                    ErrorSkip ("Size is missing");
                 } else {
                     MemberSize = Member (1);
                 }
@@ -172,16 +194,16 @@ static long DoStructInternal (long Offs, unsigned Type)
                 NextTok ();
                 Struct = ParseScopedSymTable ();
                 if (Struct == 0) {
-                    Error ("Unknown struct/union");
-                } else if (GetSymTabType (Struct) != ST_STRUCT) {
-                    Error ("Not a struct/union");
+                    ErrorSkip ("Unknown struct/union");
+                } else if (GetSymTabType (Struct) != SCOPE_STRUCT) {
+                    ErrorSkip ("Not a struct/union");
                 } else {
                     SymEntry* SizeSym = GetSizeOfScope (Struct);
                     if (!SymIsDef (SizeSym) || !SymIsConst (SizeSym, &MemberSize)) {
-                        Error ("Size of struct/union is unknown");
+                        ErrorSkip ("Size of struct/union is unknown");
                     }
                 }
-                MemberSize *= Member (MemberSize);
+                MemberSize = Member (MemberSize);
                 break;
 
             case TOK_STRUCT:
@@ -223,11 +245,11 @@ static long DoStructInternal (long Offs, unsigned Type)
     }
 
     /* If this is not a anon struct, enter a special symbol named ".size"
-     * into the symbol table of the struct that holds the size of the
-     * struct. Since the symbol starts with a dot, it cannot be accessed
-     * by user code.
-     * Leave the struct scope level.
-     */
+    ** into the symbol table of the struct that holds the size of the
+    ** struct. Since the symbol starts with a dot, it cannot be accessed
+    ** by user code.
+    ** Leave the struct scope level.
+    */
     if (!Anon) {
         /* Add a symbol */
         SymEntry* SizeSym = GetSizeOfScope (CurrentScope);
@@ -239,9 +261,9 @@ static long DoStructInternal (long Offs, unsigned Type)
 
     /* End of struct/union definition */
     if (Type == STRUCT) {
-        Consume (TOK_ENDSTRUCT, "`.ENDSTRUCT' expected");
+        Consume (TOK_ENDSTRUCT, "'.ENDSTRUCT' expected");
     } else {
-        Consume (TOK_ENDUNION, "`.ENDUNION' expected");
+        Consume (TOK_ENDUNION, "'.ENDUNION' expected");
     }
 
     /* Return the size of the struct */
@@ -253,12 +275,12 @@ static long DoStructInternal (long Offs, unsigned Type)
 long GetStructSize (SymTable* Struct)
 /* Get the size of a struct or union */
 {
-    SymEntry* Sym = SymFind (Struct, ".size", SYM_FIND_EXISTING);
-    if (Sym == 0) {
+    SymEntry* SizeSym = FindSizeOfScope (Struct);
+    if (SizeSym == 0) {
         Error ("Size of struct/union is unknown");
         return 0;
     } else {
-        return GetSymVal (Sym);
+        return GetSymVal (SizeSym);
     }
 }
 
@@ -277,6 +299,3 @@ void DoUnion (void)
 {
     DoStructInternal (0, UNION);
 }
-
-
-