1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-01 06:24:58 +03:00

Removed need to declare SENTENCE_NODE when using syntax module

This commit is contained in:
Graham Nelson 2020-03-26 09:59:32 +00:00
parent 9aa6176dc0
commit 3c59521ab7
6 changed files with 97 additions and 109 deletions

View file

@ -1,7 +1,7 @@
[Main::] Main. [Main::] Main.
The top level, which decides what is to be done and then carries A command-line interface for Inbuild functions which are not part of the
this plan out. normal operation of the Inform compiler.
@h Main routine. @h Main routine.
@ -39,6 +39,7 @@ int main(int argc, char **argv) {
InbuildModule::start(); InbuildModule::start();
targets = NEW_LINKED_LIST(inbuild_copy); targets = NEW_LINKED_LIST(inbuild_copy);
@<Read the command line@>; @<Read the command line@>;
@<Manage Inbuild@>;
if (Str::len(unit_test) > 0) dry_run_mode = TRUE; if (Str::len(unit_test) > 0) dry_run_mode = TRUE;
int use = SHELL_METHODOLOGY; int use = SHELL_METHODOLOGY;
@ -97,7 +98,64 @@ int main(int argc, char **argv) {
return 0; return 0;
} }
@ We use Foundation to read the command line: @<Manage Inbuild@> =
if (LinkedLists::len(unsorted_nest_list) == 0)
Inbuild::add_nest(
Pathnames::from_text(I"inform7/Internal"), INTERNAL_NEST_TAG);
path_to_inbuild = Pathnames::installation_path("INBUILD_PATH", I"inbuild");
pathname *P = Pathnames::subfolder(path_to_inbuild, I"Tangled");
filename *S = Filenames::in_folder(P, I"Syntax.preform");
wording W = Preform::load_from_file(S);
Preform::parse_preform(W, FALSE);
CommandLine::play_back_log();
inbuild_copy *proj = NULL, *C;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets)
if (C->edition->work->genre == project_bundle_genre) {
if (Str::len(project_bundle_request) > 0)
Errors::with_text("can only work on one project bundle at a time, so ignoring '%S'", C->edition->work->title);
else if (proj) Errors::with_text("can only work on one project bundle at a time, so ignoring '%S'", C->edition->work->title);
else proj = C;
}
proj = Inbuild::optioneering_complete(proj, FALSE);
if (proj) {
int found = FALSE;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets)
if (C == proj)
found = TRUE;
if (found == FALSE) ADD_TO_LINKED_LIST(proj, inbuild_copy, targets);
}
inbuild_nest_list = Inbuild::nest_list();
Inbuild::go_operational();
@ =
void Main::load_many(pathname *P) {
scan_directory *D = Directories::open(P);
TEMPORARY_TEXT(LEAFNAME);
while (Directories::next(D, LEAFNAME)) {
TEMPORARY_TEXT(FILENAME);
WRITE_TO(FILENAME, "%p%c%S", P, FOLDER_SEPARATOR, LEAFNAME);
Main::load_one(FILENAME, FALSE);
DISCARD_TEXT(FILENAME);
}
DISCARD_TEXT(LEAFNAME);
Directories::close(D);
}
void Main::load_one(text_stream *arg, int throwing_error) {
inbuild_copy *C = Copies::claim(arg);
if (C == NULL) {
if (throwing_error) Errors::with_text("unable to identify '%S'", arg);
return;
}
ADD_TO_LINKED_LIST(C, inbuild_copy, targets);
}
@h Command line.
Note the call below to |Inbuild::declare_options|, which adds a whole lot of
other options to the selection defined here.
@e BUILD_CLSW @e BUILD_CLSW
@e REBUILD_CLSW @e REBUILD_CLSW
@ -156,38 +214,9 @@ int main(int argc, char **argv) {
CommandLine::read(argc, argv, NULL, &Main::option, &Main::bareword); CommandLine::read(argc, argv, NULL, &Main::option, &Main::bareword);
if (LinkedLists::len(unsorted_nest_list) == 0) @ Here we handle those options not handled by the |inbuild| module.
Inbuild::add_nest(
Pathnames::from_text(I"inform7/Internal"), INTERNAL_NEST_TAG);
path_to_inbuild = Pathnames::installation_path("INBUILD_PATH", I"inbuild"); =
pathname *P = Pathnames::subfolder(path_to_inbuild, I"Tangled");
filename *S = Filenames::in_folder(P, I"Syntax.preform");
wording W = Preform::load_from_file(S);
Preform::parse_preform(W, FALSE);
CommandLine::play_back_log();
inbuild_copy *proj = NULL, *C;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets)
if (C->edition->work->genre == project_bundle_genre) {
if (Str::len(project_bundle_request) > 0)
Errors::with_text("can only work on one project bundle at a time, so ignoring '%S'", C->edition->work->title);
else if (proj) Errors::with_text("can only work on one project bundle at a time, so ignoring '%S'", C->edition->work->title);
else proj = C;
}
proj = Inbuild::optioneering_complete(proj, FALSE);
if (proj) {
int found = FALSE;
LOOP_OVER_LINKED_LIST(C, inbuild_copy, targets)
if (C == proj)
found = TRUE;
if (found == FALSE) ADD_TO_LINKED_LIST(proj, inbuild_copy, targets);
}
inbuild_nest_list = Inbuild::nest_list();
Inbuild::go_operational();
@ =
void Main::option(int id, int val, text_stream *arg, void *state) { void Main::option(int id, int val, text_stream *arg, void *state) {
switch (id) { switch (id) {
case BUILD_CLSW: inbuild_task = BUILD_TTASK; break; case BUILD_CLSW: inbuild_task = BUILD_TTASK; break;
@ -219,46 +248,29 @@ void Main::option(int id, int val, text_stream *arg, void *state) {
Inbuild::option(id, val, arg, state); Inbuild::option(id, val, arg, state);
} }
@ This is called for a command-line argument which doesn't appear as
subordinate to any switch; we take it as the name of a copy.
=
void Main::bareword(int id, text_stream *arg, void *state) { void Main::bareword(int id, text_stream *arg, void *state) {
Main::load_one(arg, TRUE); Main::load_one(arg, TRUE);
} }
void Main::load_many(pathname *P) { @h Interface to Words module.
scan_directory *D = Directories::open(P); Since we want to include the |words| module, we have to define the following
TEMPORARY_TEXT(LEAFNAME); structure and initialiser. The type |vocabulary_meaning| is expected to hold
while (Directories::next(D, LEAFNAME)) { meanings associated with a given word; when |inform7| uses |word| it is rich
TEMPORARY_TEXT(FILENAME); and full of significance, but for us it does nothing. We give it a meaningless
WRITE_TO(FILENAME, "%p%c%S", P, FOLDER_SEPARATOR, LEAFNAME); integer as its content, since in C it isn't legal to have an empty |struct|.
Main::load_one(FILENAME, FALSE);
DISCARD_TEXT(FILENAME);
}
DISCARD_TEXT(LEAFNAME);
Directories::close(D);
}
void Main::load_one(text_stream *arg, int throwing_error) { @d VOCABULARY_MEANING_INITIALISER Main::create_meaningless_vm
inbuild_copy *C = Copies::claim(arg);
if (C == NULL) {
if (throwing_error) Errors::with_text("unable to identify '%S'", arg);
return;
}
ADD_TO_LINKED_LIST(C, inbuild_copy, targets);
}
@ Since we want to include the words module, we have to define the following
structure and initialiser:
@d VOCABULARY_MEANING_INITIALISER Main::ignore
= =
typedef struct vocabulary_meaning { typedef struct vocabulary_meaning {
int enigmatic_number; int enigmatic_number;
} vocabulary_meaning; } vocabulary_meaning;
@ vocabulary_meaning Main::create_meaningless_vm(vocabulary_entry *ve) {
=
vocabulary_meaning Main::ignore(vocabulary_entry *ve) {
vocabulary_meaning vm; vocabulary_meaning vm;
vm.enigmatic_number = 90125; vm.enigmatic_number = 90125;
return vm; return vm;
@ -268,7 +280,7 @@ vocabulary_meaning Main::ignore(vocabulary_entry *ve) {
@d PREFORM_LANGUAGE_TYPE void @d PREFORM_LANGUAGE_TYPE void
@d PARSE_TREE_TRAVERSE_TYPE void @d PARSE_TREE_TRAVERSE_TYPE void
@d SENTENCE_NODE Main::sentence_level @d CCCCSENTENCE_NODE Main::sentence_level
@d PARSE_TREE_METADATA_SETUP SourceText::node_metadata @d PARSE_TREE_METADATA_SETUP SourceText::node_metadata
= =

View file

@ -910,7 +910,7 @@ void ParseTree::traverse_from(parse_node *pn, void (*visitor)(parse_node *)) {
for (; pn; pn = pn->next) { for (; pn; pn = pn->next) {
if (ParseTree::top_level(pn->node_type)) ParseTree::traverse_from(pn->down, visitor); if (ParseTree::top_level(pn->node_type)) ParseTree::traverse_from(pn->down, visitor);
if (ParseTree::visitable(pn->node_type)) { if (ParseTree::visitable(pn->node_type)) {
if (SENTENCE_NODE(pn->node_type)) current_sentence = pn; if (ParseTree::sentence_node(pn->node_type)) current_sentence = pn;
(*visitor)(pn); (*visitor)(pn);
} }
} }
@ -923,7 +923,7 @@ void ParseTree::traverse_dfirst_from(parse_node *pn, void (*visitor)(parse_node
parse_node *SCS = current_sentence; parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) { for (; pn; pn = pn->next) {
ParseTree::traverse_dfirst_from(pn->down, visitor); ParseTree::traverse_dfirst_from(pn->down, visitor);
if (SENTENCE_NODE(pn->node_type)) current_sentence = pn; if (ParseTree::sentence_node(pn->node_type)) current_sentence = pn;
(*visitor)(pn); (*visitor)(pn);
} }
current_sentence = SCS; current_sentence = SCS;
@ -934,7 +934,7 @@ void ParseTree::traverse_wfirst(parse_node_tree *T, void (*visitor)(parse_node *
void ParseTree::traverse_wfirst_from(parse_node *pn, void (*visitor)(parse_node *)) { void ParseTree::traverse_wfirst_from(parse_node *pn, void (*visitor)(parse_node *)) {
parse_node *SCS = current_sentence; parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) { for (; pn; pn = pn->next) {
if (SENTENCE_NODE(pn->node_type)) current_sentence = pn; if (ParseTree::sentence_node(pn->node_type)) current_sentence = pn;
ParseTree::traverse_wfirst_from(pn->down, visitor); ParseTree::traverse_wfirst_from(pn->down, visitor);
(*visitor)(pn); (*visitor)(pn);
} }
@ -949,7 +949,7 @@ void ParseTree::traverse_from_with_stream(text_stream *OUT, parse_node *pn, void
if (ParseTree::top_level(pn->node_type)) if (ParseTree::top_level(pn->node_type))
ParseTree::traverse_from_with_stream(OUT, pn->down, visitor); ParseTree::traverse_from_with_stream(OUT, pn->down, visitor);
if (ParseTree::visitable(pn->node_type)) { if (ParseTree::visitable(pn->node_type)) {
if (SENTENCE_NODE(pn->node_type)) current_sentence = pn; if (ParseTree::sentence_node(pn->node_type)) current_sentence = pn;
(*visitor)(OUT, pn); (*visitor)(OUT, pn);
} }
} }
@ -963,7 +963,7 @@ void ParseTree::traverse_from_int(parse_node *pn, void (*visitor)(parse_node *,
for (; pn; pn = pn->next) { for (; pn; pn = pn->next) {
if (ParseTree::top_level(pn->node_type)) ParseTree::traverse_from_int(pn->down, visitor, X); if (ParseTree::top_level(pn->node_type)) ParseTree::traverse_from_int(pn->down, visitor, X);
if (ParseTree::visitable(pn->node_type)) { if (ParseTree::visitable(pn->node_type)) {
if (SENTENCE_NODE(pn->node_type)) current_sentence = pn; if (ParseTree::sentence_node(pn->node_type)) current_sentence = pn;
(*visitor)(pn, X); (*visitor)(pn, X);
} }
} }
@ -977,7 +977,7 @@ void ParseTree::traverse_from_int_int(parse_node *pn, void (*visitor)(parse_node
for (; pn; pn = pn->next) { for (; pn; pn = pn->next) {
if (ParseTree::top_level(pn->node_type)) ParseTree::traverse_from_int_int(pn->down, visitor, X, Y); if (ParseTree::top_level(pn->node_type)) ParseTree::traverse_from_int_int(pn->down, visitor, X, Y);
if (ParseTree::visitable(pn->node_type)) { if (ParseTree::visitable(pn->node_type)) {
if (SENTENCE_NODE(pn->node_type)) current_sentence = pn; if (ParseTree::sentence_node(pn->node_type)) current_sentence = pn;
(*visitor)(pn, X, Y); (*visitor)(pn, X, Y);
} }
} }
@ -991,7 +991,7 @@ void ParseTree::traverse_from_ppn(parse_node *pn, void (*visitor)(parse_node *,
for (; pn; pn = pn->next) { for (; pn; pn = pn->next) {
if (ParseTree::top_level(pn->node_type)) ParseTree::traverse_from_ppn(pn->down, visitor, X); if (ParseTree::top_level(pn->node_type)) ParseTree::traverse_from_ppn(pn->down, visitor, X);
if (ParseTree::visitable(pn->node_type)) { if (ParseTree::visitable(pn->node_type)) {
if (SENTENCE_NODE(pn->node_type)) current_sentence = pn; if (ParseTree::sentence_node(pn->node_type)) current_sentence = pn;
(*visitor)(pn, X); (*visitor)(pn, X);
} }
} }
@ -1010,7 +1010,7 @@ void ParseTree::traverse_from_ppni(parse_node_tree *T, parse_node *pn, void (*vi
ParseTree::traverse_from_ppni(T, pn->down, visitor, H0, N); ParseTree::traverse_from_ppni(T, pn->down, visitor, H0, N);
} }
if (ParseTree::visitable(pn->node_type)) { if (ParseTree::visitable(pn->node_type)) {
if (SENTENCE_NODE(pn->node_type)) current_sentence = pn; if (ParseTree::sentence_node(pn->node_type)) current_sentence = pn;
(*visitor)(T, pn, last_h0, N); (*visitor)(T, pn, last_h0, N);
} }
} }
@ -1029,7 +1029,7 @@ int ParseTree::traverse_from_up_to_ip(parse_node *end, parse_node *pn, void (*vi
} }
} }
if (ParseTree::visitable(pn->node_type)) { if (ParseTree::visitable(pn->node_type)) {
if (SENTENCE_NODE(pn->node_type)) current_sentence = pn; if (ParseTree::sentence_node(pn->node_type)) current_sentence = pn;
(*visitor)(pn, X); (*visitor)(pn, X);
} }
} }
@ -1055,6 +1055,18 @@ int ParseTree::traverse_from_ppn_nocs(parse_node *pn, int (*visitor)(parse_node
return FALSE; return FALSE;
} }
@ This provides a way for users of the module to indicate what's a sentence:
=
int ParseTree::sentence_node(node_type_t t) {
#ifdef SENTENCE_NODE
return SENTENCE_NODE(t);
#endif
#ifndef SENTENCE_NODE
return FALSE;
#endif
}
@h Verify integrity. @h Verify integrity.
The first duty of a tree is to contain no loops, and the following checks The first duty of a tree is to contain no loops, and the following checks
that (rejecting even undirected loops). In addition, it checks that each that (rejecting even undirected loops). In addition, it checks that each

View file

@ -150,10 +150,3 @@ void Basics::preform_problem_handler(word_assemblage base_text, nonterminal *nt,
@ @
@d PARSE_TREE_TRAVERSE_TYPE void @d PARSE_TREE_TRAVERSE_TYPE void
@d SENTENCE_NODE Basics::sentence_level
=
int Basics::sentence_level(node_type_t t) {
return FALSE;
}

View file

@ -155,15 +155,6 @@ void Basics::preform_problem_handler(word_assemblage base_text, nonterminal *nt,
@ @
@d PARSE_TREE_TRAVERSE_TYPE void @d PARSE_TREE_TRAVERSE_TYPE void
@d SENTENCE_NODE Basics::sentence_level
=
int Basics::sentence_level(node_type_t t) {
return FALSE;
}
@
@d ADJECTIVE_MEANING_TYPE void @d ADJECTIVE_MEANING_TYPE void
@d VERB_MEANING_EQUALITY vc_be @d VERB_MEANING_EQUALITY vc_be
@d VERB_MEANING_POSSESSION vc_have @d VERB_MEANING_POSSESSION vc_have

View file

@ -156,15 +156,6 @@ void Basics::preform_problem_handler(word_assemblage base_text, nonterminal *nt,
@ @
@d PARSE_TREE_TRAVERSE_TYPE void @d PARSE_TREE_TRAVERSE_TYPE void
@d SENTENCE_NODE Basics::sentence_level
=
int Basics::sentence_level(node_type_t t) {
return FALSE;
}
@
@d ADJECTIVE_MEANING_TYPE void @d ADJECTIVE_MEANING_TYPE void
@d VERB_MEANING_EQUALITY vc_be @d VERB_MEANING_EQUALITY vc_be
@d VERB_MEANING_POSSESSION vc_have @d VERB_MEANING_POSSESSION vc_have

View file

@ -150,15 +150,4 @@ void Basics::preform_problem_handler(word_assemblage base_text, nonterminal *nt,
@ @
@d PARSE_TREE_TRAVERSE_TYPE void @d PARSE_TREE_TRAVERSE_TYPE void
@d SENTENCE_NODE Basics::sentence_level
=
int Basics::sentence_level(node_type_t t) {
return FALSE;
}
@
@d NO_HEADING_LEVELS 10 @d NO_HEADING_LEVELS 10