]> git.sur5r.net Git - cc65/blobdiff - src/ca65/pseudo.c
New module strstack
[cc65] / src / ca65 / pseudo.c
index 42674285af706a3ac98c457bc59f2f56cd7fc507..1388cdadc72dd32dc8acc986edb8788dda8ede56 100644 (file)
@@ -7,7 +7,7 @@
 /*                                                                           */
 /*                                                                           */
 /* (C) 1998-2003 Ullrich von Bassewitz                                       */
-/*               Römerstrasse 52                                             */
+/*               Römerstraße 52                                              */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
@@ -53,6 +53,7 @@
 #include "asserts.h"
 #include "condasm.h"
 #include "dbginfo.h"
+#include "enum.h"
 #include "error.h"
 #include "expr.h"
 #include "feature.h"
 #include "pseudo.h"
 #include "repeat.h"
 #include "segment.h"
+#include "sizeof.h"
 #include "spool.h"
+#include "struct.h"
+#include "symbol.h"
 #include "symtab.h"
 
 
@@ -80,7 +84,7 @@
 
 
 /* Keyword we're about to handle */
-static char Keyword [sizeof (SVal)+1] = ".";
+static char Keyword [sizeof (SVal)+1];
 
 /* Segment stack */
 #define MAX_PUSHED_SEGMENTS     16
@@ -114,7 +118,7 @@ static void DoInvalid (void);
 
 
 
-static unsigned OptionalAddrSize (void)
+static unsigned char OptionalAddrSize (void)
 /* If a colon follows, parse an optional address size spec and return it.
  * Otherwise return ADDR_SIZE_DEFAULT.
  */
@@ -161,12 +165,12 @@ static void SetBoolOption (unsigned char* Flag)
 
 
 
