Added a .ORG keyword to ca65 structs/unions.
Allow 24-bit numbers as operands in ca65 structs/unions.
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
/* .STRUCT/.UNION commands */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2003-2011, Ullrich von Bassewitz */
|
||||
/* Roemerstrasse 52 */
|
||||
/* D-70794 Filderstadt */
|
||||
@@ -73,20 +72,20 @@ enum {
|
||||
static long Member (long AllocSize)
|
||||
/* Read one struct member and return its size */
|
||||
{
|
||||
long Multiplicator;
|
||||
long Multiplier;
|
||||
|
||||
/* A multiplicator may follow */
|
||||
/* A multiplier may follow */
|
||||
if (CurTok.Tok != TOK_SEP) {
|
||||
Multiplicator = ConstExpression ();
|
||||
if (Multiplicator <= 0) {
|
||||
Multiplier = ConstExpression ();
|
||||
if (Multiplier <= 0) {
|
||||
ErrorSkip ("Range error");
|
||||
Multiplicator = 1;
|
||||
Multiplier = 1;
|
||||
}
|
||||
AllocSize *= Multiplicator;
|
||||
AllocSize *= Multiplier;
|
||||
}
|
||||
|
||||
/* Check the size for a reasonable value */
|
||||
if (AllocSize >= 0x10000) {
|
||||
if (AllocSize >= 0x1000000) {
|
||||
ErrorSkip ("Range error");
|
||||
}
|
||||
|
||||
@@ -102,10 +101,11 @@ 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
|
||||
** 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 (&CurTok.SVal, SCOPE_STRUCT, ADDR_SIZE_ABS, 0);
|
||||
@@ -121,7 +121,6 @@ static long DoStructInternal (long Offs, unsigned Type)
|
||||
while (CurTok.Tok != TOK_ENDSTRUCT &&
|
||||
CurTok.Tok != TOK_ENDUNION &&
|
||||
CurTok.Tok != TOK_EOF) {
|
||||
|
||||
long MemberSize;
|
||||
SymTable* Struct;
|
||||
SymEntry* Sym;
|
||||
@@ -132,14 +131,14 @@ static long DoStructInternal (long Offs, unsigned Type)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* The format is "[identifier] storage-allocator [, multiplicator]" */
|
||||
/* The format is "[identifier ].storage-allocator[ multiplier]" */
|
||||
Sym = 0;
|
||||
if (CurTok.Tok == TOK_IDENT) {
|
||||
|
||||
/* Beware: An identifier may also be a macro, in which case we have
|
||||
** to start over.
|
||||
/* Beware: An identifier may be a macro also;
|
||||
** in which case, we must start over.
|
||||
*/
|
||||
Macro* M = FindMacro (&CurTok.SVal);
|
||||
|
||||
if (M) {
|
||||
MacExpandStart (M);
|
||||
continue;
|
||||
@@ -155,10 +154,9 @@ static long DoStructInternal (long Offs, unsigned Type)
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* Read storage allocators */
|
||||
MemberSize = 0; /* In case of errors, use zero */
|
||||
/* Read the storage allocator */
|
||||
MemberSize = 0; /* In case of errors or .ORG, use zero */
|
||||
switch (CurTok.Tok) {
|
||||
|
||||
case TOK_BYTE:
|
||||
NextTok ();
|
||||
MemberSize = Member (1);
|
||||
@@ -190,6 +188,15 @@ static long DoStructInternal (long Offs, unsigned Type)
|
||||
}
|
||||
break;
|
||||
|
||||
case TOK_ORG:
|
||||
NextTok ();
|
||||
if (CurTok.Tok == TOK_SEP) {
|
||||
ErrorSkip ("Address is missing");
|
||||
} else {
|
||||
Offs = Member (1);
|
||||
}
|
||||
break;
|
||||
|
||||
case TOK_TAG:
|
||||
NextTok ();
|
||||
Struct = ParseScopedSymTable ();
|
||||
@@ -244,8 +251,8 @@ static long DoStructInternal (long Offs, unsigned Type)
|
||||
ConsumeSep ();
|
||||
}
|
||||
|
||||
/* 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
|
||||
/* If this is not an 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.
|
||||
|
||||
Reference in New Issue
Block a user