Updating compiler to commit dabfa73 from upstream dated Oct 1 2016. These changes...
authorJason Self <j@jxself.org>
Sat, 22 Oct 2016 18:34:43 +0000 (11:34 -0700)
committerJason Self <j@jxself.org>
Sat, 22 Oct 2016 18:34:43 +0000 (11:34 -0700)
asm.c
directs.c
errors.c
expressp.c
files.c
header.h
lexer.c
symbols.c
tables.c

diff --git a/asm.c b/asm.c
index a14493984a1203a2332f2038b7cb425953b7782a..d3a9d995b8cb13d2d9eadd5fd2486ce9269e288f 100644 (file)
--- 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,
index 37bbf82c411c78cba7d45c43190c0f633a1d8997..5c622ba547b2bccab0ba285f31e489c79ff450e8 100644 (file)
--- 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 <file>                                                   */
+    /*   Origsource <file> <line>                                            */
+    /*   Origsource <file> <line> <char>                                     */
+    /*   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]                     */
     /* --------------------------------------------------------------------- */
index 3d4a866bdde19bc34bd6ef82bc80ca84e37599a0..0ea92b18d9bb7dd8f36429d9961272c389cf6769 100644 (file)
--- 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 = "<no text read yet>";
     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)
index 4c32f0ec962be040b7f74feceea40de9132abfa1..270f308991371c09b1868c195b191a098453cea6 100644 (file)
@@ -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 fc0ad8ce23422b64b0b9f64f4c7f93a11143041e..4e7377e4cb9c661db45c0abbb59c484333063aab 100644 (file)
--- a/files.c
+++ b/files.c
 
 #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("<source index=\"%d\">", input_file);
+    {   debug_file_printf("<source index=\"%d\">", total_files);
         debug_file_printf("<given-path>");
         debug_file_print_with_entities(filename_given);
         debug_file_printf("</given-path>");
@@ -148,13 +153,17 @@ extern void load_sourcefile(char *filename_given, int same_directory_flag)
         debug_file_printf("</source>");
     }
 
-    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<input_file; i++) close_sourcefile(i+1);
+    for (i=0; i<total_files; i++) close_sourcefile(i+1);
+}
+
+/* ------------------------------------------------------------------------- */
+/*   Register an #origsource filename. This goes in the InputFiles table,    */
+/*   but we do not open the file or advance current_input_file.              */
+/* ------------------------------------------------------------------------- */
+
+extern int register_orig_sourcefile(char *filename)
+{
+    int ix;
+
+    /* If the filename has already been used as an origsource filename,
+       return that entry. We check the most-recently-used file first, and
+       then search the list. */
+    if (current_origsource_file > 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; ix++) {
+        if (InputFiles[ix].is_input)
+            continue;
+        if (!strcmp(filename, InputFiles[ix].filename)) {
+            current_origsource_file = ix+1;
+            return current_origsource_file;
+        }
+    }
+
+    /* This filename has never been used before. Allocate a new InputFiles
+       entry. */
+
+    char *name = filename; /* no translation */
+
+    if (total_files == MAX_SOURCE_FILES)
+        memoryerror("MAX_SOURCE_FILES", MAX_SOURCE_FILES);
+
+    if (filename_storage_left <= (int)strlen(name))
+        memoryerror("MAX_SOURCE_FILES", MAX_SOURCE_FILES);
+
+    filename_storage_left -= strlen(name)+1;
+    strcpy(filename_storage_p, name);
+    InputFiles[total_files].filename = filename_storage_p;
+
+    filename_storage_p += strlen(name)+1;
+
+    if (debugfile_switch)
+    {   debug_file_printf("<source index=\"%d\">", total_files);
+        debug_file_printf("<given-path>");
+        debug_file_print_with_entities(filename);
+        debug_file_printf("</given-path>");
+        debug_file_printf("<language>Inform 7</language>");
+        debug_file_printf("</source>");
+    }
+
+    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
+        ("<file-index>%d</file-index>", location.orig_file_index - 1);
+    if (location.orig_beg_line_number)
+        debug_file_printf
+            ("<line>%d</line>", location.orig_beg_line_number);
+    if (location.orig_beg_char_number)
+        debug_file_printf
+            ("<character>%d</character>", location.orig_beg_char_number);
+}
+
 extern void write_debug_location(debug_location location)
 {   if (location.file_index && location.file_index != 255)
     {   debug_file_printf("<source-code-location>");
         write_debug_location_internals(location);
         debug_file_printf("</source-code-location>");
     }
+    if (location.orig_file_index)
+    {   debug_file_printf("<source-code-location>");
+        write_debug_location_origsource_internals(location);
+        debug_file_printf("</source-code-location>");
+    }
 }
 
 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("</source-code-location>");
         }
+        if (locations.location.orig_file_index)
+        {   debug_file_printf("<source-code-location>");
+            write_debug_location_origsource_internals(locations.location);
+            debug_file_printf("</source-code-location>");
+        }
     }
     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)
index 94ca84f467ecb1e09f0fb9fe8108f23f34ce093b..4fdeefe3d2e73ec3f5eae074cf6f9562440639b1 100644 (file)
--- a/header.h
+++ b/header.h
 /*     #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 <unistd.h>
 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 fa45ab49a4252864fc726c0cb9fe8ce077276bee..5cccffea04b6d72031c29b755381549259019fb3 100644 (file)
--- 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 =
-{   "<before compilation>", FALSE, FALSE, 0, 0, 0, 255 };
+    {   "<before compilation>",  FALSE, FALSE, 0, 0, 0, 255, NULL, 0, 0, 0 };
 
 static LexicalBlock MakingOutput =
-{   "<constructing output>", FALSE, FALSE, 0, 0, 0, 255 };
+    {   "<constructing output>", FALSE, FALSE, 0, 0, 0, 255, NULL, 0, 0, 0 };
 
 static LexicalBlock StringLB =
-{   "<veneer routine>", FALSE, TRUE, 0, 0, 0, 255 };
+    {   "<veneer routine>",      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;
index c73259c85d04a54cd19d42bcf894e635655f7b48..13a5aee313f5d81f98da6fd9c96d1bd4899f13d7 100644 (file)
--- 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("<global namespace>", DF_NOT_IN_FUNCTION, FALSE, -1);
+        df_note_function_start("<global namespace>", DF_NOT_IN_FUNCTION, FALSE, blank_brief_location);
         df_note_function_end(DF_NOT_IN_FUNCTION);
         /* Now df_current_function is df_functions_head. */
     }
index 88f220bf56284e5af2dd687b039b71d36a731eee..7a18dbdc33f79066464c4819b4d0b2f2f107ef59 100644 (file)
--- 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");