]> git.sur5r.net Git - cc65/commitdiff
Added function .ADDRSIZE to ca65
authorJT <jeremiah.turner@gmail.com>
Mon, 20 Apr 2015 03:21:56 +0000 (23:21 -0400)
committerJT <jeremiah.turner@gmail.com>
Mon, 20 Apr 2015 03:21:56 +0000 (23:21 -0400)
src/ca65/expr.c
src/ca65/feature.c
src/ca65/feature.h
src/ca65/global.c
src/ca65/global.h
src/ca65/pseudo.c
src/ca65/scanner.c
src/ca65/token.h

index e4d6f7363a7161121fb35449816cb2475c0dce28..ad1a0b155234b1accb7cac75a93118ae76282502 100644 (file)
@@ -629,6 +629,92 @@ static ExprNode* FuncReferenced (void)
 
 
 
+static ExprNode* FuncAddrSize(void)
+/* Handle the .ADDRSIZE function */
+{
+    StrBuf    ScopeName = STATIC_STRBUF_INITIALIZER;
+    StrBuf    Name = STATIC_STRBUF_INITIALIZER;
+    SymEntry* Sym;
+    int       AddrSize;
+    int       NoScope;
+
+
+    /* Assume we don't know the size */
+    AddrSize = 0;
+
+    /* Check for a cheap local which needs special handling */
+    if (CurTok.Tok == TOK_LOCAL_IDENT) {
+
+        /* Cheap local symbol */
+        Sym = SymFindLocal(SymLast, &CurTok.SVal, SYM_FIND_EXISTING);
+        if (Sym == 0) {
+            Error("Unknown symbol or scope: `%m%p'", &CurTok.SVal);
+        }
+        else {
+            AddrSize = Sym->AddrSize;
+        }
+
+        /* Remember and skip SVal, terminate ScopeName so it is empty */
+        SB_Copy(&Name, &CurTok.SVal);
+        NextTok();
+        SB_Terminate(&ScopeName);
+
+    }
+    else {
+
+        /* Parse the scope and the name */
+        SymTable* ParentScope = ParseScopedIdent(&Name, &ScopeName);
+
+        /* Check if the parent scope is valid */
+        if (ParentScope == 0) {
+            /* No such scope */
+            SB_Done(&ScopeName);
+            SB_Done(&Name);
+            return GenLiteral0();
+        }
+
+        /* If ScopeName is empty, no explicit scope was specified. We have to
+        * search upper scope levels in this case.
+        */
+        NoScope = SB_IsEmpty(&ScopeName);
+
+        /* If we did find a scope with the name, read the symbol defining the
+        * size, otherwise search for a symbol entry with the name and scope.
+        */
+        if (NoScope) {
+            Sym = SymFindAny(ParentScope, &Name);
+        }
+        else {
+            Sym = SymFind(ParentScope, &Name, SYM_FIND_EXISTING);
+        }
+        /* If we found the symbol retrieve the size, otherwise complain */
+        if (Sym) {
+            AddrSize = Sym->AddrSize;
+        }
+        else {
+            Error("Unknown symbol or scope: `%m%p%m%p'",
+                &ScopeName, &Name);
+        }
+
+    }
+
+    /* Check if we have a size */
+    /* if we don't know, return it anyway, zero can mean unknown, or uncomment this code for an error
+    if (AddrSize == 0 ) {
+    Error ("Address size of `%m%p%m%p' is unknown", &ScopeName, &Name);
+    }
+    */
+
+    /* Free the string buffers */
+    SB_Done(&ScopeName);
+    SB_Done(&Name);
+
+    /* Return the size */
+    return GenLiteralExpr(AddrSize);
+}
+
+
+
 static ExprNode* FuncSizeOf (void)
 /* Handle the .SIZEOF function */
 {
@@ -965,6 +1051,10 @@ static ExprNode* Factor (void)
             N = Function (FuncBankByte);
             break;
 
+        case TOK_ADDRSIZE:
+            N = Function(FuncAddrSize);
+            break;
+
         case TOK_BLANK:
             N = Function (FuncBlank);
             break;
index c398d2b377adc42665a2f81cf4148d54fdcc57d2..3462d5501c30848cf3d29d3f9c2cd45938c87fe5 100644 (file)
@@ -63,6 +63,7 @@ static const char* FeatureKeys[FEAT_COUNT] = {
     "c_comments",
     "force_range",
     "underline_in_numbers",
+    "addrsize",
 };
 
 
@@ -119,6 +120,7 @@ feature_t SetFeature (const StrBuf* Key)
         case FEAT_C_COMMENTS:                 CComments         = 1;    break;
         case FEAT_FORCE_RANGE:                ForceRange        = 1;    break;
         case FEAT_UNDERLINE_IN_NUMBERS:       UnderlineInNumbers= 1;    break;
+        case FEAT_ADDRSIZE:                   AddrSize          = 1;    break;
         default:                         /* Keep gcc silent */          break;
     }
 
