long Size;
- /* Parse the scope and the name */
- SymTable* ParentScope = ParseScopedIdent (Name, &FullName);
+ if (Tok == TOK_LOCAL_IDENT) {
- /* Check if the parent scope is valid */
- if (ParentScope == 0) {
- /* No such scope */
- DoneStrBuf (&FullName);
- return GenLiteralExpr (0);
- }
+ /* Cheap local symbol, special handling */
+ Sym = SymFindLocal (SymLast, SVal, SYM_FIND_EXISTING);
+ if (Sym == 0) {
+ Error ("Unknown symbol or scope: `%s'", SB_GetConstBuf (&FullName));
+ return GenLiteralExpr (0);
+ } else {
+ SizeSym = GetSizeOfSymbol (Sym);
+ }
- /* The scope is valid, search first for a child scope, then for a symbol */
- if ((Scope = SymFindScope (ParentScope, Name, SYM_FIND_EXISTING)) != 0) {
- /* Yep, it's a scope */
- SizeSym = GetSizeOfScope (Scope);
- } else if ((Sym = SymFind (ParentScope, Name, SYM_FIND_EXISTING)) != 0) {
- SizeSym = GetSizeOfSymbol (Sym);
} else {
- Error ("Unknown symbol or scope: `%s'", SB_GetConstBuf (&FullName));
- return GenLiteralExpr (0);
+
+ /* Parse the scope and the name */
+ SymTable* ParentScope = ParseScopedIdent (Name, &FullName);
+
+ /* Check if the parent scope is valid */
+ if (ParentScope == 0) {
+ /* No such scope */
+ DoneStrBuf (&FullName);
+ return GenLiteralExpr (0);
+ }
+
+ /* The scope is valid, search first for a child scope, then for a symbol */
+ if ((Scope = SymFindScope (ParentScope, Name, SYM_FIND_EXISTING)) != 0) {
+ /* Yep, it's a scope */
+ SizeSym = GetSizeOfScope (Scope);
+ } else if ((Sym = SymFind (ParentScope, Name, SYM_FIND_EXISTING)) != 0) {
+ SizeSym = GetSizeOfSymbol (Sym);
+ } else {
+ Error ("Unknown symbol or scope: `%s'", SB_GetConstBuf (&FullName));
+ return GenLiteralExpr (0);
+ }
}
/* Check if we have a size */
static void OneLine (void)
/* Assemble one line */
-{
+{
Segment* Seg = 0;
unsigned long PC = 0;
SymEntry* Sym = 0;
NextTok ();
if (Tok != TOK_EQ) {
Error ("`=' expected");
- SkipUntilSep ();
- } else {
- /* Skip the equal sign */
- NextTok ();
- /* Enter absolute mode */
- DoPCAssign ();
- }
- }
+ SkipUntilSep ();
+ } else {
+ /* Skip the equal sign */
+ NextTok ();
+ /* Enter absolute mode */
+ DoPCAssign ();
+ }
+ }
/* If we have defined a label, remember its size. Sym is also set by
* a symbol assignment, but in this case Done is false, so we don't
#include "addrsize.h"
/* ca65 */
+#include "expr.h"
#include "sizeof.h"
#include "symtab.h"
{
SymEntry* SizeSym = GetSizeOfScope (Scope);
SymDef (SizeSym, GenLiteralExpr (Size), ADDR_SIZE_DEFAULT, SF_NONE);
+ return SizeSym;
}
{
SymEntry* SizeSym = GetSizeOfSymbol (Sym);
SymDef (SizeSym, GenLiteralExpr (Size), ADDR_SIZE_DEFAULT, SF_NONE);
+ return SizeSym;
}
NextTok ();
}
}
-
+
SymEntry* ParseScopedSymName (int AllocNew)
* symbol.
*/
if (AllocNew) {
- return NewSymEntry (Ident);
+ return NewSymEntry (Ident, SF_NONE);
} else {
return 0;
}
-int IsLocalName (const char* Name)
-/* Return true if Name is the name of a local symbol */
-{
- return (*Name == LocalStart);
-}
-
-
-
-int IsLocalNameId (unsigned Name)
-/* Return true if Name is the name of a local symbol */
-{
- return (*GetString (Name) == LocalStart);
-}
-
-
-
-SymEntry* NewSymEntry (const char* Name)
+SymEntry* NewSymEntry (const char* Name, unsigned Flags)
/* Allocate a symbol table entry, initialize and return it */
{
/* Allocate memory */
S->Locals = 0;
S->SymTab = 0;
S->Pos = CurPos;
- S->Flags = 0;
+ S->Flags = Flags;
S->V.Expr = 0;
S->ExprRefs = AUTO_COLLECTION_INITIALIZER;
S->ExportSize = ADDR_SIZE_DEFAULT;
}
/* If this is not a local symbol, remember it as the last global one */
- if (!IsLocalNameId (S->Name)) {
+ if ((S->Flags & SF_LOCAL) == 0) {
SymLast = S;
}
}
#define SF_EXPORT 0x0004 /* Export this symbol */
#define SF_IMPORT 0x0008 /* Import this symbol */
#define SF_GLOBAL 0x0010 /* Global symbol */
+#define SF_LOCAL 0x0020 /* Cheap local symbol */
#define SF_LABEL 0x0080 /* Used as a label */
#define SF_FORCED 0x0100 /* Forced import, SF_IMPORT also set */
#define SF_INDEXED 0x0800 /* Index is valid */
unsigned Flags; /* Symbol flags */
unsigned Index; /* Index of import/export entries */
union {
- struct ExprNode* Expr; /* Expression if CONST not set */
- long Val; /* Value (if CONST set) */
+ struct ExprNode* Expr; /* Symbol expression */
SymEntry* Sym; /* Symbol (if trampoline entry) */
} V;
Collection ExprRefs; /* Expressions using this symbol */
unsigned char ExportSize; /* Export address size */
unsigned char AddrSize; /* Address size of label */
- unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
+ unsigned char ConDesPrio[CD_TYPE_COUNT]; /* ConDes priorities... */
/* ...actually value+1 (used as flag) */
unsigned Name; /* Name index in global string pool */
};
-int IsLocalName (const char* Name);
-/* Return true if Name is the name of a local symbol */
-
-int IsLocalNameId (unsigned Name);
-/* Return true if Name is the name of a local symbol */
-
-SymEntry* NewSymEntry (const char* Name);
+SymEntry* NewSymEntry (const char* Name, unsigned Flags);
/* Allocate a symbol table entry, initialize and return it */
int SymSearchTree (SymEntry* T, const char* Name, SymEntry** E);
/* No last global, so there's no local table */
Error ("No preceeding global symbol");
if (AllocNew) {
- return NewSymEntry (Name);
+ return NewSymEntry (Name, SF_LOCAL);
} else {
return 0;
}
if (AllocNew) {
/* Otherwise create a new entry, insert and return it */
- SymEntry* N = NewSymEntry (Name);
+ SymEntry* N = NewSymEntry (Name, SF_LOCAL);
if (S == 0) {
Parent->Locals = N;
} else if (Cmp < 0) {
if (AllocNew) {
/* Otherwise create a new entry, insert and return it */
- SymEntry* N = NewSymEntry (Name);
+ SymEntry* N = NewSymEntry (Name, SF_NONE);
if (S == 0) {
Scope->Table[Hash] = N;
} else if (Cmp < 0) {
* enclosing scope for a symbol with the same name, and return the ZP
* attribute of this symbol if we find one.
*/
- if (!IsLocalNameId (S->Name) && (S->Flags & (SF_DEFINED | SF_IMPORT)) == 0 &&
+ if ((S->Flags & (SF_DEFINED | SF_IMPORT | SF_LOCAL)) == 0 &&
S->SymTab->Parent != 0) {
/* Try to find a symbol with the same name in the enclosing scope */