3
3
4
4
#include < cstdint>
5
5
#include < vector>
6
+ #include < iostream>
6
7
7
8
namespace LFortran
8
9
{
@@ -94,50 +95,63 @@ 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
+ uint32_t index = bisection (file_ends, out_pos);
133
+ if (files[index ].out_start .size () == 0 ) return 0 ;
134
+ uint32_t interval = bisection (files[index ].out_start , out_pos)-1 ;
135
+ uint32_t rel_pos = out_pos - files[index ].out_start [interval];
136
+ uint32_t in_pos = files[index ].in_start [interval] + rel_pos;
137
+ if (files[index ].preprocessor ) {
124
138
// If preprocessor was used, do one more remapping
125
- uint32_t interval0 = bisection (out_start0, in_pos)-1 ;
126
- if (interval_type0[interval0] == 0 ) {
139
+ uint32_t interval0 = bisection (files[ index ]. out_start0 , in_pos)-1 ;
140
+ if (files[ index ]. interval_type0 [interval0] == 0 ) {
127
141
// 1:1 interval
128
- uint32_t rel_pos0 = in_pos - out_start0[interval0];
129
- uint32_t in_pos0 = in_start0[interval0] + rel_pos0;
142
+ uint32_t rel_pos0 = in_pos - files[ index ]. out_start0 [interval0];
143
+ uint32_t in_pos0 = files[ index ]. in_start0 [interval0] + rel_pos0;
130
144
return in_pos0;
131
145
} else {
132
146
// many to many interval
133
147
uint32_t in_pos0;
134
- if (in_pos == out_start0[interval0+1 ]-1 || show_last) {
148
+ if (in_pos == files[ index ]. out_start0 [interval0+1 ]-1 || show_last) {
135
149
// The end of the interval in "out" code
136
150
// Return the end of the interval in "in" code
137
- in_pos0 = in_start0[interval0]+in_size0[interval0]-1 ;
151
+ in_pos0 = files[ index ]. in_start0 [interval0]+files[ index ]. in_size0 [interval0]-1 ;
138
152
} else {
139
153
// Otherwise return the beginning of the interval in "in"
140
- in_pos0 = in_start0[interval0];
154
+ in_pos0 = files[ index ]. in_start0 [interval0];
141
155
}
142
156
return in_pos0;
143
157
}
@@ -150,12 +164,17 @@ struct LocationManager {
150
164
// `position` starts from 0
151
165
// `line` and `col` starts from 1
152
166
// `in_newlines` starts from 0
153
- void pos_to_linecol (uint32_t position, uint32_t &line, uint32_t &col) const {
167
+ void pos_to_linecol (uint32_t position, uint32_t &line, uint32_t &col,
168
+ std::string &filename) const {
169
+ uint32_t index = bisection (file_ends, position);
170
+ for (auto &x: file_ends) std::cout << x << " \n " ;
171
+ std::cout << position << " :\n " ;
172
+ filename = files[index ].in_filename ;
154
173
const std::vector<uint32_t > *newlines;
155
- if (preprocessor) {
156
- newlines = &in_newlines0;
174
+ if (files[ index ]. preprocessor ) {
175
+ newlines = &files[ index ]. in_newlines0 ;
157
176
} else {
158
- newlines = &in_newlines;
177
+ newlines = &files[ index ]. in_newlines ;
159
178
}
160
179
int32_t interval = bisection (*newlines, position);
161
180
if (interval >= 1 && position == (*newlines)[interval-1 ]) {
@@ -179,9 +198,9 @@ struct LocationManager {
179
198
180
199
void init_simple (const std::string &input) {
181
200
uint32_t n = input.size ();
182
- out_start = {0 , n};
183
- in_start = {0 , n};
184
- get_newlines (input, in_newlines);
201
+ files. back (). out_start = {0 , n};
202
+ files. back (). in_start = {0 , n};
203
+ get_newlines (input, files. back (). in_newlines );
185
204
}
186
205
187
206
};
0 commit comments