1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-17 07:40:47 +03:00

Started on IE-0003

This commit is contained in:
Graham Nelson 2022-10-31 22:59:25 +00:00
parent c75e8a142c
commit d4ff104f03
11 changed files with 119 additions and 8 deletions

View file

@ -1,6 +1,6 @@
# Inform 7
[Version](notes/versioning.md): 10.2.0-beta+6V89 'Krypton' (30 October 2022)
[Version](notes/versioning.md): 10.2.0-beta+6V90 'Krypton' (31 October 2022)
## About Inform

View file

@ -1,3 +1,3 @@
Prerelease: beta
Build Date: 30 October 2022
Build Number: 6V89
Build Date: 31 October 2022
Build Number: 6V90

View file

@ -229,6 +229,14 @@ void CopyErrors::write(OUTPUT_STREAM, copy_error *CE) {
WRITE("empty clause in brackets in dialogue"); break;
case MisbracketedDialogueClause_SYNERROR:
WRITE("brackets '(' and ')' used in an unmatched way in dialogue"); break;
case MissingSourceFile_SYNERROR:
WRITE("cannot find source file: '%S'", CE->details); break;
case HeadingWithFileNonempty_SYNERROR:
WRITE("heading should refer only to source file '%S' but also contains material",
CE->details); break;
case MisheadedSourceFile_SYNERROR:
WRITE("source file '%S' does not begin with a heading matching 'see ...' line",
CE->details); break;
default:
WRITE("syntax error"); break;
}

View file

