Fix #136: Unbreak ..@ non-local-label mechanism.

Add testcase for this.
Also fix $-prefixed labels to match non-$-prefixed label behavior
(this has been broken for a very long time).

svn path=/trunk/yasm/; revision=2045
This commit is contained in:
Peter Johnson 2008-03-27 05:35:36 +00:00
parent 31b0b9294c
commit 698f3fe8ff
6 changed files with 79 additions and 28 deletions

View file

@ -98,6 +98,7 @@ destroy_curtok_(yasm_parser_nasm *parser_nasm)
case ID:
case LOCAL_ID:
case SPECIAL_ID:
case NONLOCAL_ID:
yasm_xfree(curval.str_val);
break;
case STRING:
@ -169,6 +170,7 @@ describe_token(int token)
case ID: str = "identifier"; break;
case LOCAL_ID: str = ".identifier"; break;
case SPECIAL_ID: str = "..identifier"; break;
case NONLOCAL_ID: str = "..@identifier"; break;
case LINE: str = "%line"; break;
default:
strch[1] = token;
@ -349,6 +351,7 @@ parse_line(yasm_parser_nasm *parser_nasm)
return parse_times(parser_nasm);
case ID:
case SPECIAL_ID:
case NONLOCAL_ID:
case LOCAL_ID:
{
char *name = ID_val;
@ -1143,6 +1146,7 @@ parse_expr6(yasm_parser_nasm *parser_nasm, expr_type type)
/*@fallthrough@*/
case ID:
case LOCAL_ID:
case NONLOCAL_ID:
sym = yasm_symtab_use(p_symtab, ID_val, cur_line);
e = p_expr_new_ident(yasm_expr_sym(sym));
yasm_xfree(ID_val);

View file

@ -62,6 +62,7 @@ enum tokentype {
ID,
LOCAL_ID,
SPECIAL_ID,
NONLOCAL_ID,
LINE,
NONE /* special token for lookahead */
};

View file

@ -70,6 +70,34 @@ static int linechg_numcount;
quot = ["'];
*/
static int
handle_dot_label(YYSTYPE *lvalp, char *tok, size_t toklen, size_t zeropos,
yasm_parser_nasm *parser_nasm)
{
/* check for special non-local labels like ..start */
if (tok[zeropos+1] == '.') {
lvalp->str_val = yasm__xstrndup(tok+zeropos, toklen-zeropos);
/* check for special non-local ..@label */
if (lvalp->str_val[zeropos+2] == '@')
return NONLOCAL_ID;
return SPECIAL_ID;
}
if (!parser_nasm->locallabel_base) {
lvalp->str_val = yasm__xstrndup(tok+zeropos, toklen-zeropos);
yasm_warn_set(YASM_WARN_GENERAL,
N_("no non-local label before `%s'"),
lvalp->str_val);
} else {
size_t len = toklen - zeropos + parser_nasm->locallabel_base_len;
lvalp->str_val = yasm_xmalloc(len + 1);
strcpy(lvalp->str_val, parser_nasm->locallabel_base);
strncat(lvalp->str_val, tok+zeropos, toklen-zeropos);
lvalp->str_val[len] = '\0';
}
return LOCAL_ID;
}
int
nasm_parser_lex(YYSTYPE *lvalp, yasm_parser_nasm *parser_nasm)
@ -77,7 +105,7 @@ nasm_parser_lex(YYSTYPE *lvalp, yasm_parser_nasm *parser_nasm)
yasm_scanner *s = &parser_nasm->s;
YYCTYPE *cursor = s->cur;
YYCTYPE endch;
size_t count, len;
size_t count;
YYCTYPE savech;
/* Handle one token of lookahead */
@ -286,38 +314,17 @@ scan:
[-+|^*&/%~$():=,\[] { RETURN(s->tok[0]); }
"]" { RETURN(s->tok[0]); }
/* special non-local ..@label */
"..@" [a-zA-Z0-9_$#@~.?]+ {
lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
RETURN(ID);
}
/* special non-local labels like ..start */
".." [a-zA-Z0-9_$#~.?]+ {
lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
RETURN(SPECIAL_ID);
}
/* local label (.label) */
"." [a-zA-Z0-9_$#@~?][a-zA-Z0-9_$#@~.?]* {
if (!parser_nasm->locallabel_base) {
lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
yasm_warn_set(YASM_WARN_GENERAL,
N_("no non-local label before `%s'"),
lvalp->str_val);
} else {
len = TOKLEN + parser_nasm->locallabel_base_len;
lvalp->str_val = yasm_xmalloc(len + 1);
strcpy(lvalp->str_val, parser_nasm->locallabel_base);
strncat(lvalp->str_val, TOK, TOKLEN);
lvalp->str_val[len] = '\0';
}
RETURN(LOCAL_ID);
"." [a-zA-Z0-9_$#@~.?]+ {
RETURN(handle_dot_label(lvalp, TOK, TOKLEN, 0, parser_nasm));
}
/* forced identifier */
"$" [a-zA-Z0-9_$#@~.?]+ {
if (TOK[1] == '.') {
/* handle like .label */
RETURN(handle_dot_label(lvalp, TOK, TOKLEN, 1, parser_nasm));
}
lvalp->str_val = yasm__xstrndup(TOK+1, TOKLEN-1);
RETURN(ID);
}

View file

@ -19,6 +19,8 @@ EXTRA_DIST += modules/parsers/nasm/tests/hexconst.asm
EXTRA_DIST += modules/parsers/nasm/tests/hexconst.hex
EXTRA_DIST += modules/parsers/nasm/tests/long.asm
EXTRA_DIST += modules/parsers/nasm/tests/long.hex
EXTRA_DIST += modules/parsers/nasm/tests/locallabel.asm
EXTRA_DIST += modules/parsers/nasm/tests/locallabel.hex
EXTRA_DIST += modules/parsers/nasm/tests/nasm-prefix.asm
EXTRA_DIST += modules/parsers/nasm/tests/nasm-prefix.hex
EXTRA_DIST += modules/parsers/nasm/tests/newsect.asm

View file

@ -0,0 +1,21 @@
label:
db 0
.local:
db 0
..@local1:
.local2:
dw label.local
dw label.local2
$label2:
db 0
$.local:
db 0
$..@local2:
$.local2:
dw label2.local
dw label2.local2
dw $label2.local
dw $label2.local2

View file

@ -0,0 +1,16 @@
00
00
01
00
02
00
00
00
07
00
08
00
07
00
08
00