1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-02 23:14:57 +03:00
inform7/inter/bytecode-module/Chapter 3/Text Provenance.w
2023-04-28 11:18:56 +01:00

83 lines
2 KiB
OpenEdge ABL

[Provenance::] Text Provenance.
Recording where fragments of text originally came from.
@ Inter code sometimes needs to contain fragments of not-yet-parsed Inform 6
syntax code, in the form of |SPLAT_IST| and |INSERT_IST| instructions. In order
for it to be possible to relate errors in those fragments to the original text
files they came from, we need to record their "provenance".
This is only a wrapper for saying something like "line 17 in |whatever.txt|".
Line numbers count from 1 at the top of a text file.
=
typedef struct text_provenance {
struct text_stream *textual_filename;
int line_number;
} text_provenance;
@ This provides a "don't know, or, it didn't come from a text file, I made it up"
value:
=
text_provenance Provenance::nowhere(void) {
text_provenance nowhere;
nowhere.textual_filename = NULL;
nowhere.line_number = 0;
return nowhere;
}
int Provenance::is_somewhere(text_provenance where) {
if (Str::len(where.textual_filename) > 0) return TRUE;
return FALSE;
}
@ Composing:
=
text_provenance Provenance::at_file_and_line(text_stream *file, int line) {
text_provenance somewhere;
somewhere.textual_filename = Str::duplicate(file);
somewhere.line_number = line;
return somewhere;
}
@ Decomposing:
=
int Provenance::get_line(text_provenance where) {
if (Provenance::is_somewhere(where)) return where.line_number;
return 0;
}
filename *Provenance::get_filename(text_provenance where) {
if (Provenance::is_somewhere(where))
return Filenames::from_text(where.textual_filename);
return NULL;
}
@ Altering in place:
=
void Provenance::set_line(text_provenance *where, int lc) {
if ((where) && (Provenance::is_somewhere(*where)))
where->line_number = lc;
}
void Provenance::advance_line(text_provenance *where, int by) {
if ((where) && (Provenance::is_somewhere(*where)))
where->line_number += by;
}
@ Writing to text:
=
void Provenance::write(OUTPUT_STREAM, text_provenance at) {
if (Provenance::is_somewhere(at)) {
TextualInter::write_text(OUT, at.textual_filename);
WRITE(" %d", at.line_number);
} else {
WRITE("<nowhere>");
}
}