From 37041256066b0f4023b2664ae4932a23b9b09d55 Mon Sep 17 00:00:00 2001 From: Jason Self Date: Sat, 22 Oct 2016 11:34:43 -0700 Subject: [PATCH] Updating compiler to commit dabfa73 from upstream dated Oct 1 2016. These changes are similiarly relicensed to GPL per Section 4(c)(ii) of the Artistic License 2.0. --- asm.c | 5 +-- directs.c | 68 +++++++++++++++++++++++++++- errors.c | 45 +++++++++++-------- expressp.c | 11 ++++- files.c | 116 +++++++++++++++++++++++++++++++++++++++++++----- header.h | 128 +++++++++++++++++++++++++---------------------------- lexer.c | 117 +++++++++++++++++++++++++++++++++++++++++++----- symbols.c | 24 +++++----- tables.c | 4 +- 9 files changed, 390 insertions(+), 128 deletions(-) diff --git a/asm.c b/asm.c index a144939..d3a9d99 100644 --- a/asm.c +++ b/asm.c @@ -1423,9 +1423,8 @@ extern int32 assemble_routine_header(int no_locals, stackargs = TRUE; } - if (veneer_mode) routine_starts_line = -1; - else routine_starts_line = ErrorReport.line_number - + FILE_LINE_SCALE_FACTOR*ErrorReport.file_number; + if (veneer_mode) routine_starts_line = blank_brief_location; + else routine_starts_line = get_brief_location(&ErrorReport); if (asm_trace_level > 0) { printf("\n%5d +%05lx [ %s ", ErrorReport.line_number, diff --git a/directs.c b/directs.c index 37bbf82..5c622ba 100644 --- a/directs.c +++ b/directs.c @@ -28,7 +28,7 @@ int no_routines, /* Number of routines compiled so far */ no_termcs; /* Number of terminating characters */ int terminating_characters[32]; -int32 routine_starts_line; /* Source code line on which the current +brief_location routine_starts_line; /* Source code location where the current routine starts. (Useful for reporting "unused variable" warnings on the start line rather than the end line.) */ @@ -662,6 +662,72 @@ Fake_Action directives to a point after the inclusion of \"Parser\".)"); make_object(FALSE, NULL, -1, -1, -1); return FALSE; /* See "objects.c" */ + /* --------------------------------------------------------------------- */ + /* Origsource */ + /* Origsource */ + /* Origsource */ + /* Origsource */ + /* */ + /* The first three forms declare that all following lines are derived */ + /* from the named Inform 7 source file (with an optional line number */ + /* and character number). This will be reported in error messages and */ + /* in debug output. The declaration holds through the next Origsource */ + /* directive (but does not apply to included files). */ + /* */ + /* The fourth form, with no arguments, clears the declaration. */ + /* */ + /* Unlike the Include directive, Origsource does not open the named */ + /* file or even verify that it exists. The filename is treated as an */ + /* opaque string. */ + /* --------------------------------------------------------------------- */ + + case ORIGSOURCE_CODE: + { + char *origsource_file = NULL; + int32 origsource_line = 0; + int32 origsource_char = 0; + + /* Parse some optional tokens followed by a mandatory semicolon. */ + + get_next_token(); + if (!((token_type == SEP_TT) && (token_value == SEMICOLON_SEP))) { + if (token_type != DQ_TT) { + return ebf_error_recover("a file name in double-quotes", + token_text); + } + origsource_file = token_text; + + get_next_token(); + if (!((token_type == SEP_TT) && (token_value == SEMICOLON_SEP))) { + if (token_type != NUMBER_TT) { + return ebf_error_recover("a file line number", + token_text); + } + origsource_line = token_value; + if (origsource_line < 0) + origsource_line = 0; + + get_next_token(); + if (!((token_type == SEP_TT) && (token_value == SEMICOLON_SEP))) { + if (token_type != NUMBER_TT) { + return ebf_error_recover("a file line number", + token_text); + } + origsource_char = token_value; + if (origsource_char < 0) + origsource_char = 0; + + get_next_token(); + } + } + } + + put_token_back(); + + set_origsource_location(origsource_file, origsource_line, origsource_char); + } + break; + /* --------------------------------------------------------------------- */ /* Property [long] [additive] name [alias oldname] */ /* --------------------------------------------------------------------- */ diff --git a/errors.c b/errors.c index 3d4a866..0ea92b1 100644 --- a/errors.c +++ b/errors.c @@ -44,7 +44,7 @@ static void print_preamble(void) int j, with_extension_flag = FALSE; char *p; j = ErrorReport.file_number; - if (j <= 0 || j > input_file) p = ErrorReport.source; + if (j <= 0 || j > total_files) p = ErrorReport.source; else p = InputFiles[j-1].filename; if (!p) p = ""; @@ -55,6 +55,21 @@ static void print_preamble(void) if (!(ErrorReport.main_flag)) printf("\"%s\", ", p); printf("line %d: ", ErrorReport.line_number); + if (ErrorReport.orig_file) { + char *op; + if (ErrorReport.orig_file <= 0 || ErrorReport.orig_file > total_files) + op = ErrorReport.orig_source; + else + op = InputFiles[ErrorReport.orig_file-1].filename; + printf("(\"%s\"", op); + if (ErrorReport.orig_line) { + printf(", %d", ErrorReport.orig_line); + if (ErrorReport.orig_char) { + printf(":%d", ErrorReport.orig_char); + } + } + printf("): "); + } break; case 1: /* Microsoft error message format */ @@ -216,15 +231,11 @@ extern void error_numbered(char *s1, int val) error(error_message_buff); } -extern void error_named_at(char *s1, char *s2, int32 report_line) +extern void error_named_at(char *s1, char *s2, brief_location report_line) { int i; ErrorPosition E = ErrorReport; - if (report_line != -1) - { ErrorReport.file_number = report_line/FILE_LINE_SCALE_FACTOR; - ErrorReport.line_number = report_line%FILE_LINE_SCALE_FACTOR; - ErrorReport.main_flag = (ErrorReport.file_number == 1); - } + export_brief_location(report_line, &ErrorReport); snprintf(error_message_buff, ERROR_BUFLEN,"%s \"%s\"",s1,s2); ellipsize_error_message_buff(); @@ -321,15 +332,11 @@ extern void warning_named(char *s1, char *s2) message(2,error_message_buff); } -extern void dbnu_warning(char *type, char *name, int32 report_line) +extern void dbnu_warning(char *type, char *name, brief_location report_line) { int i; ErrorPosition E = ErrorReport; if (nowarnings_switch) { no_suppressed_warnings++; return; } - if (report_line != -1) - { ErrorReport.file_number = report_line/FILE_LINE_SCALE_FACTOR; - ErrorReport.line_number = report_line%FILE_LINE_SCALE_FACTOR; - ErrorReport.main_flag = (ErrorReport.file_number == 1); - } + export_brief_location(report_line, &ErrorReport); snprintf(error_message_buff, ERROR_BUFLEN, "%s \"%s\" declared but not used", type, name); ellipsize_error_message_buff(); i = concise_switch; concise_switch = TRUE; @@ -338,7 +345,7 @@ extern void dbnu_warning(char *type, char *name, int32 report_line) ErrorReport = E; } -extern void uncalled_routine_warning(char *type, char *name, int32 report_line) +extern void uncalled_routine_warning(char *type, char *name, brief_location report_line) { int i; /* This is called for functions which have been detected by the track-unused-routines module. These will often (but not always) @@ -346,11 +353,7 @@ extern void uncalled_routine_warning(char *type, char *name, int32 report_line) than routine addresses. */ ErrorPosition E = ErrorReport; if (nowarnings_switch) { no_suppressed_warnings++; return; } - if (report_line != -1) - { ErrorReport.file_number = report_line/FILE_LINE_SCALE_FACTOR; - ErrorReport.line_number = report_line%FILE_LINE_SCALE_FACTOR; - ErrorReport.main_flag = (ErrorReport.file_number == 1); - } + export_brief_location(report_line, &ErrorReport); if (OMIT_UNUSED_ROUTINES) snprintf(error_message_buff, ERROR_BUFLEN, "%s \"%s\" unused and omitted", type, name); else @@ -486,6 +489,10 @@ extern void errors_begin_pass(void) ErrorReport.file_number = -1; ErrorReport.source = ""; ErrorReport.main_flag = FALSE; + ErrorReport.orig_source = NULL; + ErrorReport.orig_file = 0; + ErrorReport.orig_line = 0; + ErrorReport.orig_char = 0; } extern void errors_allocate_arrays(void) diff --git a/expressp.c b/expressp.c index 4c32f0e..270f308 100644 --- a/expressp.c +++ b/expressp.c @@ -142,6 +142,14 @@ but not used as a value:", unicode); current_token.symflags = sflags[symbol]; switch(stypes[symbol]) { case ROUTINE_T: + /* Replaced functions must always be backpatched + because there could be another definition coming. */ + if (sflags[symbol] & REPLACE_SFLAG) + { current_token.marker = SYMBOL_MV; + if (module_switch) import_symbol(symbol); + v = symbol; + break; + } current_token.marker = IROUTINE_MV; break; case GLOBAL_VARIABLE_T: @@ -1881,7 +1889,8 @@ extern assembly_operand parse_expression(int context) if ((a.type == ENDEXP_TT) && (b.type == ENDEXP_TT)) { if (emitter_sp == 0) - { compiler_error("SR error: emitter stack empty"); + { error("No expression between brackets '(' and ')'"); + put_token_back(); return AO; } if (emitter_sp > 1) diff --git a/files.c b/files.c index fc0ad8c..4e7377e 100644 --- a/files.c +++ b/files.c @@ -28,7 +28,12 @@ #include "header.h" -int input_file; /* Number of source files so far */ +int total_files; /* Number of files so far, including + #include and #origsource files */ +int total_input_files; /* Number of source files so far + (excludes #origsource) */ +int current_input_file; /* Most recently-opened source file */ +static int current_origsource_file; /* Most recently-used #origsource */ int32 total_chars_read; /* Characters read in (from all source files put together) */ @@ -114,12 +119,12 @@ extern void load_sourcefile(char *filename_given, int same_directory_flag) int x = 0; FILE *handle; - if (input_file == MAX_SOURCE_FILES) + if (total_files == MAX_SOURCE_FILES) memoryerror("MAX_SOURCE_FILES", MAX_SOURCE_FILES); do { x = translate_in_filename(x, name, filename_given, same_directory_flag, - (input_file==0)?1:0); + (total_files==0)?1:0); handle = fopen(name,"r"); } while ((handle == NULL) && (x != 0)); @@ -128,12 +133,12 @@ extern void load_sourcefile(char *filename_given, int same_directory_flag) filename_storage_left -= strlen(name)+1; strcpy(filename_storage_p, name); - InputFiles[input_file].filename = filename_storage_p; + InputFiles[total_files].filename = filename_storage_p; filename_storage_p += strlen(name)+1; if (debugfile_switch) - { debug_file_printf("", input_file); + { debug_file_printf("", total_files); debug_file_printf(""); debug_file_print_with_entities(filename_given); debug_file_printf(""); @@ -148,13 +153,17 @@ extern void load_sourcefile(char *filename_given, int same_directory_flag) debug_file_printf(""); } - InputFiles[input_file].handle = handle; - if (InputFiles[input_file].handle==NULL) + InputFiles[total_files].handle = handle; + if (InputFiles[total_files].handle==NULL) fatalerror_named("Couldn't open source file", name); + InputFiles[total_files].is_input = TRUE; + if (line_trace_level > 0) printf("\nOpening file \"%s\"\n",name); - input_file++; + total_files++; + total_input_files++; + current_input_file = total_files; } static void close_sourcefile(int file_number) @@ -176,7 +185,67 @@ static void close_sourcefile(int file_number) extern void close_all_source(void) { int i; - for (i=0; i 0 && current_origsource_file <= total_files) { + if (!strcmp(filename, InputFiles[current_origsource_file-1].filename)) + return current_origsource_file; + } + + for (ix=0; ix", total_files); + debug_file_printf(""); + debug_file_print_with_entities(filename); + debug_file_printf(""); + debug_file_printf("Inform 7"); + debug_file_printf(""); + } + + InputFiles[total_files].handle = NULL; + InputFiles[total_files].is_input = FALSE; + + total_files++; + current_origsource_file = total_files; + return current_origsource_file; } /* ------------------------------------------------------------------------- */ @@ -188,7 +257,7 @@ extern int file_load_chars(int file_number, char *buffer, int length) { int read_in; FILE *handle; - if (file_number-1 > input_file) + if (file_number-1 > total_files) { buffer[0] = 0; return 1; } handle = InputFiles[file_number-1].handle; @@ -1369,12 +1438,28 @@ static void write_debug_location_internals(debug_location location) } } +static void write_debug_location_origsource_internals(debug_location location) +{ debug_file_printf + ("%d", location.orig_file_index - 1); + if (location.orig_beg_line_number) + debug_file_printf + ("%d", location.orig_beg_line_number); + if (location.orig_beg_char_number) + debug_file_printf + ("%d", location.orig_beg_char_number); +} + extern void write_debug_location(debug_location location) { if (location.file_index && location.file_index != 255) { debug_file_printf(""); write_debug_location_internals(location); debug_file_printf(""); } + if (location.orig_file_index) + { debug_file_printf(""); + write_debug_location_origsource_internals(location); + debug_file_printf(""); + } } extern void write_debug_locations(debug_locations locations) @@ -1386,6 +1471,11 @@ extern void write_debug_locations(debug_locations locations) write_debug_location_internals(current->location); debug_file_printf(""); } + if (locations.location.orig_file_index) + { debug_file_printf(""); + write_debug_location_origsource_internals(locations.location); + debug_file_printf(""); + } } else { write_debug_location(locations.location); @@ -1725,7 +1815,11 @@ extern void init_files_vars(void) } extern void files_begin_prepass(void) -{ input_file = 0; +{ + total_files = 0; + total_input_files = 0; + current_input_file = 0; + current_origsource_file = 0; } extern void files_begin_pass(void) diff --git a/header.h b/header.h index 94ca84f..4fdeefe 100644 --- a/header.h +++ b/header.h @@ -52,15 +52,14 @@ /* #define ATARIST - for the Atari ST */ /* #define BEOS - for the BeBox */ /* #define LINUX - for Linux under gcc (essentially as Unix) */ -/* #define MACINTOSH - for the Apple Mac under Think C or Codewarrior */ +/* #define MACOS - for the Apple Mac with OS X (another Unix) */ +/* #define MAC_CLASSIC - for the Apple Mac under Think C or Codewarrior */ /* #define MAC_MPW - for MPW under Codewarrior (and maybe Think C) */ /* #define OS2 - for OS/2 32-bit mode under IBM's C Set++ */ -/* #define OSX - for the Apple Mac with OS X (another Unix) */ /* #define PC - for 386+ IBM PCs, eg. Microsoft Visual C/C++ */ /* #define PC_QUICKC - for small IBM PCs under QuickC */ /* #define PC_WIN32 - for Borland C++ or Microsoft Visual C++ */ /* #define UNIX - for Unix under gcc (or big IBM PC under djgpp) */ -/* #define UNIX64 - for 64-bit Unix under gcc */ /* #define VMS - for VAX or ALPHA under DEC C, but not VAX C */ /* */ /* In most cases executables are already available at */ @@ -293,10 +292,10 @@ static int32 unique_task_id(void) /* Macintosh block */ /* ------------------------------------------------------------------------- */ #ifdef MAC_MPW -#define MACINTOSH +#define MAC_CLASSIC #endif -#ifdef MACINTOSH +#ifdef MAC_CLASSIC /* 1 */ #ifdef MAC_MPW #define MACHINE_STRING "Macintosh Programmer's Workshop" @@ -342,15 +341,15 @@ static int32 unique_task_id(void) #define FN_SEP '/' #endif /* ------------------------------------------------------------------------- */ -/* OSX block */ +/* MACOS block */ /* ------------------------------------------------------------------------- */ -#ifdef OSX +#ifdef MACOS /* 1 */ -#define MACHINE_STRING "Mac OS X" +#define MACHINE_STRING "MacOS" /* 2 */ #define HAS_REALPATH /* 3 */ -#define DEFAULT_MEMORY_SIZE LARGE_SIZE +#define DEFAULT_MEMORY_SIZE HUGE_SIZE /* 4 */ #define FN_SEP '/' /* 5 */ @@ -417,44 +416,21 @@ static int32 unique_task_id(void) /* ------------------------------------------------------------------------- */ #ifdef UNIX /* 1 */ -#define MACHINE_STRING "Unix" -/* 2 */ -#define USE_TEMPORARY_FILES -#define HAS_REALPATH -/* 3 */ -#define DEFAULT_MEMORY_SIZE HUGE_SIZE -/* 4 */ -#define FN_SEP '/' -/* 5 */ -#define PATHLEN 512 -#define Temporary_Directory "/tmp" -#define INCLUDE_TASK_ID -#ifdef MAIN_INFORM_FILE -static int32 unique_task_id(void) -{ return (int32)getpid(); -} -#endif -#endif -/* ------------------------------------------------------------------------- */ -/* UNIX64 block */ -/* ------------------------------------------------------------------------- */ -#ifdef UNIX64 -/* 1 */ #ifndef MACHINE_STRING #define MACHINE_STRING "Unix" #endif /* 2 */ -#define USE_TEMPORARY_FILES #define HAS_REALPATH /* 3 */ #define DEFAULT_MEMORY_SIZE HUGE_SIZE /* 4 */ #define FN_SEP '/' /* 5 */ -#define Temporary_Directory "/tmp" #define PATHLEN 512 +#define Temporary_Directory "/tmp" #define INCLUDE_TASK_ID #ifdef MAIN_INFORM_FILE +#include static int32 unique_task_id(void) { return (int32)getpid(); } @@ -733,20 +709,6 @@ static int32 unique_task_id(void) #define GPAGESIZE 256 /* All Glulx memory boundaries must be multiples of GPAGESIZE. */ -/* In many places the compiler encodes a source-code location (file and - line number) into an int32 value. The encoded value looks like - file_number + FILE_LINE_SCALE_FACTOR*line_number. This will go - badly if a source file has more than FILE_LINE_SCALE_FACTOR lines, - of course. But this value is roughly eight million, which is a lot - of lines. - - There is also potential trouble if we have more than 512 source files; - perhaps 256, depending on signedness issues. However, there are other - spots in the compiler that assume no more than 255 source files, so - we'll stick with this for now. -*/ -#define FILE_LINE_SCALE_FACTOR (0x800000L) - /* ------------------------------------------------------------------------- */ /* Structure definitions (there are a few others local to files) */ /* ------------------------------------------------------------------------- */ @@ -826,6 +788,10 @@ typedef struct debug_location_s int32 end_line_number; int32 beginning_character_number; int32 end_character_number; + int32 orig_file_index; + int32 orig_beg_line_number; + int32 orig_beg_char_number; + /* We only track the beginning #origsource location, not the end. */ } debug_location; typedef struct debug_locations_s @@ -834,11 +800,21 @@ typedef struct debug_locations_s int reference_count; } debug_locations; +typedef struct brief_location_s +{ int32 file_index; + int32 line_number; + int32 orig_file_index; + int32 orig_line_number; +} brief_location; + typedef struct debug_location_beginning_s { debug_locations *head; int32 beginning_byte_index; int32 beginning_line_number; int32 beginning_character_number; + int32 orig_file_index; + int32 orig_beg_line_number; + int32 orig_beg_char_number; } debug_location_beginning; typedef struct keyword_group_s @@ -862,6 +838,10 @@ typedef struct FileId_s /* Source code file identifier: */ { char *filename; /* The filename (after translation) */ FILE *handle; /* Handle of file (when open), or NULL when closed */ + int is_input; /* Is this a source file that we are + parsing? If not, this is an + origsource filename (and handle + is NULL). */ } FileId; typedef struct ErrorPosition_s @@ -869,6 +849,10 @@ typedef struct ErrorPosition_s char *source; int line_number; int main_flag; + int orig_file; + char *orig_source; + int32 orig_line; + int32 orig_char; } ErrorPosition; /* A memory block can hold at most ALLOC_CHUNK_SIZE * 72: */ @@ -1359,19 +1343,20 @@ typedef struct operator_s #define MESSAGE_CODE 23 #define NEARBY_CODE 24 #define OBJECT_CODE 25 -#define PROPERTY_CODE 26 -#define RELEASE_CODE 27 -#define REPLACE_CODE 28 -#define SERIAL_CODE 29 -#define SWITCHES_CODE 30 -#define STATUSLINE_CODE 31 -#define STUB_CODE 32 -#define SYSTEM_CODE 33 -#define TRACE_CODE 34 -#define UNDEF_CODE 35 -#define VERB_CODE 36 -#define VERSION_CODE 37 -#define ZCHARACTER_CODE 38 +#define ORIGSOURCE_CODE 26 +#define PROPERTY_CODE 27 +#define RELEASE_CODE 28 +#define REPLACE_CODE 29 +#define SERIAL_CODE 30 +#define SWITCHES_CODE 31 +#define STATUSLINE_CODE 32 +#define STUB_CODE 33 +#define SYSTEM_CODE 34 +#define TRACE_CODE 35 +#define UNDEF_CODE 36 +#define VERB_CODE 37 +#define VERSION_CODE 38 +#define ZCHARACTER_CODE 39 #define OPENBLOCK_CODE 100 #define CLOSEBLOCK_CODE 101 @@ -2253,7 +2238,7 @@ extern void make_upper_case(char *str); /* Extern definitions for "directs" */ /* ------------------------------------------------------------------------- */ -extern int32 routine_starts_line; +extern brief_location routine_starts_line; extern int no_routines, no_named_routines, no_locals, no_termcs; extern int terminating_characters[]; @@ -2278,7 +2263,7 @@ extern void memoryerror(char *s, int32 size) NORETURN; extern void error(char *s); extern void error_named(char *s1, char *s2); extern void error_numbered(char *s1, int val); -extern void error_named_at(char *s1, char *s2, int32 report_line); +extern void error_named_at(char *s1, char *s2, brief_location report_line); extern void ebf_error(char *s1, char *s2); extern void char_error(char *s, int ch); extern void unicode_char_error(char *s, int32 uni); @@ -2286,8 +2271,8 @@ extern void no_such_label(char *lname); extern void warning(char *s); extern void warning_numbered(char *s1, int val); extern void warning_named(char *s1, char *s2); -extern void dbnu_warning(char *type, char *name, int32 report_line); -extern void uncalled_routine_warning(char *type, char *name, int32 report_line); +extern void dbnu_warning(char *type, char *name, brief_location report_line); +extern void uncalled_routine_warning(char *type, char *name, brief_location report_line); extern void obsolete_warning(char *s1); extern void link_error(char *s); extern void link_error_named(char *s1, char *s2); @@ -2338,7 +2323,9 @@ extern int test_for_incdec(assembly_operand AO); /* Extern definitions for "files" */ /* ------------------------------------------------------------------------- */ -extern int input_file; +extern int total_files; +extern int current_input_file; +extern int total_input_files; extern FileId *InputFiles; extern FILE *Temp1_fp, *Temp2_fp, *Temp3_fp; @@ -2390,6 +2377,7 @@ extern void add_to_checksum(void *address); extern void load_sourcefile(char *story_name, int style); extern int file_load_chars(int file_number, char *buffer, int length); extern void close_all_source(void); +extern int register_orig_sourcefile(char *filename); extern void output_file(void); @@ -2487,6 +2475,10 @@ extern void report_errors_at_current_line(void); extern debug_location get_current_debug_location(void); extern debug_location get_error_report_debug_location(void); extern int32 get_current_line_start(void); +extern void set_origsource_location(char *source, int32 line, int32 charnum); +extern brief_location get_brief_location(ErrorPosition *errpos); +extern void export_brief_location(brief_location loc, ErrorPosition *errpos); +extern brief_location blank_brief_location; extern void put_token_back(void); extern void get_next_token(void); @@ -2609,7 +2601,7 @@ extern int no_symbols; extern int32 **symbs; extern int32 *svals; extern int *smarks; -extern int32 *slines; +extern brief_location *slines; extern int *sflags; #ifdef VAX extern char *stypes; @@ -2640,7 +2632,7 @@ extern void issue_unused_warnings(void); extern void add_symbol_replacement_mapping(int original, int renamed); extern int find_symbol_replacement(int *value); extern void df_note_function_start(char *name, uint32 address, - int embedded_flag, int32 source_line); + int embedded_flag, brief_location source_line); extern void df_note_function_end(uint32 endaddress); extern void df_note_function_symbol(int symbol); extern void locate_dead_functions(void); diff --git a/lexer.c b/lexer.c index fa45ab4..5cccffe 100644 --- a/lexer.c +++ b/lexer.c @@ -91,6 +91,9 @@ extern debug_location get_token_location(void) result.end_line_number = location->end_line_number; result.beginning_character_number = location->end_character_number; result.end_character_number = location->end_character_number; + result.orig_file_index = location->orig_file_index; + result.orig_beg_line_number = location->orig_beg_line_number; + result.orig_beg_char_number = location->orig_beg_char_number; return result; } @@ -110,6 +113,12 @@ static void set_token_location(debug_location location) location.end_line_number; last_token_location->location.end_character_number = location.end_character_number; + last_token_location->location.orig_file_index = + location.orig_file_index; + last_token_location->location.orig_beg_line_number = + location.orig_beg_line_number; + last_token_location->location.orig_beg_char_number = + location.orig_beg_char_number; } else { debug_locations*successor = my_malloc @@ -133,6 +142,10 @@ extern debug_location_beginning get_token_location_beginning(void) last_token_location->location.end_line_number; result.beginning_character_number = last_token_location->location.end_character_number; + result.orig_file_index = last_token_location->location.orig_file_index; + result.orig_beg_line_number = last_token_location->location.orig_beg_line_number; + result.orig_beg_char_number = last_token_location->location.orig_beg_char_number; + return result; } @@ -194,6 +207,14 @@ extern debug_locations get_token_location_end result.location.beginning_character_number = beginning.beginning_character_number; } + + result.location.orig_file_index = + beginning.orig_file_index; + result.location.orig_beg_line_number = + beginning.orig_beg_line_number; + result.location.orig_beg_char_number = + beginning.orig_beg_char_number; + result.next = beginning.head->next; result.reference_count = 0; return result; @@ -444,7 +465,7 @@ keyword_group directives = "default", "dictionary", "end", "endif", "extend", "fake_action", "global", "ifdef", "ifndef", "ifnot", "ifv3", "ifv5", "iftrue", "iffalse", "import", "include", "link", "lowstring", "message", - "nearby", "object", "property", "release", "replace", + "nearby", "object", "origsource", "property", "release", "replace", "serial", "switches", "statusline", "stub", "system_file", "trace", "undef", "verb", "version", "zcharacter", "" }, @@ -905,16 +926,20 @@ typedef struct LexicalBlock_s int file_no; /* Or 255 if not from a file; used for debug information */ + char *orig_source; /* From #origsource direct */ + int orig_file; + int32 orig_line; + int32 orig_char; } LexicalBlock; static LexicalBlock NoFileOpen = -{ "", FALSE, FALSE, 0, 0, 0, 255 }; + { "", FALSE, FALSE, 0, 0, 0, 255, NULL, 0, 0, 0 }; static LexicalBlock MakingOutput = -{ "", FALSE, FALSE, 0, 0, 0, 255 }; + { "", FALSE, FALSE, 0, 0, 0, 255, NULL, 0, 0, 0 }; static LexicalBlock StringLB = -{ "", FALSE, TRUE, 0, 0, 0, 255 }; + { "", FALSE, TRUE, 0, 0, 0, 255, NULL, 0, 0, 0 }; static LexicalBlock *CurrentLB; /* The current lexical block of input text */ @@ -927,6 +952,28 @@ extern int is_systemfile(void) { return ((CurrentLB->sys_flag)?1:0); } +extern void set_origsource_location(char *source, int32 line, int32 charnum) +{ + if (!source) { + /* Clear the Origsource declaration. */ + CurrentLB->orig_file = 0; + CurrentLB->orig_source = NULL; + CurrentLB->orig_line = 0; + CurrentLB->orig_char = 0; + return; + } + + /* Get the file number for a new or existing InputFiles entry. */ + int file_no = register_orig_sourcefile(source); + + CurrentLB->orig_file = file_no; + CurrentLB->orig_source = InputFiles[file_no-1].filename; + CurrentLB->orig_line = line; + CurrentLB->orig_char = charnum; +} + +/* Error locations. */ + extern debug_location get_current_debug_location(void) { debug_location result; /* Assume that all input characters are one byte. */ @@ -938,6 +985,9 @@ extern debug_location get_current_debug_location(void) result.beginning_character_number = CurrentLB->chars_read - CurrentLB->line_start; result.end_character_number = result.beginning_character_number; + result.orig_file_index = CurrentLB->orig_file; + result.orig_beg_line_number = CurrentLB->orig_line; + result.orig_beg_char_number = CurrentLB->orig_char; return result; } @@ -952,6 +1002,10 @@ extern void report_errors_at_current_line(void) ErrorReport.main_flag = CurrentLB->main_flag; if (debugfile_switch) ErrorReport_debug_location = get_current_debug_location(); + ErrorReport.orig_file = CurrentLB->orig_file; + ErrorReport.orig_source = CurrentLB->orig_source; + ErrorReport.orig_line = CurrentLB->orig_line; + ErrorReport.orig_char = CurrentLB->orig_char; } extern debug_location get_error_report_debug_location(void) @@ -962,6 +1016,31 @@ extern int32 get_current_line_start(void) { return CurrentLB->line_start; } +brief_location blank_brief_location; + +extern brief_location get_brief_location(ErrorPosition *errpos) +{ + brief_location loc; + loc.file_index = errpos->file_number; + loc.line_number = errpos->line_number; + loc.orig_file_index = errpos->orig_file; + loc.orig_line_number = errpos->orig_line; + return loc; +} + +extern void export_brief_location(brief_location loc, ErrorPosition *errpos) +{ + if (loc.file_index != -1) + { errpos->file_number = loc.file_index; + errpos->line_number = loc.line_number; + errpos->main_flag = (errpos->file_number == 1); + errpos->orig_source = NULL; + errpos->orig_file = loc.orig_file_index; + errpos->orig_line = loc.orig_line_number; + errpos->orig_char = 0; + } +} + /* ------------------------------------------------------------------------- */ /* Hash printing and line counting */ /* ------------------------------------------------------------------------- */ @@ -1181,7 +1260,7 @@ static int File_sp; /* Stack pointer */ static Sourcefile *CF; /* Top entry on stack */ -static int last_no_files; +static int last_input_file; static void begin_buffering_file(int i, int file_no) { int j, cnt; uchar *p; @@ -1216,6 +1295,8 @@ static void begin_buffering_file(int i, int file_no) FileStack[i].LB.chars_read = LOOKAHEAD_SIZE; FileStack[i].LB.filename = InputFiles[file_no-1].filename; FileStack[i].LB.file_no = file_no; + FileStack[i].LB.orig_source = NULL; FileStack[i].LB.orig_file = 0; + FileStack[i].LB.orig_line = 0; FileStack[i].LB.orig_char = 0; CurrentLB = &(FileStack[i].LB); CF = &(FileStack[i]); @@ -1235,20 +1316,29 @@ static void create_char_pipeline(void) { File_sp = 0; begin_buffering_file(File_sp++, 1); - pipeline_made = TRUE; last_no_files = input_file; + pipeline_made = TRUE; + last_input_file = current_input_file; } static int get_next_char_from_pipeline(void) { uchar *p; - while (last_no_files < input_file) + while (last_input_file < current_input_file) { /* An "Include" file must have opened since the last character - was read... */ + was read. Perhaps more than one. We run forward through the + list and add them to the include stack. But we ignore + "Origsource" files (which were never actually opened for + reading). */ + + last_input_file++; + if (!InputFiles[last_input_file-1].is_input) + continue; - begin_buffering_file(File_sp++, ++last_no_files); + begin_buffering_file(File_sp++, last_input_file); } - last_no_files = input_file; + if (last_input_file != current_input_file) + compiler_error("last_input_file did not match after Include"); if (File_sp == 0) { lookahead = 0; lookahead2 = 0; lookahead3 = 0; return 0; @@ -1728,6 +1818,10 @@ extern void restart_lexer(char *lexical_source, char *name) extern void init_lexer_vars(void) { + blank_brief_location.file_index = -1; + blank_brief_location.line_number = 0; + blank_brief_location.orig_file_index = 0; + blank_brief_location.orig_line_number = 0; } extern void lexer_begin_prepass(void) @@ -1790,6 +1884,9 @@ extern void lexer_allocate_arrays(void) first_token_locations->location.end_line_number = 0; first_token_locations->location.beginning_character_number = 0; first_token_locations->location.end_character_number = 0; + first_token_locations->location.orig_file_index = 0; + first_token_locations->location.orig_beg_line_number = 0; + first_token_locations->location.orig_beg_char_number = 0; first_token_locations->next = NULL; first_token_locations->reference_count = 0; last_token_location = first_token_locations; diff --git a/symbols.c b/symbols.c index c73259c..13a5aee 100644 --- a/symbols.c +++ b/symbols.c @@ -65,7 +65,7 @@ int no_named_constants; /* Copied into story file */ int32 **symbs; int32 *svals; int *smarks; /* Glulx-only */ - int32 *slines; + brief_location *slines; int *sflags; #ifdef VAX char *stypes; /* In VAX C, insanely, "signed char" is illegal */ @@ -244,8 +244,7 @@ extern int symbol_index(char *p, int hashcode) unbound-symbol-causes-asm-error? */ sflags[no_symbols] = UNKNOWN_SFLAG; stypes[no_symbols] = CONSTANT_T; - slines[no_symbols] = ErrorReport.line_number - + FILE_LINE_SCALE_FACTOR*ErrorReport.file_number; + slines[no_symbols] = get_brief_location(&ErrorReport); if (debugfile_switch) { nullify_debug_file_position (&symbol_debug_backpatch_positions[no_symbols]); @@ -330,8 +329,8 @@ static void describe_flags(int flags) extern void describe_symbol(int k) { printf("%4d %-16s %2d:%04d %04x %s ", k, (char *) (symbs[k]), - (int)(slines[k]/FILE_LINE_SCALE_FACTOR), - (int)(slines[k]%FILE_LINE_SCALE_FACTOR), + (int)(slines[k].file_index), + (int)(slines[k].line_number), svals[k], typename(stypes[k])); describe_flags(sflags[k]); } @@ -521,8 +520,7 @@ static void assign_symbol_base(int index, int32 value, int type) if (sflags[index] & UNKNOWN_SFLAG) { sflags[index] &= (~UNKNOWN_SFLAG); if (is_systemfile()) sflags[index] |= INSF_SFLAG; - slines[index] = ErrorReport.line_number - + FILE_LINE_SCALE_FACTOR*ErrorReport.file_number; + slines[index] = get_brief_location(&ErrorReport); } } @@ -599,14 +597,14 @@ static void emit_debug_information_for_predefined_symbol static void create_symbol(char *p, int32 value, int type) { int i = symbol_index(p, -1); - svals[i] = value; stypes[i] = type; slines[i] = 0; + svals[i] = value; stypes[i] = type; slines[i] = blank_brief_location; sflags[i] = USED_SFLAG + SYSTEM_SFLAG; emit_debug_information_for_predefined_symbol(p, i, value, type); } static void create_rsymbol(char *p, int value, int type) { int i = symbol_index(p, -1); - svals[i] = value; stypes[i] = type; slines[i] = 0; + svals[i] = value; stypes[i] = type; slines[i] = blank_brief_location; sflags[i] = USED_SFLAG + SYSTEM_SFLAG + REDEFINABLE_SFLAG; emit_debug_information_for_predefined_symbol(p, i, value, type); } @@ -827,7 +825,7 @@ typedef struct df_reference_struct df_reference_t; struct df_function_struct { char *name; /* borrowed reference, generally to the symbs[] table */ - int32 source_line; /* copied from routine_starts_line */ + brief_location source_line; /* copied from routine_starts_line */ int sysfile; /* does this occur in a system file? */ uint32 address; /* function offset in zcode_area (not the final address) */ uint32 newaddress; /* function offset after stripping */ @@ -898,7 +896,7 @@ uint32 df_total_size_after_stripping; Any symbol referenced from now on will be associated with the function. */ extern void df_note_function_start(char *name, uint32 address, - int embedded_flag, int32 source_line) + int embedded_flag, brief_location source_line) { df_function_t *func; int bucket; @@ -1374,7 +1372,7 @@ extern void symbols_allocate_arrays(void) svals = my_calloc(sizeof(int32), MAX_SYMBOLS, "symbol values"); if (glulx_mode) smarks = my_calloc(sizeof(int), MAX_SYMBOLS, "symbol markers"); - slines = my_calloc(sizeof(int32), MAX_SYMBOLS, "symbol lines"); + slines = my_calloc(sizeof(brief_location), MAX_SYMBOLS, "symbol lines"); stypes = my_calloc(sizeof(char), MAX_SYMBOLS, "symbol types"); sflags = my_calloc(sizeof(int), MAX_SYMBOLS, "symbol flags"); if (debugfile_switch) @@ -1407,7 +1405,7 @@ extern void symbols_allocate_arrays(void) df_functions_sorted = NULL; df_functions_sorted_count = 0; - df_note_function_start("", DF_NOT_IN_FUNCTION, FALSE, -1); + df_note_function_start("", DF_NOT_IN_FUNCTION, FALSE, blank_brief_location); df_note_function_end(DF_NOT_IN_FUNCTION); /* Now df_current_function is df_functions_head. */ } diff --git a/tables.c b/tables.c index 88f220b..7a18dbd 100644 --- a/tables.c +++ b/tables.c @@ -953,7 +953,7 @@ or less."); { printf("In:\ %3d source code files %6d syntactic lines\n\ %6d textual lines %8ld characters ", - input_file, no_syntax_lines, + total_input_files, no_syntax_lines, total_source_line_count, (long int) total_chars_read); if (character_set_unicode) printf("(UTF-8)\n"); else if (character_set_setting == 0) printf("(plain ASCII)\n"); @@ -1631,7 +1631,7 @@ table format requested (producing number 2 format instead)"); { printf("In:\ %3d source code files %6d syntactic lines\n\ %6d textual lines %8ld characters ", - input_file, no_syntax_lines, + total_input_files, no_syntax_lines, total_source_line_count, (long int) total_chars_read); if (character_set_unicode) printf("(UTF-8)\n"); else if (character_set_setting == 0) printf("(plain ASCII)\n"); -- 2.31.1