diff --git a/src/asm/asmy.y b/src/asm/asmy.y index 363a8b14..178437c0 100644 --- a/src/asm/asmy.y +++ b/src/asm/asmy.y @@ -551,7 +551,12 @@ static void strsubUTF8(char *dest, const char *src, uint32_t pos, uint32_t len) %left NEG /* negation -- unary minus */ %token T_LABEL +%token T_LOCAL_LABEL +%type scoped_label +%type scoped_label_bare %token T_ID +%token T_LOCAL_ID +%type scoped_id %token T_POP_EQU %token T_POP_SET %token T_POP_EQUAL @@ -654,22 +659,34 @@ line : label | pseudoop ; +scoped_label_bare : T_LABEL | T_LOCAL_LABEL ; +scoped_label : T_LABEL ':' + { + strcpy($$, $1); + } + | T_LOCAL_LABEL ':' + { + strcpy($$, $1); + } +; +scoped_id : T_ID | T_LOCAL_ID ; + label : /* empty */ - | T_LABEL + | scoped_label_bare { if ($1[0] == '.') sym_AddLocalReloc($1); else sym_AddReloc($1); } - | T_LABEL ':' + | scoped_label { if ($1[0] == '.') sym_AddLocalReloc($1); else sym_AddReloc($1); } - | T_LABEL ':' ':' + | scoped_label ':' { if ($1[0] == '.') sym_AddLocalReloc($1); @@ -921,7 +938,7 @@ purge_list : purge_list_entry | purge_list_entry comma purge_list ; -purge_list_entry : T_ID +purge_list_entry : scoped_id { sym_Purge($1); } @@ -934,7 +951,7 @@ import_list : import_list_entry | import_list_entry comma import_list ; -import_list_entry : T_ID +import_list_entry : scoped_id { /* * This is done automatically if the label isn't found @@ -951,7 +968,7 @@ export_list : export_list_entry | export_list_entry comma export_list ; -export_list_entry : T_ID +export_list_entry : scoped_id { sym_Export($1); } @@ -964,7 +981,7 @@ global_list : global_list_entry | global_list_entry comma global_list ; -global_list_entry : T_ID +global_list_entry : scoped_id { sym_Export($1); } @@ -1229,7 +1246,7 @@ relocexpr : relocexpr_no_str } ; -relocexpr_no_str : T_ID +relocexpr_no_str : scoped_id { rpn_Symbol(&$$, $1); } @@ -1261,7 +1278,7 @@ relocexpr_no_str : T_ID | T_OP_NOT relocexpr %prec NEG { rpn_UNNOT(&$$, &$2); } | T_OP_HIGH '(' relocexpr ')' { rpn_HIGH(&$$, &$3); } | T_OP_LOW '(' relocexpr ')' { rpn_LOW(&$$, &$3); } - | T_OP_BANK '(' T_ID ')' + | T_OP_BANK '(' scoped_id ')' { /* '@' is also a T_ID, it is handled here. */ rpn_BankSymbol(&$$, $3); @@ -1272,7 +1289,7 @@ relocexpr_no_str : T_ID } | T_OP_DEF { oDontExpandStrings = true; - } '(' T_ID ')' + } '(' scoped_id ')' { struct sSymbol const *sym = sym_FindSymbol($4); if (sym && !(sym_IsDefined(sym) && sym->type != SYM_LABEL)) diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 6cf73a56..558879ec 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -913,10 +913,18 @@ scanagain: goto scanagain; } - if (token->nToken == T_ID && linestart) - return T_LABEL; - else - return token->nToken; + uint32_t type = token->nToken; + + if (type == T_ID && strchr(yylval.tzSym, '.')) + type = T_LOCAL_ID; + + if (linestart) { + if (type == T_ID) + return T_LABEL; + if (type == T_LOCAL_ID) + return T_LOCAL_LABEL; + } + return type; } /* Longest match was a keyword or operator. */ diff --git a/test/asm/label-macro-arg.asm b/test/asm/label-macro-arg.asm index 7fe0d6cb..24c1e040 100644 --- a/test/asm/label-macro-arg.asm +++ b/test/asm/label-macro-arg.asm @@ -40,6 +40,6 @@ ENDM test_char _ test_char @ test_char # - test_char . + test_char . test_char : diff --git a/test/asm/label-macro-arg.err b/test/asm/label-macro-arg.err index c1d8ae33..9350062d 100644 --- a/test/asm/label-macro-arg.err +++ b/test/asm/label-macro-arg.err @@ -1,5 +1,7 @@ -ERROR: label-macro-arg.asm(45) -> label-macro-arg.asm::test_char(31): - Label "sizeof_" created outside of a SECTION +ERROR: label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(31): + Local label in main scope while expanding symbol "VAR_DEF" -ERROR: label-macro-arg.asm(45) -> label-macro-arg.asm::test_char(31): - Macro 'something' not defined +ERROR: label-macro-arg.asm(44) -> label-macro-arg.asm::test_char(31): + syntax error +while expanding symbol "VAR_DEF" +error: Assembly aborted (2 errors)! diff --git a/test/asm/label-macro-arg.out b/test/asm/label-macro-arg.out index 0a5d086f..26e33473 100644 --- a/test/asm/label-macro-arg.out +++ b/test/asm/label-macro-arg.out @@ -5,4 +5,3 @@ $8 sizeof__something equals $1 sizeof_@something equals $1 sizeof_#something equals $1 -sizeof_.something equals $1