3
3
4
4
#include < cstdint>
5
5
#include < vector>
6
+ // #include <iostream>
6
7
7
8
namespace LFortran
8
9
{
@@ -94,50 +95,67 @@ struct LocationManager {
94
95
//
95
96
//
96
97
//
97
- std::vector<uint32_t > out_start; // consecutive intervals in the output code
98
- std::vector<uint32_t > in_start; // start + size in the original code
99
- std::vector<uint32_t > in_newlines; // position of all \n in the original code
98
+ struct FileLocations {
99
+ std::vector<uint32_t > out_start; // consecutive intervals in the output code
100
+ std::vector<uint32_t > in_start; // start + size in the original code
101
+ std::vector<uint32_t > in_newlines; // position of all \n in the original code
100
102
101
- // For preprocessor (if preprocessor==true).
102
- // TODO: design a common structure, that also works with #include, that
103
- // has these mappings for each file
104
- bool preprocessor = false ;
105
- std::string in_filename;
106
- uint32_t current_line=0 ;
107
- std::vector<uint32_t > out_start0; // consecutive intervals in the output code
108
- std::vector<uint32_t > in_start0; // start + size in the original code
109
- std::vector<uint32_t > in_size0; // Size of the `in` interval
110
- std::vector<uint32_t > interval_type0; // 0 .... 1:1; 1 ... many to many;
111
- std::vector<uint32_t > in_newlines0; // position of all \n in the original code
112
- // std::vector<uint32_t> filename_id; // file name for each interval, ID
113
- // std::vector<std::string> filenames; // filenames lookup for an ID
103
+ // For preprocessor (if preprocessor==true).
104
+ // TODO: design a common structure, that also works with #include, that
105
+ // has these mappings for each file
106
+ bool preprocessor = false ;
107
+ std::string in_filename;
108
+ uint32_t current_line=0 ;
109
+ std::vector<uint32_t > out_start0; // consecutive intervals in the output code
110
+ std::vector<uint32_t > in_start0; // start + size in the original code
111
+ std::vector<uint32_t > in_size0; // Size of the `in` interval
112
+ std::vector<uint32_t > interval_type0; // 0 .... 1:1; 1 ... many to many;
113
+ std::vector<uint32_t > in_newlines0; // position of all \n in the original code
114
+ };
115
+ std::vector<FileLocations> files;
116
+ std::vector<uint32_t > file_ends; // position of all ends of files
117
+ // For a given Location we use the `file_ends` and bisection to determine
118
+ // the file (index) which the location is from. Then we use this index into
119
+ // the `files` vector and use `in_newlines` and other information to
120
+ // determine the line and column inside this file, and the `in_filename`
121
+ // field to determine the filename. This happens when the diagnostic is
122
+ // printed. The `pos_to_linecol` function below should be modified to
123
+ // return line, column and the filename:
124
+ //
125
+ // void pos_to_linecol(uint32_t position, uint32_t &line, uint32_t &col,
126
+ // std::string &filename) const;
114
127
115
128
// Converts a position in the output code to a position in the original code
116
129
// Every character in the output code has a corresponding location in the
117
130
// original code, so this function always succeeds
118
131
uint32_t output_to_input_pos (uint32_t out_pos, bool show_last) const {
119
- if (out_start.size () == 0 ) return 0 ;
120
- uint32_t interval = bisection (out_start, out_pos)-1 ;
121
- uint32_t rel_pos = out_pos - out_start[interval];
122
- uint32_t in_pos = in_start[interval] + rel_pos;
123
- if (preprocessor) {
132
+ // std::cout << "out: " << out_pos << "\n";
133
+ uint32_t index = bisection (file_ends, out_pos);
134
+ if (index == file_ends.size ()) index -= 1 ;
135
+ // std::cout << index << ":\n";
136
+ if (files[index ].out_start .size () == 0 ) return 0 ;
137
+ uint32_t interval = bisection (files[index ].out_start , out_pos)-1 ;
138
+ uint32_t rel_pos = out_pos - files[index ].out_start [interval];
139
+ uint32_t in_pos = files[index ].in_start [interval] + rel_pos;
140
+ // std::cout << "in: "<< in_pos << "\n";
141
+ if (files[index ].preprocessor ) {
124
142
// If preprocessor was used, do one more remapping
125
- uint32_t interval0 = bisection (out_start0, in_pos)-1 ;
126
- if (interval_type0[interval0] == 0 ) {
143
+ uint32_t interval0 = bisection (files[ index ]. out_start0 , in_pos)-1 ;
144
+ if (files[ index ]. interval_type0 [interval0] == 0 ) {
127
145
// 1:1 interval
128
- uint32_t rel_pos0 = in_pos - out_start0[interval0];
129
- uint32_t in_pos0 = in_start0[interval0] + rel_pos0;
146
+ uint32_t rel_pos0 = in_pos - files[ index ]. out_start0 [interval0];
147
+ uint32_t in_pos0 = files[ index ]. in_start0 [interval0] + rel_pos0;
130
148
return in_pos0;
131
149
} else {
132
150
// many to many interval
133
151
uint32_t in_pos0;
134
- if (in_pos == out_start0[interval0+1 ]-1 || show_last) {
152
+ if (in_pos == files[ index ]. out_start0 [interval0+1 ]-1 || show_last) {
135
153
// The end of the interval in "out" code
136
154
// Return the end of the interval in "in" code
137
- in_pos0 = in_start0[interval0]+in_size0[interval0]-1 ;
155
+ in_pos0 = files[ index ]. in_start0 [interval0]+files[ index ]. in_size0 [interval0]-1 ;
138
156
} else {
139
157
// Otherwise return the beginning of the interval in "in"
140
- in_pos0 = in_start0[interval0];
158
+ in_pos0 = files[ index ]. in_start0 [interval0];
141
159
}
142
160
return in_pos0;
143
161
}
@@ -150,12 +168,26 @@ struct LocationManager {
150
168
// `position` starts from 0
151
169
// `line` and `col` starts from 1
152
170
// `in_newlines` starts from 0
153
- void pos_to_linecol (uint32_t position, uint32_t &line, uint32_t &col) const {
171
+ void pos_to_linecol (uint32_t position, uint32_t &line, uint32_t &col,
172
+ std::string &filename) const {
173
+ uint32_t index = bisection (file_ends, position);
174
+ if (index == file_ends.size ()) index -= 1 ;
175
+ // std::cout << position << ": Pos1\n";
176
+ filename = files[index ].in_filename ;
177
+ // std::cout << "----------------------------\n";
178
+ // for (auto &x: file_ends) std::cout << x << "\n";
179
+ // std::cout << "----------------------------\n";
180
+ // std::cout << file_ends[index] << ": "<< file_ends[index - 1] << ": " << position - file_ends[index - 1] << "\n";
181
+ if (index > 0 ) position -= file_ends[index - 1 ];
182
+ // std::cout << index << "_\n";
183
+ // std::cout << position << ": Pos2\n";
184
+ // std::cout << filename << ": Name\n";
185
+ // exit(0);
154
186
const std::vector<uint32_t > *newlines;
155
- if (preprocessor) {
156
- newlines = &in_newlines0;
187
+ if (files[ index ]. preprocessor ) {
188
+ newlines = &files[ index ]. in_newlines0 ;
157
189
} else {
158
- newlines = &in_newlines;
190
+ newlines = &files[ index ]. in_newlines ;
159
191
}
160
192
int32_t interval = bisection (*newlines, position);
161
193
if (interval >= 1 && position == (*newlines)[interval-1 ]) {
@@ -179,9 +211,9 @@ struct LocationManager {
179
211
180
212
void init_simple (const std::string &input) {
181
213
uint32_t n = input.size ();
182
- out_start = {0 , n};
183
- in_start = {0 , n};
184
- get_newlines (input, in_newlines);
214
+ files. back (). out_start = {0 , n};
215
+ files. back (). in_start = {0 , n};
216
+ get_newlines (input, files. back (). in_newlines );
185
217
}
186
218
187
219
};
0 commit comments