/*@null@*/ /*@dependent@*/ const char *in_filename = (const char *)NULL;
unsigned int line_number = 1;
+unsigned int line_number_inc = 1;
unsigned int asm_options = 0;
int indent_level = 0;
/*@null@*/ /*@dependent@*/ extern const char *in_filename;
extern unsigned int line_number;
+
+/* Amount to increase line_number by after each line. Should be 0 or 1, set by
+ * %line (in NASM syntax). Initialized to 1 at startup.
+ * (0 is for 1-line macros that expand to multiple lines).
+ */
+extern unsigned int line_number_inc;
+
extern unsigned int asm_options;
extern int indent_level;
%token <intn> INTNUM
%token <flt> FLTNUM
-%token <str_val> DIRECTIVE_NAME STRING
+%token <str_val> DIRECTIVE_NAME STRING FILENAME
%token <int_info> BYTE WORD DWORD QWORD TWORD DQWORD
%token <int_info> DECLARE_DATA
%token <int_info> RESERVE_SPACE
%token <int_info> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID
%token <str_val> ID LOCAL_ID SPECIAL_ID
+%token LINE
/* instruction tokens (dynamically generated) */
/* @TOKENS@ */
$2);
if (nasm_parser_temp_bc)
nasm_parser_prev_bc = nasm_parser_temp_bc;
- line_number++;
+ line_number += line_number_inc;
}
;
line: '\n' { $$ = (bytecode *)NULL; }
| lineexp '\n'
+ | LINE INTNUM '+' INTNUM FILENAME '\n' {
+ line_number = intnum_get_uint($2);
+ line_number_inc = intnum_get_uint($4);
+ line_number -= line_number_inc; /* as we'll add it back in */
+ switch_filename($5);
+ intnum_delete($2);
+ intnum_delete($4);
+ xfree($5);
+ $$ = (bytecode *)NULL;
+ }
| directive '\n' { $$ = (bytecode *)NULL; }
| error '\n' {
Error(_("label or instruction expected at start of line"));
%token <intn> INTNUM
%token <flt> FLTNUM
-%token <str_val> DIRECTIVE_NAME STRING
+%token <str_val> DIRECTIVE_NAME STRING FILENAME
%token <int_info> BYTE WORD DWORD QWORD TWORD DQWORD
%token <int_info> DECLARE_DATA
%token <int_info> RESERVE_SPACE
%token <int_info> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID
%token <str_val> ID LOCAL_ID SPECIAL_ID
+%token LINE
/* instruction tokens (dynamically generated) */
/* @TOKENS@ */
$2);
if (nasm_parser_temp_bc)
nasm_parser_prev_bc = nasm_parser_temp_bc;
- line_number++;
+ line_number += line_number_inc;
}
;
line: '\n' { $$ = (bytecode *)NULL; }
| lineexp '\n'
+ | LINE INTNUM '+' INTNUM FILENAME '\n' {
+ line_number = intnum_get_uint($2);
+ line_number_inc = intnum_get_uint($4);
+ line_number -= line_number_inc; /* as we'll add it back in */
+ switch_filename($5);
+ intnum_delete($2);
+ intnum_delete($4);
+ xfree($5);
+ $$ = (bytecode *)NULL;
+ }
| directive '\n' { $$ = (bytecode *)NULL; }
| error '\n' {
Error(_("label or instruction expected at start of line"));
/* last "base" label for local (.) labels */
char *nasm_parser_locallabel_base = (char *)NULL;
+static int linechg_numcount;
+
%}
%option noyywrap
%option nounput
%option case-insensitive
-%x DIRECTIVE
+%x DIRECTIVE LINECHG LINECHG2
%s DIRECTIVE2
DIGIT [0-9]
return STRING;
}
+ /* %line linenum+lineinc filename */
+^%line { BEGIN LINECHG; linechg_numcount = 0; return LINE; }
+<LINECHG>{DIGIT}+ {
+ linechg_numcount++;
+ yylval.intn = intnum_new_dec(yytext);
+ return INTNUM;
+}
+<LINECHG>\n { BEGIN INITIAL; return '\n'; }
+<LINECHG>[+] { return yytext[0]; }
+<LINECHG>{WS}+ {
+ if (linechg_numcount == 2)
+ BEGIN LINECHG2;
+}
+<LINECHG2>\n { BEGIN INITIAL; return '\n'; }
+<LINECHG2>\r ;
+<LINECHG2>[^\r\n]+ {
+ BEGIN LINECHG;
+ yylval.str_val = xstrdup(yytext);
+ return FILENAME;
+}
+
/* directive: [name value] */
^{WS}*"[" { BEGIN DIRECTIVE; return '['; }
<DIRECTIVE>"]" { BEGIN INITIAL; return ']'; }
/*@null@*/ /*@dependent@*/ const char *in_filename = (const char *)NULL;
unsigned int line_number = 1;
+unsigned int line_number_inc = 1;
unsigned int asm_options = 0;
int indent_level = 0;
/*@null@*/ /*@dependent@*/ extern const char *in_filename;
extern unsigned int line_number;
+
+/* Amount to increase line_number by after each line. Should be 0 or 1, set by
+ * %line (in NASM syntax). Initialized to 1 at startup.
+ * (0 is for 1-line macros that expand to multiple lines).
+ */
+extern unsigned int line_number_inc;
+
extern unsigned int asm_options;
extern int indent_level;
/*@null@*/ /*@dependent@*/ const char *in_filename = (const char *)NULL;
unsigned int line_number = 1;
+unsigned int line_number_inc = 1;
unsigned int asm_options = 0;
int indent_level = 0;
/*@null@*/ /*@dependent@*/ extern const char *in_filename;
extern unsigned int line_number;
+
+/* Amount to increase line_number by after each line. Should be 0 or 1, set by
+ * %line (in NASM syntax). Initialized to 1 at startup.
+ * (0 is for 1-line macros that expand to multiple lines).
+ */
+extern unsigned int line_number_inc;
+
extern unsigned int asm_options;
extern int indent_level;
%token <intn> INTNUM
%token <flt> FLTNUM
-%token <str_val> DIRECTIVE_NAME STRING
+%token <str_val> DIRECTIVE_NAME STRING FILENAME
%token <int_info> BYTE WORD DWORD QWORD TWORD DQWORD
%token <int_info> DECLARE_DATA
%token <int_info> RESERVE_SPACE
%token <int_info> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID
%token <str_val> ID LOCAL_ID SPECIAL_ID
+%token LINE
/* instruction tokens (dynamically generated) */
/* @TOKENS@ */
$2);
if (nasm_parser_temp_bc)
nasm_parser_prev_bc = nasm_parser_temp_bc;
- line_number++;
+ line_number += line_number_inc;
}
;
line: '\n' { $$ = (bytecode *)NULL; }
| lineexp '\n'
+ | LINE INTNUM '+' INTNUM FILENAME '\n' {
+ line_number = intnum_get_uint($2);
+ line_number_inc = intnum_get_uint($4);
+ line_number -= line_number_inc; /* as we'll add it back in */
+ switch_filename($5);
+ intnum_delete($2);
+ intnum_delete($4);
+ xfree($5);
+ $$ = (bytecode *)NULL;
+ }
| directive '\n' { $$ = (bytecode *)NULL; }
| error '\n' {
Error(_("label or instruction expected at start of line"));
%token <intn> INTNUM
%token <flt> FLTNUM
-%token <str_val> DIRECTIVE_NAME STRING
+%token <str_val> DIRECTIVE_NAME STRING FILENAME
%token <int_info> BYTE WORD DWORD QWORD TWORD DQWORD
%token <int_info> DECLARE_DATA
%token <int_info> RESERVE_SPACE
%token <int_info> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID
%token <str_val> ID LOCAL_ID SPECIAL_ID
+%token LINE
/* instruction tokens (dynamically generated) */
/* @TOKENS@ */
$2);
if (nasm_parser_temp_bc)
nasm_parser_prev_bc = nasm_parser_temp_bc;
- line_number++;
+ line_number += line_number_inc;
}
;
line: '\n' { $$ = (bytecode *)NULL; }
| lineexp '\n'
+ | LINE INTNUM '+' INTNUM FILENAME '\n' {
+ line_number = intnum_get_uint($2);
+ line_number_inc = intnum_get_uint($4);
+ line_number -= line_number_inc; /* as we'll add it back in */
+ switch_filename($5);
+ intnum_delete($2);
+ intnum_delete($4);
+ xfree($5);
+ $$ = (bytecode *)NULL;
+ }
| directive '\n' { $$ = (bytecode *)NULL; }
| error '\n' {
Error(_("label or instruction expected at start of line"));
/* last "base" label for local (.) labels */
char *nasm_parser_locallabel_base = (char *)NULL;
+static int linechg_numcount;
+
%}
%option noyywrap
%option nounput
%option case-insensitive
-%x DIRECTIVE
+%x DIRECTIVE LINECHG LINECHG2
%s DIRECTIVE2
DIGIT [0-9]
return STRING;
}
+ /* %line linenum+lineinc filename */
+^%line { BEGIN LINECHG; linechg_numcount = 0; return LINE; }
+<LINECHG>{DIGIT}+ {
+ linechg_numcount++;
+ yylval.intn = intnum_new_dec(yytext);
+ return INTNUM;
+}
+<LINECHG>\n { BEGIN INITIAL; return '\n'; }
+<LINECHG>[+] { return yytext[0]; }
+<LINECHG>{WS}+ {
+ if (linechg_numcount == 2)
+ BEGIN LINECHG2;
+}
+<LINECHG2>\n { BEGIN INITIAL; return '\n'; }
+<LINECHG2>\r ;
+<LINECHG2>[^\r\n]+ {
+ BEGIN LINECHG;
+ yylval.str_val = xstrdup(yytext);
+ return FILENAME;
+}
+
/* directive: [name value] */
^{WS}*"[" { BEGIN DIRECTIVE; return '['; }
<DIRECTIVE>"]" { BEGIN INITIAL; return ']'; }