mirror of
https://github.com/ganelson/inform.git
synced 2024-06-26 04:00:43 +03:00
Runtime representation of dialogue beats
This commit is contained in:
parent
3d53a40960
commit
0736bf435f
|
@ -1,6 +1,6 @@
|
||||||
# Inform 7
|
# Inform 7
|
||||||
|
|
||||||
[Version](notes/versioning.md): 10.2.0-beta+6V62 'Krypton' (16 September 2022)
|
[Version](notes/versioning.md): 10.2.0-beta+6V63 'Krypton' (17 September 2022)
|
||||||
|
|
||||||
## About Inform
|
## About Inform
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
Prerelease: beta
|
Prerelease: beta
|
||||||
Build Date: 16 September 2022
|
Build Date: 17 September 2022
|
||||||
Build Number: 6V62
|
Build Number: 6V63
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
Behaviour specific to copies of either the projectbundle or projectfile genres.
|
Behaviour specific to copies of either the projectbundle or projectfile genres.
|
||||||
|
|
||||||
@h Scanning metadata.
|
@h Scanning metadata.
|
||||||
Metadata for pipelines -- or rather, the complete lack of same -- is stored
|
Metadata for projects is stored in the following structure.
|
||||||
in the following structure.
|
|
||||||
|
|
||||||
=
|
=
|
||||||
typedef struct inform_project {
|
typedef struct inform_project {
|
||||||
|
@ -563,7 +562,8 @@ because of the following sort:
|
||||||
kit_dependency *kd;
|
kit_dependency *kd;
|
||||||
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
LOOP_OVER_LINKED_LIST(kd, kit_dependency, project->kits_to_include)
|
||||||
if ((Str::eq(kd->kit->as_copy->edition->work->title, I"CommandParserKit")) ||
|
if ((Str::eq(kd->kit->as_copy->edition->work->title, I"CommandParserKit")) ||
|
||||||
(Str::eq(kd->kit->as_copy->edition->work->title, I"WorldModelKit")))
|
(Str::eq(kd->kit->as_copy->edition->work->title, I"WorldModelKit")) ||
|
||||||
|
(Str::eq(kd->kit->as_copy->edition->work->title, I"DialogueKit")))
|
||||||
basic = FALSE;
|
basic = FALSE;
|
||||||
if (basic == FALSE) {
|
if (basic == FALSE) {
|
||||||
TEMPORARY_TEXT(err)
|
TEMPORARY_TEXT(err)
|
||||||
|
@ -699,6 +699,25 @@ filename *Projects::get_primary_output(inform_project *proj) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@h Detecting dialogue.
|
||||||
|
There's an awkward timing issue with detecting dialogue in the source text.
|
||||||
|
The rule is that an Inform project should depend on DialogueKit if it contains
|
||||||
|
content under a dialogue section, but not otherwise. That in turn activates
|
||||||
|
the "dialogue" compiler feature. On the other hand, the source text also has
|
||||||
|
material placed under headings which are for use with dialogue only. So we
|
||||||
|
can't read the entire source text first and then decide: we have to switch
|
||||||
|
on the dialogue feature the moment any dialogue matter is found. This is
|
||||||
|
done by having the //syntax// module call the following:
|
||||||
|
|
||||||
|
=
|
||||||
|
inform_project *project_being_scanned = NULL;
|
||||||
|
void Projects::dialogue_present(void) {
|
||||||
|
if (project_being_scanned) {
|
||||||
|
Projects::add_kit_dependency(project_being_scanned, I"DialogueKit", NULL, NULL, NULL);
|
||||||
|
Projects::activate_elements(project_being_scanned);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@h The full graph.
|
@h The full graph.
|
||||||
This can be quite grandiose even though most of it will never come to anything,
|
This can be quite grandiose even though most of it will never come to anything,
|
||||||
rather like a family tree for a minor European royal family.
|
rather like a family tree for a minor European royal family.
|
||||||
|
@ -708,11 +727,9 @@ void Projects::construct_graph(inform_project *proj) {
|
||||||
if (proj == NULL) return;
|
if (proj == NULL) return;
|
||||||
if (proj->chosen_build_target == NULL) {
|
if (proj->chosen_build_target == NULL) {
|
||||||
Projects::finalise_kit_dependencies(proj);
|
Projects::finalise_kit_dependencies(proj);
|
||||||
|
project_being_scanned = proj;
|
||||||
Copies::get_source_text(proj->as_copy);
|
Copies::get_source_text(proj->as_copy);
|
||||||
if (proj->syntax_tree->contains_dialogue) {
|
project_being_scanned = NULL;
|
||||||
Projects::add_kit_dependency(proj, I"DialogueKit", NULL, NULL, NULL);
|
|
||||||
Projects::activate_elements(proj);
|
|
||||||
}
|
|
||||||
build_vertex *V = proj->as_copy->vertex;
|
build_vertex *V = proj->as_copy->vertex;
|
||||||
@<Construct the graph upstream of V@>;
|
@<Construct the graph upstream of V@>;
|
||||||
@<Construct the graph downstream of V@>;
|
@<Construct the graph downstream of V@>;
|
||||||
|
|
|
@ -290,6 +290,11 @@ void SourceText::new_beginend(parse_node *pn, inbuild_copy *C) {
|
||||||
if (Node::get_type(pn) == ENDHERE_NT) Inclusions::check_ends_here(pn, E);
|
if (Node::get_type(pn) == ENDHERE_NT) Inclusions::check_ends_here(pn, E);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ This callback is called by //syntax// when it first reaches a dialogue line
|
||||||
|
or beat.
|
||||||
|
|
||||||
|
@d DIALOGUE_WARNING_SYNTAX_CALLBACK Projects::dialogue_present
|
||||||
|
|
||||||
@ Lastly, this callback is called by //syntax// when it hits a sentence like:
|
@ Lastly, this callback is called by //syntax// when it hits a sentence like:
|
||||||
|
|
||||||
>> Use interactive fiction language element.
|
>> Use interactive fiction language element.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"is": {
|
"is": {
|
||||||
"type": "kit",
|
"type": "kit",
|
||||||
"title": "BasicInformExtrasKit",
|
"title": "BasicInformExtrasKit",
|
||||||
"version": "10.2.0-beta+6V62"
|
"version": "10.2.0-beta+6V63"
|
||||||
},
|
},
|
||||||
"kit-details": {
|
"kit-details": {
|
||||||
"has-priority": 1
|
"has-priority": 1
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"is": {
|
"is": {
|
||||||
"type": "kit",
|
"type": "kit",
|
||||||
"title": "BasicInformKit",
|
"title": "BasicInformKit",
|
||||||
"version": "10.2.0-beta+6V62"
|
"version": "10.2.0-beta+6V63"
|
||||||
},
|
},
|
||||||
"needs": [ {
|
"needs": [ {
|
||||||
"unless": {
|
"unless": {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"is": {
|
"is": {
|
||||||
"type": "kit",
|
"type": "kit",
|
||||||
"title": "CommandParserKit",
|
"title": "CommandParserKit",
|
||||||
"version": "10.2.0-beta+6V62"
|
"version": "10.2.0-beta+6V63"
|
||||||
},
|
},
|
||||||
"needs": [ {
|
"needs": [ {
|
||||||
"need": {
|
"need": {
|
||||||
|
|
|
@ -5,6 +5,108 @@ Run-time support for dialogue.
|
||||||
@h Placeholder.
|
@h Placeholder.
|
||||||
|
|
||||||
=
|
=
|
||||||
|
Global latest_performed_beat = 0;
|
||||||
|
Array DialogueTopicPool --> 20;
|
||||||
|
|
||||||
|
[ DirectorEmptyDialogueTopicPool;
|
||||||
|
DialogueTopicPool-->0 = 0;
|
||||||
|
];
|
||||||
|
|
||||||
|
[ DirectorAddLiveSubjectList obj i;
|
||||||
|
for (i=18:i>0:i--) DialogueTopicPool-->i = DialogueTopicPool-->(i-1);
|
||||||
|
DialogueTopicPool-->0 = obj;
|
||||||
|
DialogueTopicPool-->19 = 0;
|
||||||
|
];
|
||||||
|
|
||||||
|
[ DirectorRemoveLiveSubjectList obj i j;
|
||||||
|
for (i=0:i<20:i++) {
|
||||||
|
if (DialogueTopicPool-->i == 0) return;
|
||||||
|
if (DialogueTopicPool-->i == obj) {
|
||||||
|
for (j=i:j<19:j++) DialogueTopicPool-->j = DialogueTopicPool-->(j+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DialogueTopicPool-->19 = 0;
|
||||||
|
];
|
||||||
|
|
||||||
|
[ DirectorLiveSubjectList list len i;
|
||||||
|
if ((list==0) || (BlkValueWeakKind(list) ~= LIST_OF_TY)) return 0;
|
||||||
|
len = 0;
|
||||||
|
while (DialogueTopicPool-->len) len++;
|
||||||
|
LIST_OF_TY_SetLength(list, len);
|
||||||
|
for (i=0: i<len: i++)
|
||||||
|
LIST_OF_TY_PutItem(list, i+1, DialogueTopicPool-->i);
|
||||||
|
return list;
|
||||||
|
];
|
||||||
|
|
||||||
|
[ DirectorAlterLiveSubjectList list len i;
|
||||||
|
if ((list==0) || (BlkValueWeakKind(list) ~= LIST_OF_TY)) return 0;
|
||||||
|
len = BlkValueRead(list, LIST_LENGTH_F);
|
||||||
|
if (len > 19) len = 19;
|
||||||
|
for (i=0: i<len: i++)
|
||||||
|
DialogueTopicPool-->i = BlkValueRead(list, LIST_ITEM_BASE+i);
|
||||||
|
DialogueTopicPool-->len = 0;
|
||||||
|
DialogueTopicPool-->19 = 0;
|
||||||
|
];
|
||||||
|
|
||||||
[ DirectorBegin;
|
[ DirectorBegin;
|
||||||
|
DirectorEmptyDialogueTopicPool();
|
||||||
|
latest_performed_beat = 0;
|
||||||
rfalse;
|
rfalse;
|
||||||
];
|
];
|
||||||
|
|
||||||
|
[ DirectorPerform db;
|
||||||
|
print "Performing beat ", (PrintDialogueBeatName) db, "^";
|
||||||
|
latest_performed_beat = db;
|
||||||
|
];
|
||||||
|
|
||||||
|
[ DirectorListLiveTopics i t;
|
||||||
|
for (i=0: i<20: i++) {
|
||||||
|
t = DialogueTopicPool-->i;
|
||||||
|
if (t == 0) return;
|
||||||
|
print (name) t, "^";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
[ DirectorBeatAvailable db fn;
|
||||||
|
if ((db == 0) || (db > TableOfDialogueBeats-->0)) rfalse;
|
||||||
|
fn = TableOfDialogueBeats-->(3*db - 2);
|
||||||
|
if (fn) {
|
||||||
|
return (fn)(latest_performed_beat);
|
||||||
|
}
|
||||||
|
rtrue;
|
||||||
|
];
|
||||||
|
|
||||||
|
[ DirectorBeatRelevant db fn;
|
||||||
|
if ((db == 0) || (db > TableOfDialogueBeats-->0)) rfalse;
|
||||||
|
fn = TableOfDialogueBeats-->(3*db - 1);
|
||||||
|
if (fn) {
|
||||||
|
return (fn)(DialogueTopicPool);
|
||||||
|
}
|
||||||
|
rfalse;
|
||||||
|
];
|
||||||
|
|
||||||
|
[ DirectorBeatPrintStructure db tab pc which depth i;
|
||||||
|
if ((db == 0) || (db > TableOfDialogueBeats-->0)) return;
|
||||||
|
print (PrintDialogueBeatName) db;
|
||||||
|
print " (";
|
||||||
|
if (DirectorBeatAvailable(db)) print "available"; else print "unavailable";
|
||||||
|
print ", ";
|
||||||
|
if (DirectorBeatRelevant(db)) print "relevant"; else print "irrelevant";
|
||||||
|
print "):^";
|
||||||
|
tab = TableOfDialogueBeats-->(3*db);
|
||||||
|
if (tab) {
|
||||||
|
pc = 0;
|
||||||
|
while (tab-->pc) {
|
||||||
|
which = (tab-->pc)/100;
|
||||||
|
depth = (tab-->pc)%100;
|
||||||
|
for (i=0: i<depth: i++) print " ";
|
||||||
|
switch (which) {
|
||||||
|
1: print "Line ", (PrintDialogueLineName) tab-->(pc+1), "^";
|
||||||
|
2: print "Choice ", (PrintDialogueChoiceName) tab-->(pc+1), "^";
|
||||||
|
3: print "Decision of type ", tab-->(pc+1), "^";
|
||||||
|
default: print "*** Unimplemented ***^";
|
||||||
|
}
|
||||||
|
pc = pc + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -2,7 +2,7 @@
|
||||||
"is": {
|
"is": {
|
||||||
"type": "kit",
|
"type": "kit",
|
||||||
"title": "EnglishLanguageKit",
|
"title": "EnglishLanguageKit",
|
||||||
"version": "10.2.0-beta+6V62"
|
"version": "10.2.0-beta+6V63"
|
||||||
},
|
},
|
||||||
"needs": [ {
|
"needs": [ {
|
||||||
"need": {
|
"need": {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"is": {
|
"is": {
|
||||||
"type": "kit",
|
"type": "kit",
|
||||||
"title": "WorldModelKit",
|
"title": "WorldModelKit",
|
||||||
"version": "10.2.0-beta+6V62"
|
"version": "10.2.0-beta+6V63"
|
||||||
},
|
},
|
||||||
"needs": [ {
|
"needs": [ {
|
||||||
"need": {
|
"need": {
|
||||||
|
|
96
inform7/Tests/Test Cases/DialogueBeats.txt
Normal file
96
inform7/Tests/Test Cases/DialogueBeats.txt
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
The Cricket History Museum is a room. The bat, the ball and the pads are here. Daphne is a woman in the Museum. The trophy case is in the Museum. The urn and the scoring pencil are in the case.
|
||||||
|
|
||||||
|
Daphne can be honest or disingenuous.
|
||||||
|
|
||||||
|
A dialogue beat can be dramatic, quiet or subdued.
|
||||||
|
|
||||||
|
Spoken rapidly is a performance style.
|
||||||
|
|
||||||
|
When play begins:
|
||||||
|
say "== The stock...";
|
||||||
|
showme the list of dialogue beats;
|
||||||
|
showme the list of dialogue lines;
|
||||||
|
showme the list of dialogue choices;
|
||||||
|
say "== Dual scene and beat naming...";
|
||||||
|
showme the alpha scene;
|
||||||
|
showme the alpha beat;
|
||||||
|
say "== Properties...";
|
||||||
|
showme the list of dramatic dialogue beats;
|
||||||
|
showme the list of subdued dialogue beats;
|
||||||
|
say "== Performance...";
|
||||||
|
showme the list of unperformed dialogue beats;
|
||||||
|
perform the alpha beat;
|
||||||
|
showme the list of unperformed dialogue beats;
|
||||||
|
say "== The live conversational subject list...";
|
||||||
|
showme the live conversational subject list;
|
||||||
|
make the bat a live conversational subject;
|
||||||
|
make the ball a live conversational subject;
|
||||||
|
showme the live conversational subject list;
|
||||||
|
make the bat a dead conversational subject;
|
||||||
|
showme the live conversational subject list;
|
||||||
|
make the ball a dead conversational subject;
|
||||||
|
showme the live conversational subject list;
|
||||||
|
make the ball a dead conversational subject;
|
||||||
|
showme the live conversational subject list;
|
||||||
|
alter the live conversational subject list to { Daphne, the pads };
|
||||||
|
showme the live conversational subject list;
|
||||||
|
say "== Relevance...";
|
||||||
|
alter the live conversational subject list to { the bat };
|
||||||
|
showme the live conversational subject list;
|
||||||
|
showme the list of relevant dialogue beats;
|
||||||
|
alter the live conversational subject list to { the ball };
|
||||||
|
showme the live conversational subject list;
|
||||||
|
showme the list of relevant dialogue beats;
|
||||||
|
alter the live conversational subject list to { the bat, the scoring pencil };
|
||||||
|
showme the live conversational subject list;
|
||||||
|
showme the list of relevant dialogue beats;
|
||||||
|
say "== Availability...";
|
||||||
|
now every dialogue beat is unperformed;
|
||||||
|
showme the list of available dialogue beats;
|
||||||
|
perform the gamma beat;
|
||||||
|
showme the list of available dialogue beats;
|
||||||
|
perform the nu beat;
|
||||||
|
showme the list of available dialogue beats;
|
||||||
|
now Daphne is honest;
|
||||||
|
showme the list of available dialogue beats;
|
||||||
|
say "== Structure...";
|
||||||
|
repeat with B running through dialogue beats:
|
||||||
|
showme the beat structure of B;
|
||||||
|
|
||||||
|
Section 1 - Meeting (dialogue)
|
||||||
|
|
||||||
|
(This is the alpha scene.)
|
||||||
|
|
||||||
|
Daphne: "Welcome to the Museum of Cricket."
|
||||||
|
|
||||||
|
(This is the beta beat. About the bat.)
|
||||||
|
|
||||||
|
Daphne: "Made of willow, the cricket bat is sprung to provide a good drive."
|
||||||
|
|
||||||
|
(This is the gamma beat. About the ball and everything in the case.)
|
||||||
|
|
||||||
|
Daphne: "A cricket ball is made with a core of cork, which is layered with tightly wound string, and covered by a leather case with a slightly raised sewn seam."
|
||||||
|
|
||||||
|
(This is the delta beat. Immediately after the gamma beat. Quiet.)
|
||||||
|
|
||||||
|
Daphne: "I forgot to mention, British Standard BS 5993 specifies the construction details, dimensions, quality and performance of cricket balls."
|
||||||
|
|
||||||
|
(This is the epsilon beat. After the gamma beat. Subdued.)
|
||||||
|
|
||||||
|
Daphne: "Dukes balls have a prouder seam and will tend to swing more than Kookaburra balls."
|
||||||
|
|
||||||
|
(This is the nu beat.)
|
||||||
|
|
||||||
|
Daphne: "Cricket's kind of dull, when you think about it."
|
||||||
|
|
||||||
|
Ball (this is the disgruntled ball line): "I disagree!"
|
||||||
|
|
||||||
|
Bat: "I especially enjoy it."
|
||||||
|
|
||||||
|
(This is the mu beat. If Daphne is honest.)
|
||||||
|
|
||||||
|
Daphne: "I prefer softball, honestly."
|
||||||
|
|
||||||
|
(This is the eta beat. Before the nu beat.)
|
||||||
|
|
||||||
|
Daphne: "This is the foremost museum in New South Wales."
|
65
inform7/Tests/Test Cases/_Results_Ideal/DialogueBeats.txt
Normal file
65
inform7/Tests/Test Cases/_Results_Ideal/DialogueBeats.txt
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
Cricket History Museum
|
||||||
|
== The stock...
|
||||||
|
"list of dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, delta beat, epsilon beat, nu beat, mu beat, eta beat}
|
||||||
|
"list of dialogue lines" = list of dialogue lines: {line-1, line-2, line-3, line-4, line-5, line-6, disgruntled ball line, line-8, line-9, line-10}
|
||||||
|
"list of dialogue choices" = list of dialogue choices: {}
|
||||||
|
== Dual scene and beat naming...
|
||||||
|
scene: alpha scene
|
||||||
|
dialogue beat: alpha beat
|
||||||
|
== Properties...
|
||||||
|
"list of dramatic dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, nu beat, mu beat, eta beat}
|
||||||
|
"list of subdued dialogue beats" = list of dialogue beats: {epsilon beat}
|
||||||
|
== Performance...
|
||||||
|
"list of unperformed dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, delta beat, epsilon beat, nu beat, mu beat, eta beat}
|
||||||
|
Performing beat alpha beat
|
||||||
|
"list of unperformed dialogue beats" = list of dialogue beats: {beta beat, gamma beat, delta beat, epsilon beat, nu beat, mu beat, eta beat}
|
||||||
|
== The live conversational subject list...
|
||||||
|
"live conversational subject list" = list of objects: {}
|
||||||
|
"live conversational subject list" = list of objects: {ball, bat}
|
||||||
|
"live conversational subject list" = list of objects: {ball}
|
||||||
|
"live conversational subject list" = list of objects: {}
|
||||||
|
"live conversational subject list" = list of objects: {}
|
||||||
|
"live conversational subject list" = list of objects: {Daphne, pads}
|
||||||
|
== Relevance...
|
||||||
|
"live conversational subject list" = list of objects: {bat}
|
||||||
|
"list of relevant dialogue beats" = list of dialogue beats: {beta beat, gamma beat}
|
||||||
|
"live conversational subject list" = list of objects: {ball}
|
||||||
|
"list of relevant dialogue beats" = list of dialogue beats: {gamma beat}
|
||||||
|
"live conversational subject list" = list of objects: {bat, scoring pencil}
|
||||||
|
"list of relevant dialogue beats" = list of dialogue beats: {beta beat, gamma beat}
|
||||||
|
== Availability...
|
||||||
|
"list of available dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, nu beat, eta beat}
|
||||||
|
Performing beat gamma beat
|
||||||
|
"list of available dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, epsilon beat, nu beat, eta beat}
|
||||||
|
Performing beat nu beat
|
||||||
|
"list of available dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, epsilon beat, nu beat}
|
||||||
|
"list of available dialogue beats" = list of dialogue beats: {alpha beat, beta beat, gamma beat, epsilon beat, nu beat, mu beat}
|
||||||
|
== Structure...
|
||||||
|
alpha beat (available, irrelevant):
|
||||||
|
Line line-1
|
||||||
|
beta beat (available, relevant):
|
||||||
|
Line line-2
|
||||||
|
gamma beat (available, relevant):
|
||||||
|
Line line-3
|
||||||
|
delta beat (unavailable, irrelevant):
|
||||||
|
Line line-4
|
||||||
|
epsilon beat (available, irrelevant):
|
||||||
|
Line line-5
|
||||||
|
nu beat (available, irrelevant):
|
||||||
|
Line line-6
|
||||||
|
Line disgruntled ball line
|
||||||
|
Line line-8
|
||||||
|
mu beat (available, irrelevant):
|
||||||
|
Line line-9
|
||||||
|
eta beat (unavailable, irrelevant):
|
||||||
|
Line line-10
|
||||||
|
|
||||||
|
Welcome
|
||||||
|
An Interactive Fiction
|
||||||
|
Release 1 / Serial number 160428 / Inform 7 v10.2.0 / D
|
||||||
|
|
||||||
|
Cricket History Museum
|
||||||
|
You can see a bat, a ball, a pads, Daphne and a trophy case (in which are an urn and a scoring pencil) here.
|
||||||
|
|
||||||
|
> > Cricket History Museum
|
||||||
|
> Are you sure you want to quit?
|
|
@ -211,7 +211,9 @@ here, which only happens when special runs are made for compiler testing.
|
||||||
BENCH(RTTableColumns::compile)
|
BENCH(RTTableColumns::compile)
|
||||||
BENCH(RTEquations::compile)
|
BENCH(RTEquations::compile)
|
||||||
BENCH(ImperativeDefinitions::compile_first_block)
|
BENCH(ImperativeDefinitions::compile_first_block)
|
||||||
BENCH(RTDialogue::compile)
|
BENCH(RTDialogueBeats::compile)
|
||||||
|
BENCH(RTDialogueLines::compile)
|
||||||
|
BENCH(RTDialogueChoices::compile)
|
||||||
BENCH(RTRules::compile)
|
BENCH(RTRules::compile)
|
||||||
BENCH(RTRulebooks::compile)
|
BENCH(RTRulebooks::compile)
|
||||||
BENCH(RTRulebooks::compile_nros)
|
BENCH(RTRulebooks::compile_nros)
|
||||||
|
|
|
@ -1269,6 +1269,36 @@ The print protagonist internal rule translates into Inter as
|
||||||
@h Dialogue support.
|
@h Dialogue support.
|
||||||
|
|
||||||
=
|
=
|
||||||
Section 10 - Performance Styles (for dialogue language element only)
|
Section 10 - Dialogue (for dialogue language element only)
|
||||||
|
|
||||||
There is a performance style called spoken normally.
|
There is a performance style called spoken normally.
|
||||||
|
|
||||||
|
A dialogue beat can be performed or unperformed. A dialogue beat is usually
|
||||||
|
unperformed.
|
||||||
|
A dialogue beat can be recurring or non-recurring. A dialogue beat is usually
|
||||||
|
non-recurring.
|
||||||
|
|
||||||
|
To make (T - an object) a live conversational subject:
|
||||||
|
(- DirectorAddLiveSubjectList({T}); -).
|
||||||
|
To make (T - an object) a dead conversational subject:
|
||||||
|
(- DirectorRemoveLiveSubjectList({T}); -).
|
||||||
|
|
||||||
|
To decide what list of objects is the live conversational subject list:
|
||||||
|
(- DirectorLiveSubjectList({-new:list of objects}) -).
|
||||||
|
To alter the live conversational subject list to (L - list of objects):
|
||||||
|
(- DirectorAlterLiveSubjectList({-by-reference:L}); -).
|
||||||
|
|
||||||
|
To perform (B - a dialogue beat):
|
||||||
|
ask DialogueKit to perform B;
|
||||||
|
now B is performed.
|
||||||
|
|
||||||
|
To ask DialogueKit to perform (B - a dialogue beat):
|
||||||
|
(- DirectorPerform({B}); -).
|
||||||
|
|
||||||
|
To showme the beat structure of (B - dialogue beat): (- DirectorBeatPrintStructure({B}); -).
|
||||||
|
|
||||||
|
Definition: A dialogue beat is available rather than unavailable if Inter routine
|
||||||
|
"DirectorBeatAvailable" says so (it meets all its after or before, if and unless conditions).
|
||||||
|
|
||||||
|
Definition: A dialogue beat is relevant rather than irrelevant if Inter routine
|
||||||
|
"DirectorBeatRelevant" says so (one of the topics it is about is currently live).
|
||||||
|
|
|
@ -106,7 +106,7 @@ typedef struct dialogue_beat {
|
||||||
db->some_time_before = NEW_LINKED_LIST(parse_node);
|
db->some_time_before = NEW_LINKED_LIST(parse_node);
|
||||||
db->about_list = NEW_LINKED_LIST(parse_node);
|
db->about_list = NEW_LINKED_LIST(parse_node);
|
||||||
db->root = NULL;
|
db->root = NULL;
|
||||||
db->compilation_data = RTDialogue::new_beat(PN, db);
|
db->compilation_data = RTDialogueBeats::new_beat(PN, db);
|
||||||
|
|
||||||
@ Each clause can be one of about 10 possibilities, as follows, and the
|
@ Each clause can be one of about 10 possibilities, as follows, and the
|
||||||
wording tells us immediately which possibility it is, even early in the run.
|
wording tells us immediately which possibility it is, even early in the run.
|
||||||
|
|
|
@ -50,7 +50,7 @@ typedef struct dialogue_choice {
|
||||||
dc->selection_parameter = EMPTY_WORDING;
|
dc->selection_parameter = EMPTY_WORDING;
|
||||||
dc->to_perform = NULL;
|
dc->to_perform = NULL;
|
||||||
dc->selection_type = BLANK_DSEL;
|
dc->selection_type = BLANK_DSEL;
|
||||||
dc->compilation_data = RTDialogue::new_choice(PN, dc);
|
dc->compilation_data = RTDialogueChoices::new(PN, dc);
|
||||||
|
|
||||||
@ Each choice produces an instance of the kind |dialogue choice|, using the name
|
@ Each choice produces an instance of the kind |dialogue choice|, using the name
|
||||||
given in its clauses if one was.
|
given in its clauses if one was.
|
||||||
|
|
|
@ -56,7 +56,7 @@ typedef struct dialogue_line {
|
||||||
dl->speaker_text = EMPTY_WORDING;
|
dl->speaker_text = EMPTY_WORDING;
|
||||||
dl->speaker_description = NULL;
|
dl->speaker_description = NULL;
|
||||||
dl->without_speaking = FALSE;
|
dl->without_speaking = FALSE;
|
||||||
dl->compilation_data = RTDialogue::new_line(PN, dl);
|
dl->compilation_data = RTDialogueLines::new(PN, dl);
|
||||||
dl->speech_text = EMPTY_WORDING;
|
dl->speech_text = EMPTY_WORDING;
|
||||||
dl->mentioning = NEW_LINKED_LIST(parse_node);
|
dl->mentioning = NEW_LINKED_LIST(parse_node);
|
||||||
dl->how_performed = PerformanceStyles::default();
|
dl->how_performed = PerformanceStyles::default();
|
||||||
|
|
|
@ -11,6 +11,7 @@ handles that kind, so it won't be dealt with in the code for this feature.
|
||||||
=
|
=
|
||||||
void Dialogue::start(void) {
|
void Dialogue::start(void) {
|
||||||
Dialogue::declare_annotations();
|
Dialogue::declare_annotations();
|
||||||
|
PluginCalls::plug(NEW_PROPERTY_NOTIFY_PLUG, Dialogue::new_property_notify);
|
||||||
PluginCalls::plug(NEW_BASE_KIND_NOTIFY_PLUG, Dialogue::new_base_kind_notify);
|
PluginCalls::plug(NEW_BASE_KIND_NOTIFY_PLUG, Dialogue::new_base_kind_notify);
|
||||||
PluginCalls::plug(COMPARE_CONSTANT_PLUG, Dialogue::compare_CONSTANT);
|
PluginCalls::plug(COMPARE_CONSTANT_PLUG, Dialogue::compare_CONSTANT);
|
||||||
}
|
}
|
||||||
|
@ -37,6 +38,27 @@ int Dialogue::new_base_kind_notify(kind *new_base, text_stream *name, wording W)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ The following either/or property needs some compiler support:
|
||||||
|
|
||||||
|
= (early code)
|
||||||
|
property *P_performed = NULL;
|
||||||
|
|
||||||
|
@ We will need to compile code using this.
|
||||||
|
|
||||||
|
=
|
||||||
|
<notable-dialogue-properties> ::=
|
||||||
|
performed
|
||||||
|
|
||||||
|
@ =
|
||||||
|
int Dialogue::new_property_notify(property *prn) {
|
||||||
|
if (<notable-dialogue-properties>(prn->name)) {
|
||||||
|
switch (<<r>>) {
|
||||||
|
case 0: P_performed = prn; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
@ The rest of this section is to some extent boiler-plate code: it provides for
|
@ The rest of this section is to some extent boiler-plate code: it provides for
|
||||||
specific beats and lines to be represented as rvalues, both inside the compiler
|
specific beats and lines to be represented as rvalues, both inside the compiler
|
||||||
(and when typechecking) and at runtime.
|
(and when typechecking) and at runtime.
|
||||||
|
|
|
@ -959,7 +959,15 @@ void Hierarchy::establish(void) {
|
||||||
@e INLINE_PROPERTIES_HAP
|
@e INLINE_PROPERTIES_HAP
|
||||||
@e INLINE_PROPERTY_HL
|
@e INLINE_PROPERTY_HL
|
||||||
@e DIRECTION_HL
|
@e DIRECTION_HL
|
||||||
@e BEAT_FILTER_FN_HL
|
@e INSTANCE_IS_DB_MD_HL
|
||||||
|
@e INSTANCE_IS_DL_MD_HL
|
||||||
|
@e INSTANCE_IS_DC_MD_HL
|
||||||
|
@e BEAT_AVAILABLE_MD_HL
|
||||||
|
@e BEAT_AVAILABLE_FN_HL
|
||||||
|
@e BEAT_RELEVANT_MD_HL
|
||||||
|
@e BEAT_RELEVANT_FN_HL
|
||||||
|
@e BEAT_STRUCTURE_MD_HL
|
||||||
|
@e BEAT_STRUCTURE_HL
|
||||||
|
|
||||||
@<Establish instances@> =
|
@<Establish instances@> =
|
||||||
submodule_identity *instances = LargeScale::register_submodule_identity(I"instances");
|
submodule_identity *instances = LargeScale::register_submodule_identity(I"instances");
|
||||||
|
@ -1052,7 +1060,15 @@ void Hierarchy::establish(void) {
|
||||||
H_F_G(REGION_FOUND_IN_FN_HL, I"region_found_in_fn", I"RFI_for_I")
|
H_F_G(REGION_FOUND_IN_FN_HL, I"region_found_in_fn", I"RFI_for_I")
|
||||||
H_F_G(TSD_DOOR_DIR_FN_HL, I"tsd_door_dir_fn", I"TSD_door_dir_value")
|
H_F_G(TSD_DOOR_DIR_FN_HL, I"tsd_door_dir_fn", I"TSD_door_dir_value")
|
||||||
H_F_G(TSD_DOOR_TO_FN_HL, I"tsd_door_to_fn", I"TSD_door_to_value")
|
H_F_G(TSD_DOOR_TO_FN_HL, I"tsd_door_to_fn", I"TSD_door_to_value")
|
||||||
H_F_G(BEAT_FILTER_FN_HL, I"beat_filter_fn", I"DB_filter")
|
H_C_U(INSTANCE_IS_DB_MD_HL, I"^is_dialogue_beat")
|
||||||
|
H_C_U(INSTANCE_IS_DL_MD_HL, I"^is_dialogue_line")
|
||||||
|
H_C_U(INSTANCE_IS_DC_MD_HL, I"^is_dialogue_choice")
|
||||||
|
H_C_U(BEAT_AVAILABLE_MD_HL, I"^available")
|
||||||
|
H_F_U(BEAT_AVAILABLE_FN_HL, I"available_fn")
|
||||||
|
H_C_U(BEAT_RELEVANT_MD_HL, I"^relevant")
|
||||||
|
H_F_U(BEAT_RELEVANT_FN_HL, I"relevant_fn")
|
||||||
|
H_C_U(BEAT_STRUCTURE_MD_HL, I"^structure")
|
||||||
|
H_C_U(BEAT_STRUCTURE_HL, I"structure")
|
||||||
H_F_U(INST_SHOWME_FN_HL, I"showme_fn")
|
H_F_U(INST_SHOWME_FN_HL, I"showme_fn")
|
||||||
H_BEGIN_AP(INLINE_PROPERTIES_HAP, I"inline_property", I"_inline_property")
|
H_BEGIN_AP(INLINE_PROPERTIES_HAP, I"inline_property", I"_inline_property")
|
||||||
H_C_U(INLINE_PROPERTY_HL, I"inline")
|
H_C_U(INLINE_PROPERTY_HL, I"inline")
|
||||||
|
|
340
inform7/runtime-module/Chapter 5/Dialogue Beat Instances.w
Normal file
340
inform7/runtime-module/Chapter 5/Dialogue Beat Instances.w
Normal file
|
@ -0,0 +1,340 @@
|
||||||
|
[RTDialogueBeats::] Dialogue Beat Instances.
|
||||||
|
|
||||||
|
To compile any dialogue details in the instances submodule.
|
||||||
|
|
||||||
|
@h Compilation data for dialogue beats.
|
||||||
|
Each |dialogue_beat| object contains this data:
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct dialogue_beat_compilation_data {
|
||||||
|
struct parse_node *where_created;
|
||||||
|
struct inter_name *available_function;
|
||||||
|
struct inter_name *relevant_function;
|
||||||
|
struct inter_name *structure_array;
|
||||||
|
} dialogue_beat_compilation_data;
|
||||||
|
|
||||||
|
dialogue_beat_compilation_data RTDialogueBeats::new_beat(parse_node *PN, dialogue_beat *db) {
|
||||||
|
dialogue_beat_compilation_data dbcd;
|
||||||
|
dbcd.where_created = PN;
|
||||||
|
dbcd.available_function = NULL;
|
||||||
|
dbcd.relevant_function = NULL;
|
||||||
|
dbcd.structure_array = NULL;
|
||||||
|
return dbcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
package_request *RTDialogueBeats::package(dialogue_beat *db) {
|
||||||
|
if (db->as_instance == NULL) internal_error("not available yet");
|
||||||
|
return RTInstances::package(db->as_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
inter_name *RTDialogueBeats::available_fn_iname(dialogue_beat *db) {
|
||||||
|
if (db->compilation_data.available_function == NULL)
|
||||||
|
db->compilation_data.available_function =
|
||||||
|
Hierarchy::make_iname_in(BEAT_AVAILABLE_FN_HL, RTDialogueBeats::package(db));
|
||||||
|
return db->compilation_data.available_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
inter_name *RTDialogueBeats::relevant_fn_iname(dialogue_beat *db) {
|
||||||
|
if (db->compilation_data.relevant_function == NULL)
|
||||||
|
db->compilation_data.relevant_function =
|
||||||
|
Hierarchy::make_iname_in(BEAT_RELEVANT_FN_HL, RTDialogueBeats::package(db));
|
||||||
|
return db->compilation_data.relevant_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
inter_name *RTDialogueBeats::structure_fn_iname(dialogue_beat *db) {
|
||||||
|
if (db->compilation_data.structure_array == NULL)
|
||||||
|
db->compilation_data.structure_array =
|
||||||
|
Hierarchy::make_iname_in(BEAT_STRUCTURE_HL, RTDialogueBeats::package(db));
|
||||||
|
return db->compilation_data.structure_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
@h Compilation of dialogue.
|
||||||
|
|
||||||
|
=
|
||||||
|
void RTDialogueBeats::compile(void) {
|
||||||
|
dialogue_beat *db;
|
||||||
|
LOOP_OVER(db, dialogue_beat) {
|
||||||
|
text_stream *desc = Str::new();
|
||||||
|
WRITE_TO(desc, "dialogue beat %d", db->allocation_id);
|
||||||
|
Sequence::queue(&RTDialogueBeats::beat_compilation_agent, STORE_POINTER_dialogue_beat(db), desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RTDialogueBeats::beat_compilation_agent(compilation_subtask *ct) {
|
||||||
|
dialogue_beat *db = RETRIEVE_POINTER_dialogue_beat(ct->data);
|
||||||
|
current_sentence = db->compilation_data.where_created;
|
||||||
|
package_request *PR = RTDialogueBeats::package(db);
|
||||||
|
@<Deal with the availability of the beat@>;
|
||||||
|
@<Deal with the relevance of the beat@>;
|
||||||
|
@<Compile the structure array@>;
|
||||||
|
}
|
||||||
|
|
||||||
|
@<Deal with the availability of the beat@> =
|
||||||
|
int conditions = 0;
|
||||||
|
for (parse_node *clause = db->cue_at->down; clause; clause = clause->next) {
|
||||||
|
int c = Annotations::read_int(clause, dialogue_beat_clause_ANNOT);
|
||||||
|
if ((c == IF_DBC) || (c == UNLESS_DBC)) conditions++;
|
||||||
|
}
|
||||||
|
if ((db->immediately_after) ||
|
||||||
|
(LinkedLists::len(db->some_time_after) > 0) ||
|
||||||
|
(LinkedLists::len(db->some_time_before) > 0) ||
|
||||||
|
(conditions > 0)) {
|
||||||
|
Hierarchy::apply_metadata_from_iname(PR,
|
||||||
|
BEAT_AVAILABLE_MD_HL, RTDialogueBeats::available_fn_iname(db));
|
||||||
|
@<Compile the available function@>;
|
||||||
|
}
|
||||||
|
|
||||||
|
@<Compile the available function@> =
|
||||||
|
packaging_state save = Functions::begin(RTDialogueBeats::available_fn_iname(db));
|
||||||
|
local_variable *latest = LocalVariables::new_internal_commented(I"latest", I"most recently performed beat");
|
||||||
|
LocalVariables::set_kind(latest, K_dialogue_beat);
|
||||||
|
inter_symbol *latest_s = LocalVariables::declare(latest);
|
||||||
|
if (db->immediately_after) @<Check the immediately after condition@>;
|
||||||
|
@<Check the after and before conditions@>;
|
||||||
|
@<Check the if and unless conditions@>;
|
||||||
|
EmitCode::rtrue();
|
||||||
|
Functions::end(save);
|
||||||
|
|
||||||
|
@<Check the immediately after condition@> =
|
||||||
|
EmitCode::inv(IF_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::inv(NE_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::val_symbol(K_value, latest_s);
|
||||||
|
EmitCode::val_number(0);
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::code();
|
||||||
|
EmitCode::down();
|
||||||
|
@<Return false if latest does not match the immediately after description@>;
|
||||||
|
EmitCode::rfalse();
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::up();
|
||||||
|
|
||||||
|
@<Return false if latest does not match the immediately after description@> =
|
||||||
|
EmitCode::inv(IF_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
instance *I = Rvalues::to_instance(db->immediately_after);
|
||||||
|
if (I) {
|
||||||
|
EmitCode::inv(NE_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::val_symbol(K_value, latest_s);
|
||||||
|
EmitCode::val_iname(K_dialogue_beat, RTInstances::value_iname(I));
|
||||||
|
EmitCode::up();
|
||||||
|
} else {
|
||||||
|
pcalc_prop *prop = Propositions::negate(Descriptions::to_proposition(db->immediately_after));
|
||||||
|
if (prop) {
|
||||||
|
TypecheckPropositions::type_check(prop,
|
||||||
|
TypecheckPropositions::tc_no_problem_reporting());
|
||||||
|
CompilePropositions::to_test_as_condition(Lvalues::new_LOCAL_VARIABLE(EMPTY_WORDING, latest), prop);
|
||||||
|
} else {
|
||||||
|
internal_error("cannot test");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EmitCode::code();
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::rfalse();
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::up();
|
||||||
|
|
||||||
|
@<Check the after and before conditions@> =
|
||||||
|
parse_node *desc;
|
||||||
|
LOOP_OVER_LINKED_LIST(desc, parse_node, db->some_time_after) {
|
||||||
|
int negate_me = FALSE;
|
||||||
|
@<Work out proposition@>;
|
||||||
|
}
|
||||||
|
LOOP_OVER_LINKED_LIST(desc, parse_node, db->some_time_before) {
|
||||||
|
int negate_me = TRUE;
|
||||||
|
@<Work out proposition@>;
|
||||||
|
}
|
||||||
|
|
||||||
|
@<Work out proposition@> =
|
||||||
|
instance *I = Rvalues::to_instance(desc);
|
||||||
|
pcalc_prop *prop = NULL;
|
||||||
|
adjective *adj = EitherOrProperties::as_adjective(P_performed);
|
||||||
|
if (I) {
|
||||||
|
prop = AdjectivalPredicates::new_atom(adj, negate_me, Terms::new_constant(desc));
|
||||||
|
} else {
|
||||||
|
pcalc_prop *exists = Atoms::QUANTIFIER_new(exists_quantifier, 0, 0);
|
||||||
|
pcalc_prop *domain = KindPredicates::new_atom(K_dialogue_beat, Terms::new_variable(0));
|
||||||
|
pcalc_prop *performed = AdjectivalPredicates::new_atom(adj, negate_me, Terms::new_variable(0));
|
||||||
|
pcalc_prop *desc_prop = Descriptions::to_proposition(desc);
|
||||||
|
prop = Propositions::concatenate(exists,
|
||||||
|
Propositions::concatenate(domain,
|
||||||
|
Propositions::concatenate(performed,
|
||||||
|
desc_prop)));
|
||||||
|
}
|
||||||
|
prop = Propositions::negate(prop);
|
||||||
|
EmitCode::inv(IF_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
TypecheckPropositions::type_check(prop,
|
||||||
|
TypecheckPropositions::tc_no_problem_reporting());
|
||||||
|
CompilePropositions::to_test_as_condition(NULL, prop);
|
||||||
|
EmitCode::code();
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::rfalse();
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::up();
|
||||||
|
|
||||||
|
@<Check the if and unless conditions@> =
|
||||||
|
current_sentence = db->cue_at;
|
||||||
|
for (parse_node *clause = db->cue_at->down; clause; clause = clause->next) {
|
||||||
|
wording CW = Node::get_text(clause);
|
||||||
|
int c = Annotations::read_int(clause, dialogue_beat_clause_ANNOT);
|
||||||
|
switch (c) {
|
||||||
|
case IF_DBC:
|
||||||
|
case UNLESS_DBC: {
|
||||||
|
<dialogue-beat-clause>(CW);
|
||||||
|
wording A = GET_RW(<dialogue-beat-clause>, 1);
|
||||||
|
if (<s-condition>(A)) {
|
||||||
|
parse_node *cond = <<rp>>;
|
||||||
|
if (Dash::validate_conditional_clause(cond)) {
|
||||||
|
EmitCode::inv(IF_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
if (c == IF_DBC) {
|
||||||
|
EmitCode::inv(NOT_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
}
|
||||||
|
CompileValues::to_code_val_of_kind(cond, K_truth_state);
|
||||||
|
if (c == IF_DBC) {
|
||||||
|
EmitCode::up();
|
||||||
|
}
|
||||||
|
EmitCode::code();
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::rfalse();
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::up();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@<Deal with the relevance of the beat@> =
|
||||||
|
if (LinkedLists::len(db->about_list) > 0) {
|
||||||
|
Hierarchy::apply_metadata_from_iname(PR,
|
||||||
|
BEAT_RELEVANT_MD_HL, RTDialogueBeats::relevant_fn_iname(db));
|
||||||
|
@<Compile the relevant function@>;
|
||||||
|
}
|
||||||
|
|
||||||
|
@<Compile the relevant function@> =
|
||||||
|
packaging_state save = Functions::begin(RTDialogueBeats::relevant_fn_iname(db));
|
||||||
|
local_variable *pool = LocalVariables::new_internal_commented(I"pool", I"pool of live topics");
|
||||||
|
local_variable *iv = LocalVariables::new_internal_commented(I"iv", I"index variable");
|
||||||
|
local_variable *topic = LocalVariables::new_internal_commented(I"topic", I"live topic");
|
||||||
|
inter_symbol *pool_s = LocalVariables::declare(pool);
|
||||||
|
inter_symbol *iv_s = LocalVariables::declare(iv);
|
||||||
|
inter_symbol *topic_s = LocalVariables::declare(topic);
|
||||||
|
@<Check the about list against the subject pool@>;
|
||||||
|
EmitCode::rfalse();
|
||||||
|
Functions::end(save);
|
||||||
|
|
||||||
|
@<Check the about list against the subject pool@> =
|
||||||
|
inter_symbol *loop_label = EmitCode::reserve_label(I"about_loop");
|
||||||
|
EmitCode::place_label(loop_label);
|
||||||
|
EmitCode::inv(STORE_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::ref_symbol(K_value, topic_s);
|
||||||
|
EmitCode::inv(LOOKUP_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::val_symbol(K_value, pool_s);
|
||||||
|
EmitCode::val_symbol(K_value, iv_s);
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::inv(IF_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::inv(NE_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::val_symbol(K_value, topic_s);
|
||||||
|
EmitCode::val_number(0);
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::code();
|
||||||
|
EmitCode::down();
|
||||||
|
parse_node *desc;
|
||||||
|
LOOP_OVER_LINKED_LIST(desc, parse_node, db->about_list) {
|
||||||
|
instance *I = Rvalues::to_instance(desc);
|
||||||
|
EmitCode::inv(IF_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
if (I) {
|
||||||
|
EmitCode::inv(EQ_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::val_symbol(K_value, topic_s);
|
||||||
|
EmitCode::val_iname(K_value, RTInstances::value_iname(I));
|
||||||
|
EmitCode::up();
|
||||||
|
} else {
|
||||||
|
pcalc_prop *prop = Descriptions::to_proposition(desc);
|
||||||
|
if (prop) {
|
||||||
|
TypecheckPropositions::type_check(prop,
|
||||||
|
TypecheckPropositions::tc_no_problem_reporting());
|
||||||
|
CompilePropositions::to_test_as_condition(
|
||||||
|
Lvalues::new_LOCAL_VARIABLE(EMPTY_WORDING, topic), prop);
|
||||||
|
} else {
|
||||||
|
internal_error("cannot test");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EmitCode::code();
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::rtrue();
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::up();
|
||||||
|
}
|
||||||
|
EmitCode::inv(POSTINCREMENT_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::ref_symbol(K_value, iv_s);
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::inv(JUMP_BIP);
|
||||||
|
EmitCode::down();
|
||||||
|
EmitCode::lab(loop_label);
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::up();
|
||||||
|
EmitCode::rfalse();
|
||||||
|
|
||||||
|
@ And this is always present.
|
||||||
|
|
||||||
|
@<Compile the structure array@> =
|
||||||
|
Hierarchy::apply_metadata_from_iname(PR,
|
||||||
|
BEAT_STRUCTURE_MD_HL, RTDialogueBeats::structure_fn_iname(db));
|
||||||
|
packaging_state save =
|
||||||
|
EmitArrays::begin_word(RTDialogueBeats::structure_fn_iname(db), K_value);
|
||||||
|
RTDialogueBeats::compile_structure_r(db->root, 1);
|
||||||
|
EmitArrays::numeric_entry(0);
|
||||||
|
EmitArrays::end(save);
|
||||||
|
|
||||||
|
@ =
|
||||||
|
void RTDialogueBeats::compile_structure_r(dialogue_node *dn, inter_ti depth) {
|
||||||
|
while (dn) {
|
||||||
|
if (dn->if_line) {
|
||||||
|
EmitArrays::numeric_entry(depth + 100);
|
||||||
|
EmitArrays::iname_entry(RTInstances::value_iname(dn->if_line->as_instance));
|
||||||
|
} else if (dn->if_choice) {
|
||||||
|
EmitArrays::numeric_entry(depth + 200);
|
||||||
|
EmitArrays::iname_entry(RTInstances::value_iname(dn->if_choice->as_instance));
|
||||||
|
} else if (dn->if_decision) {
|
||||||
|
EmitArrays::numeric_entry(depth + 300);
|
||||||
|
EmitArrays::numeric_entry((inter_ti) (dn->if_decision->decision_type));
|
||||||
|
} else internal_error("unimplemented dialogue node compilation");
|
||||||
|
if (dn->child_node)
|
||||||
|
RTDialogueBeats::compile_structure_r(dn->child_node, depth+1);
|
||||||
|
dn = dn->next_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ =
|
||||||
|
void RTDialogueBeats::log_r(dialogue_node *dn) {
|
||||||
|
while (dn) {
|
||||||
|
if (dn->if_line)
|
||||||
|
LOG("Line %d = %W\n",
|
||||||
|
dn->if_line->allocation_id, Node::get_text(dn->if_line->compilation_data.where_created));
|
||||||
|
if (dn->if_choice)
|
||||||
|
LOG("Choice %d = %W\n",
|
||||||
|
dn->if_choice->allocation_id, Node::get_text(dn->if_choice->compilation_data.where_created));
|
||||||
|
if (dn->child_node) {
|
||||||
|
if (dn->child_node->parent_node != dn) LOG("*** Broken parentage ***\n");
|
||||||
|
LOG_INDENT;
|
||||||
|
RTDialogueBeats::log_r(dn->child_node);
|
||||||
|
LOG_OUTDENT;
|
||||||
|
}
|
||||||
|
dn = dn->next_node;
|
||||||
|
}
|
||||||
|
}
|
36
inform7/runtime-module/Chapter 5/Dialogue Choice Instances.w
Normal file
36
inform7/runtime-module/Chapter 5/Dialogue Choice Instances.w
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
[RTDialogueChoices::] Dialogue Choice Instances.
|
||||||
|
|
||||||
|
To compile any dialogue details in the instances submodule.
|
||||||
|
|
||||||
|
@h Compilation data for dialogue choices.
|
||||||
|
Each |dialogue_choice| object contains this data:
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct dialogue_choice_compilation_data {
|
||||||
|
struct parse_node *where_created;
|
||||||
|
} dialogue_choice_compilation_data;
|
||||||
|
|
||||||
|
dialogue_choice_compilation_data RTDialogueChoices::new(parse_node *PN, dialogue_choice *dc) {
|
||||||
|
dialogue_choice_compilation_data dlcd;
|
||||||
|
dlcd.where_created = PN;
|
||||||
|
return dlcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@h Compilation of dialogue.
|
||||||
|
|
||||||
|
=
|
||||||
|
void RTDialogueChoices::compile(void) {
|
||||||
|
dialogue_choice *dc;
|
||||||
|
LOOP_OVER(dc, dialogue_choice) {
|
||||||
|
text_stream *desc = Str::new();
|
||||||
|
WRITE_TO(desc, "dialogue choice %d", dc->allocation_id);
|
||||||
|
Sequence::queue(&RTDialogueChoices::choice_compilation_agent,
|
||||||
|
STORE_POINTER_dialogue_choice(dc), desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ =
|
||||||
|
void RTDialogueChoices::choice_compilation_agent(compilation_subtask *ct) {
|
||||||
|
dialogue_choice *dc = RETRIEVE_POINTER_dialogue_choice(ct->data);
|
||||||
|
current_sentence = dc->compilation_data.where_created;
|
||||||
|
}
|
35
inform7/runtime-module/Chapter 5/Dialogue Line Instances.w
Normal file
35
inform7/runtime-module/Chapter 5/Dialogue Line Instances.w
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
[RTDialogueLines::] Dialogue.
|
||||||
|
|
||||||
|
To compile any dialogue details in the instances submodule.
|
||||||
|
|
||||||
|
@h Compilation data for dialogue lines.
|
||||||
|
Each |dialogue_line| object contains this data:
|
||||||
|
|
||||||
|
=
|
||||||
|
typedef struct dialogue_line_compilation_data {
|
||||||
|
struct parse_node *where_created;
|
||||||
|
} dialogue_line_compilation_data;
|
||||||
|
|
||||||
|
dialogue_line_compilation_data RTDialogueLines::new(parse_node *PN, dialogue_line *dl) {
|
||||||
|
dialogue_line_compilation_data dlcd;
|
||||||
|
dlcd.where_created = PN;
|
||||||
|
return dlcd;
|
||||||
|
}
|
||||||
|
|
||||||
|
@h Compilation of dialogue.
|
||||||
|
|
||||||
|
=
|
||||||
|
void RTDialogueLines::compile(void) {
|
||||||
|
dialogue_line *dl;
|
||||||
|
LOOP_OVER(dl, dialogue_line) {
|
||||||
|
text_stream *desc = Str::new();
|
||||||
|
WRITE_TO(desc, "dialogue line %d", dl->allocation_id);
|
||||||
|
Sequence::queue(&RTDialogueLines::line_compilation_agent, STORE_POINTER_dialogue_line(dl), desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ =
|
||||||
|
void RTDialogueLines::line_compilation_agent(compilation_subtask *ct) {
|
||||||
|
dialogue_line *dl = RETRIEVE_POINTER_dialogue_line(ct->data);
|
||||||
|
current_sentence = dl->compilation_data.where_created;
|
||||||
|
}
|
|
@ -1,160 +0,0 @@
|
||||||
[RTDialogue::] Dialogue.
|
|
||||||
|
|
||||||
To compile the dialogue submodule for a compilation unit, which contains
|
|
||||||
something to be worked out.
|
|
||||||
|
|
||||||
@h Compilation data for dialogue beats.
|
|
||||||
Each |dialogue_beat| object contains this data:
|
|
||||||
|
|
||||||
=
|
|
||||||
typedef struct dialogue_beat_compilation_data {
|
|
||||||
struct parse_node *where_created;
|
|
||||||
struct inter_name *usage_filter_function;
|
|
||||||
} dialogue_beat_compilation_data;
|
|
||||||
|
|
||||||
dialogue_beat_compilation_data RTDialogue::new_beat(parse_node *PN, dialogue_beat *db) {
|
|
||||||
dialogue_beat_compilation_data dbcd;
|
|
||||||
dbcd.where_created = PN;
|
|
||||||
dbcd.usage_filter_function = NULL;
|
|
||||||
|
|
||||||
return dbcd;
|
|
||||||
}
|
|
||||||
|
|
||||||
inter_name *RTDialogue::beat_filter(dialogue_beat *db) {
|
|
||||||
if (db->compilation_data.usage_filter_function == NULL)
|
|
||||||
db->compilation_data.usage_filter_function =
|
|
||||||
Hierarchy::make_iname_in(BEAT_FILTER_FN_HL, RTInstances::package(db->as_instance));
|
|
||||||
return db->compilation_data.usage_filter_function;
|
|
||||||
}
|
|
||||||
|
|
||||||
@h Compilation data for dialogue lines.
|
|
||||||
Each |dialogue_line| object contains this data:
|
|
||||||
|
|
||||||
=
|
|
||||||
typedef struct dialogue_line_compilation_data {
|
|
||||||
struct parse_node *where_created;
|
|
||||||
} dialogue_line_compilation_data;
|
|
||||||
|
|
||||||
dialogue_line_compilation_data RTDialogue::new_line(parse_node *PN, dialogue_line *dl) {
|
|
||||||
dialogue_line_compilation_data dlcd;
|
|
||||||
dlcd.where_created = PN;
|
|
||||||
return dlcd;
|
|
||||||
}
|
|
||||||
|
|
||||||
@h Compilation data for dialogue choices.
|
|
||||||
Each |dialogue_choice| object contains this data:
|
|
||||||
|
|
||||||
=
|
|
||||||
typedef struct dialogue_choice_compilation_data {
|
|
||||||
struct parse_node *where_created;
|
|
||||||
} dialogue_choice_compilation_data;
|
|
||||||
|
|
||||||
dialogue_choice_compilation_data RTDialogue::new_choice(parse_node *PN, dialogue_choice *dc) {
|
|
||||||
dialogue_choice_compilation_data dlcd;
|
|
||||||
dlcd.where_created = PN;
|
|
||||||
return dlcd;
|
|
||||||
}
|
|
||||||
|
|
||||||
@h Compilation of dialogue.
|
|
||||||
|
|
||||||
=
|
|
||||||
void RTDialogue::compile(void) {
|
|
||||||
dialogue_beat *db;
|
|
||||||
LOOP_OVER(db, dialogue_beat) {
|
|
||||||
text_stream *desc = Str::new();
|
|
||||||
WRITE_TO(desc, "dialogue beat %d", db->allocation_id);
|
|
||||||
Sequence::queue(&RTDialogue::beat_compilation_agent, STORE_POINTER_dialogue_beat(db), desc);
|
|
||||||
}
|
|
||||||
dialogue_line *dl;
|
|
||||||
LOOP_OVER(dl, dialogue_line) {
|
|
||||||
text_stream *desc = Str::new();
|
|
||||||
WRITE_TO(desc, "dialogue line %d", dl->allocation_id);
|
|
||||||
Sequence::queue(&RTDialogue::line_compilation_agent, STORE_POINTER_dialogue_line(dl), desc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RTDialogue::beat_compilation_agent(compilation_subtask *ct) {
|
|
||||||
dialogue_beat *db = RETRIEVE_POINTER_dialogue_beat(ct->data);
|
|
||||||
current_sentence = db->compilation_data.where_created;
|
|
||||||
LOG("Beat %d = %W name '%W' scene '%W'\n",
|
|
||||||
db->allocation_id, Node::get_text(current_sentence), db->beat_name, db->scene_name);
|
|
||||||
RTDialogue::log_r(db->root);
|
|
||||||
packaging_state save = Functions::begin(RTDialogue::beat_filter(db));
|
|
||||||
local_variable *latest = LocalVariables::new_internal_commented(I"latest", I"most recently performed beat");
|
|
||||||
LocalVariables::set_kind(latest, K_dialogue_beat);
|
|
||||||
local_variable *pool = LocalVariables::new_internal_commented(I"pool", I"pool of live topics");
|
|
||||||
inter_symbol *latest_s = LocalVariables::declare(latest);
|
|
||||||
inter_symbol *pool_s = LocalVariables::declare(pool);
|
|
||||||
if (db->immediately_after) {
|
|
||||||
EmitCode::inv(IF_BIP);
|
|
||||||
EmitCode::down();
|
|
||||||
EmitCode::inv(NE_BIP);
|
|
||||||
EmitCode::down();
|
|
||||||
EmitCode::val_symbol(K_value, latest_s);
|
|
||||||
EmitCode::val_number(0);
|
|
||||||
EmitCode::up();
|
|
||||||
EmitCode::code();
|
|
||||||
EmitCode::down();
|
|
||||||
@<Return true if latest matches the immediately after description@>;
|
|
||||||
EmitCode::rfalse();
|
|
||||||
EmitCode::up();
|
|
||||||
EmitCode::up();
|
|
||||||
}
|
|
||||||
EmitCode::inv(STORE_BIP);
|
|
||||||
EmitCode::down();
|
|
||||||
EmitCode::ref_symbol(K_value, pool_s);
|
|
||||||
EmitCode::val_number(0);
|
|
||||||
EmitCode::up();
|
|
||||||
EmitCode::rfalse();
|
|
||||||
Functions::end(save);
|
|
||||||
}
|
|
||||||
|
|
||||||
@<Return true if latest matches the immediately after description@> =
|
|
||||||
EmitCode::inv(IF_BIP);
|
|
||||||
EmitCode::down();
|
|
||||||
LOG("IA cond is $T\n", db->immediately_after);
|
|
||||||
instance *I = Rvalues::to_instance(db->immediately_after);
|
|
||||||
if (I) {
|
|
||||||
EmitCode::inv(EQ_BIP);
|
|
||||||
EmitCode::down();
|
|
||||||
EmitCode::val_symbol(K_value, latest_s);
|
|
||||||
EmitCode::val_iname(K_dialogue_beat, RTInstances::value_iname(I));
|
|
||||||
EmitCode::up();
|
|
||||||
} else {
|
|
||||||
pcalc_prop *prop = Descriptions::to_proposition(db->immediately_after);
|
|
||||||
if (prop) {
|
|
||||||
CompilePropositions::to_test_as_condition(Lvalues::new_LOCAL_VARIABLE(EMPTY_WORDING, latest), prop);
|
|
||||||
} else {
|
|
||||||
internal_error("cannot test");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EmitCode::code();
|
|
||||||
EmitCode::down();
|
|
||||||
EmitCode::rtrue();
|
|
||||||
EmitCode::up();
|
|
||||||
EmitCode::up();
|
|
||||||
|
|
||||||
@ =
|
|
||||||
void RTDialogue::line_compilation_agent(compilation_subtask *ct) {
|
|
||||||
dialogue_line *dl = RETRIEVE_POINTER_dialogue_line(ct->data);
|
|
||||||
current_sentence = dl->compilation_data.where_created;
|
|
||||||
LOG("Line %d = %W name '%W'\n", dl->allocation_id, Node::get_text(current_sentence), dl->line_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RTDialogue::log_r(dialogue_node *dn) {
|
|
||||||
while (dn) {
|
|
||||||
if (dn->if_line)
|
|
||||||
LOG("Line %d = %W\n",
|
|
||||||
dn->if_line->allocation_id, Node::get_text(dn->if_line->compilation_data.where_created));
|
|
||||||
if (dn->if_choice)
|
|
||||||
LOG("Choice %d = %W\n",
|
|
||||||
dn->if_choice->allocation_id, Node::get_text(dn->if_choice->compilation_data.where_created));
|
|
||||||
if (dn->child_node) {
|
|
||||||
if (dn->child_node->parent_node != dn) LOG("*** Broken parentage ***\n");
|
|
||||||
LOG_INDENT;
|
|
||||||
RTDialogue::log_r(dn->child_node);
|
|
||||||
LOG_OUTDENT;
|
|
||||||
}
|
|
||||||
dn = dn->next_node;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -157,6 +157,15 @@ void RTInstances::compilation_agent(compilation_subtask *t) {
|
||||||
if ((K_sound_name) && (Kinds::eq(K, K_sound_name)))
|
if ((K_sound_name) && (Kinds::eq(K, K_sound_name)))
|
||||||
Hierarchy::apply_metadata_from_number(pack,
|
Hierarchy::apply_metadata_from_number(pack,
|
||||||
INSTANCE_IS_SOUND_MD_HL, 1);
|
INSTANCE_IS_SOUND_MD_HL, 1);
|
||||||
|
if ((K_dialogue_beat) && (Kinds::eq(K, K_dialogue_beat)))
|
||||||
|
Hierarchy::apply_metadata_from_number(pack,
|
||||||
|
INSTANCE_IS_DB_MD_HL, 1);
|
||||||
|
if ((K_dialogue_line) && (Kinds::eq(K, K_dialogue_line)))
|
||||||
|
Hierarchy::apply_metadata_from_number(pack,
|
||||||
|
INSTANCE_IS_DL_MD_HL, 1);
|
||||||
|
if ((K_dialogue_choice) && (Kinds::eq(K, K_dialogue_choice)))
|
||||||
|
Hierarchy::apply_metadata_from_number(pack,
|
||||||
|
INSTANCE_IS_DC_MD_HL, 1);
|
||||||
if ((K_figure_name) && (Kinds::eq(K, K_figure_name)))
|
if ((K_figure_name) && (Kinds::eq(K, K_figure_name)))
|
||||||
Hierarchy::apply_metadata_from_number(pack,
|
Hierarchy::apply_metadata_from_number(pack,
|
||||||
INSTANCE_IS_FIGURE_MD_HL, 1);
|
INSTANCE_IS_FIGURE_MD_HL, 1);
|
||||||
|
|
|
@ -61,7 +61,9 @@ Chapter 5: Provision Submodules
|
||||||
Multimedia
|
Multimedia
|
||||||
Tables
|
Tables
|
||||||
Table Columns
|
Table Columns
|
||||||
Dialogue
|
Dialogue Beat Instances
|
||||||
|
Dialogue Line Instances
|
||||||
|
Dialogue Choice Instances
|
||||||
Rules
|
Rules
|
||||||
Rulebooks
|
Rulebooks
|
||||||
Variables
|
Variables
|
||||||
|
|
46
inter/pipeline-module/Chapter 5/Dialogue.w
Normal file
46
inter/pipeline-module/Chapter 5/Dialogue.w
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
[SynopticDialogue::] Dialogue.
|
||||||
|
|
||||||
|
To compile the main/synoptic/dialogue submodule.
|
||||||
|
|
||||||
|
@ Our inventory |inv| already contains a list |inv->instance_nodes| of all packages
|
||||||
|
in the tree with type |_instance|.
|
||||||
|
|
||||||
|
For the moment, at least, it seems too ambitious to dynamically renumber instances
|
||||||
|
in the linking stage. Until then, this section is something of a placeholder,
|
||||||
|
making only a debugging function.
|
||||||
|
|
||||||
|
=
|
||||||
|
void SynopticDialogue::compile(inter_tree *I, pipeline_step *step, tree_inventory *inv) {
|
||||||
|
if (InterNodeList::array_len(inv->instance_nodes) > 0)
|
||||||
|
InterNodeList::array_sort(inv->instance_nodes, MakeSynopticModuleStage::module_order);
|
||||||
|
@<Define DIALOGUEBEATS array@>;
|
||||||
|
}
|
||||||
|
|
||||||
|
@<Define DIALOGUEBEATS array@> =
|
||||||
|
inter_ti count = 0;
|
||||||
|
for (int i=0; i<InterNodeList::array_len(inv->instance_nodes); i++) {
|
||||||
|
inter_package *pack =
|
||||||
|
PackageInstruction::at_this_head(inv->instance_nodes->list[i].node);
|
||||||
|
if (Metadata::read_optional_numeric(pack, I"^is_dialogue_beat")) count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
inter_name *iname = HierarchyLocations::iname(I, DIALOGUEBEATS_HL);
|
||||||
|
Synoptic::begin_array(I, step, iname);
|
||||||
|
Synoptic::numeric_entry(count);
|
||||||
|
if (count == 0) Synoptic::numeric_entry(0);
|
||||||
|
for (int i=0; i<InterNodeList::array_len(inv->instance_nodes); i++) {
|
||||||
|
inter_package *pack =
|
||||||
|
PackageInstruction::at_this_head(inv->instance_nodes->list[i].node);
|
||||||
|
if (Metadata::read_optional_numeric(pack, I"^is_dialogue_beat")) {
|
||||||
|
inter_symbol *filter = Metadata::optional_symbol(pack, I"^available");
|
||||||
|
if (filter) Synoptic::symbol_entry(filter);
|
||||||
|
else Synoptic::numeric_entry(0);
|
||||||
|
inter_symbol *rel = Metadata::optional_symbol(pack, I"^relevant");
|
||||||
|
if (rel) Synoptic::symbol_entry(rel);
|
||||||
|
else Synoptic::numeric_entry(0);
|
||||||
|
inter_symbol *str = Metadata::optional_symbol(pack, I"^structure");
|
||||||
|
if (str) Synoptic::symbol_entry(str);
|
||||||
|
else Synoptic::numeric_entry(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Synoptic::end_array(I);
|
|
@ -28,6 +28,7 @@ int MakeSynopticModuleStage::run(pipeline_step *step) {
|
||||||
SynopticChronology::compile(I, step, inv);
|
SynopticChronology::compile(I, step, inv);
|
||||||
SynopticExtensions::compile(I, step, inv);
|
SynopticExtensions::compile(I, step, inv);
|
||||||
SynopticInstances::compile(I, step, inv);
|
SynopticInstances::compile(I, step, inv);
|
||||||
|
SynopticDialogue::compile(I, step, inv);
|
||||||
SynopticKinds::compile(I, step, inv);
|
SynopticKinds::compile(I, step, inv);
|
||||||
SynopticMultimedia::compile(I, step, inv);
|
SynopticMultimedia::compile(I, step, inv);
|
||||||
SynopticProperties::compile(I, step, inv);
|
SynopticProperties::compile(I, step, inv);
|
||||||
|
|
|
@ -21,6 +21,7 @@ void SynopticHierarchy::establish(inter_tree *I) {
|
||||||
@<Resources for activities@>;
|
@<Resources for activities@>;
|
||||||
@<Resources for chronology@>;
|
@<Resources for chronology@>;
|
||||||
@<Resources for conjugations@>;
|
@<Resources for conjugations@>;
|
||||||
|
@<Resources for dialogue@>;
|
||||||
@<Resources for extensions@>;
|
@<Resources for extensions@>;
|
||||||
@<Resources for instances@>;
|
@<Resources for instances@>;
|
||||||
@<Resources for kinds@>;
|
@<Resources for kinds@>;
|
||||||
|
@ -117,6 +118,15 @@ The |/main/synoptic/conjugations| submodule.
|
||||||
SYN_SUBMD(I"conjugations")
|
SYN_SUBMD(I"conjugations")
|
||||||
SYN_CONST(TABLEOFVERBS_HL, I"TableOfVerbs")
|
SYN_CONST(TABLEOFVERBS_HL, I"TableOfVerbs")
|
||||||
|
|
||||||
|
@h Dialogue.
|
||||||
|
The |/main/synoptic/dialogue| submodule.
|
||||||
|
|
||||||
|
@e DIALOGUEBEATS_HL
|
||||||
|
|
||||||
|
@<Resources for dialogue@> =
|
||||||
|
SYN_SUBMD(I"dialogue")
|
||||||
|
SYN_CONST(DIALOGUEBEATS_HL, I"TableOfDialogueBeats")
|
||||||
|
|
||||||
@h Extensions.
|
@h Extensions.
|
||||||
The |/main/synoptic/extensions| submodule.
|
The |/main/synoptic/extensions| submodule.
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,7 @@ Chapter 5: Synoptic Module
|
||||||
Activities
|
Activities
|
||||||
Actions
|
Actions
|
||||||
Instances
|
Instances
|
||||||
|
Dialogue
|
||||||
Kinds
|
Kinds
|
||||||
Properties
|
Properties
|
||||||
Relations
|
Relations
|
||||||
|
|
|
@ -706,6 +706,11 @@ here. This hand-tooled parser is annoyingly long to write out, but only in
|
||||||
order to catch improbable unmatched-bracket errors with tidy error messages.
|
order to catch improbable unmatched-bracket errors with tidy error messages.
|
||||||
|
|
||||||
@<Make a DIALOGUE node@> =
|
@<Make a DIALOGUE node@> =
|
||||||
|
#ifdef DIALOGUE_WARNING_SYNTAX_CALLBACK
|
||||||
|
if (T->contains_dialogue == FALSE) {
|
||||||
|
DIALOGUE_WARNING_SYNTAX_CALLBACK();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
T->contains_dialogue = TRUE;
|
T->contains_dialogue = TRUE;
|
||||||
if ((Lexer::word(Wordings::first_wn(W)) == OPENBRACKET_V) &&
|
if ((Lexer::word(Wordings::first_wn(W)) == OPENBRACKET_V) &&
|
||||||
(Lexer::word(Wordings::last_wn(W)) == CLOSEBRACKET_V))
|
(Lexer::word(Wordings::last_wn(W)) == CLOSEBRACKET_V))
|
||||||
|
|
Loading…
Reference in a new issue