mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 10:42:07 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe65e07cb6 | ||
|
|
bb12806da1 | ||
|
|
fa36042131 | ||
|
|
efaad99f25 | ||
|
|
62d820c261 | ||
|
|
a53d795361 | ||
|
|
2e60c4dd2e | ||
|
|
ce8a13a562 |
@@ -439,6 +439,7 @@ void if_skip_to_endc( void )
|
|||||||
|
|
||||||
%type <sVal> relocconst
|
%type <sVal> relocconst
|
||||||
%type <nConstValue> const
|
%type <nConstValue> const
|
||||||
|
%type <nConstValue> uconst
|
||||||
%type <nConstValue> const_3bit
|
%type <nConstValue> const_3bit
|
||||||
%type <sVal> const_8bit
|
%type <sVal> const_8bit
|
||||||
%type <sVal> const_16bit
|
%type <sVal> const_16bit
|
||||||
@@ -587,7 +588,11 @@ label : /* empty */
|
|||||||
else
|
else
|
||||||
sym_AddReloc($1);
|
sym_AddReloc($1);
|
||||||
} | T_LABEL ':' ':' {
|
} | T_LABEL ':' ':' {
|
||||||
sym_AddReloc($1);
|
if ($1[0] == '.') {
|
||||||
|
sym_AddLocalReloc($1);
|
||||||
|
} else {
|
||||||
|
sym_AddReloc($1);
|
||||||
|
}
|
||||||
sym_Export($1);
|
sym_Export($1);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -688,7 +693,7 @@ shift : T_POP_SHIFT
|
|||||||
{ sym_ShiftCurrentMacroArgs(); }
|
{ sym_ShiftCurrentMacroArgs(); }
|
||||||
;
|
;
|
||||||
|
|
||||||
rept : T_POP_REPT const
|
rept : T_POP_REPT uconst
|
||||||
{
|
{
|
||||||
copyrept();
|
copyrept();
|
||||||
fstk_RunRept( $2 );
|
fstk_RunRept( $2 );
|
||||||
@@ -706,7 +711,7 @@ equs : T_LABEL T_POP_EQUS string
|
|||||||
{ sym_AddString( $1, $3 ); }
|
{ sym_AddString( $1, $3 ); }
|
||||||
;
|
;
|
||||||
|
|
||||||
rsset : T_POP_RSSET const
|
rsset : T_POP_RSSET uconst
|
||||||
{ sym_AddSet( "_RS", $2 ); }
|
{ sym_AddSet( "_RS", $2 ); }
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -714,28 +719,28 @@ rsreset : T_POP_RSRESET
|
|||||||
{ sym_AddSet( "_RS", 0 ); }
|
{ sym_AddSet( "_RS", 0 ); }
|
||||||
;
|
;
|
||||||
|
|
||||||
rl : T_LABEL T_POP_RL const
|
rl : T_LABEL T_POP_RL uconst
|
||||||
{
|
{
|
||||||
sym_AddEqu( $1, sym_GetConstantValue("_RS") );
|
sym_AddEqu( $1, sym_GetConstantValue("_RS") );
|
||||||
sym_AddSet( "_RS", sym_GetConstantValue("_RS")+4*$3 );
|
sym_AddSet( "_RS", sym_GetConstantValue("_RS")+4*$3 );
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
rw : T_LABEL T_POP_RW const
|
rw : T_LABEL T_POP_RW uconst
|
||||||
{
|
{
|
||||||
sym_AddEqu( $1, sym_GetConstantValue("_RS") );
|
sym_AddEqu( $1, sym_GetConstantValue("_RS") );
|
||||||
sym_AddSet( "_RS", sym_GetConstantValue("_RS")+2*$3 );
|
sym_AddSet( "_RS", sym_GetConstantValue("_RS")+2*$3 );
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
rb : T_LABEL T_POP_RB const
|
rb : T_LABEL T_POP_RB uconst
|
||||||
{
|
{
|
||||||
sym_AddEqu( $1, sym_GetConstantValue("_RS") );
|
sym_AddEqu( $1, sym_GetConstantValue("_RS") );
|
||||||
sym_AddSet( "_RS", sym_GetConstantValue("_RS")+$3 );
|
sym_AddSet( "_RS", sym_GetConstantValue("_RS")+$3 );
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
ds : T_POP_DS const
|
ds : T_POP_DS uconst
|
||||||
{ out_Skip( $2 ); }
|
{ out_Skip( $2 ); }
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -817,7 +822,7 @@ include : T_POP_INCLUDE string
|
|||||||
|
|
||||||
incbin : T_POP_INCBIN string
|
incbin : T_POP_INCBIN string
|
||||||
{ out_BinaryFile( $2 ); }
|
{ out_BinaryFile( $2 ); }
|
||||||
| T_POP_INCBIN string ',' const ',' const
|
| T_POP_INCBIN string ',' uconst ',' uconst
|
||||||
{
|
{
|
||||||
out_BinaryFileSlice( $2, $4, $6 );
|
out_BinaryFileSlice( $2, $4, $6 );
|
||||||
}
|
}
|
||||||
@@ -1038,6 +1043,14 @@ relocconst : T_ID
|
|||||||
{ $$ = $2; }
|
{ $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
uconst : const
|
||||||
|
{
|
||||||
|
if($1 < 0)
|
||||||
|
fatalerror("Constant mustn't be negative: %d", $1);
|
||||||
|
$$=$1;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
const : T_ID { $$ = sym_GetConstantValue($1); }
|
const : T_ID { $$ = sym_GetConstantValue($1); }
|
||||||
| T_NUMBER { $$ = $1; }
|
| T_NUMBER { $$ = $1; }
|
||||||
| string { $$ = str2int($1); }
|
| string { $$ = str2int($1); }
|
||||||
@@ -1064,16 +1077,18 @@ const : T_ID { $$ = sym_GetConstantValue($1); }
|
|||||||
| const T_OP_SHL const { $$ = $1 << $3; }
|
| const T_OP_SHL const { $$ = $1 << $3; }
|
||||||
| const T_OP_SHR const { $$ = $1 >> $3; }
|
| const T_OP_SHR const { $$ = $1 >> $3; }
|
||||||
| const T_OP_MUL const { $$ = $1 * $3; }
|
| const T_OP_MUL const { $$ = $1 * $3; }
|
||||||
| const T_OP_DIV const {
|
| const T_OP_DIV const
|
||||||
if ($3 == 0)
|
{
|
||||||
fatalerror("division by zero");
|
if ($3 == 0)
|
||||||
$$ = $1 / $3;
|
fatalerror("division by zero");
|
||||||
}
|
$$ = $1 / $3;
|
||||||
| const T_OP_MOD const {
|
}
|
||||||
if ($3 == 0)
|
| const T_OP_MOD const
|
||||||
fatalerror("division by zero");
|
{
|
||||||
$$ = $1 % $3;
|
if ($3 == 0)
|
||||||
}
|
fatalerror("division by zero");
|
||||||
|
$$ = $1 % $3;
|
||||||
|
}
|
||||||
| T_OP_ADD const %prec NEG { $$ = +$2; }
|
| T_OP_ADD const %prec NEG { $$ = +$2; }
|
||||||
| T_OP_SUB const %prec NEG { $$ = -$2; }
|
| T_OP_SUB const %prec NEG { $$ = -$2; }
|
||||||
| T_OP_NOT const %prec NEG { $$ = 0xFFFFFFFF^$2; }
|
| T_OP_NOT const %prec NEG { $$ = 0xFFFFFFFF^$2; }
|
||||||
@@ -1109,7 +1124,7 @@ const : T_ID { $$ = sym_GetConstantValue($1); }
|
|||||||
|
|
||||||
string : T_STRING
|
string : T_STRING
|
||||||
{ strcpy($$,$1); }
|
{ strcpy($$,$1); }
|
||||||
| T_OP_STRSUB '(' string ',' const ',' const ')'
|
| T_OP_STRSUB '(' string ',' uconst ',' uconst ')'
|
||||||
{ strncpy($$,$3+$5-1,$7); $$[$7]=0; }
|
{ strncpy($$,$3+$5-1,$7); $$[$7]=0; }
|
||||||
| T_OP_STRCAT '(' string ',' string ')'
|
| T_OP_STRCAT '(' string ',' string ')'
|
||||||
{ strcpy($$,$3); strcat($$,$5); }
|
{ strcpy($$,$3); strcat($$,$5); }
|
||||||
@@ -1123,33 +1138,33 @@ section:
|
|||||||
{
|
{
|
||||||
out_NewSection($2,$4);
|
out_NewSection($2,$4);
|
||||||
}
|
}
|
||||||
| T_POP_SECTION string ',' sectiontype '[' const ']'
|
| T_POP_SECTION string ',' sectiontype '[' uconst ']'
|
||||||
{
|
{
|
||||||
if( $6>=0 && $6<0x10000 )
|
if( $6>=0 && $6<0x10000 )
|
||||||
out_NewAbsSection($2,$4,$6,-1);
|
out_NewAbsSection($2,$4,$6,-1);
|
||||||
else
|
else
|
||||||
yyerror("Address $%x not 16-bit", $6);
|
yyerror("Address $%x not 16-bit", $6);
|
||||||
}
|
}
|
||||||
| T_POP_SECTION string ',' sectiontype ',' T_OP_ALIGN '[' const ']'
|
| T_POP_SECTION string ',' sectiontype ',' T_OP_ALIGN '[' uconst ']'
|
||||||
{
|
{
|
||||||
out_NewAlignedSection($2, $4, $8, -1);
|
out_NewAlignedSection($2, $4, $8, -1);
|
||||||
}
|
}
|
||||||
| T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']'
|
| T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' uconst ']'
|
||||||
{
|
{
|
||||||
bankrangecheck($2, $4, -1, $8);
|
bankrangecheck($2, $4, -1, $8);
|
||||||
}
|
}
|
||||||
| T_POP_SECTION string ',' sectiontype '[' const ']' ',' T_OP_BANK '[' const ']'
|
| T_POP_SECTION string ',' sectiontype '[' uconst ']' ',' T_OP_BANK '[' uconst ']'
|
||||||
{
|
{
|
||||||
if ($6 < 0 || $6 > 0x10000) {
|
if ($6 < 0 || $6 > 0x10000) {
|
||||||
yyerror("Address $%x not 16-bit", $6);
|
yyerror("Address $%x not 16-bit", $6);
|
||||||
}
|
}
|
||||||
bankrangecheck($2, $4, $6, $11);
|
bankrangecheck($2, $4, $6, $11);
|
||||||
}
|
}
|
||||||
| T_POP_SECTION string ',' sectiontype ',' T_OP_ALIGN '[' const ']' ',' T_OP_BANK '[' const ']'
|
| T_POP_SECTION string ',' sectiontype ',' T_OP_ALIGN '[' uconst ']' ',' T_OP_BANK '[' uconst ']'
|
||||||
{
|
{
|
||||||
out_NewAlignedSection($2, $4, $8, $13);
|
out_NewAlignedSection($2, $4, $8, $13);
|
||||||
}
|
}
|
||||||
| T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']' ',' T_OP_ALIGN '[' const ']'
|
| T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' uconst ']' ',' T_OP_ALIGN '[' uconst ']'
|
||||||
{
|
{
|
||||||
out_NewAlignedSection($2, $4, $13, $8);
|
out_NewAlignedSection($2, $4, $13, $8);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -475,6 +475,7 @@ setuplex(void)
|
|||||||
lex_FloatAddSecondRange(id, '\\', '\\');
|
lex_FloatAddSecondRange(id, '\\', '\\');
|
||||||
lex_FloatAddSecondRange(id, '@', '@');
|
lex_FloatAddSecondRange(id, '@', '@');
|
||||||
lex_FloatAddSecondRange(id, '#', '#');
|
lex_FloatAddSecondRange(id, '#', '#');
|
||||||
|
lex_FloatAddRange(id, '.', '.');
|
||||||
lex_FloatAddRange(id, 'a', 'z');
|
lex_FloatAddRange(id, 'a', 'z');
|
||||||
lex_FloatAddRange(id, 'A', 'Z');
|
lex_FloatAddRange(id, 'A', 'Z');
|
||||||
lex_FloatAddRange(id, '0', '9');
|
lex_FloatAddRange(id, '0', '9');
|
||||||
|
|||||||
@@ -260,11 +260,7 @@ writesymbol(struct sSymbol * pSym, FILE * f)
|
|||||||
sectid = -1;
|
sectid = -1;
|
||||||
type = SYM_IMPORT;
|
type = SYM_IMPORT;
|
||||||
} else {
|
} else {
|
||||||
if (pSym->nType & SYMF_LOCAL) {
|
strcpy(symname, pSym->tzName);
|
||||||
strcpy(symname, pSym->pScope->tzName);
|
|
||||||
strcat(symname, pSym->tzName);
|
|
||||||
} else
|
|
||||||
strcpy(symname, pSym->tzName);
|
|
||||||
|
|
||||||
if (pSym->nType & SYMF_EXPORT) {
|
if (pSym->nType & SYMF_EXPORT) {
|
||||||
/* Symbol should be exported */
|
/* Symbol should be exported */
|
||||||
|
|||||||
@@ -223,13 +223,17 @@ GlobalLabel
|
|||||||
AnotherGlobal:
|
AnotherGlobal:
|
||||||
\&.locallabel
|
\&.locallabel
|
||||||
\&.yet_a_local:
|
\&.yet_a_local:
|
||||||
|
AnotherGlobal.with_another_local:
|
||||||
ThisWillBeExported:: ;note the two colons
|
ThisWillBeExported:: ;note the two colons
|
||||||
|
ThisWillBeExported.too::
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
In the line where a label is defined there musn't be any whitespace before it.
|
In the line where a label is defined there musn't be any whitespace before it.
|
||||||
Local labels are only accessible within the scope they are defined.
|
Local labels are only accessible within the scope they are defined.
|
||||||
A scope starts after a global label and ends at the next global label.
|
A scope starts after a global label and ends at the next global label.
|
||||||
Declaring a normal label with :: does an EXPORT at the same time.
|
Declaring a label (global or local) with :: does an EXPORT at the same time.
|
||||||
|
Local labels can be declared as scope.local or simply as as .local.
|
||||||
|
If the former notation is used, the scope must be the actual current scope.
|
||||||
.Pp
|
.Pp
|
||||||
Labels will normally change their value during the link process and are thus not
|
Labels will normally change their value during the link process and are thus not
|
||||||
constant.
|
constant.
|
||||||
@@ -303,6 +307,8 @@ There are four commands in the RS group of commands:
|
|||||||
.Ic _RS No and adds Ar constexpr No to Ic _RS .
|
.Ic _RS No and adds Ar constexpr No to Ic _RS .
|
||||||
.It Ic RW Ar constexpr Ta Sets the preceding symbol to
|
.It Ic RW Ar constexpr Ta Sets the preceding symbol to
|
||||||
.Ic _RS No and adds Ar constexpr No * 2 to Ic _RS.
|
.Ic _RS No and adds Ar constexpr No * 2 to Ic _RS.
|
||||||
|
.It Ic RL Ar constexpr Ta Sets the preceding symbol to
|
||||||
|
.Ic _RS No and adds Ar constexpr No * 4 to Ic _RS.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
Note that a colon (:) following the symbol-name is not allowed.
|
Note that a colon (:) following the symbol-name is not allowed.
|
||||||
@@ -992,6 +998,7 @@ machine.
|
|||||||
.It Sx PUSHS
|
.It Sx PUSHS
|
||||||
.It Sx REPT
|
.It Sx REPT
|
||||||
.It Sx RB
|
.It Sx RB
|
||||||
|
.It Sx RL
|
||||||
.It Sx ROM0
|
.It Sx ROM0
|
||||||
.It Sx ROMX
|
.It Sx ROMX
|
||||||
.It Sx RSRESET
|
.It Sx RSRESET
|
||||||
|
|||||||
121
src/asm/symbol.c
121
src/asm/symbol.c
@@ -114,26 +114,16 @@ createsymbol(char *s)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find a symbol by name and scope
|
* Creates the full name of a local symbol in a given scope, by prepending
|
||||||
|
* the name with the parent symbol's name.
|
||||||
*/
|
*/
|
||||||
struct sSymbol *
|
size_t
|
||||||
findsymbol(char *s, struct sSymbol * scope)
|
fullSymbolName(char *output, size_t outputSize, char *localName, struct sSymbol *scope)
|
||||||
{
|
{
|
||||||
struct sSymbol **ppsym;
|
struct sSymbol *parent = scope->pScope ? scope->pScope : scope;
|
||||||
SLONG hash;
|
return snprintf(output, outputSize, "%s%s", parent->tzName, localName);
|
||||||
|
|
||||||
hash = calchash(s);
|
|
||||||
ppsym = &(tHashedSymbols[hash]);
|
|
||||||
|
|
||||||
while ((*ppsym) != NULL) {
|
|
||||||
if ((strcmp(s, (*ppsym)->tzName) == 0)
|
|
||||||
&& ((*ppsym)->pScope == scope)) {
|
|
||||||
return (*ppsym);
|
|
||||||
} else
|
|
||||||
ppsym = &((*ppsym)->pNext);
|
|
||||||
}
|
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -144,13 +134,25 @@ findpsymbol(char *s, struct sSymbol * scope)
|
|||||||
{
|
{
|
||||||
struct sSymbol **ppsym;
|
struct sSymbol **ppsym;
|
||||||
SLONG hash;
|
SLONG hash;
|
||||||
|
char fullname[MAXSYMLEN + 1];
|
||||||
|
|
||||||
|
if (s[0] == '.' && scope) {
|
||||||
|
fullSymbolName(fullname, sizeof(fullname), s, scope);
|
||||||
|
s = fullname;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *seperator;
|
||||||
|
if ((seperator = strchr(s, '.'))) {
|
||||||
|
if (strchr(seperator + 1, '.')) {
|
||||||
|
fatalerror("'%s' is a nonsensical reference to a nested local symbol", s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hash = calchash(s);
|
hash = calchash(s);
|
||||||
ppsym = &(tHashedSymbols[hash]);
|
ppsym = &(tHashedSymbols[hash]);
|
||||||
|
|
||||||
while ((*ppsym) != NULL) {
|
while ((*ppsym) != NULL) {
|
||||||
if ((strcmp(s, (*ppsym)->tzName) == 0)
|
if ((strcmp(s, (*ppsym)->tzName) == 0)) {
|
||||||
&& ((*ppsym)->pScope == scope)) {
|
|
||||||
return (ppsym);
|
return (ppsym);
|
||||||
} else
|
} else
|
||||||
ppsym = &((*ppsym)->pNext);
|
ppsym = &((*ppsym)->pNext);
|
||||||
@@ -158,6 +160,16 @@ findpsymbol(char *s, struct sSymbol * scope)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find a symbol by name and scope
|
||||||
|
*/
|
||||||
|
struct sSymbol *
|
||||||
|
findsymbol(char *s, struct sSymbol * scope)
|
||||||
|
{
|
||||||
|
struct sSymbol **ppsym = findpsymbol(s, scope);
|
||||||
|
return ppsym ? *ppsym : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find a symbol by name and scope
|
* Find a symbol by name and scope
|
||||||
*/
|
*/
|
||||||
@@ -593,31 +605,17 @@ sym_AddSet(char *tzSym, SLONG value)
|
|||||||
void
|
void
|
||||||
sym_AddLocalReloc(char *tzSym)
|
sym_AddLocalReloc(char *tzSym)
|
||||||
{
|
{
|
||||||
if ((nPass == 1)
|
if (pScope) {
|
||||||
|| ((nPass == 2) && (sym_isDefined(tzSym) == 0))) {
|
if (strlen(tzSym) + strlen(pScope->tzName) > MAXSYMLEN) {
|
||||||
/* only add local reloc symbols in pass 1 */
|
fatalerror("Symbol too long");
|
||||||
struct sSymbol *nsym;
|
}
|
||||||
|
|
||||||
if (pScope) {
|
char fullname[MAXSYMLEN + 1];
|
||||||
if ((nsym = findsymbol(tzSym, pScope)) != NULL) {
|
fullSymbolName(fullname, sizeof(fullname), tzSym, pScope);
|
||||||
if (nsym->nType & SYMF_DEFINED) {
|
sym_AddReloc(fullname);
|
||||||
yyerror("'%s' already defined", tzSym);
|
|
||||||
}
|
} else {
|
||||||
} else
|
fatalerror("Local label in main scope");
|
||||||
nsym = createsymbol(tzSym);
|
|
||||||
|
|
||||||
if (nsym) {
|
|
||||||
nsym->nValue = nPC;
|
|
||||||
nsym->nType |=
|
|
||||||
SYMF_RELOC | SYMF_LOCAL | SYMF_DEFINED;
|
|
||||||
if (exportall) {
|
|
||||||
nsym->nType |= SYMF_EXPORT;
|
|
||||||
}
|
|
||||||
nsym->pScope = pScope;
|
|
||||||
nsym->pSection = pCurrentSection;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
fatalerror("Local label in main scope");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,12 +625,32 @@ sym_AddLocalReloc(char *tzSym)
|
|||||||
void
|
void
|
||||||
sym_AddReloc(char *tzSym)
|
sym_AddReloc(char *tzSym)
|
||||||
{
|
{
|
||||||
|
struct sSymbol* scope = NULL;
|
||||||
|
|
||||||
if ((nPass == 1)
|
if ((nPass == 1)
|
||||||
|| ((nPass == 2) && (sym_isDefined(tzSym) == 0))) {
|
|| ((nPass == 2) && (sym_isDefined(tzSym) == 0))) {
|
||||||
/* only add reloc symbols in pass 1 */
|
/* only add reloc symbols in pass 1 */
|
||||||
struct sSymbol *nsym;
|
struct sSymbol *nsym;
|
||||||
|
char *localPtr = NULL;
|
||||||
|
|
||||||
|
if ((localPtr = strchr(tzSym, '.')) != NULL) {
|
||||||
|
if (!pScope) {
|
||||||
|
fatalerror("Local label in main scope");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sSymbol *parent = pScope->pScope ? pScope->pScope : pScope;
|
||||||
|
int parentLen = localPtr - tzSym;
|
||||||
|
|
||||||
|
if (strchr(localPtr + 1, '.') != NULL) {
|
||||||
|
fatalerror("'%s' is a nonsensical reference to a nested local symbol", tzSym);
|
||||||
|
} else if (strlen(parent->tzName) != parentLen || strncmp(tzSym, parent->tzName, parentLen) != 0) {
|
||||||
|
yyerror("Not currently in the scope of '%.*s'", parentLen, tzSym);
|
||||||
|
}
|
||||||
|
|
||||||
|
scope = parent;
|
||||||
|
}
|
||||||
|
|
||||||
if ((nsym = findsymbol(tzSym, NULL)) != NULL) {
|
if ((nsym = findsymbol(tzSym, scope)) != NULL) {
|
||||||
if (nsym->nType & SYMF_DEFINED) {
|
if (nsym->nType & SYMF_DEFINED) {
|
||||||
yyerror("'%s' already defined", tzSym);
|
yyerror("'%s' already defined", tzSym);
|
||||||
}
|
}
|
||||||
@@ -642,14 +660,17 @@ sym_AddReloc(char *tzSym)
|
|||||||
if (nsym) {
|
if (nsym) {
|
||||||
nsym->nValue = nPC;
|
nsym->nValue = nPC;
|
||||||
nsym->nType |= SYMF_RELOC | SYMF_DEFINED;
|
nsym->nType |= SYMF_RELOC | SYMF_DEFINED;
|
||||||
|
if (localPtr) {
|
||||||
|
nsym->nType |= SYMF_LOCAL;
|
||||||
|
}
|
||||||
if (exportall) {
|
if (exportall) {
|
||||||
nsym->nType |= SYMF_EXPORT;
|
nsym->nType |= SYMF_EXPORT;
|
||||||
}
|
}
|
||||||
nsym->pScope = NULL;
|
nsym->pScope = scope;
|
||||||
nsym->pSection = pCurrentSection;
|
nsym->pSection = pCurrentSection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pScope = findsymbol(tzSym, NULL);
|
pScope = findsymbol(tzSym, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -705,7 +726,7 @@ sym_Export(char *tzSym)
|
|||||||
/* only export symbols in pass 1 */
|
/* only export symbols in pass 1 */
|
||||||
struct sSymbol *nsym;
|
struct sSymbol *nsym;
|
||||||
|
|
||||||
if ((nsym = findsymbol(tzSym, 0)) == NULL)
|
if ((nsym = sym_FindSymbol(tzSym)) == NULL)
|
||||||
nsym = createsymbol(tzSym);
|
nsym = createsymbol(tzSym);
|
||||||
|
|
||||||
if (nsym)
|
if (nsym)
|
||||||
@@ -713,7 +734,7 @@ sym_Export(char *tzSym)
|
|||||||
} else {
|
} else {
|
||||||
struct sSymbol *nsym;
|
struct sSymbol *nsym;
|
||||||
|
|
||||||
if ((nsym = findsymbol(tzSym, 0)) != NULL) {
|
if ((nsym = sym_FindSymbol(tzSym)) != NULL) {
|
||||||
if (nsym->nType & SYMF_DEFINED)
|
if (nsym->nType & SYMF_DEFINED)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -732,7 +753,7 @@ sym_Global(char *tzSym)
|
|||||||
/* only globalize symbols in pass 2 */
|
/* only globalize symbols in pass 2 */
|
||||||
struct sSymbol *nsym;
|
struct sSymbol *nsym;
|
||||||
|
|
||||||
nsym = findsymbol(tzSym, 0);
|
nsym = sym_FindSymbol(tzSym);
|
||||||
|
|
||||||
if ((nsym == NULL) || ((nsym->nType & SYMF_DEFINED) == 0)) {
|
if ((nsym == NULL) || ((nsym->nType & SYMF_DEFINED) == 0)) {
|
||||||
if (nsym == NULL)
|
if (nsym == NULL)
|
||||||
|
|||||||
6
test/asm/local-wrong-parent.asm
Normal file
6
test/asm/local-wrong-parent.asm
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
SECTION "sec", ROM0
|
||||||
|
|
||||||
|
Parent:
|
||||||
|
db 0
|
||||||
|
WrongParent.child
|
||||||
|
db 0
|
||||||
3
test/asm/local-wrong-parent.out
Normal file
3
test/asm/local-wrong-parent.out
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
ERROR: local-wrong-parent.asm(5):
|
||||||
|
Not currently in the scope of 'WrongParent'
|
||||||
|
error: Assembly aborted in pass 1 (1 errors)!
|
||||||
7
test/asm/remote-local-explicit.asm
Normal file
7
test/asm/remote-local-explicit.asm
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
SECTION "sec", ROM0
|
||||||
|
|
||||||
|
Parent:
|
||||||
|
Parent.child::
|
||||||
|
db 0
|
||||||
|
NotParent:
|
||||||
|
dw Parent.child
|
||||||
0
test/asm/remote-local-explicit.out
Normal file
0
test/asm/remote-local-explicit.out
Normal file
7
test/asm/remote-local-noexist.asm
Normal file
7
test/asm/remote-local-noexist.asm
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
SECTION "sec", ROM0
|
||||||
|
|
||||||
|
Parent:
|
||||||
|
.child:
|
||||||
|
db 0
|
||||||
|
NotParent:
|
||||||
|
dw Parent.child.fail
|
||||||
2
test/asm/remote-local-noexist.out
Normal file
2
test/asm/remote-local-noexist.out
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ERROR: remote-local-noexist.asm(7):
|
||||||
|
'Parent.child.fail' is a nonsensical reference to a nested local symbol
|
||||||
7
test/asm/remote-local.asm
Normal file
7
test/asm/remote-local.asm
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
SECTION "sec", ROM0
|
||||||
|
|
||||||
|
Parent:
|
||||||
|
.child:
|
||||||
|
db 0
|
||||||
|
NotParent:
|
||||||
|
dw Parent.child
|
||||||
0
test/asm/remote-local.out
Normal file
0
test/asm/remote-local.out
Normal file
Reference in New Issue
Block a user