index 9682ad9b93314ee860beae01a31e8b31c046deb8..3a520a54a3e2ff5eee997eb6214035b7f41490e9 100644 (file)
@@ -65,6 +65,7 @@ typedef enum {
     FEAT_C_COMMENTS,
     FEAT_FORCE_RANGE,
     FEAT_UNDERLINE_IN_NUMBERS,
+    FEAT_ADDRSIZE,
 
     /* Special value: Number of features available */
     FEAT_COUNT
index b3d6d6c6ed5190e91512e4dc08886e14bac9826f..77ed66e7f5306d4fa4d1cb2c9f0ca9fb1d7105ee 100644 (file)
@@ -82,3 +82,4 @@ unsigned char OrgPerSeg          = 0;   /* Make .org local to current seg */
 unsigned char CComments          = 0;   /* Allow C like comments */
 unsigned char ForceRange         = 0;   /* Force values into expected range */
 unsigned char UnderlineInNumbers = 0;   /* Allow underlines in numbers */
+unsigned char AddrSize           = 0;   /* Allow .ADDRSIZE function */
index 378a776e651e7e9fd6af8d8e341b3c80706fb0ec..fb254f835342f13a07379c36ab0555395c4c66ec 100644 (file)
@@ -84,6 +84,8 @@ extern unsigned char    OrgPerSeg;          /* Make .org local to current seg */
 extern unsigned char    CComments;          /* Allow C like comments */
 extern unsigned char    ForceRange;         /* Force values into expected range */
 extern unsigned char    UnderlineInNumbers; /* Allow underlines in numbers */
+extern unsigned char    AddrSize;           /* Allow .ADDRSIZE function */
+
 
 
 
index 0b066c7bd9cc3b38ec1bae4f7b4d6f3493fe9d4b..2e8a473a5e745321d62ed591f0fff0ecbe72e118 100644 (file)
@@ -1964,6 +1964,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,           DoA16           },
     { ccNone,           DoA8            },
     { ccNone,           DoAddr          },      /* .ADDR */
+    { ccNone,           DoUnexpected    },      /* .ADDRSIZE */
     { ccNone,           DoAlign         },
     { ccNone,           DoASCIIZ        },
     { ccNone,           DoAssert        },
index 890e1c7a33c264434a65337a12612a48bf0fc444..9543c98726bfbbd5aab71613ed87c8f08e5ad461 100644 (file)
@@ -135,6 +135,7 @@ struct DotKeyword {
     { ".A16",           TOK_A16         },
     { ".A8",            TOK_A8          },
     { ".ADDR",          TOK_ADDR        },
+    { ".ADDRSIZE",      TOK_ADDRSIZE    },
     { ".ALIGN",         TOK_ALIGN       },
     { ".AND",           TOK_BOOLAND     },
     { ".ASCIIZ",        TOK_ASCIIZ      },
@@ -723,8 +724,24 @@ static token_t FindDotKeyword (void)
     R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
                  sizeof (DotKeywords [0]), CmpDotKeyword);
     if (R != 0) {
+
+        /* By default, disable any somewhat experiemental DotKeyword. */
+
+        switch (R->Tok) {
+
+            case TOK_ADDRSIZE:
+                /* Disallow .ADDRSIZE function by default */
+                if (AddrSize == 0) {
+                    return TOK_NONE;
+                }
+                break;
+
+            default:
+                break;
+        }
         return R->Tok;
-    } else {
+    }
+    else {
         return TOK_NONE;
     }
 }
index 803b12785d304cd93b3fd1e896f545f3f6411f4a..7aaba34c3315ba4a64db6d06f0f8d87a4ca104a5 100644 (file)
@@ -123,6 +123,7 @@ typedef enum token_t {
     TOK_A16             = TOK_FIRSTPSEUDO,
     TOK_A8,
     TOK_ADDR,
+    TOK_ADDRSIZE,
     TOK_ALIGN,
     TOK_ASCIIZ,
     TOK_ASSERT,