-static void ExportImport (void (*Func) (SymEntry*, unsigned, unsigned),
-                          unsigned DefAddrSize, unsigned Flags)
+static void ExportImport (void (*Func) (SymEntry*, unsigned char, unsigned),
+                          unsigned char DefAddrSize, unsigned Flags)
 /* Export or import symbols */
 {
     SymEntry* Sym;
-    unsigned  AddrSize;
+    unsigned char AddrSize;
 
     while (1) {
 
@@ -227,6 +231,10 @@ static void ConDes (const char* Name, unsigned Type)
 {
     long Prio;
 
+
+    /* Find the symbol table entry, allocate a new one if necessary */
+    SymEntry* Sym = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
+
     /* Optional constructor priority */
     if (Tok == TOK_COMMA) {
        /* Priority value follows */
@@ -243,7 +251,7 @@ static void ConDes (const char* Name, unsigned Type)
     }
 
     /* Define the symbol */
-    SymConDes (Name, Type, (unsigned) Prio);
+    SymConDes (Sym, ADDR_SIZE_DEFAULT, Type, (unsigned) Prio);
 }
 
 
@@ -700,11 +708,11 @@ static void DoEnd (void)
 static void DoEndProc (void)
 /* Leave a lexical level */
 {
-    if (CurrentScope != RootScope) {
-        SymLeaveLevel ();
-    } else {
+    if (GetCurrentSymTabType () != ST_PROC) {
         /* No local scope */
-        ErrorSkip ("No open lexical level");
+        ErrorSkip ("No open .PROC");
+    } else {
+        SymLeaveLevel ();
     }
 }
 
@@ -713,11 +721,11 @@ static void DoEndProc (void)
 static void DoEndScope (void)
 /* Leave a lexical level */
 {
-    if (CurrentScope != RootScope) {
-        SymLeaveLevel ();
-    } else {
+    if ( GetCurrentSymTabType () != ST_SCOPE) {
         /* No local scope */
-        ErrorSkip ("No open lexical level");
+        ErrorSkip ("No open .SCOPE");
+    } else {
+        SymLeaveLevel ();
     }
 }
 
@@ -1294,16 +1302,18 @@ static void DoPopSeg (void)
 static void DoProc (void)
 /* Start a new lexical scope */
 {
+    char Name[sizeof(SVal)];
+    unsigned char AddrSize;
+
     if (Tok == TOK_IDENT) {
 
-        unsigned AddrSize;
+        SymEntry* Sym;
 
        /* The new scope has a name. Remember it. */
-        char Name[sizeof(SVal)];
         strcpy (Name, SVal);
 
         /* Search for the symbol, generate a new one if needed */
-       SymEntry* Sym = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
+               Sym = SymFind (CurrentScope, Name, SYM_ALLOC_NEW);
 
         /* Skip the scope name */
         NextTok ();
@@ -1314,17 +1324,17 @@ static void DoProc (void)
         /* Mark the symbol as defined */
        SymDef (Sym, GenCurrentPC (), AddrSize, SF_LABEL);
 
-        /* Enter a new scope with the given name */
-        SymEnterLevel (Name, AddrSize);
-
     } else {
 
         /* A .PROC statement without a name */
-        char Buf[sizeof (SVal)];
-        SymEnterLevel (AnonName (Buf, sizeof (Buf), "Scope"), ADDR_SIZE_DEFAULT);
         Warning (1, "Unnamed .PROCs are deprecated, please use .SCOPE");
+        AnonName (Name, sizeof (Name), "PROC");
+        AddrSize = ADDR_SIZE_DEFAULT;
 
     }
+
+    /* Enter a new scope */
+    SymEnterLevel (Name, ST_PROC, AddrSize);
 }
 
 
@@ -1413,27 +1423,28 @@ static void DoScope (void)
 /* Start a local scope */
 {
     char Name[sizeof (SVal)];
+    unsigned char AddrSize;
 
-    if (Tok == TOK_IDENT) {
 
-        unsigned AddrSize;
+    if (Tok == TOK_IDENT) {
 
-       /* The new scope has a name. Remember and skip it. */
+       /* The new scope has a name. Remember and skip it. */
         strcpy (Name, SVal);
         NextTok ();
 
-        /* Read an optional address size specifier */
-        AddrSize = OptionalAddrSize ();
-
-        /* Enter a new scope with the given name */
-        SymEnterLevel (Name, AddrSize);
-
     } else {
 
         /* An unnamed scope */
-        SymEnterLevel (AnonName (Name, sizeof (Name), "Scope"), ADDR_SIZE_DEFAULT);
+        AnonName (Name, sizeof (Name), "SCOPE");
 
     }
+
+    /* Read an optional address size specifier */
+    AddrSize = OptionalAddrSize ();
+
+    /* Enter the new scope */
+    SymEnterLevel (Name, ST_SCOPE, AddrSize);
+
 }
 
 
@@ -1489,14 +1500,6 @@ static void DoSmart (void)
 
 
 
-static void DoStruct (void)
-/* Struct definition */
-{
-    Error ("Not implemented");
-}
-
-
-
 static void DoSunPlus (void)
 /* Switch to the SUNPLUS CPU */
 {
@@ -1505,10 +1508,49 @@ static void DoSunPlus (void)
 
 
 
-static void DoUnion (void)
-/* Union definition */
+static void DoTag (void)
+/* Allocate space for a struct */
 {
-    Error ("Not implemented");
+    SymEntry* SizeSym;
+    long Size;
+
+    /* Read the struct name */
+    SymTable* Struct = ParseScopedSymTable ();
+
+    /* Check the supposed struct */
+    if (Struct == 0) {
+        ErrorSkip ("Unknown struct");
+        return;
+    }
+    if (GetSymTabType (Struct) != ST_STRUCT) {
+        ErrorSkip ("Not a struct");
+        return;
+    }
+
+    /* Get the symbol that defines the size of the struct */
+    SizeSym = GetSizeOfScope (Struct);
+
+    /* Check if it does exist and if its value is known */
+    if (SizeSym == 0 || !SymIsConst (SizeSym, &Size)) {
+        ErrorSkip ("Size of struct/union is unknown");
+        return;
+    }
+
+    /* Optional multiplicator may follow */
+    if (Tok == TOK_COMMA) {
+        long Multiplicator;
+        NextTok ();
+        Multiplicator = ConstExpression ();
+        /* Multiplicator must make sense */
+        if (Multiplicator <= 0) {
+            ErrorSkip ("Range error");
+            return;
+        }
+        Size *= Multiplicator;
+    }
+
+    /* Emit fill fragments */
+    EmitFill (Size);
 }
 
 
@@ -1586,6 +1628,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoASCIIZ        },
     { ccNone,           DoAssert        },
     { ccNone,          DoAutoImport    },
+    { ccNone,          DoUnexpected    },      /* .BANKBYTE */
     { ccNone,          DoUnexpected    },      /* .BLANK */
     { ccNone,          DoBss           },
     { ccNone,          DoByte          },
@@ -1608,12 +1651,15 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccKeepToken,     DoConditionals  },      /* .ELSE */
     { ccKeepToken,     DoConditionals  },      /* .ELSEIF */
     { ccKeepToken,             DoEnd           },
+    { ccNone,           DoUnexpected    },      /* .ENDENUM */
     { ccKeepToken,     DoConditionals  },      /* .ENDIF */
     { ccNone,          DoUnexpected    },      /* .ENDMACRO */
     { ccNone,          DoEndProc       },
     { ccNone,          DoUnexpected    },      /* .ENDREPEAT */
     { ccNone,           DoEndScope      },
     { ccNone,           DoUnexpected    },      /* .ENDSTRUCT */
+    { ccNone,           DoUnexpected    },      /* .ENDUNION */
+    { ccNone,           DoEnum          },
     { ccNone,          DoError         },
     { ccNone,          DoExitMacro     },
     { ccNone,          DoExport        },
@@ -1625,6 +1671,8 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoUnexpected    },      /* .FORCEWORD */
     { ccNone,          DoGlobal        },
     { ccNone,          DoGlobalZP      },
+    { ccNone,          DoUnexpected    },      /* .HIBYTE */
+    { ccNone,          DoUnexpected    },      /* .HIWORD */
     { ccNone,          DoI16           },
     { ccNone,          DoI8            },
     { ccKeepToken,     DoConditionals  },      /* .IF */
@@ -1648,8 +1696,10 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoLineCont      },
     { ccNone,          DoList          },
     { ccNone,                  DoListBytes     },
+    { ccNone,          DoUnexpected    },      /* .LOBYTE */
     { ccNone,          DoUnexpected    },      /* .LOCAL */
     { ccNone,          DoLocalChar     },
+    { ccNone,          DoUnexpected    },      /* .LOWORD */
     { ccNone,          DoMacPack       },
     { ccNone,          DoMacro         },
     { ccNone,                  DoUnexpected    },      /* .MATCH */
@@ -1671,17 +1721,18 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoRepeat        },
     { ccNone,          DoRes           },
     { ccNone,          DoInvalid       },      /* .RIGHT */
-    { ccNone,          DoROData        },   
+    { ccNone,          DoROData        },
     { ccNone,           DoScope         },
     { ccNone,          DoSegment       },
     { ccNone,                  DoSetCPU        },
+    { ccNone,           DoUnexpected    },      /* .SIZEOF */
     { ccNone,          DoSmart         },
     { ccNone,          DoUnexpected    },      /* .STRAT */
     { ccNone,                  DoUnexpected    },      /* .STRING */
     { ccNone,          DoUnexpected    },      /* .STRLEN */
     { ccNone,           DoStruct        },
     { ccNone,          DoSunPlus       },
-    { ccNone,           DoUnexpected    },      /* .TAG */
+    { ccNone,           DoTag           },
     { ccNone,          DoUnexpected    },      /* .TCOUNT */
     { ccNone,                  DoUnexpected    },      /* .TIME */
     { ccNone,           DoUnion         },
@@ -1700,14 +1751,6 @@ static CtrlDesc CtrlCmdTab [] = {
 
 
 
-int TokIsPseudo (unsigned Tok)
-/* Return true if the given token is a pseudo instruction token */
-{
-    return (Tok >= TOK_FIRSTPSEUDO && Tok <= TOK_LASTPSEUDO);
-}
-
-
-
 void HandlePseudo (void)
 /* Handle a pseudo instruction */
 {
@@ -1728,7 +1771,7 @@ void HandlePseudo (void)
 
     /* Remember the instruction, then skip it if needed */
     if ((D->Flags & ccKeepToken) == 0) {
-       strcpy (Keyword+1, SVal);
+       strcpy (Keyword, SVal);
        NextTok ();
     }