#include "nexttok.h"
#include "objfile.h"
#include "segment.h"
-#include "struct.h"
+#include "sizeof.h"
#include "studyexpr.h"
#include "symbol.h"
#include "symtab.h"
+static ExprNode* Symbol (SymEntry* S)
+/* Reference a symbol and return an expression for it */
+{
+ if (S == 0) {
+ /* Some weird error happened before */
+ return GenLiteralExpr (0);
+ } else {
+ /* Mark the symbol as referenced */
+ SymRef (S);
+ /* Remove the symbol if possible */
+ if (SymHasExpr (S)) {
+ return CloneExpr (GetSymExpr (S));
+ } else {
+ /* Create symbol node */
+ return GenSymExpr (S);
+ }
+ }
+}
+
+
+
static ExprNode* FuncBlank (void)
/* Handle the .BLANK builtin function */
{
static ExprNode* FuncSizeOf (void)
/* Handle the .SIZEOF function */
{
- long Size;
-
/* Get the struct for the scoped struct name */
SymTable* Struct = ParseScopedSymTable (SYM_FIND_EXISTING);
/* Check if the given symbol is really a struct */
if (GetSymTabType (Struct) != ST_STRUCT) {
Error ("Argument to .SIZEOF is not a struct");
- Size = 1;
+ return GenLiteralExpr (0);
} else {
- Size = GetStructSize (Struct);
+ return Symbol (GetSizeOfScope (Struct));
}
-
- /* Return the size */
- return GenLiteralExpr (Size);
}
-static ExprNode* Symbol (SymEntry* S)
-/* Reference a symbol and return an expression for it */
-{
- if (S == 0) {
- /* Some weird error happened before */
- return GenLiteralExpr (0);
- } else {
- /* Mark the symbol as referenced */
- SymRef (S);
- /* Remove the symbol if possible */
- if (SymHasExpr (S)) {
- return CloneExpr (GetSymExpr (S));
- } else {
- /* Create symbol node */
- return GenSymExpr (S);
- }
- }
-}
-
-
-
static ExprNode* Factor (void)
{
ExprNode* L;
break;
case TOK_LOCAL_IDENT:
- N = Symbol (SymFindLocal (SVal, SYM_ALLOC_NEW));
+ N = Symbol (SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW));
NextTok ();
break;
if (Tok == TOK_IDENT) {
Sym = SymFind (CurrentScope, SVal, SYM_ALLOC_NEW);
} else {
- Sym = SymFindLocal (SVal, SYM_ALLOC_NEW);
+ Sym = SymFindLocal (SymLast, SVal, SYM_ALLOC_NEW);
}
NextTok ();
repeat.o \
scanner.o \
segment.o \
+ sizeof.o \
spool.o \
struct.o \
studyexpr.o \
repeat.obj \
scanner.obj \
segment.obj \
+ sizeof.obj \
spool.obj \
struct.obj \
studyexpr.obj \
--- /dev/null
+/*****************************************************************************/
+/* */
+/* sizeof.c */
+/* */
+/* Handle sizes of types and data */
+/* */
+/* */
+/* */
+/* (C) 2003 Ullrich von Bassewitz */
+/* Römerstraße 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+/* ca65 */
+#include "sizeof.h"
+#include "symtab.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* The name of the symbol used to encode the size. The name of this entry is
+ * choosen so that it cannot be accessed by the user.
+ */
+static const char SizeEntryName[] = ".size";
+
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+SymEntry* GetSizeOfScope (SymTable* Scope)
+/* Get the size of a scope. The function returns the symbol table entry that
+ * encodes the size, and will create a new entry if it does not exist.
+ */
+{
+ return SymFind (Scope, SizeEntryName, SYM_ALLOC_NEW);
+}
+
+
+
+SymEntry* GetSizeOfSymbol (SymEntry* Sym)
+/* Get the size of a symbol table entry. The function returns the symbol table
+ * entry that encodes the size of the symbol and will create a new one if it
+ * does not exist.
+ */
+{
+ return SymFindLocal (Sym, SizeEntryName, SYM_ALLOC_NEW);
+}
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* sizeof.h */
+/* */
+/* Handle sizes of types and data */
+/* */
+/* */
+/* */
+/* (C) 2003 Ullrich von Bassewitz */
+/* Römerstraße 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef SIZEOF_H
+#define SIZEOF_H
+
+
+
+/*****************************************************************************/
+/* Forwards */
+/*****************************************************************************/
+
+
+
+struct SymEntry;
+struct SymTable;
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+struct SymEntry* GetSizeOfScope (struct SymTable* Scope);
+/* Get the size of a scope. The function returns the symbol table entry that
+ * encodes the size, and will create a new entry if it does not exist.
+ */
+
+struct SymEntry* GetSizeOfSymbol (struct SymEntry* Sym);
+/* Get the size of a symbol table entry. The function returns the symbol table
+ * entry that encodes the size of the symbol and will create a new one if it
+ * does not exist.
+ */
+
+
+
+/* End of sizeof.h */
+#endif
+
+
+
#include "expr.h"
#include "nexttok.h"
#include "scanner.h"
+#include "sizeof.h"
#include "symbol.h"
#include "symtab.h"
#include "struct.h"
} else if (GetSymTabType (Struct) != ST_STRUCT) {
Error ("Not a struct/union");
} else {
- MemberSize = Member (GetStructSize (Struct));
+ SymEntry* SizeSym = GetSizeOfScope (Struct);
+ if (!SymIsDef (SizeSym)) {
+ Error ("Size of struct/union is unknown");
+ } else {
+ MemberSize = GetSymVal (SizeSym);
+ }
}
break;
*/
if (!Anon) {
/* Add a symbol */
- SymEntry* SizeSym = SymFind (CurrentScope, ".size", SYM_ALLOC_NEW);
+ SymEntry* SizeSym = GetSizeOfScope (CurrentScope);
SymDef (SizeSym, GenLiteralExpr (Size), ADDR_SIZE_DEFAULT, SF_NONE);
/* Close the struct scope */
-SymEntry* SymFindLocal (const char* Name, int AllocNew)
+SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew)
/* Find a cheap local symbol. If AllocNew is given and the entry is not
* found, create a new one. Return the entry found, or the new entry created,
* or - in case AllocNew is zero - return 0.
int Cmp;
/* Local symbol, get the table */
- if (!SymLast) {
+ if (!Parent) {
/* No last global, so there's no local table */
Error ("No preceeding global symbol");
if (AllocNew) {
}
/* Search for the symbol if we have a table */
- Cmp = SymSearchTree (SymLast->Locals, Name, &S);
+ Cmp = SymSearchTree (Parent->Locals, Name, &S);
/* If we found an entry, return it */
if (Cmp == 0) {
/* Otherwise create a new entry, insert and return it */
SymEntry* N = NewSymEntry (Name);
if (S == 0) {
- SymLast->Locals = N;
+ Parent->Locals = N;
} else if (Cmp < 0) {
S->Left = N;
} else {
* scope.
*/
-SymEntry* SymFindLocal (const char* Name, int AllocNew);
+SymEntry* SymFindLocal (SymEntry* Parent, const char* Name, int AllocNew);
/* Find a cheap local symbol. If AllocNew is given and the entry is not
* found, create a new one. Return the entry found, or the new entry created,
* or - in case AllocNew is zero - return 0.