mirror of
https://github.com/yasm/yasm
synced 2026-08-26 22:26:05 -04:00
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:
parent
31b0b9294c
commit
698f3fe8ff
6 changed files with 79 additions and 28 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ enum tokentype {
|
|||
ID,
|
||||
LOCAL_ID,
|
||||
SPECIAL_ID,
|
||||
NONLOCAL_ID,
|
||||
LINE,
|
||||
NONE /* special token for lookahead */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
21
modules/parsers/nasm/tests/locallabel.asm
Normal file
21
modules/parsers/nasm/tests/locallabel.asm
Normal 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
|
||||
|
||||
|
||||
16
modules/parsers/nasm/tests/locallabel.hex
Normal file
16
modules/parsers/nasm/tests/locallabel.hex
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
00
|
||||
00
|
||||
01
|
||||
00
|
||||
02
|
||||
00
|
||||
00
|
||||
00
|
||||
07
|
||||
00
|
||||
08
|
||||
00
|
||||
07
|
||||
00
|
||||
08
|
||||
00
|
||||
Loading…
Add table
Add a link
Reference in a new issue