Merge branch 'master' into macexpand
This commit is contained in:
@@ -133,24 +133,26 @@ static void SetIfCond (IfDesc* ID, int C)
|
||||
|
||||
|
||||
|
||||
static void ElseClause (IfDesc* ID, const char* Directive)
|
||||
/* Enter an .ELSE clause */
|
||||
static int ElseClause (IfDesc* ID, const char* Directive)
|
||||
/* Enter an .ELSE clause. Return true if this was ok, zero on errors. */
|
||||
{
|
||||
/* Check if we have an open .IF - otherwise .ELSE is not allowed */
|
||||
if (ID == 0) {
|
||||
Error ("Unexpected %s", Directive);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for a duplicate else, then remember that we had one */
|
||||
if (ID->Flags & ifElse) {
|
||||
/* We already had a .ELSE ! */
|
||||
Error ("Duplicate .ELSE");
|
||||
return 0;
|
||||
}
|
||||
ID->Flags |= ifElse;
|
||||
|
||||
/* Condition is inverted now */
|
||||
ID->Flags ^= ifCond;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -226,46 +228,52 @@ void DoConditionals (void)
|
||||
D = GetCurrentIf ();
|
||||
|
||||
/* Allow an .ELSE */
|
||||
ElseClause (D, ".ELSE");
|
||||
if (ElseClause (D, ".ELSE")) {
|
||||
/* Remember the data for the .ELSE */
|
||||
if (D) {
|
||||
ReleaseFullLineInfo (&D->LineInfos);
|
||||
GetFullLineInfo (&D->LineInfos);
|
||||
D->Name = ".ELSE";
|
||||
}
|
||||
|
||||
/* Remember the data for the .ELSE */
|
||||
if (D) {
|
||||
ReleaseFullLineInfo (&D->LineInfos);
|
||||
GetFullLineInfo (&D->LineInfos);
|
||||
D->Name = ".ELSE";
|
||||
/* Calculate the new overall condition */
|
||||
CalcOverallIfCond ();
|
||||
|
||||
/* Skip .ELSE */
|
||||
NextTok ();
|
||||
ExpectSep ();
|
||||
} else {
|
||||
/* Problem with .ELSE, ignore remainder of line */
|
||||
SkipUntilSep ();
|
||||
}
|
||||
|
||||
/* Calculate the new overall condition */
|
||||
CalcOverallIfCond ();
|
||||
|
||||
/* Skip .ELSE */
|
||||
NextTok ();
|
||||
ExpectSep ();
|
||||
break;
|
||||
|
||||
case TOK_ELSEIF:
|
||||
D = GetCurrentIf ();
|
||||
/* Handle as if there was an .ELSE first */
|
||||
ElseClause (D, ".ELSEIF");
|
||||
if (ElseClause (D, ".ELSEIF")) {
|
||||
/* Calculate the new overall if condition */
|
||||
CalcOverallIfCond ();
|
||||
|
||||
/* Calculate the new overall if condition */
|
||||
CalcOverallIfCond ();
|
||||
/* Allocate and prepare a new descriptor */
|
||||
D = AllocIf (".ELSEIF", 0);
|
||||
NextTok ();
|
||||
|
||||
/* Allocate and prepare a new descriptor */
|
||||
D = AllocIf (".ELSEIF", 0);
|
||||
NextTok ();
|
||||
/* Ignore the new condition if we are inside a false .ELSE
|
||||
** branch. This way we won't get any errors about undefined
|
||||
** symbols or similar...
|
||||
*/
|
||||
if (IfCond) {
|
||||
SetIfCond (D, ConstExpression ());
|
||||
ExpectSep ();
|
||||
}
|
||||
|
||||
/* Ignore the new condition if we are inside a false .ELSE
|
||||
** branch. This way we won't get any errors about undefined
|
||||
** symbols or similar...
|
||||
*/
|
||||
if (IfCond) {
|
||||
SetIfCond (D, ConstExpression ());
|
||||
ExpectSep ();
|
||||
/* Get the new overall condition */
|
||||
CalcOverallIfCond ();
|
||||
} else {
|
||||
/* Problem with .ELSEIF, ignore remainder of line */
|
||||
SkipUntilSep ();
|
||||
}
|
||||
|
||||
/* Get the new overall condition */
|
||||
CalcOverallIfCond ();
|
||||
break;
|
||||
|
||||
case TOK_ENDIF:
|
||||
|
||||
@@ -67,6 +67,7 @@ static const char* const FeatureKeys[FEAT_COUNT] = {
|
||||
"bracket_as_indirect",
|
||||
"string_escapes",
|
||||
"long_jsr_jmp_rts",
|
||||
"line_continuations",
|
||||
};
|
||||
|
||||
|
||||
@@ -121,6 +122,7 @@ void SetFeature (feature_t Feature, unsigned char On)
|
||||
case FEAT_BRACKET_AS_INDIRECT: BracketAsIndirect = On; break;
|
||||
case FEAT_STRING_ESCAPES: StringEscapes = On; break;
|
||||
case FEAT_LONG_JSR_JMP_RTS: LongJsrJmpRts = On; break;
|
||||
case FEAT_LINE_CONTINUATIONS: LineCont = On; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ typedef enum {
|
||||
FEAT_BRACKET_AS_INDIRECT,
|
||||
FEAT_STRING_ESCAPES,
|
||||
FEAT_LONG_JSR_JMP_RTS,
|
||||
FEAT_LINE_CONTINUATIONS,
|
||||
|
||||
/* Special value: Number of features available */
|
||||
FEAT_COUNT
|
||||
|
||||
@@ -169,6 +169,7 @@ static const struct {
|
||||
unsigned Count;
|
||||
InsDesc Ins[56];
|
||||
} InsTab6502 = {
|
||||
/* CAUTION: table must be sorted for bsearch */
|
||||
sizeof (InsTab6502.Ins) / sizeof (InsTab6502.Ins[0]),
|
||||
{
|
||||
{ "ADC", 0x080A26C, 0x60, 0, PutAll },
|
||||
@@ -235,6 +236,7 @@ static const struct {
|
||||
unsigned Count;
|
||||
InsDesc Ins[75];
|
||||
} InsTab6502X = {
|
||||
/* CAUTION: table must be sorted for bsearch */
|
||||
sizeof (InsTab6502X.Ins) / sizeof (InsTab6502X.Ins[0]),
|
||||
{
|
||||
{ "ADC", 0x080A26C, 0x60, 0, PutAll },
|
||||
@@ -324,6 +326,7 @@ static const struct {
|
||||
unsigned Count;
|
||||
InsDesc Ins[71];
|
||||
} InsTab6502DTV = {
|
||||
/* CAUTION: table must be sorted for bsearch */
|
||||
sizeof (InsTab6502DTV.Ins) / sizeof (InsTab6502DTV.Ins[0]),
|
||||
{
|
||||
{ "ADC", 0x080A26C, 0x60, 0, PutAll },
|
||||
@@ -405,6 +408,7 @@ static const struct {
|
||||
unsigned Count;
|
||||
InsDesc Ins[66];
|
||||
} InsTab65SC02 = {
|
||||
/* CAUTION: table must be sorted for bsearch */
|
||||
sizeof (InsTab65SC02.Ins) / sizeof (InsTab65SC02.Ins[0]),
|
||||
{
|
||||
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
||||
@@ -481,6 +485,7 @@ static const struct {
|
||||
unsigned Count;
|
||||
InsDesc Ins[100];
|
||||
} InsTab65C02 = {
|
||||
/* CAUTION: table must be sorted for bsearch */
|
||||
sizeof (InsTab65C02.Ins) / sizeof (InsTab65C02.Ins[0]),
|
||||
{
|
||||
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
||||
@@ -591,6 +596,7 @@ static const struct {
|
||||
unsigned Count;
|
||||
InsDesc Ins[133];
|
||||
} InsTab4510 = {
|
||||
/* CAUTION: table must be sorted for bsearch */
|
||||
sizeof (InsTab4510.Ins) / sizeof (InsTab4510.Ins[0]),
|
||||
{
|
||||
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
||||
@@ -734,6 +740,7 @@ static const struct {
|
||||
unsigned Count;
|
||||
InsDesc Ins[100];
|
||||
} InsTab65816 = {
|
||||
/* CAUTION: table must be sorted for bsearch */
|
||||
sizeof (InsTab65816.Ins) / sizeof (InsTab65816.Ins[0]),
|
||||
{
|
||||
{ "ADC", 0x0b8f6fc, 0x60, 0, PutAll },
|
||||
@@ -844,6 +851,7 @@ static const struct {
|
||||
unsigned Count;
|
||||
InsDesc Ins[26];
|
||||
} InsTabSweet16 = {
|
||||
/* CAUTION: table must be sorted for bsearch */
|
||||
sizeof (InsTabSweet16.Ins) / sizeof (InsTabSweet16.Ins[0]),
|
||||
{
|
||||
{ "ADD", AMSW16_REG, 0xA0, 0, PutSweet16 },
|
||||
@@ -880,6 +888,7 @@ static const struct {
|
||||
unsigned Count;
|
||||
InsDesc Ins[135];
|
||||
} InsTabHuC6280 = {
|
||||
/* CAUTION: table must be sorted for bsearch */
|
||||
sizeof (InsTabHuC6280.Ins) / sizeof (InsTabHuC6280.Ins[0]),
|
||||
{
|
||||
{ "ADC", 0x080A66C, 0x60, 0, PutAll },
|
||||
|
||||
@@ -162,3 +162,28 @@ unsigned GetStackDepth (void)
|
||||
{
|
||||
return ICount;
|
||||
}
|
||||
|
||||
|
||||
InputStack RetrieveInputStack (void)
|
||||
/* Retrieve the current input stack. This will also clear it. Used when
|
||||
** including a file. The current input stack is stored together with the old
|
||||
** input file and restored when the file is closed.
|
||||
*/
|
||||
{
|
||||
/* We do not touch the counter so input sources are counted across
|
||||
** includes.
|
||||
*/
|
||||
InputStack S = IStack;
|
||||
IStack = 0;
|
||||
return S;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RestoreInputStack (InputStack S)
|
||||
/* Restore an old input stack that was retrieved by RetrieveInputStack(). */
|
||||
{
|
||||
CHECK (IStack == 0);
|
||||
IStack = S;
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,17 @@
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Opaque pointer to an input stack */
|
||||
typedef void* InputStack;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
@@ -63,8 +74,20 @@ void CheckInputStack (void);
|
||||
** stuff on the input stack.
|
||||
*/
|
||||
|
||||
|
||||
unsigned GetStackDepth (void);
|
||||
|
||||
InputStack RetrieveInputStack (void);
|
||||
/* Retrieve the current input stack. This will also clear it. Used when
|
||||
** including a file. The current input stack is stored together with the old
|
||||
** input file and restored when the file is closed.
|
||||
*/
|
||||
|
||||
void RestoreInputStack (InputStack S);
|
||||
/* Restore an old input stack that was retrieved by RetrieveInputStack(). */
|
||||
|
||||
|
||||
|
||||
/* End of istack.h */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -719,6 +719,24 @@ static void OneLine (void)
|
||||
NextTok ();
|
||||
}
|
||||
|
||||
/* Handle @-style unnamed labels */
|
||||
if (CurTok.Tok == TOK_ULABEL) {
|
||||
if (CurTok.IVal != 0) {
|
||||
Error ("Invalid unnamed label definition");
|
||||
}
|
||||
ULabDef ();
|
||||
NextTok ();
|
||||
|
||||
/* Skip the colon. If NoColonLabels is enabled, allow labels without
|
||||
** a colon if there is no whitespace before the identifier.
|
||||
*/
|
||||
if (CurTok.Tok == TOK_COLON) {
|
||||
NextTok ();
|
||||
} else if (CurTok.WS || !NoColonLabels) {
|
||||
Error ("':' expected");
|
||||
}
|
||||
}
|
||||
|
||||
/* If the first token on the line is an identifier, check for a macro or
|
||||
** an instruction.
|
||||
*/
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "check.h"
|
||||
#include "filestat.h"
|
||||
#include "fname.h"
|
||||
#include "tgttrans.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
/* ca65 */
|
||||
@@ -113,6 +114,7 @@ struct CharSource {
|
||||
token_t Tok; /* Last token */
|
||||
int C; /* Last character */
|
||||
int SkipN; /* For '\r\n' line endings, skip '\n\ if next */
|
||||
InputStack IStack; /* Saved input stack */
|
||||
const CharSourceFunctions* Func; /* Pointer to function table */
|
||||
union {
|
||||
InputFile File; /* File data */
|
||||
@@ -129,6 +131,7 @@ static int C = 0; /* Current input character */
|
||||
int ForcedEnd = 0;
|
||||
|
||||
/* List of dot keywords with the corresponding tokens */
|
||||
/* CAUTION: table must be sorted for bsearch */
|
||||
struct DotKeyword {
|
||||
const char* Key; /* MUST be first field */
|
||||
token_t Tok;
|
||||
@@ -321,6 +324,9 @@ static void UseCharSource (CharSource* S)
|
||||
S->Tok = CurTok.Tok;
|
||||
S->C = C;
|
||||
|
||||
/* Remember the current input stack */
|
||||
S->IStack = RetrieveInputStack ();
|
||||
|
||||
/* Use the new input source */
|
||||
S->Next = Source;
|
||||
Source = S;
|
||||
@@ -347,7 +353,10 @@ static void DoneCharSource (void)
|
||||
|
||||
/* Restore the old token */
|
||||
CurTok.Tok = Source->Tok;
|
||||
C = Source->C;
|
||||
C = Source->C;
|
||||
|
||||
/* Restore the old input source */
|
||||
RestoreInputStack (Source->IStack);
|
||||
|
||||
/* Remember the last stacked input source */
|
||||
S = Source->Next;
|
||||
@@ -792,14 +801,33 @@ static void ReadIdent (void)
|
||||
static void ReadStringConst (int StringTerm)
|
||||
/* Read a string constant into SVal. */
|
||||
{
|
||||
int NeedNext;
|
||||
|
||||
/* Skip the leading string terminator */
|
||||
NextChar ();
|
||||
|
||||
/* Read the string */
|
||||
while (1) {
|
||||
int Cooked = 1;
|
||||
NeedNext = 1;
|
||||
|
||||
if (StringTerm == 0 && SB_GetLen(&CurTok.SVal) == 1) {
|
||||
if (C == '\'') {
|
||||
break;
|
||||
}
|
||||
else if (MissingCharTerm) {
|
||||
NeedNext = 0;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
Error ("Illegal character constant");
|
||||
}
|
||||
}
|
||||
|
||||
if (C == StringTerm) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (C == '\n' || C == EOF) {
|
||||
Error ("Newline in string constant");
|
||||
break;
|
||||
@@ -812,20 +840,74 @@ static void ReadStringConst (int StringTerm)
|
||||
case EOF:
|
||||
Error ("Unterminated escape sequence in string constant");
|
||||
break;
|
||||
case '\\':
|
||||
case '\'':
|
||||
case '"':
|
||||
case '?':
|
||||
C = '\?';
|
||||
break;
|
||||
case 't':
|
||||
C = '\x09';
|
||||
case 'a':
|
||||
C = '\a';
|
||||
break;
|
||||
case 'b':
|
||||
C = '\b';
|
||||
break;
|
||||
case 'e':
|
||||
C = '\x1B'; /* see comments in cc65/scanner.c */
|
||||
break;
|
||||
case 'f':
|
||||
C = '\f';
|
||||
break;
|
||||
case 'r':
|
||||
C = '\x0D';
|
||||
C = '\r';
|
||||
break;
|
||||
case 'n':
|
||||
C = '\x0A';
|
||||
C = '\n';
|
||||
break;
|
||||
case 't':
|
||||
C = '\t';
|
||||
break;
|
||||
case 'v':
|
||||
C = '\v';
|
||||
break;
|
||||
case '\\':
|
||||
C = '\\'; /* unnecessary but more readable */
|
||||
break;
|
||||
case '\'':
|
||||
C = '\''; /* unnecessary but more readable */
|
||||
if (StringTerm == 0) {
|
||||
/* special case used by character constants
|
||||
** when LooseStringTerm not set. this will
|
||||
** cause '\' to be a valid character constant
|
||||
*/
|
||||
C = '\\';
|
||||
NeedNext = 0;
|
||||
}
|
||||
break;
|
||||
case '\"':
|
||||
C = '\"'; /* unnecessary but more readable */
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
{ /* brace needed for scoping */
|
||||
int Count = 1;
|
||||
int Final = DigitVal(C);
|
||||
Cooked = 0;
|
||||
NextChar ();
|
||||
while (IsODigit (C) && Count++ < 3) {
|
||||
Final = (Final << 3) | DigitVal(C);
|
||||
NextChar();
|
||||
}
|
||||
if (C >= 256)
|
||||
Error ("Octal character constant out of range");
|
||||
}
|
||||
break;
|
||||
case 'X':
|
||||
case 'x':
|
||||
Cooked = 0;
|
||||
NextChar ();
|
||||
if (IsXDigit (C)) {
|
||||
char high_nibble = DigitVal (C) << 4;
|
||||
@@ -843,14 +925,19 @@ static void ReadStringConst (int StringTerm)
|
||||
}
|
||||
|
||||
/* Append the char to the string */
|
||||
SB_AppendChar (&CurTok.SVal, C);
|
||||
SB_AppendCharCooked (&CurTok.SVal, C, Cooked);
|
||||
|
||||
/* Skip the character */
|
||||
NextChar ();
|
||||
if (NeedNext) {
|
||||
/* Skip the character */
|
||||
NextChar ();
|
||||
NeedNext = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip the trailing terminator */
|
||||
NextChar ();
|
||||
if (NeedNext) {
|
||||
/* Skip the trailing terminator */
|
||||
NextChar ();
|
||||
}
|
||||
|
||||
/* Terminate the string */
|
||||
SB_Terminate (&CurTok.SVal);
|
||||
@@ -1135,17 +1222,33 @@ Again:
|
||||
/* Local symbol? */
|
||||
if (C == LocalStart) {
|
||||
|
||||
/* Read the identifier. */
|
||||
ReadIdent ();
|
||||
NextChar ();
|
||||
|
||||
/* Start character alone is not enough */
|
||||
if (SB_GetLen (&CurTok.SVal) == 1) {
|
||||
Error ("Invalid cheap local symbol");
|
||||
goto Again;
|
||||
if (IsIdChar (C)) {
|
||||
/* Read a local identifier */
|
||||
CurTok.Tok = TOK_LOCAL_IDENT;
|
||||
SB_AppendChar (&CurTok.SVal, LocalStart);
|
||||
ReadIdent ();
|
||||
} else {
|
||||
/* Read an unnamed label */
|
||||
CurTok.IVal = 0;
|
||||
CurTok.Tok = TOK_ULABEL;
|
||||
|
||||
if (C == '-' || C == '<') {
|
||||
int PrevC = C;
|
||||
do {
|
||||
--CurTok.IVal;
|
||||
NextChar ();
|
||||
} while (C == PrevC);
|
||||
} else if (C == '+' || C == '>') {
|
||||
int PrevC = C;
|
||||
do {
|
||||
++CurTok.IVal;
|
||||
NextChar ();
|
||||
} while (C == PrevC);
|
||||
}
|
||||
}
|
||||
|
||||
/* A local identifier */
|
||||
CurTok.Tok = TOK_LOCAL_IDENT;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1325,22 +1428,30 @@ CharAgain:
|
||||
break;
|
||||
|
||||
case '-':
|
||||
case '<':
|
||||
{
|
||||
int PrevC = C;
|
||||
CurTok.IVal = 0;
|
||||
do {
|
||||
--CurTok.IVal;
|
||||
NextChar ();
|
||||
} while (C == '-');
|
||||
} while (C == PrevC);
|
||||
CurTok.Tok = TOK_ULABEL;
|
||||
break;
|
||||
}
|
||||
|
||||
case '+':
|
||||
case '>':
|
||||
{
|
||||
int PrevC = C;
|
||||
CurTok.IVal = 0;
|
||||
do {
|
||||
++CurTok.IVal;
|
||||
NextChar ();
|
||||
} while (C == '+');
|
||||
} while (C == PrevC);
|
||||
CurTok.Tok = TOK_ULABEL;
|
||||
break;
|
||||
}
|
||||
|
||||
case '=':
|
||||
NextChar ();
|
||||
@@ -1445,11 +1556,11 @@ CharAgain:
|
||||
return;
|
||||
|
||||
case '\'':
|
||||
/* Hack: If we allow ' as terminating character for strings, read
|
||||
** the following stuff as a string, and check for a one character
|
||||
** string later.
|
||||
*/
|
||||
if (LooseStringTerm) {
|
||||
/* Hack: If we allow ' as terminating character for strings, read
|
||||
** the following stuff as a string, and check for a one character
|
||||
** string later.
|
||||
*/
|
||||
ReadStringConst ('\'');
|
||||
if (SB_GetLen (&CurTok.SVal) == 1) {
|
||||
CurTok.IVal = SB_AtUnchecked (&CurTok.SVal, 0);
|
||||
@@ -1458,22 +1569,16 @@ CharAgain:
|
||||
CurTok.Tok = TOK_STRCON;
|
||||
}
|
||||
} else {
|
||||
/* Always a character constant */
|
||||
NextChar ();
|
||||
if (C == EOF || IsControl (C)) {
|
||||
/* Always a character constant
|
||||
** Hack: Pass 0 to ReadStringConst for special handling.
|
||||
*/
|
||||
ReadStringConst(0);
|
||||
if (SB_GetLen(&CurTok.SVal) != 1) {
|
||||
Error ("Illegal character constant");
|
||||
goto CharAgain;
|
||||
}
|
||||
CurTok.IVal = C;
|
||||
CurTok.IVal = SB_AtUnchecked (&CurTok.SVal, 0);
|
||||
CurTok.Tok = TOK_CHARCON;
|
||||
NextChar ();
|
||||
if (C != '\'') {
|
||||
if (!MissingCharTerm) {
|
||||
Error ("Illegal character constant");
|
||||
}
|
||||
} else {
|
||||
NextChar ();
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -1508,7 +1613,7 @@ CharAgain:
|
||||
/* In case of the main file, do not close it, but return EOF. */
|
||||
if (Source && Source->Next) {
|
||||
DoneCharSource ();
|
||||
goto Again;
|
||||
goto Restart;
|
||||
} else {
|
||||
CurTok.Tok = TOK_EOF;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ typedef enum token_t {
|
||||
TOK_REG, /* Sweet16 R.. register (in sweet16 mode) */
|
||||
|
||||
TOK_ASSIGN, /* := */
|
||||
TOK_ULABEL, /* :++ or :-- */
|
||||
TOK_ULABEL, /* An unnamed label */
|
||||
|
||||
TOK_EQ, /* = */
|
||||
TOK_NE, /* <> */
|
||||
|
||||
@@ -107,8 +107,12 @@ ExprNode* ULabRef (int Which)
|
||||
int Index;
|
||||
ULabel* L;
|
||||
|
||||
/* Which can never be 0 */
|
||||
PRECONDITION (Which != 0);
|
||||
/* Which should not be 0 */
|
||||
if (Which == 0) {
|
||||
Error ("Invalid unnamed label reference");
|
||||
/* We must return something valid */
|
||||
return GenCurrentPC();
|
||||
}
|
||||
|
||||
/* Get the index of the referenced label */
|
||||
if (Which > 0) {
|
||||
|
||||
Reference in New Issue
Block a user