Added a .ORG keyword to ca65 structs/unions.

Allow 24-bit numbers as operands in ca65 structs/unions.
This commit is contained in:
Greg King
2019-09-11 17:55:49 -04:00
parent 3b128ba59f
commit 0896deedef
2 changed files with 111 additions and 71 deletions

View File

@@ -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.