@ -150,6 +150,9 @@ typedef struct heading {
struct inbuild_work *for_use_with; /* e.g. "for use with ... by ..." */
struct wording in_place_of_text; /* e.g. "in place of ... in ... by ..." */
struct wording heading_text; /* once provisos have been stripped away */
struct wording external_file; /* e.g. "see ..." */
struct source_file *external_file_read;
int external_file_loaded;
struct noun *list_of_contents; /* tagged names defined under this */
struct noun *last_in_list_of_contents;
struct heading *parent_heading;
@ -174,6 +177,9 @@ heading *Headings::new(parse_node_tree *T, parse_node *pn, int level, source_loc
h->index_definitions_made_under_this = TRUE;
h->use_with_or_without = NOT_APPLICABLE;
h->in_place_of_text = EMPTY_WORDING;
h->external_file = EMPTY_WORDING;
h->external_file_read = NULL;
h->external_file_loaded = FALSE;
h->for_use_with = NULL;
h->sentence_declaring = pn;
h->holds_dialogue = FALSE;
@ -265,6 +271,7 @@ heading *Headings::attach(parse_node_tree *T, parse_node *pn) {
@d USE_WITHOUT_HQ 6
@d IN_PLACE_OF_HQ 7
@d DIALOGUE_HQ 8
@d EXTERNAL_HQ 9
@<Parse heading text for release or other stipulations@> =
current_sentence = pn;
@ -290,6 +297,10 @@ heading *Headings::attach(parse_node_tree *T, parse_node *pn) {
h->use_with_or_without = TRUE;
h->in_place_of_text = GET_RW(<extension-qualifier>, 1);
break;
case EXTERNAL_HQ:
h->external_file = GET_RW(<bracketed-heading-qualifier>, 1);
Word::dequote(Wordings::first_wn(h->external_file));
break;
}
W = GET_RW(<heading-qualifier>, 1);
}
@ -325,6 +336,7 @@ is determined.
unindexed | ==> { UNINDEXED_HQ, - }
dialogue | ==> { DIALOGUE_HQ, - }
dialog | ==> { DIALOGUE_HQ, - }
see { <quoted-text> } | ==> { EXTERNAL_HQ, - }
<platform-qualifier> | ==> { pass 1 }
<extension-qualifier> ==> { pass 1 }
@ -396,6 +408,7 @@ void Headings::assemble_tree(parse_node_tree *T) {
heading *h;
@<Disassemble the whole heading tree to a pile of twigs@>;
LOOP_OVER_LINKED_LIST(h, heading, T->headings->subordinates) {
// LOG("H = %W, level %d\n", h->heading_text, h->level);
@<If h is outside the tree, make it a child of the pseudo-heading@>;
@<Run through subsequent equal or subordinate headings to move them downward@>;
}

View file

@ -40,12 +40,63 @@ build_vertex *Inclusions::spawned_from_vertex(parse_node *H0) {
return inclusions_errors_to->vertex;
}
@
@e MissingSourceFile_SYNERROR
@e HeadingWithFileNonempty_SYNERROR
@e MisheadedSourceFile_SYNERROR
=
void Inclusions::visit(parse_node_tree *T, parse_node *pn, parse_node *last_H0,
int *includes_cleared) {
if (Node::get_type(pn) == INCLUDE_NT) {
@<Replace INCLUDE node with sentence nodes for any extensions required@>;
*includes_cleared = FALSE;
}
if (Node::get_type(pn) == HEADING_NT) {
heading *h = Node::get_embodying_heading(pn);
if ((h) && (Wordings::nonempty(h->external_file)) && (h->external_file_loaded == FALSE)) {
inform_project *proj = ProjectBundleManager::from_copy(inclusions_errors_to);
if ((proj) && (proj->as_copy->location_if_path)) {
pathname *P = Pathnames::down(Projects::materials_path(proj), I"Source");
text_stream *leaf = Str::new();
WRITE_TO(leaf, "%W", h->external_file);
h->external_file_loaded = TRUE;
if (pn->down) {
copy_error *CE = CopyErrors::new_T(SYNTAX_CE, HeadingWithFileNonempty_SYNERROR, leaf);
CopyErrors::supply_node(CE, pn);
Copies::attach_error(inclusions_errors_to, CE);
} else {
filename *F = Filenames::in(P, leaf);
if (TextFiles::exists(F) == FALSE) {
copy_error *CE = CopyErrors::new_T(SYNTAX_CE, MissingSourceFile_SYNERROR, leaf);
CopyErrors::supply_node(CE, pn);
Copies::attach_error(inclusions_errors_to, CE);
} else {
int l = SyntaxTree::push_bud(T, pn);
source_file *S = SourceText::read_file(inclusions_errors_to, F, leaf, FALSE, FALSE);
if (S) {
h->external_file_read = S;
wording SW = S->text_read;
int N = Wordings::length(h->heading_text);
wording TOPW = Wordings::up_to(SW, Wordings::first_wn(SW) + N - 1);
wording RESTW = Wordings::from(SW, Wordings::first_wn(SW) + N);
if ((Wordings::match(h->heading_text, TOPW) == FALSE) ||
(compare_word(Wordings::first_wn(RESTW), OPENBRACKET_V))) {
copy_error *CE = CopyErrors::new_T(SYNTAX_CE, MisheadedSourceFile_SYNERROR, leaf);
CopyErrors::supply_node(CE, pn);
Copies::attach_error(inclusions_errors_to, CE);
} else if (Wordings::nonempty(RESTW))
Sentences::break_into_project_copy(T,
RESTW, inclusions_errors_to, proj);
}
SyntaxTree::pop_bud(T, l);
*includes_cleared = FALSE;
}
}
}
}
}
}
@ The INCLUDE node becomes an INCLUSION, which in turn contains the extension's code.

View file

@ -2,7 +2,7 @@
"is": {
"type": "kit",
"title": "BasicInformExtrasKit",
"version": "10.2.0-beta+6V89"
"version": "10.2.0-beta+6V90"
},
"kit-details": {
"has-priority": 1

View file

@ -2,7 +2,7 @@
"is": {
"type": "kit",
"title": "BasicInformKit",
"version": "10.2.0-beta+6V89"
"version": "10.2.0-beta+6V90"
},
"needs": [ {
"unless": {

View file

@ -2,7 +2,7 @@
"is": {
"type": "kit",
"title": "CommandParserKit",
"version": "10.2.0-beta+6V89"
"version": "10.2.0-beta+6V90"
},
"needs": [ {
"need": {

View file

@ -2,7 +2,7 @@
"is": {
"type": "kit",
"title": "EnglishLanguageKit",
"version": "10.2.0-beta+6V89"
"version": "10.2.0-beta+6V90"
},
"needs": [ {
"need": {

View file

@ -2,7 +2,7 @@
"is": {
"type": "kit",
"title": "WorldModelKit",
"version": "10.2.0-beta+6V89"
"version": "10.2.0-beta+6V90"
},
"needs": [ {
"need": {

View file

@ -479,6 +479,45 @@ void SourceProblems::issue_problems_arising(inbuild_copy *C) {
"can only be used to clarify clauses, if necessary.");
Problems::issue_problem_end();
break;
case MissingSourceFile_SYNERROR:
current_sentence = CE->details_node;
Problems::quote_source(1, current_sentence);
Problems::quote_stream(2, CE->details);
StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...));
Problems::issue_problem_segment(
"I can't find the source file holding the content of the heading %1 - "
"it should be '%2' in the 'Source' subdirectory of the materials "
"for this project.");
Problems::issue_problem_end();
break;
case HeadingWithFileNonempty_SYNERROR:
current_sentence = CE->details_node;
Problems::quote_source(1, current_sentence);
Problems::quote_stream(2, CE->details);
Problems::quote_source(3, current_sentence->down);
StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...));
Problems::issue_problem_segment(
"The heading %1 should refer only to the contents of the file "
"'%2' (in the 'Source' subdirectory of the materials for this "
"project) but in fact goes on to contain other material too. "
"That other material (see %3) needs to be put under a new "
"heading of equal or greater priority (or else moved to the file).");
Problems::issue_problem_end();
break;
case MisheadedSourceFile_SYNERROR:
current_sentence = CE->details_node;
Problems::quote_source(1, current_sentence);
Problems::quote_stream(2, CE->details);
heading *h = Node::get_embodying_heading(current_sentence);
if (h) Problems::quote_wording(3, h->heading_text);
StandardProblems::handmade_problem(Task::syntax_tree(), _p_(...));
Problems::issue_problem_segment(
"The heading %1 says that its contents are in the file "
"'%2' (in the 'Source' subdirectory of the materials for this "
"project). If so, then that file needs to start with a matching "
"opening line, giving the same heading name '%3'; and it doesn't.");
Problems::issue_problem_end();
break;
default:
internal_error("unknown syntax error");
}