@@ -132,6 +134,7 @@ we now more efficiently remove them.)
intblocked_by_conditional; used in code generation
+structtext_provenanceprovenance; used for error reportingCLASS_DEFINITION} inter_schema_node;
@@ -139,7 +142,8 @@ we now more efficiently remove them.)
-voidInterSchemas::mark_unclosed(inter_schema_node *isn) {
+voidInterSchemas::mark_unclosed(inter_schema_node *isn) {while (isn) {if (isn->isn_type == CODE_ISNT) isn->unclosed = TRUE;isn = isn->parent_node;
@@ -207,7 +222,7 @@ at the top of the tree to serve that role.
-voidInterSchemas::mark_unopened(inter_schema_node *isn) {
+voidInterSchemas::mark_unopened(inter_schema_node *isn) {while (isn) {if (isn->isn_type == CODE_ISNT) {isn->unopened = TRUE;
@@ -217,7 +232,7 @@ at the top of the tree to serve that role.
inter_schema *sch = isn->parent_schema;inter_schema_node *top = sch->node_tree;inter_schema_node *code_isn =
-InterSchemas::new_node(isn->parent_schema, CODE_ISNT);
+InterSchemas::new_node(isn->parent_schema, CODE_ISNT, NULL);code_isn->child_node = top;sch->node_tree = code_isn;for (inter_schema_node *n = top; n; n = n->next_node)
@@ -243,7 +258,7 @@ associate this with any single node, so we mark the schema as a whole.
@@ -313,7 +328,7 @@ compilation process, and never survive into the final schema:
intpreinsert; fleeting markers onlyintpostinsert;
-
+intline_offset; counting lines for error message useCLASS_DEFINITION} inter_schema_token;
@@ -321,8 +336,8 @@ compilation process, and never survive into the final schema:
§10.
-inter_schema_token *InterSchemas::new_token(inttype, text_stream *material,
-inter_tioperation_primitive, intreserved_word, intn) {
+inter_schema_token *InterSchemas::new_token(inttype, text_stream *material,
+inter_tioperation_primitive, intreserved_word, intn, intoffset) {inter_schema_token *t = CREATE(inter_schema_token);t->ist_type = type;t->material = Str::duplicate(material);
@@ -344,6 +359,7 @@ compilation process, and never survive into the final schema:
t->constant_number = n;t->preinsert = FALSE;t->postinsert = FALSE;
+t->line_offset = offset;returnt;}
@@ -459,13 +475,13 @@ compilation process, and never survive into the final schema:
§14. Token insertion.
-voidInterSchemas::add_token(inter_schema *sch, inter_schema_token *t) {
+voidInterSchemas::add_token(inter_schema *sch, inter_schema_token *t) {if (sch->node_tree == NULL)
-sch->node_tree = InterSchemas::new_node(sch, EXPRESSION_ISNT);
+sch->node_tree = InterSchemas::new_node(sch, EXPRESSION_ISNT, t);InterSchemas::add_token_to_node(sch->node_tree, t);}
-voidInterSchemas::add_token_to_node(inter_schema_node *isn, inter_schema_token *t) {
+voidInterSchemas::add_token_to_node(inter_schema_node *isn, inter_schema_token *t) {if (isn->expression_tokens == NULL) isn->expression_tokens = t;else {inter_schema_token *p = isn->expression_tokens;
@@ -475,7 +491,7 @@ compilation process, and never survive into the final schema:
t->owner = isn;}
-voidInterSchemas::add_token_after(inter_schema_token *t, inter_schema_token *existing) {
+voidInterSchemas::add_token_after(inter_schema_token *t, inter_schema_token *existing) {if (existing == NULL) internal_error("can't add after null element");inter_schema_token *was = existing->next;existing->next = t;
@@ -487,7 +503,7 @@ compilation process, and never survive into the final schema:
-voidInterSchemas::changed_tokens_on(inter_schema_node *isn) {
+voidInterSchemas::changed_tokens_on(inter_schema_node *isn) {if (isn)for (inter_schema_token *l = isn->expression_tokens; l; l=l->next)l->owner = isn;
@@ -497,33 +513,33 @@ compilation process, and never survive into the final schema:
§2. Abbreviated I6S notation. This is a slicker notation used inside the calculus module for purposes
@@ -107,7 +107,7 @@ I6S code can only come from within the compiler itself, and means a bug.
if (de) return (inter_schema *) Dictionaries::value_for_entry(de);inter_schema *result = ParsingSchemas::back_end(from, TRUE,
-no_quoted_inames, quoted_inames);
+no_quoted_inames, quoted_inames, Provenance::nowhere());Dictionaries::create(i6s_inter_schema_cache, from);Dictionaries::write_value(i6s_inter_schema_cache, from, (void *) result);
@@ -153,16 +153,16 @@ so it's the caller's responsibility to check for those and act accordingly.
§4.1. A tail will only be present if the definition contains {-block}. If it
@@ -231,8 +231,8 @@ such operations are nested, they will work. We might then write:
inter_schema *ParsingSchemas::back_end(text_stream *from, intabbreviated,
-intno_quoted_inames, void **quoted_inames) {
-inter_schema *sch = InterSchemas::new(from);
+intno_quoted_inames, void **quoted_inames, text_provenanceprovenance) {
+inter_schema *sch = InterSchemas::new(from, provenance);if ((Log::aspect_switched_on(SCHEMA_COMPILATION_DA)) || (Log::aspect_switched_on(SCHEMA_COMPILATION_DETAILS_DA)))LOG("\n\n------------\nCompiling inter schema from: <%S>\n", from);
diff --git a/docs/building-module/2-rmf.html b/docs/building-module/2-rmf.html
index 9e74435ad..ca65419fd 100644
--- a/docs/building-module/2-rmf.html
+++ b/docs/building-module/2-rmf.html
@@ -196,14 +196,14 @@ and inserts them around the single statements in question.
if ((prev) && (t->preinsert > 0)) {t->preinsert--;inter_schema_token *open_b =
-InterSchemas::new_token(OPEN_BRACE_ISTT, I"{", 0, 0, -1);
+InterSchemas::new_token(OPEN_BRACE_ISTT, I"{", 0, 0, -1, t->line_offset);InterSchemas::add_token_after(open_b, prev);changed = TRUE; }if (t->postinsert > 0) {t->postinsert--;inter_schema_token *close_b =
-InterSchemas::new_token(CLOSE_BRACE_ISTT, I"}", 0, 0, -1);
+InterSchemas::new_token(CLOSE_BRACE_ISTT, I"}", 0, 0, -1, t->line_offset);InterSchemas::add_token_after(close_b, t);changed = TRUE; }
@@ -284,12 +284,12 @@ are removed.
if ((prev) && (t->ist_type == OPEN_BRACE_ISTT)) {prev->next = NULL;inter_schema_node *code_isn =
-InterSchemas::new_node(isn->parent_schema, CODE_ISNT);
+InterSchemas::new_node(isn->parent_schema, CODE_ISNT, t);isn->child_node = code_isn;code_isn->parent_node = isn;inter_schema_node *new_isn =
-InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t);code_isn->child_node = new_isn;new_isn->parent_node = code_isn;
@@ -319,7 +319,7 @@ are removed.
resumed = resumed->next;if (resumed) {inter_schema_node *new_isn =
-InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t);new_isn->expression_tokens = resumed;new_isn->parent_node = isn->parent_node;InterSchemas::changed_tokens_on(new_isn);
@@ -374,7 +374,7 @@ We want to represent them, however, by independent subtrees. So:
if (t->ist_type == CLOSE_ROUND_ISTT) bl--;if ((bl == 0) && (t->ist_type == DIVIDER_ISTT) && (t->next)) {inter_schema_node *new_isn =
-InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t);new_isn->expression_tokens = t->next;new_isn->parent_node = isn->parent_node;if (isn->child_node) {
@@ -482,7 +482,8 @@ of statements (or expressions), hierarchically arranged in code blocks.
t->ist_type = WHITE_SPACE_ISTT;t->material = I" ";if (t->next) {
-inter_schema_node *new_isn = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+inter_schema_node *new_isn =
+InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, t);new_isn->expression_tokens = t->next;new_isn->parent_node = isn->parent_node;if (isn->child_node) {
@@ -544,7 +545,7 @@ early commands off from the subsequent matter. Thus:
}if ((m) && (n) && (n->ist_type == RESERVED_ISTT)) {inter_schema_node *new_isn =
-InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n);new_isn->expression_tokens = n;new_isn->parent_node = isn->parent_node;if (isn->child_node) {
@@ -643,12 +644,12 @@ We break this up as three code blocks:
inter_schema_node *sw_val = NULL;inter_schema_node *sw_code = NULL;if (defaulter) {
-sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT);
+sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT, n);isn->child_node = sw_code;sw_code->parent_node = isn; } else {
-sw_val = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
-sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT);
+sw_val = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n);
+sw_code = InterSchemas::new_node(isn->parent_schema, CODE_ISNT, n);sw_val->next_node = sw_code;sw_val->parent_node = isn; isn->child_node = sw_val;sw_code->parent_node = isn;
@@ -683,7 +684,7 @@ We break this up as three code blocks:
isn->isn_clarifier = CASE_BIP;inter_schema_node *sw_code_exp =
-InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n);sw_code_exp->expression_tokens = n->next;sw_code->child_node = sw_code_exp;
@@ -802,7 +803,7 @@ our work simpler to take one of those meanings out of the picture.
if (n->reserved_word == PRINT_I6RW) n->material = I"print";elsen->material = I"print_ret";inter_schema_node *new_isn =
-InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n);new_isn->expression_tokens = n;new_isn->parent_node = isn->parent_node;InterSchemas::changed_tokens_on(new_isn);
@@ -1136,13 +1137,13 @@ turned into function calls too, leaving:
cons->expression_tokens = printing_rule;inter_schema_token *open_b =
-InterSchemas::new_token(OPEN_ROUND_ISTT, I"(", 0, 0, -1);
+InterSchemas::new_token(OPEN_ROUND_ISTT, I"(", 0, 0, -1, printing_rule->line_offset);InterSchemas::add_token_after(open_b, cons->expression_tokens);open_b->next = n;n = open_b;while ((n) && (n->next)) n = n->next;inter_schema_token *close_b =
-InterSchemas::new_token(CLOSE_ROUND_ISTT, I")", 0, 0, -1);
+InterSchemas::new_token(CLOSE_ROUND_ISTT, I")", 0, 0, -1, printing_rule->line_offset);InterSchemas::add_token_after(close_b, n);which_statement = 0;operand1 = NULL;
@@ -1160,17 +1161,17 @@ character, and one to return inter_schema_node *save_next = cons->next_node;cons->next_node =
-InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT);
+InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT, n);cons->next_node->parent_node = cons->parent_node;cons->next_node->isn_clarifier = PRINT_BIP;cons->next_node->child_node =
-InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, n);cons->next_node->child_node->parent_node = cons->next_node;InterSchemas::add_token_to_node(cons->next_node->child_node,
-InterSchemas::new_token(DQUOTED_ISTT, I"\n", 0, 0, -1));
+InterSchemas::new_token(DQUOTED_ISTT, I"\n", 0, 0, -1, 0));cons->next_node->next_node =
-InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT);
+InterSchemas::new_node(cons->parent_schema, STATEMENT_ISNT, n);cons->next_node->next_node->parent_node = cons->parent_node;cons->next_node->next_node->isn_clarifier = RETURN_BIP;
@@ -1218,7 +1219,7 @@ to know about the difference.
cons->dir_clarifier = InterSchemas::opening_directive_word(cons);if (InterSchemas::second_dark_token(cons)) {inter_schema_node *new_isn =
-InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, first);cons->child_node = new_isn;new_isn->parent_node = cons;new_isn->expression_tokens = InterSchemas::second_dark_token(cons);
@@ -1251,7 +1252,7 @@ to be recognised for what they are.
if ((n) && (Str::eq(l->material, I")"))) continue;if (l->ist_type != WHITE_SPACE_ISTT) {inter_schema_node *new_isn =
-InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(cons->parent_schema, EXPRESSION_ISNT, n);new_isn->expression_tokens = l; l->next = NULL; l->owner = new_isn;if (l->operation_primitive) {l->ist_type = IDENTIFIER_ISTT;
@@ -1308,7 +1309,7 @@ assembly instructions @push
-inter_schema_node *sub_node = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+inter_schema_node *sub_node = InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from);sub_node->expression_tokens = from;for (inter_schema_token *l = sub_node->expression_tokens; l; l=l->next)if (l->next == to)
@@ -1690,7 +1697,7 @@ evaluation — evaluate a
prev = n; n = n->next;while ((n) && (n->ist_type == WHITE_SPACE_ISTT)) { prev = n; n = n->next; }inter_schema_node *new_isn =
-InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, n);new_isn->expression_tokens = n;new_isn->parent_node = isn->parent_node;InterSchemas::changed_tokens_on(new_isn);
@@ -1721,7 +1728,8 @@ We correct those to uses of the special inter_schema_node *A = isn->child_node;inter_schema_node *B = isn->child_node->next_node;if ((A) && (B) && (B->next_node)) {
-inter_schema_node *C = InterSchemas::new_node(isn->parent_schema, OPERATION_ISNT);
+inter_schema_node *C =
+InterSchemas::new_node_near_node(isn->parent_schema, OPERATION_ISNT, A);C->isn_clarifier = ALTERNATIVECASE_BIP;C->child_node = A;A->parent_node = C; B->parent_node = C;
@@ -1891,7 +1899,7 @@ level, as in the case of x -
inter_schema_node *left_operand_node =
-InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from);left_operand_node->expression_tokens = from;for (inter_schema_token *l = left_operand_node->expression_tokens; l; l=l->next)if (l->next == to)
@@ -1907,7 +1915,7 @@ level, as in the case of x -
inter_schema_node *right_operand_node =
-InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT);
+InterSchemas::new_node(isn->parent_schema, EXPRESSION_ISNT, from);right_operand_node->expression_tokens = from;InterSchemas::changed_tokens_on(right_operand_node);if (isn->child_node == NULL) {
@@ -2066,7 +2074,7 @@ array lookup is performed to find the address of the function to call.
generates Inter code equivalent to the example above.4 But the real power of
diff --git a/docs/building-test/1-ut.html b/docs/building-test/1-ut.html
index b67601f66..7ebecf234 100644
--- a/docs/building-test/1-ut.html
+++ b/docs/building-test/1-ut.html
@@ -135,7 +135,8 @@ function togglePopup(material_id) {
LOG("Test: parse schema from:\n%S\n", iut->test_input);Str::trim_white_space(iut->test_input);
-inter_schema *sch = ParsingSchemas::from_text(iut->test_input);
+inter_schema *sch = ParsingSchemas::from_text(iut->test_input,
+Provenance::at_file_and_line(I"hypothetical.txt", 1));if (sch == NULL) LOG("<null schema>\n");elseif (sch->node_tree == NULL) LOG("<nodeless scheme\n");elseInterSchemas::log(DL, sch);
diff --git a/docs/bytecode-module/3-ic.html b/docs/bytecode-module/3-ic.html
index 986ba5283..d9abc2d36 100644
--- a/docs/bytecode-module/3-ic.html
+++ b/docs/bytecode-module/3-ic.html
@@ -687,7 +687,7 @@ not the place to explain it. See Inter in
}
diff --git a/docs/bytecode-module/3-idt.html b/docs/bytecode-module/3-idt.html
index 4667c150c..f1d944c42 100644
--- a/docs/bytecode-module/3-idt.html
+++ b/docs/bytecode-module/3-idt.html
@@ -1077,7 +1077,7 @@ function arguments are contravariant.
}
diff --git a/docs/bytecode-module/3-ie.html b/docs/bytecode-module/3-ie.html
index 03dbe057c..7eda2274c 100644
--- a/docs/bytecode-module/3-ie.html
+++ b/docs/bytecode-module/3-ie.html
@@ -208,7 +208,7 @@ exist. See InterInstruction::tree_lint<
}
diff --git a/docs/bytecode-module/3-iibf.html b/docs/bytecode-module/3-iibf.html
index be36659fa..41e575dd7 100644
--- a/docs/bytecode-module/3-iibf.html
+++ b/docs/bytecode-module/3-iibf.html
@@ -1051,7 +1051,7 @@ the definition of any symbol created in the instruction to }
diff --git a/docs/bytecode-module/3-iitf.html b/docs/bytecode-module/3-iitf.html
index fe1352820..162ed3cea 100644
--- a/docs/bytecode-module/3-iitf.html
+++ b/docs/bytecode-module/3-iitf.html
@@ -481,7 +481,7 @@ the filter test.
Recording where fragments of text originally came from.
+
+
§1. 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.
+