diff --git a/src/ca65/main.c b/src/ca65/main.c index 3ec6c84ee..f3100162a 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -707,6 +707,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. */ diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 185100025..146c74958 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -1124,17 +1124,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; } @@ -1314,22 +1330,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 (); diff --git a/src/ca65/token.h b/src/ca65/token.h index b8bbb6d6e..8f935f7a1 100644 --- a/src/ca65/token.h +++ b/src/ca65/token.h @@ -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, /* <> */ diff --git a/src/ca65/ulabel.c b/src/ca65/ulabel.c index 1127c3743..19bec0671 100644 --- a/src/ca65/ulabel.c +++ b/src/ca65/ulabel.c @@ -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) {