1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-03 07:24:58 +03:00
inform7/retrospective/6M62/ni.c

132533 lines
4.5 MiB

/* Tangled output generated by inweb-C: do not edit */
#include <stdio.h>
#include <ctype.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <math.h>
#include <errno.h>
#include <errno.h>
#ifdef PLATFORM_LINUX
#define PLATFORM_UNIX /* Manually added: alias LINUX to UNIX */
#endif
#define NI_VERSION "Inform 7"
#define NI_BUILD "6M62"
#define PREFORM_PUNCTUATION_MARKS "{}[]_^?&\\"
#define TRUE 1
#define FALSE 0
#define NOT_APPLICABLE 2
#define UTF8_ENC 1 /* Write as UTF-8 without BOM */
#define ISO_ENC 2 /* Write as ISO Latin-1 (i.e., no conversion needed) */
#define MAX_FILENAME_LENGTH 1025
#define MEMORY_MANAGEMENT \
int allocation_id; /* Numbered from 0 upwards in creation order */\
void *next_structure; /* Next object in double-linked list */\
void *prev_structure; /* Previous object in double-linked list */
#define parse_node_MT 0
#define vocabulary_entry_array_MT 1
#define excerpt_meaning_MT 2
#define heading_MT 3
#define phrase_MT 4
#define action_name_MT 5
#define action_pattern_array_MT 6
#define named_action_pattern_MT 7
#define inference_MT 8
#define source_file_MT 9
#define grammar_verb_MT 10
#define grammar_line_MT 11
#define test_scenario_MT 12
#define property_MT 13
#define property_permission_MT 14
#define extension_file_MT 15
#define rulebook_MT 16
#define booking_MT 17
#define phrase_option_array_MT 18
#define instance_MT 19
#define table_MT 20
#define table_column_MT 21
#define literal_text_MT 24
#define text_substitution_MT 25
#define invocation_array_MT 26
#define action_name_list_array_MT 27
#define connected_submap_MT 28
#define implication_MT 29
#define activity_MT 30
#define activity_list_array_MT 31
#define use_option_MT 32
#define i6_memory_setting_MT 33
#define documentation_ref_MT 34
#define adjectival_phrase_MT 35
#define definition_MT 36
#define lexicon_entry_MT 37
#define plural_dictionary_entry_MT 38
#define verb_usage_MT 40
#define preposition_usage_MT 41
#define adjective_usage_array_MT 42
#define binary_predicate_MT 43
#define pcalc_prop_array_MT 44
#define pcalc_func_array_MT 45
#define pcalc_prop_deferral_MT 46
#define scene_MT 47
#define scene_connector_array_MT 48
#define literal_pattern_MT 49
#define generalisation_MT 50
#define command_index_entry_MT 51
#define kind_constructor_comparison_schema_array_MT 52
#define auxiliary_file_MT 53
#define extension_census_datum_MT 54
#define extension_dictionary_entry_MT 55
#define known_extension_clash_MT 56
#define i6_schema_array_MT 57
#define list_together_routine_MT 58
#define past_tense_condition_record_MT 60
#define past_tense_action_record_MT 61
#define blorb_figure_MT 62
#define named_rulebook_outcome_MT 63
#define loop_over_scope_MT 64
#define noun_filter_token_MT 65
#define label_namespace_MT 66
#define kind_constructor_MT 67
#define dimensional_rule_array_MT 68
#define determiner_MT 69
#define parse_node_annotation_array_MT 71
#define stacked_variable_array_MT 72
#define stacked_variable_list_array_MT 73
#define stacked_variable_owner_array_MT 74
#define stacked_variable_owner_list_array_MT 75
#define ap_optional_clause_array_MT 76
#define blorb_sound_MT 77
#define external_file_MT 78
#define pointer_allocation_MT 79
#define kind_constructor_casting_rule_array_MT 80
#define ph_stack_frame_box_MT 81
#define i6_inclusion_matter_MT 82
#define kind_array_MT 83
#define literal_list_MT 85
#define extension_identifier_database_entry_array_MT 86
#define I6T_intervention_MT 87
#define control_structure_phrase_MT 88
#define quantifier_MT 89
#define adjective_meaning_MT 90
#define measurement_definition_MT 91
#define reserved_command_verb_MT 92
#define internal_test_case_MT 93
#define kind_template_definition_MT 94
#define kind_macro_definition_MT 95
#define kind_template_obligation_MT 96
#define unit_sequence_array_MT 97
#define literal_pattern_name_MT 98
#define equation_MT 99
#define equation_symbol_MT 100
#define equation_node_MT 101
#define placement_affecting_array_MT 105
#define activity_crossref_array_MT 106
#define VM_usage_note_MT 107
#define time_period_array_MT 108
#define invocation_options_array_MT 110
#define simple_memory_claim_MT 111
#define inv_token_problem_token_MT 112
#define application_array_MT 114
#define spatial_data_MT 115
#define plugin_call_array_MT 116
#define plugin_MT 117
#define map_data_MT 118
#define regions_data_MT 119
#define text_stream_array_MT 120
#define counting_data_MT 121
#define parsing_data_MT 122
#define parsing_pp_data_MT 123
#define nonlocal_variable_MT 124
#define inference_subject_MT 125
#define property_of_value_storage_MT 126
#define kind_constructor_instance_array_MT 127
#define to_phrase_request_MT 128
#define constant_phrase_MT 129
#define kind_variable_declaration_MT 130
#define runtime_kind_structure_MT 131
#define match_trie_array_MT 132
#define use_as_event_MT 134
#define cached_understanding_MT 135
#define nametag_MT 136
#define instance_usage_array_MT 137
#define rubric_holder_MT 138
#define EPS_map_level_MT 139
#define rule_MT 140
#define rulebook_outcome_MT 141
#define applicability_condition_MT 142
#define natural_language_MT 143
#define nonterminal_MT 144
#define production_list_MT 145
#define production_MT 146
#define ptoken_MT 147
#define llist_entry_MT 148
#define understanding_item_array_MT 149
#define understanding_reference_array_MT 150
#define response_message_MT 151
#define verb_conjugation_MT 152
#define match_avinue_array_MT 153
#define individual_name_MT 154
#define cluster_MT 155
#define table_contribution_array_MT 156
#define index_page_MT 157
#define index_element_MT 158
#define contents_entry_MT 159
#define local_variable_array_MT 160
#define slash_gpr_MT 161
#define relation_guard_MT 162
#define filename_MT 163
#define pathname_MT 164
#define pcalc_term_array_MT 165
#define NO_MEMORY_TYPES 166 /* must be 1 more than the highest |_MT| constant above */
#define SAFETY_MARGIN 32
#define BLANK_END_SIZE 128
#define MAX_BLOCKS_ALLOWED 15000
#define MEMORY_GRANULARITY 300*1024*CPU_WORDSIZE_MULTIPLIER /* which must be divisible by 1024 */
#define INTEGRITY_NUMBER 0x12345678 /* a value unlikely to be in memory just by chance */
#define CREATE(type_name) (allocate_##type_name())
#define COPY(to, from, type_name) (copy_##type_name(to, from))
#define DESTROY(this, type_name) (deallocate_##type_name(this))
#define FIRST_OBJECT(type_name) ((type_name *) alloc_status[type_name##_MT].first_in_memory)
#define LAST_OBJECT(type_name) ((type_name *) alloc_status[type_name##_MT].last_in_memory)
#define NEXT_OBJECT(this, type_name) ((type_name *) (this->next_structure))
#define PREV_OBJECT(this, type_name) ((type_name *) (this->prev_structure))
#define NUMBER_CREATED(type_name) (alloc_status[type_name##_MT].objects_count)
#define LOOP_OVER(var, type_name)\
for (var=FIRST_OBJECT(type_name); var != NULL; var = NEXT_OBJECT(var, type_name))
#define LOOP_BACKWARDS_OVER(var, type_name)\
for (var=LAST_OBJECT(type_name); var != NULL; var = PREV_OBJECT(var, type_name))
#define NEW_OBJECT(type_name) ((type_name *) Memory__allocate(type_name##_MT, sizeof(type_name)))
#define ALLOCATE_INDIVIDUALLY(type_name) \
MAKE_REFERENCE_ROUTINES(type_name, type_name##_MT)\
type_name *allocate_##type_name(void) {\
alloc_status[type_name##_MT].name_of_type = #type_name;\
type_name *prev_obj = LAST_OBJECT(type_name);\
type_name *new_obj = NEW_OBJECT(type_name);\
new_obj->allocation_id = alloc_status[type_name##_MT].objects_allocated-1;\
new_obj->next_structure = NULL;\
if (prev_obj != NULL)\
prev_obj->next_structure = (void *) new_obj;\
new_obj->prev_structure = prev_obj;\
alloc_status[type_name##_MT].objects_count++;\
return new_obj;\
}\
void deallocate_##type_name(type_name *kill_me) {\
type_name *prev_obj = PREV_OBJECT(kill_me, type_name);\
type_name *next_obj = NEXT_OBJECT(kill_me, type_name);\
if (prev_obj == NULL) {\
alloc_status[type_name##_MT].first_in_memory = next_obj;\
} else {\
prev_obj->next_structure = next_obj;\
}\
if (next_obj == NULL) {\
alloc_status[type_name##_MT].last_in_memory = prev_obj;\
} else {\
next_obj->prev_structure = prev_obj;\
}\
alloc_status[type_name##_MT].objects_count--;\
}\
void copy_##type_name(type_name *to, type_name *from) {\
type_name *prev_obj = to->prev_structure;\
type_name *next_obj = to->next_structure;\
int aid = to->allocation_id;\
*to = *from;\
to->allocation_id = aid;\
to->next_structure = next_obj;\
to->prev_structure = prev_obj;\
}
#define ALLOCATE_IN_ARRAYS(type_name, NO_TO_ALLOCATE_TOGETHER)\
MAKE_REFERENCE_ROUTINES(type_name, type_name##_array_MT)\
typedef struct type_name##_array {\
int used;\
struct type_name array[NO_TO_ALLOCATE_TOGETHER];\
MEMORY_MANAGEMENT\
} type_name##_array;\
ALLOCATE_INDIVIDUALLY(type_name##_array)\
type_name##_array *next_##type_name##_array = NULL;\
struct type_name *allocate_##type_name(void) {\
if ((next_##type_name##_array == NULL) ||\
(next_##type_name##_array->used >= NO_TO_ALLOCATE_TOGETHER)) {\
alloc_status[type_name##_array_MT].no_allocated_together = NO_TO_ALLOCATE_TOGETHER;\
next_##type_name##_array = allocate_##type_name##_array();\
next_##type_name##_array->used = 0;\
}\
return &(next_##type_name##_array->array[\
next_##type_name##_array->used++]);\
}
#define EXTENSION_DICTIONARY_MREASON 0
#define INDEX_SORTING_MREASON 1
#define INSTANCE_COUNTING_MREASON 2
#define LEXER_TEXT_MREASON 3
#define LEXER_WORDS_MREASON 4
#define MAP_INDEX_MREASON 5
#define PARTITION_MREASON 6
#define STREAM_MREASON 7
#define TYPE_TABLES_MREASON 8
#define INV_LIST_MREASON 9
#define COMPILATION_SIZE_MREASON 10
#define OBJECT_COMPILATION_MREASON 11
#define DOC_FRAGMENT_MREASON 12
#define FILENAME_STORAGE_MREASON 13
#define RELATION_CONSTRUCTION_MREASON 14
#define NUMBER_OF_MREASONS 15
#define NULL_GENERAL_POINTER (Memory__store_gp_null())
#define GENERAL_POINTER_IS_NULL(gp) (Memory__test_gp_null(gp))
#define COMPARE_GENERAL_POINTERS(gp1, gp2)\
(gp1.pointer_to_data == gp2.pointer_to_data)
#define GENERAL_POINTER_AS_INT(gp) \
((pointer_sized_int) gp.pointer_to_data)
#define MAKE_REFERENCE_ROUTINES(type_name, id_code)\
general_pointer STORE_POINTER_##type_name(type_name *data) {\
general_pointer gp;\
gp.pointer_to_data = (void *) data;\
gp.run_time_type_code = id_code;\
return gp;\
}\
type_name *RETRIEVE_POINTER_##type_name(general_pointer gp) {\
if (gp.run_time_type_code != id_code) {\
LOG("Wanted ID code %d, found %d\n", id_code, gp.run_time_type_code);\
internal_error("attempt to retrieve wrong pointer type as " #type_name);\
}\
return (type_name *) gp.pointer_to_data;\
}\
general_pointer PASS_POINTER_##type_name(general_pointer gp) {\
if (gp.run_time_type_code != id_code) {\
LOG("Wanted ID code %d, found %d\n", id_code, gp.run_time_type_code);\
internal_error("attempt to pass wrong pointer type as " #type_name);\
}\
return gp;\
}\
int VALID_POINTER_##type_name(general_pointer gp) {\
if (gp.run_time_type_code == id_code) return TRUE;\
return FALSE;\
}
#define OUTPUT_STREAM text_stream *OUT /* used only as a function prototype argument */
#define PUT(c) Streams__putc(c, OUT)
#define PUT_TO(stream, c) Streams__putc(c, stream)
#define INDENT Streams__indent(OUT);
#define STREAM_INDENT(x) Streams__indent(x);
#define OUTDENT Streams__outdent(OUT);
#define STREAM_OUTDENT(x) Streams__outdent(x);
#define SET_INDENT(N) Streams__set_indentation(OUT, N);
#define STDOUT Streams__get_stdout()
#define STDERR Streams__get_stderr()
#define TEMPORARY_STREAM \
char dest[2048];\
text_stream TEMP_stream_structure = Streams__new_buffer(2048, dest);\
text_stream *TEMP = &TEMP_stream_structure;
#define CLOSE_TEMPORARY_STREAM \
STREAM_CLOSE(TEMP);
#define STREAM_OPEN_TO_FILE(new, fn, enc) Streams__open_to_file(new, fn, enc)
#define STREAM_OPEN_TO_FILE_APPEND(new, fn, enc) Streams__open_to_file_append(new, fn, enc)
#define STREAM_OPEN_IN_MEMORY(new) Streams__open_to_memory(new, 20480)
#define SMALL_STREAM_OPEN_IN_MEMORY(new) Streams__open_to_memory(new, 2048)
#define STREAM_CLOSE(stream) Streams__close(stream)
#define STREAM_NEW CREATE(text_stream)
#define STREAM_FLUSH(stream) Streams__flush(stream)
#define STREAM_EXTENT(x) Streams__get_position(x)
#define STREAM_USE_XML_ESCAPES(x, state) if (x) x->use_xml_escapes = state;
#define STREAM_ENCODING(x) ((x)?(x->encoding_to_write_to_file):ISO_ENC)
#define STREAM_MUST_BE_IN_MEMORY(x) \
if ((x != NULL) && (x->write_to_memory == NULL))\
internal_error("text_stream not in memory");
#define STREAM_BACKSPACE(x) Streams__set_position(x, Streams__get_position(x) - 1)
#define STREAM_ERASE_BACK_TO(start_position) Streams__set_position(OUT, start_position)
#define STREAM_MIN_ACCESSIBLE_LENGTH 255
#define STREAM_MOST_RECENT_CHAR(x) Streams__latest(x)
#define STREAM_COPY(to, from) Streams__copy(to, from)
#define STREAM_TEXT(x) Streams__get_text(x)
#define SPACE_AT_END_OF_STREAM 5
#define ACTION_CREATIONS_DA 0
#define ACTION_PATTERN_COMPILATION_DA 1
#define ACTION_PATTERN_PARSING_DA 2
#define ASSEMBLIES_DA 3
#define ASSERTIONS_DA 4
#define CASE_INSENSITIVE_FILEHANDLING_DA 5
#define CONDITIONS_DA 6
#define CONSTRUCTED_PAST_PARTICIPLES_DA 7
#define CONSTRUCTED_PLURALS_DA 8
#define DEBUGGING_LOG_CONTENTS_DA 9
#define DEBUGGING_LOG_INCLUSIONS_DA 10
#define DESCRIPTION_COMPILATION_DA 11
#define EXCERPT_MEANINGS_DA 12
#define EXCERPT_PARSING_DA 13
#define EXPRESSIONS_DA 14
#define EXTENSIONS_CENSUS_DA 15
#define FIGURE_CREATIONS_DA 16
#define GRAMMAR_DA 17
#define GRAMMAR_CONSTRUCTION_DA 18
#define HEADINGS_DA 19
#define IMPLICATIONS_DA 20
#define INFERENCES_DA 21
#define KIND_CHANGES_DA 22
#define KIND_CHECKING_DA 23
#define KIND_CREATIONS_DA 24
#define LEXICAL_OUTPUT_DA 25
#define LOCAL_VARIABLES_DA 26
#define MATCHING_DA 27
#define MEANING_LIST_ALLOCATION_DA 28
#define MEMORY_ALLOCATION_DA 29
#define NOUN_RESOLUTION_DA 30
#define OBJECT_COMPILATION_DA 31
#define OBJECT_CREATIONS_DA 32
#define OBJECT_TREE_DA 33
#define PHRASE_COMPARISONS_DA 34
#define PHRASE_COMPILATION_DA 35
#define PHRASE_CREATIONS_DA 36
#define PHRASE_REGISTRATION_DA 37
#define PHRASE_USAGE_DA 38
#define PREDICATE_CALCULUS_DA 39
#define PREDICATE_CALCULUS_WORKINGS_DA 40
#define PRONOUNS_DA 41
#define PROPERTY_CREATIONS_DA 42
#define PROPERTY_PROVISION_DA 43
#define PROPERTY_TRANSLATIONS_DA 44
#define RELATION_DEFINITIONS_DA 45
#define RULE_ATTACHMENTS_DA 46
#define RULEBOOK_COMPILATION_DA 47
#define SPATIAL_MAP_DA 48
#define SPATIAL_MAP_WORKINGS_DA 49
#define SPECIFICATION_PERMISSIONS_DA 50
#define SPECIFICATION_USAGE_DA 51
#define SPECIFICITIES_DA 52
#define TABLES_DA 53
#define TEMPLATE_READING_DA 54
#define TEXT_SUBSTITUTIONS_DA 55
#define TIME_PERIODS_DA 56
#define VARIABLE_CREATIONS_DA 57
#define VERIFICATIONS_DA 58
#define VOCABULARY_DA 59
#define ONLY_DLR 1
#define EVERYTHING_DLR 2
#define NOTHING_DLR 4
#define SOMETHING_DLR 8
#define PREFORM_DLR 16
#define SINGLE_ESCAPE(ch, tp, rt)\
case ch: {\
tp data1;\
data1 = va_arg(ap, tp); /* extract next argument as tp */\
rt(data1);\
break;\
}
#define DOUBLE_ESCAPE(ch, tp1, tp2, rt)\
case ch: {\
tp1 data1; tp2 data2;\
data1 = va_arg(ap, tp1); /* extract next argument as tp1 */\
data2 = va_arg(ap, tp2); /* extract next argument as tp2 */\
rt(data1, data2);\
break;\
}
#define NO_FS_AREAS 3
#define MATERIALS_FS_AREA 0 /* must match |ORIGIN_WAS_*| constants minus 1 */
#define EXTERNAL_FS_AREA 1
#define INTERNAL_FS_AREA 2
#define CENTRED_OUTCOME_IMAGE_STYLE 1
#define SIDE_OUTCOME_IMAGE_STYLE 2
#define SOURCE_REF_CHAR '\xf0'
#define FORCE_NEW_PARA_CHAR '\xd0'
#define MAX_SOURCE_REF_LENGTH (MAX_FILENAME_LENGTH + 20)
#define CORNER_SIZE 8 /* measured in pixels */
#define ROUND_BOX_TOP 1
#define ROUND_BOX_BOTTOM 2
#define EDOC_TOC_LINK_STYLE "STYLE=\"text-decoration: none\""
#define EDOC_TOC_LINK_FONT "<font color=\"#000000\">" /* this must open a |<font>| tag */
#define EDOC_ALL_EXAMPLES_CLOSED -1 /* do not change this without also changing Extensions */
#define EDOC_FRAGMENT_ONLY -2 /* must differ from this and from all example variant numbers */
#define EDOC_TOC_C_HEAD_FONT "<font color=\"#800000\">" /* this must open a |<font>| tag */
#define EDOC_TOC_S_HEAD_FONT "<font color=\"#000000\">" /* this must open a |<font>| tag */
#define MAX_EXTENT_OF_FRAGMENTS 256*1024
#define NOUN_LEXE 1 /* a kind */
#define PROPER_NOUN_LEXE 2 /* an instance of "object" */
#define ADJECTIVAL_PHRASE_LEXE 3 /* the subject of a "Definition:" */
#define ENUMERATED_CONSTANT_LEXE 4 /* e.g., "green" if colour is a kind of value and green a colour */
#define VERB_LEXE 5 /* an ordinary verb */
#define ABLE_VERB_LEXE 6 /* a "to be able to..." verb */
#define PREP_LEXE 7 /* a "to be upon..." sort of verb */
#define AVERB_LEXE 8 /* an auxiliary verb */
#define MVERB_LEXE 9 /* a meaningless verb */
#define MISCELLANEOUS_LEXE 10 /* a connective, article or determiner */
#define MAX_TEXT_FOR_LEXICON_ENTRY (MAX_WORDS_IN_ASSEMBLAGE*MAX_WORD_LENGTH + MAX_WORDS_IN_ASSEMBLAGE)
#define PROBLEM_BUFFER_LENGTH 10000
#define PBUFF problem_buffer+Platform__strlen(problem_buffer)
#define QUOTATION_TOLERANCE_LIMIT 100
#define PROBLEM_WORD_WRAP_WIDTH 80
#define PATIENCE_EXHAUSTION_POINT 100
#define internal_error(X) Problems__Issue__internal_error_fn(X, __FILE__, __LINE__)
#define internal_error_tree_unsafe(X) Problems__Issue__internal_error_tu_fn(X, __FILE__, __LINE__)
#define internal_error_if_node_type_wrong(X, Y) Problems__Issue__nodal_check(X, Y, __FILE__, __LINE__)
#define internal_error_on_node_type(X) Problems__Issue__internal_error_on_node_type_fn(X, __FILE__, __LINE__)
#define _p_(sigil) #sigil, __FILE__, __LINE__
#define SIGIL_ARGUMENTS char *sigil, char *file, int line
#define ACT_ON_SIGIL \
LOG("Problem %s issued from %s, line %d\n", sigil, file, line);\
if (telemetry_recording) {\
Log__ensure_telemetry_file();\
WRITE_TO(telmy, "Problem %s issued from %s, line %d\n", sigil, file, line);\
}\
sigil_of_latest_problem = sigil;\
sigil_of_latest_unlinked_problem = sigil;\
if (echo_problem_message_sigils) WRITE_TO(STDERR, "Problem__ %s\n", sigil);
#define PASS_SIGIL sigil, file, line
#define HASH_TAB_SIZE 1000 /* the possible hash codes are 0 up to this minus 1 */
#define NUMBER_HASH 0 /* literal decimal integers, and no other words, have this hash code */
#define TEXT_HASH 1 /* double quoted texts, and no other words, have this hash code */
#define I6_HASH 2 /* the |(-| word introducing an I6 inclusion uniquely has this hash code */
#define TRIE_START -1
#define TRIE_END -2
#define TRIE_ANYTHING 10003
#define TRIE_ANY_GROUP 10001
#define TRIE_NOT_GROUP 10002
#define TRIE_STOP -3
#define MAX_TRIE_GROUP_SIZE 26
#define MAX_TRIE_REWIND 10 /* that should be far, far more rewinding than necessary */
#define MAX_WORDS_IN_ASSEMBLAGE 32 /* do not reduce this below 5 */
#define NAME_IN_ENGLISH_LFIELD 1 /* e.g. "German" */
#define NAME_NATIVE_LFIELD 2 /* e.g. "Deutsch" */
#define CUE_NATIVE_LFIELD 3 /* e.g. "in deutscher Sprache" */
#define ISO_639_CODE_LFIELD 4 /* e.g. "de": an ISO 639-1 code */
#define TRANSLATOR_LFIELD 5 /* e.g. "Team GerX" */
#define MAX_LANGUAGE_FIELDS 6 /* one more than the highest number above */
#define NEUTER_GENDER 1 /* can be used as Scandinavian "common gender" */
#define MASCULINE_GENDER 2
#define FEMININE_GENDER 3
#define FIRST_PERSON_SINGULAR 0
#define SECOND_PERSON_SINGULAR 1
#define THIRD_PERSON_SINGULAR 2
#define FIRST_PERSON_PLURAL 3
#define SECOND_PERSON_PLURAL 4
#define THIRD_PERSON_PLURAL 5
#define NO_KNOWN_TENSES 7 /* allowing for two optional extras in non-English languages */
#define IS_TENSE 0 /* Present */
#define WAS_TENSE 1 /* Past */
#define HASBEEN_TENSE 2 /* Present perfect */
#define HADBEEN_TENSE 3 /* Past perfect */
#define WILLBE_TENSE 4 /* Future (not used in assertions or conditions) */
#define MAX_BUNDLE_ABOUT_LINE_LENGTH 256 /* which is far more than necessary, really */
#define MAX_PREFORM_LINE_LENGTH 256
#define MAX_RANGES_PER_PRODUCTION 5 /* in fact, one less than this, since range 0 is reserved */
#define GET_RW(nt, N) (nt->range_result[N])
#define PUT_RW(nt, N, W) { nt->range_result[N] = W; }
#define INHERIT_RANGES(from, to) {\
for (int i=1; i<MAX_RANGES_PER_PRODUCTION; i++) /* not copying range 0 */\
to->range_result[i] = from->range_result[i];\
}
#define CLEAR_RW(from) {\
for (int i=0; i<MAX_RANGES_PER_PRODUCTION; i++) /* including range 0 */\
from->range_result[i] = EMPTY_WORDING;\
}
#define MAX_RESULTS_PER_PRODUCTION 10
#define INFINITE_WORD_COUNT 1000000000
#define MAX_STRUTS_PER_PRODUCTION 10
#define MAX_PTOKENS_PER_PRODUCTION 16
#define SINGLE_WILDCARD_PTC 1
#define MULTIPLE_WILDCARD_PTC 2
#define POSSIBLY_EMPTY_WILDCARD_PTC 3
#define FIXED_WORD_PTC 4
#define NONTERMINAL_PTC 5
#define REGISTER_NONTERMINAL(quotedname, identifier)\
identifier = Preform__find_nonterminal(Vocabulary__entry_for_text(quotedname));\
identifier->result_compositor = identifier##C;
#define INTERNAL_NONTERMINAL(quotedname, identifier, min, max)\
identifier = Preform__find_nonterminal(Vocabulary__entry_for_text(quotedname));\
identifier->min_nt_words = min; identifier->max_nt_words = max;\
identifier->internal_definition = identifier##R;\
identifier->marked_internal = TRUE;
#define OUTSIDE_PTBRACE 0
#define ABOUT_TO_OPEN_PTBRACE 1
#define INSIDE_PTBRACE 2
#define RESERVED_NT_BITS 6
#define PTOKEN_ELASTIC -1
#define RANGE_OPTIMISATION_LENGTH 10
#define FAIL_NONTERMINAL -100000
#define FAIL_NONTERMINAL_TO FAIL_NONTERMINAL+1000
#define BASE_FORM_TYPE 0
#define INFINITIVE_FORM_TYPE 1
#define PRESENT_PARTICIPLE_FORM_TYPE 2
#define PAST_PARTICIPLE_FORM_TYPE 3
#define ADJOINT_INFINITIVE_FORM_TYPE 4
#define MAX_FORM_TYPES 123
#define ALL_DET_NAME 0
#define EACH_DET_NAME 1
#define EVERY_DET_NAME 2
#define NO_DET_NAME 3
#define NONE_DET_NAME 4
#define SOME_DET_NAME 5
#define ANY_DET_NAME 6
#define ALL_BUT_DET_NAME 7
#define ALL_EXCEPT_DET_NAME 8
#define ALMOST_ALL_DET_NAME 9
#define ALMOST_NO_DET_NAME 10
#define MOST_DET_NAME 11
#define UNDER_HALF_DET_NAME 12
#define AT_LEAST_DET_NAME 13
#define AT_MOST_DET_NAME 14
#define EXACTLY_DET_NAME 15
#define FEWER_THAN_DET_NAME 16
#define LESS_THAN_DET_NAME 17
#define MORE_THAN_DET_NAME 18
#define GREATER_THAN_DET_NAME 19
#define OTHER_THAN_DET_NAME 20
#define TIMES_UNIT 1 /* used for "for the third time" */
#define TURNS_UNIT 2 /* used for "for three turns" */
#define EQ_REPM 1
#define LT_REPM 2
#define LE_REPM 3
#define GT_REPM 4
#define GE_REPM 5
#define NO_REPM 6
#define CONDITION_KADJ 1 /* defined by a condition in I7 source text */
#define PHRASE_KADJ 2 /* defined by an explicit but nameless rule */
#define I6_ROUTINE_KADJ 3 /* defined by a named I6 routine */
#define I6_CONDITION_KADJ 4 /* defined by an explicit I6 schema */
#define MEASUREMENT_KADJ 5 /* defined by numerical comparison with a property value */
#define ENUMERATIVE_KADJ 6 /* defined by a property like "colour" with named values */
#define EORP_KADJ 7 /* defined by an either/or property like "closed" */
#define NO_ADJECTIVE_TASKS 3
#define TEST_ADJECTIVE_TASK 1 /* test if currently true */
#define NOW_ADJECTIVE_TRUE_TASK 2 /* assert now true */
#define NOW_ADJECTIVE_FALSE_TASK 3 /* assert now false */
#define LOOP_OVER_SORTED_MEANINGS(aph, am)\
for (am = Adjectives__Phrases__get_sorted_definition_list(aph); am; am=am->next_sorted)
#define LITERAL_FORMS_LOOP(lp, K)\
for (lp = Kinds__Behaviour__list_of_literal_forms(K); lp;\
lp=lp->next_for_this_kind)
#define MAX_ELEMENTS_PER_LITERAL 8
#define MAX_TOKENS_PER_LITERAL 100
#define WORD_LPT 1
#define CHARACTER_LPT 2
#define ELEMENT_LPT 3
#define MAX_REAL_LITERAL_LENGTH 120
#define ISSUING_LP_PROBLEM \
if (last_LP_problem_at == Wordings__first_wn(W)) return NULL;\
last_LP_problem_at = Wordings__first_wn(W);
#define LP_SCALED_UP 1 /* |LP_scaling| must be one of these three constants, if used */
#define LP_SCALED_DOWN -1
#define LP_SCALED_AT 2
#define PARTS_LPC 1
#define SCALING_LPC 2
#define OFFSET_LPC 3
#define EQUIVALENT_LPC 4
#define OPTIONAL_LSO 1
#define PREAMBLE_OPTIONAL_LSO 2
#define WITHOUT_LEADING_ZEROS_LSO 4
#define SINGULAR_LPN 1
#define PLURAL_LPN 2
#define IN_LPN 4
#define TIMES_LPN 8
#define ABANDON_LPN 16
#define MAX_TOKENS_PER_EXCERPT_MEANING 32
#define MISCELLANEOUS_MC 0x00000001 /* a grab-bag of other possible nouns */
#define VOID_PHRASE_MC 0x00000002 /* e.g., |award # points| */
#define VALUE_PHRASE_MC 0x00000004 /* e.g., |number of rows in #| */
#define COND_PHRASE_MC 0x00000008 /* e.g., |# has not ended| */
#define NAMETAG_MC 0x00000010 /* e.g., |upright chair| */
#define PROPERTY_MC 0x00000020 /* e.g., |carrying capacity| */
#define NAMED_CONSTANT_MC 0x00000040 /* e.g., |green| */
#define ADJECTIVE_MC 0x00000080 /* e.g., |invisible| */
#define TABLE_MC 0x00000100 /* e.g., |table of rankings| */
#define TABLE_COLUMN_MC 0x00000200 /* e.g., |rank| */
#define KIND_SLOW_MC 0x00000400 /* e.g., |weight| */
#define RULE_MC 0x00000800 /* e.g., |update chronological records rule| */
#define RULEBOOK_MC 0x00001000 /* e.g., |instead| */
#define ACTIVITY_MC 0x00002000 /* e.g., |reading a command| */
#define EQUATION_MC 0x00004000 /* e.g., |Newton's Second Law| */
#define VARIABLE_MC 0x00008000 /* e.g., |left hand status line| */
#define NAMED_AP_MC 0x00010000 /* e.g., |bad behaviour| */
#define SAY_PHRASE_MC 0x00020000 /* e.g., |say # in words| */
#define PHRASE_CONSTANT_MC 0x00040000 /* e.g., |doubling function| */
#define ING_MC 0x00800000 /* a word ending in -ing */
#define PREPOSITION_MC 0x01000000 /* a word which might introduce a relative clause */
#define ORDINAL_MC 0x02000000 /* first, second, third, ..., twelfth */
#define KIND_FAST_MC 0x04000000 /* number, text, relation, rule, ... */
#define I6_MC 0x08000000 /* piece of verbatim I6 code */
#define TEXTWITHSUBS_MC 0x10000000 /* double-quoted text literal with substitutions */
#define TEXT_MC 0x20000000 /* double-quoted text literal without substitutions */
#define NUMBER_MC 0x40000000 /* one, two, ..., twelve, 1, 2, ... */
#define ACTION_PARTICIPLE_MC 0x80000000 /* a word like "taking" */
#define CAPITALISED_VARIANT_FORM (1 << 30)
#define KIND_PRIORITY 1
#define INSTANCE_PRIORITY 2
#define MAX_NAMETAG_PRIORITY 2
#define NAMETAG_HAS_NO_MC 0xffffffff
#define PARSE_EXACTLY_NTOPT 1
#define REGISTER_SINGULAR_NTOPT 2
#define REGISTER_PLURAL_NTOPT 4
#define ATTACH_TO_SEARCH_LIST_NTOPT 8
#define TRANS_KIND 1
#define TRANS_INSTANCE 2
#define NO_GRAMMATICAL_GENDERS 3
#define LOOP_OVER_INSTANCES(I, K)\
LOOP_OVER(I, instance)\
if (Instances__of_kind(I, K))
#define LOOP_OVER_ENUMERATION_INSTANCES(I) \
LOOP_OVER(I, instance)\
if (Kinds__Behaviour__is_an_enumeration(Instances__to_kind(I)))
#define LOOP_OVER_OBJECT_INSTANCES(I) \
LOOP_OVER_INSTANCES(I, K_object)
#define MAX_OBJECT_INDEX_DEPTH 10000
#define EQUALITY_KBP 1 /* there is exactly one of these: the $x=y$ predicate */
#define QUASINUMERIC_KBP 2 /* the inequality comparison $\leq$, $<$ and so on */
#define SPATIAL_KBP 3 /* a relation associated with a map connection */
#define MAP_CONNECTING_KBP 4 /* a relation associated with a map connection */
#define PROPERTY_SETTING_KBP 5 /* a relation associated with a value property */
#define PROPERTY_SAME_KBP 6 /* another relation associated with a value property */
#define PROPERTY_COMPARISON_KBP 7 /* another relation associated with a value property */
#define LISTED_IN_KBP 8 /* a relation for indirect table lookups, one for each column name */
#define PROVISION_KBP 9 /* a relation for specifying which objects provide which properties */
#define UNIVERSAL_KBP 10 /* a relation for applying general other relations */
#define EXPLICIT_KBP 100 /* defined explicitly in the source text; the others are all implicit */
#define Relation_Implicit -1 /* all implicit BPs have this form, and all others are explicit */
#define Relation_OtoO 1 /* one to one: "R relates one K to one K" */
#define Relation_OtoV 2 /* one to various: "R relates one K to various K" */
#define Relation_VtoO 3 /* various to one: "R relates various K to one K" */
#define Relation_VtoV 4 /* various to various: "R relates various K to various K" */
#define Relation_Sym_OtoO 5 /* symmetric one to one: "R relates one K to another" */
#define Relation_Sym_VtoV 6 /* symmetric various to various: "R relates K to each other" */
#define Relation_Equiv 7 /* equivalence relation: "R relates K to each other in groups" */
#define Relation_ByRoutine 8 /* relation tested by a routine: "R relates K to L when (some condition)" */
#define DECLINE_TO_MATCH 1000 /* not one of the three legal |*_MATCH| values */
#define NEVER_MATCH_SAYING_WHY_NOT 1001 /* not one of the three legal |*_MATCH| values */
#define EQUALITY_RELATION_NAME 0
#define UNIVERSAL_RELATION_NAME 1
#define MEANING_RELATION_NAME 2
#define PROVISION_RELATION_NAME 3
#define GE_RELATION_NAME 4
#define GT_RELATION_NAME 5
#define LE_RELATION_NAME 6
#define LT_RELATION_NAME 7
#define ADJACENCY_RELATION_NAME 8
#define REGIONAL_CONTAINMENT_RELATION_NAME 9
#define CONTAINMENT_RELATION_NAME 10
#define SUPPORT_RELATION_NAME 11
#define INCORPORATION_RELATION_NAME 12
#define CARRYING_RELATION_NAME 13
#define HOLDING_RELATION_NAME 14
#define WEARING_RELATION_NAME 15
#define POSSESSION_RELATION_NAME 16
#define VISIBILITY_RELATION_NAME 17
#define TOUCHABILITY_RELATION_NAME 18
#define CONCEALMENT_RELATION_NAME 19
#define ENCLOSURE_RELATION_NAME 20
#define ROOM_CONTAINMENT_RELATION_NAME 21
#define FRF_RBIT 1
#define ONE_RBIT 2
#define VAR_RBIT 4
#define ANOTHER_RBIT 8
#define EACHOTHER_RBIT 16
#define GROUPS_RBIT 32
#define WHEN_RBIT 64
#define CALLED_RBIT 128
#define MAX_WORDS_IN_VERB (MAX_WORDS_IN_ASSEMBLAGE - 4)
#define LOOP_OVER_USAGES(vu) \
for (vu = vu_search_list; vu; vu = vu->next_in_search_list)
#define PREP_VERBU 2
#define REGULAR_VERBU 3
#define NONE_VERBU 4
#define DEFAULT_VERBU 5
#define PROP_VERBM 1
#define REL_VERBM 2
#define REV_REL_VERBM 3
#define NONE_VERBM 4
#define MAX_WORDS_IN_PREPOSITION (MAX_WORDS_IN_ASSEMBLAGE - 2)
#define STRING_BEGIN '"' /* Strings are always double-quoted */
#define STRING_END '"'
#define TEXT_SUBSTITUTION_BEGIN '[' /* Inside strings, this denotes a text substitution */
#define TEXT_SUBSTITUTION_END ']'
#define TEXT_SUBSTITUTION_SEPARATOR ','
#define COMMENT_BEGIN '[' /* Text between these, outside strings, is comment */
#define COMMENT_END ']'
#define INFORM6_ESCAPE_BEGIN_1 '(' /* Text beginning with this pair is literal I6 code */
#define INFORM6_ESCAPE_BEGIN_2 '-'
#define INFORM6_ESCAPE_END_1 '-'
#define INFORM6_ESCAPE_END_2 ')'
#define PARAGRAPH_BREAK "|__" /* Inserted as a special word to mark paragraph breaks */
#define NEWLINE_IN_STRING ((char) 0x7f) /* Within quoted text, all newlines are converted to this */
#define UNICODE_CHAR_IN_STRING ((char) 0x1b) /* To represent awkward characters in metadata only */
#define STANDARD_PUNCTUATION_MARKS ".,:;?!(){}[]" /* Do not add to this list lightly! */
#define TEXT_STORAGE_CHUNK_SIZE 600000 /* Must exceed |MAX_VERBATIM_LENGTH+MAX_WORD_LENGTH| */
#define MAX_STRING_LENGTH 3000 /* This is supposed to be {\it interactive} fiction... */
#define MAX_VERBATIM_LENGTH 200000 /* Largest quantity of Inform 6 which can be quoted verbatim. */
#define MAX_WORD_LENGTH 128 /* Maximum length of any unquoted word */
#define GROSS_AMOUNT_OF_INDENTATION 26
#define is_whitespace(c) ((c == ' ') || (c == '\n') || (c == '\t'))
#define ORDINARY_KW 0
#define COMMENT_KW 1
#define STRING_KW 2
#define I6_INCLUSION_KW 3
#define MANDATORY_INSERTED_TEXT "Include the Standard Rules by Graham Nelson.\n\n"
#define ORIGIN_WAS_PRIMARY_SOURCE 0
#define ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA 1 /* must match |*_FS_AREA| numbers plus 1 */
#define ORIGIN_WAS_USER_EXTENSIONS_AREA 2
#define ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA 3
#define compare_word(w, voc) (Lexer__word(w) == (voc))
#define compare_words(w1, w2) (Lexer__word(w1) == Lexer__word(w2))
#define compare_words_cs(w1, w2) (strcmp(Lexer__word_raw_text(w1), Lexer__word_raw_text(w2)) == 0)
#define EMPTY_WORDING ((wording) { -1, -1 })
#define EMPTY_WORDING_INIT { -1, -1 }
#define LOOP_THROUGH_WORDING(i, W)\
if (W.word_A >= 0)\
for (int i=W.word_A; i<=W.word_B; i++)
#define STRING_TOLERANCE_LIMIT 70
#define feed_t int /* (not a typedef only because it makes trouble for inweb) */
#define node_type_t unsigned int /* (not a typedef only because it makes trouble for inweb) */
#define BASE_OF_ENUMERATED_NTS 0x80000000
#define INVALID_NT 0x80000000 /* Should never exist in the tree */
#define ROOT_NT 0x80000001 /* Only one such node exists: the tree root */
#define INCLUSION_NT 0x80000002 /* Holds a block of source material */
#define HEADING_NT 0x80000003 /* "Chapter VIII: Never Turn Your Back On A Shreve" */
#define BIBLIOGRAPHIC_NT 0x80000004 /* For the initial title sentence */
#define INCLUDE_NT 0x80000005 /* "Include School Rules by Argus Filch" */
#define BEGINHERE_NT 0x80000006 /* "The Standard Rules begin here" */
#define ENDHERE_NT 0x80000007 /* "The Standard Rules end here" */
#define SENTENCE_NT 0x80000008 /* "The Garden is a room" */
#define ROUTINE_NT 0x80000009 /* "Instead of taking something, ..." */
#define INFORM6CODE_NT 0x8000000A /* "Include (- ... -) */
#define TABLE_NT 0x8000000B /* "Table 1 - Counties of England" */
#define EQUATION_NT 0x8000000C /* "Equation 2 - Newton's Second Law" */
#define TRACE_NT 0x8000000D /* A sentence consisting of an asterisk and optional quoted text */
#define RELATIONSHIP_NT 0x8000000E /* "on" */
#define CALLED_NT 0x8000000F /* "On the table is a container called the box" */
#define WITH_NT 0x80000010 /* "The footstool is a supporter with capacity 2" */
#define AND_NT 0x80000011 /* "whisky and soda" */
#define KIND_NT 0x80000012 /* "A woman is a kind of person" */
#define X_OF_Y_NT 0x80000013 /* "description of the painting" */
#define AVERB_NT 0x80000014 /* "is" */
#define CREATED_NT 0x80000015 /* "a vehicle called Sarah Jane's car" */
#define PROPER_NOUN_NT 0x80000016 /* "the red handkerchief" */
#define PROPERTY_LIST_NT 0x80000017 /* "capacity 2" */
#define FROM_NT 0x80000018 /* "East from the Garden is the Grove" */
#define ALLOWED_NT 0x80000019 /* "An animal is allowed to have a description" */
#define EVERY_NT 0x8000001A /* "every container" */
#define COMMON_NOUN_NT 0x8000001B /* "a container" */
#define ACTION_NT 0x8000001C /* "taking something closed" */
#define ADJECTIVE_NT 0x8000001D /* "open" */
#define PROPERTYCALLED_NT 0x8000001E /* "A man has a number called age" */
#define TOKEN_NT 0x8000001F /* Used for tokens in grammar */
#define CODE_BLOCK_NT 0x80000020 /* Holds a block of source material */
#define INVOCATION_LIST_NT 0x80000021 /* Single invocation of a (possibly compound) phrase */
#define INVOCATION_LIST_SAY_NT 0x80000022 /* Single thing to be said */
#define AMBIGUITY_NT 0x80000023 /* Single invocation of a (possibly compound) phrase */
#define INVOCATION_NT 0x80000024 /* Usage of a phrase */
#define VOID_CONTEXT_NT 0x80000025 /* When a void phrase is required */
#define RVALUE_CONTEXT_NT 0x80000026 /* Arguments, in effect */
#define LVALUE_CONTEXT_NT 0x80000027 /* Named storage location */
#define LVALUE_TR_CONTEXT_NT 0x80000028 /* Table reference */
#define SPECIFIC_RVALUE_CONTEXT_NT 0x80000029 /* Argument must be an exact value */
#define MATCHING_RVALUE_CONTEXT_NT 0x8000002A /* Argument must match a description */
#define NEW_LOCAL_CONTEXT_NT 0x8000002B /* Argument which creates a local */
#define LVALUE_LOCAL_CONTEXT_NT 0x8000002C /* Argument which names a local */
#define CONDITION_CONTEXT_NT 0x8000002D /* Used for "now" conditions */
#define UNKNOWN_VNT 0x8000002E /* "arfle barfle gloop" */
#define CONSTANT_VNT 0x8000002F /* "7", "the can't lock a locked door rule", etc. */
#define PHRASE_TO_DECIDE_VALUE_VNT 0x80000030 /* "holder of the black box" */
#define LOCAL_VARIABLE_VNT 0x80000031 /* "the running total", say */
#define NONLOCAL_VARIABLE_VNT 0x80000032 /* "the location" */
#define PROPERTY_VALUE_VNT 0x80000033 /* "the carrying capacity of the cedarwood box" */
#define TABLE_ENTRY_VNT 0x80000034 /* "tonnage in row X of the Table of Corvettes" */
#define LIST_ENTRY_VNT 0x80000035 /* "item 4 in L" */
#define LOGICAL_NOT_VNT 0x80000036 /* "not A" */
#define LOGICAL_TENSE_VNT 0x80000037 /* in the past, A */
#define LOGICAL_AND_VNT 0x80000038 /* "A and B" */
#define LOGICAL_OR_VNT 0x80000039 /* "A or B" */
#define TEST_PROPOSITION_VNT 0x8000003A /* if "the cat is on the mat" */
#define TEST_PHRASE_OPTION_VNT 0x8000003B /* "giving full details", say */
#define TEST_VALUE_VNT 0x8000003C /* when a value is used as a condition */
#define NO_ENUMERATED_NTS TEST_VALUE_VNT - BASE_OF_ENUMERATED_NTS + 1
#define action_meaning_ANNOT 1 /* |action_pattern|: meaning in parse tree when used as noun */
#define aph_ANNOT 2 /* |adjectival_phrase|: which adjective is asserted */
#define category_of_I6_translation_ANNOT 3 /* int: what sort of "translates into I6" sentence this is */
#define clears_pronouns_ANNOT 4 /* |int|: this sentence erases the current value of "it" */
#define colon_block_command_ANNOT 5 /* int: this COMMAND uses the ":" not begin/end syntax */
#define condition_tense_ANNOT 7 /* |time_period|: for specification nodes */
#define constant_action_name_ANNOT 8 /* |action_name|: for constant values */
#define constant_action_pattern_ANNOT 9 /* |action_pattern|: for constant values */
#define constant_activity_ANNOT 10 /* |activity|: for constant values */
#define constant_binary_predicate_ANNOT 11 /* |binary_predicate|: for constant values */
#define constant_constant_phrase_ANNOT 13 /* |constant_phrase|: for constant values */
#define constant_enumeration_ANNOT 14 /* |int|: which one from an enumerated kind */
#define constant_equation_ANNOT 15 /* |equation|: for constant values */
#define constant_grammar_verb_ANNOT 16 /* |grammar_verb|: for constant values */
#define constant_instance_ANNOT 17 /* |instance|: for constant values */
#define constant_local_variable_ANNOT 18 /* |local_variable|: for constant values */
#define constant_named_rulebook_outcome_ANNOT 19 /* |named_rulebook_outcome|: for constant values */
#define constant_nonlocal_variable_ANNOT 20 /* |nonlocal_variable|: for constant values */
#define constant_number_ANNOT 21 /* |int|: which integer this is */
#define constant_property_ANNOT 22 /* |property|: for constant values */
#define constant_rule_ANNOT 23 /* |rule|: for constant values */
#define constant_rulebook_ANNOT 24 /* |rulebook|: for constant values */
#define constant_scene_ANNOT 25 /* |scene|: for constant values */
#define constant_table_ANNOT 26 /* |table|: for constant values */
#define constant_table_column_ANNOT 27 /* |table_column|: for constant values */
#define constant_text_ANNOT 28 /* |text_stream|: for constant values */
#define constant_use_option_ANNOT 29 /* |use_option|: for constant values */
#define constant_verb_conjugation_ANNOT 30 /* |verb_conjugation|: for constant values */
#define control_structure_used_ANNOT 31 /* |control_structure_phrase|: for CODE BLOCK nodes only */
#define converted_SN_ANNOT 32 /* |int|: marking descriptions */
#define creation_proposition_ANNOT 33 /* |pcalc_prop|: proposition which newly created value satisfies */
#define creation_site_ANNOT 34 /* |int|: whether an instance was created from this node */
#define defn_language_ANNOT 35 /* |natural_language|: what language this definition is in */
#define embodying_heading_ANNOT 36 /* |heading|: for parse nodes of headings */
#define end_control_structure_used_ANNOT 37 /* |control_structure_phrase|: for CODE BLOCK nodes only */
#define epistemological_status_ANNOT 38 /* |int|: a bitmap of results from checking an ambiguous reading */
#define evaluation_ANNOT 39 /* |parse_node|: result of evaluating the text */
#define explicit_literal_ANNOT 40 /* |int|: my value is an explicit integer or text */
#define from_text_substitution_ANNOT 41 /* |int|: whether this is an implicit say invocation */
#define gender_reference_ANNOT 42 /* |int|: used by PROPER NOUN nodes for evident genders */
#define grammar_token_code_ANNOT 43 /* int: used to identify grammar tokens */
#define grammar_token_literal_ANNOT 44 /* int: for grammar tokens which are literal words */
#define grammar_token_relation_ANNOT 45 /* |binary_predicate|: for relation tokens */
#define grammar_value_ANNOT 46 /* |parse_node|: used as a marker when evaluating Understand grammar */
#define heading_level_ANNOT 47 /* int: for HEADING nodes, a hierarchical level, 0 (highest) to 9 (lowest) */
#define implicit_in_creation_of_ANNOT 48 /* |inference_subject|: for assemblies */
#define implicitly_refers_to_ANNOT 49 /* int: this will implicitly refer to something */
#define implicitness_count_ANNOT 50 /* int: keeping track of recursive assemblies */
#define indentation_level_ANNOT 51 /* |int|: for routines written with Pythonesque indentation */
#define interpretation_of_subject_ANNOT 52 /* |inference_subject|: subject, during passes */
#define is_phrase_option_ANNOT 53 /* |int|: this unparsed text is a phrase option */
#define kind_of_new_variable_ANNOT 55 /* |kind|: what if anything is returned */
#define kind_of_value_ANNOT 56 /* |kind|: for specification nodes */
#define kind_required_by_context_ANNOT 57 /* |kind|: what if anything is expected here */
#define kind_resulting_ANNOT 58 /* |kind|: what if anything is returned */
#define kind_variable_declarations_ANNOT 59 /* |kind_variable_declaration|: and of these */
#define language_element_ANNOT 60 /* |int|: this node is not really a sentence, but a language definition Use */
#define log_inclusion_sense_ANNOT 61 /* |int|: should we include or exclude this from the debugging log? */
#define lpe_options_ANNOT 62 /* |int|: options set for a literal pattern part */
#define meaning_ANNOT 63 /* |excerpt_meaning|: for leaves */
#define modal_verb_ANNOT 64 /* |verb_conjugation|: relevant only for that: e.g., "might" */
#define multiplicity_ANNOT 65 /* |int|: e.g., 5 for "five gold rings" */
#define negated_boolean_ANNOT 66 /* int: set if adjective/verb meant negatively */
#define new_relation_here_ANNOT 67 /* |binary_predicate|: new relation as subject of "relates" sentence */
#define nothing_object_ANNOT 68 /* |int|: this represents |nothing| at run-time */
#define nounphrase_article_ANNOT 69 /* int: definite or indefinite article: see below */
#define nowhere_ANNOT 70 /* |int|: used by the spatial plugin to show this represents "nowhere" */
#define phrase_invoked_ANNOT 71 /* |phrase|: the phrase believed to be invoked... */
#define phrase_option_ANNOT 72 /* |int|: $2^i$ where $i$ is the option number, $0\leq i<16$ */
#define phrase_options_invoked_ANNOT 73 /* |invocation_options|: details of any options used */
#define plural_reference_ANNOT 74 /* int: used by PROPER NOUN nodes for evident plurals */
#define problem_falls_under_ANNOT 75 /* |parse_node|: what heading the sentence falls under */
#define property_name_used_as_noun_ANNOT 76 /* |int|: in ambiguous cases such as "open" */
#define proposition_ANNOT 77 /* |pcalc_prop|: for specification nodes */
#define pu_ANNOT 78 /* |preposition_usage|: for e.g. "is on" */
#define quant_ANNOT 79 /* |quantifier|: for quantified excerpts like "three baskets" */
#define quantification_parameter_ANNOT 80 /* |int|: e.g., 3 for "three baskets" */
#define record_as_self_ANNOT 81 /* |int|: record recipient as |self| when writing this */
#define relationship_ANNOT 82 /* |binary_predicate|: for RELATIONSHIP nodes */
#define relationship_node_type_ANNOT 83 /* int: what kind of inference this assertion makes */
#define resolved_ANNOT 84 /* int: temp storage when resolving NPs */
#define response_code_ANNOT 85 /* |int|: for responses only */
#define results_from_splitting_ANNOT 86 /* |int|: node in a routine's parse tree from comma block notation */
#define row_amendable_ANNOT 87 /* int: a candidate row for a table amendment */
#define save_self_ANNOT 88 /* |int|: this invocation must save and preserve |self| at run-time */
#define say_adjective_ANNOT 89 /* |adjectival_phrase|: ...or the adjective to be agreed with by "say" */
#define say_verb_ANNOT 90 /* |verb_conjugation|: ...or the verb to be conjugated by "say" */
#define say_verb_negated_ANNOT 91 /* relevant only for that */
#define self_object_ANNOT 92 /* |int|: this represents |self| at run-time */
#define sentence_is_existential_ANNOT 93 /* |int|: such as "there is a man" */
#define sentence_unparsed_ANNOT 94 /* int: set if verbs haven't been sought yet here */
#define slash_class_ANNOT 95 /* int: used when partitioning grammar tokens */
#define slash_dash_dash_ANNOT 96 /* |int|: used when partitioning grammar tokens */
#define ssp_closing_segment_wn_ANNOT 97 /* |int|: identifier for the last of these, or |-1| */
#define ssp_segment_count_ANNOT 98 /* |int|: number of subsequent complex-say phrases in stream */
#define subject_ANNOT 99 /* |inference_subject|: what this node describes */
#define subject_term_ANNOT 100 /* |pcalc_term|: what the subject of the subtree was */
#define suppress_heading_dependencies_ANNOT 101 /* int: ignore extension dependencies on this heading node */
#define suppress_newlines_ANNOT 102 /* |int|: whether the next say term runs on */
#define table_cell_unspecified_ANNOT 103 /* int: used to mark table entries as unset */
#define text_unescaped_ANNOT 104 /* |int|: flag used only for literal texts */
#define token_as_parsed_ANNOT 105 /* |parse_node|: what if anything is returned */
#define token_check_to_do_ANNOT 106 /* |parse_node|: what if anything is returned */
#define token_to_be_parsed_against_ANNOT 107 /* |parse_node|: what if anything is returned */
#define turned_already_ANNOT 108 /* |int|: aliasing like "player" to "yourself" performed already */
#define unproven_ANNOT 109 /* |int|: this invocation needs run-time typechecking */
#define verb_id_ANNOT 110 /* int: identifying what kind of VERB node */
#define verb_problem_issued_ANNOT 111 /* |int|: has a problem message about the primary verb been issued already? */
#define verbal_certainty_ANNOT 112 /* int: a certainty level attached to a sentence */
#define vu_ANNOT 113 /* |verb_usage|: for e.g. "does not carry" */
#define you_can_ignore_ANNOT 114 /* |int|: for assertions now drained of meaning */
#define MAX_ANNOT_NUMBER 114
#define DECLARE_ANNOTATION_FUNCTIONS(annotation_name, pointer_type)\
void ParseTree__set_##annotation_name(parse_node *pn, pointer_type *bp);\
pointer_type *ParseTree__get_##annotation_name(parse_node *pn);
#define DEF_ART 1 /* the definite article */
#define INDEF_ART 2 /* the indefinite article */
#define NO_ART 3 /* no article supplied */
#define IT_ART 4 /* a special case to handle "it" */
#define INVALID_NCAT 0
#define L1_NCAT 1
#define L2_NCAT 2
#define L3_NCAT 3
#define L4_NCAT 4
#define UNKNOWN_NCAT 5
#define LVALUE_NCAT 6
#define RVALUE_NCAT 7
#define COND_NCAT 8
#define NO_NODE_CATEGORIES 9
#define PHRASAL_NFLAG 0x00000001 /* compiles to a function call */
#define DONT_VISIT_NFLAG 0x00000002 /* not visited in traverses */
#define ASSERT_NFLAG 0x00000004 /* allow this on either side of an assertion? */
#define INFTY 1000000000 /* if ever a node has more than a billion children, we are in trouble anyway */
#define MAKE_ANNOTATION_FUNCTIONS(annotation_name, pointer_type)\
void ParseTree__set_##annotation_name(parse_node *pn, pointer_type *bp) {\
ParseTree__pn_annotate_pointer(pn, annotation_name##_ANNOT,\
STORE_POINTER_##pointer_type(bp));\
}\
pointer_type *ParseTree__get_##annotation_name(parse_node *pn) {\
pointer_type *pt = NULL;\
if (ParseTree__has_annotation(pn, annotation_name##_ANNOT))\
pt = RETRIEVE_POINTER_##pointer_type(\
ParseTree__pn_pointer_annotation(pn, annotation_name##_ANNOT));\
return pt;\
}
#define LOOP_THROUGH_ALTERNATIVES(p, from)\
for (p = from; p; p = p->next_alternative)
#define MAX_ATTACHMENT_STACK_SIZE 100 /* must be at least the number of heading levels plus 3 */
#define LOOP_OVER_NODE_TYPES(t) \
for (node_type_t t=BASE_OF_ENUMERATED_NTS; t<BASE_OF_ENUMERATED_NTS+NO_ENUMERATED_NTS; t++)
#define NO_HEADING_LEVELS 10
#define PLATFORM_UNMET_HQ 0
#define PLATFORM_MET_HQ 1
#define NOT_FOR_RELEASE_HQ 2
#define FOR_RELEASE_ONLY_HQ 3
#define UNINDEXED_HQ 4
#define USE_WITH_HQ 5
#define USE_WITHOUT_HQ 6
#define IN_PLACE_OF_HQ 7
#define LOOP_OVER_NAMETAGS_UNDER(nt, h)\
for (nt=h->list_of_contents; nt; nt=Nametags__name_resolution_data(nt)->next_under_heading)
#define LOOP_OVER_NT_SEARCH_LIST(nt) \
for (nt = nt_search_start; nt; nt = Nametags__name_resolution_data(nt)->next_to_search)
#define ASSERT_VB 10 /* "The bat and ball are on the table." */
#define HAS_VB 11 /* "The silver bars have score 10." */
#define USEMEANS_VB 20 /* "Use American dialect means ..." */
#define TRANSLATES_VB 21 /* "Lighted translates into I6 as |"light"|" */
#define TRANSLATESU_VB 22 /* "Black king chess piece translates into Unicode as 9818" */
#define TRANSLATESL_VB 23 /* "Man translates into French as un homme" */
#define PLURAL_VB 24 /* "The plural of woman is women." */
#define SPECIFIES_VB 25 /* "10'23 specifies a running time." */
#define DEFINED_BY_VB 30 /* "The colours are defined by Table 1." */
#define EPISODE_VB 31 /* "The story is episode..." */
#define FIGURE_VB 32 /* "Figure... is the file..." */
#define SOUND_VB 33 /* "Sound... is the file..." */
#define FILE_VB 34 /* "File... is the file..." */
#define CANBE_VB 35 /* "A door can be open or closed." */
#define NEW_ACTION_VB 36 /* "Taking something is an action." */
#define NEW_ACTIVITY_VB 37 /* "Description is an activity." */
#define NEW_MEANINGLESS_VERB_VB 38 /* "The verb to eat..." */
#define NEW_VERB_VB 39 /* "The verb to eat..." */
#define NEW_ADJ_VB 40 /* "In French petit is an adjective meaning..." */
#define NEW_RELATION_VB 41 /* "Knowledge relates..." */
#define IN_RULEBOOK_VB 50 /* "The time passes rule is listed in the turn sequence rulebook." */
#define NOT_IN_RULEBOOK_VB 51 /* "The blossom rule is not listed in..." */
#define BEGINS_WHEN_VB 52 /* "Scene begins when ..." */
#define ENDS_WHEN_VB 53 /* "Scene ends when ..." */
#define NO_EFFECT_IF_VB 54 /* "The time passes rule does nothing if ..." */
#define NO_EFFECT_UNLESS_VB 55 /* "The time passes rule does nothing unless ..." */
#define NO_EFFECT_AT_ALL_VB 56 /* "The time passes rule does nothing." */
#define SUBSTITUTES_VB 57 /* "The time passes slowly rule substitutes for the time passes rule." */
#define SUBSTITUTES_IF_VB 58 /* "The time passes slowly rule substitutes for the time passes rule if ..." */
#define SUBSTITUTES_UNLESS_VB 59 /* "The time passes slowly rule substitutes for the time passes rule unless ..." */
#define USE_VB 60 /* "Use American dialect." */
#define UNDERSTAND_VB 61 /* "Understand "take [noun]" as taking the noun." */
#define TEST_VB 62 /* "Test ... with "..."." */
#define DEBUG_VB 63 /* "Include ... in the debugging log." */
#define DOC_VB 64 /* "Document ... at ..." */
#define RELEASE_VB 65 /* "Release along with..." */
#define MAP_PARAMETER_VB 66 /* "Index map with ..." */
#define BAD_NONVERB 1000
#define GENERATE_RAW_NP \
0; *XP = (preform_lookahead_mode == FALSE)?(Sentences__NPs__new_raw(W)):NULL
#define STANDARD_RELN 0 /* the default annotation value: never explicitly set */
#define PARENTAGE_HERE_RELN 1 /* only ever set by the Spatial plugin */
#define DIRECTION_RELN 2
#define MAX_DIRECTIONS 100 /* the Standard Rules define only 12, so this is plenty */
#define NO_SIGF 0
#define SAY_SIGF 1
#define NOW_SIGF 2
#define MAX_EXTENSION_TITLE_LENGTH 51
#define MAX_EXTENSION_AUTHOR_LENGTH 51
#define MAX_RUBRIC_LENGTH 500
#define LONGEST_LINE_IN_EX_TEMPLATE 1024
#define LINE_MARKING_START_OF_CENSUS "<a name=on>"
#define LINE_MARKING_END_OF_CENSUS "<a name=off>"
#define MAX_VERSION_NUMBER_LENGTH 10 /* for |999/991231| */
#define EI_HASH_CODING_BASE 499
#define NO_EIDB_CONTEXTS 5
#define LOADED_EIDBC 0
#define INSTALLED_EIDBC 1
#define DICTIONARY_REFERRED_EIDBC 2
#define HYPOTHETICAL_EIDBC 3
#define USEWITH_EIDBC 4
#define RESERVED_AUTHOR_NAME "Reserved"
#define MAX_TITLING_LINE_LENGTH 501 /* lots, allowing for an improbably large number of virtual machine restrictions */
#define LONGEST_POSSIBLE_CENSUS_ERROR MAX_TITLING_LINE_LENGTH*2
#define CE_BY_TITLE 1
#define CE_BY_AUTHOR 2
#define CE_BY_INSTALL 3
#define CE_BY_DATE 4
#define CE_BY_LENGTH 5
#define FIRST_STRIPE_COLOUR "#ffffff"
#define SECOND_STRIPE_COLOUR "#f3f6fa"
#define CENSUS_TITLING_FG "#ffffff"
#define CENSUS_TITLING_BG "#808080"
#define UNINDEXED_SYMBOL "<img border=\"0\" src=\"inform:/doc_images/unindexed_bullet.png\">"
#define INDEXED_SYMBOL "<img border=\"0\" src=\"inform:/doc_images/indexed_bullet.png\">"
#define BUILT_IN_SYMBOL "<img border=\"0\" src=\"inform:/doc_images/builtin_ext.png\">"
#define OVERRIDING_SYMBOL "<img border=\"0\" src=\"inform:/doc_images/override_ext.png\">"
#define PROJECT_SPECIFIC_SYMBOL "<img border=\"0\" src=\"inform:/doc_images/pspec_ext.png\">"
#define MAX_ED_CATEGORY_LENGTH 32
#define MAX_ED_HEADWORD_LENGTH 128
#define MAX_ED_LINE_LENGTH 512
#define TINT_FOR_SAME_WORD "#FF8080"
#define EDES_DEFINE_SAME_WORD(X, Y) ((X) && (Y) && (strcmp(X->sorting, Y->sorting) == 0))
#define MAX_OF_NTS_AND_VBS 75
#define REGISTER_SENTENCE_HANDLER(sh_name) {\
sentence_handler *the_sh = &sh_name##_handler;\
if ((the_sh->sentence_node_type == SENTENCE_NT) && (the_sh->verb_type != -1))\
how_to_handle_sentences[the_sh->verb_type] = the_sh;\
else\
how_to_handle_nodes[the_sh->sentence_node_type - BASE_OF_ENUMERATED_NTS] = the_sh;\
}
#define FORBID_CREATION 0 /* never create an object with this name */
#define ALLOW_CREATION 1 /* create an object with this name if that looks sensible */
#define MANDATE_CREATION 2 /* always create an object with this name, except for "it" */
#define MAX_DUPLICATES_AT_ONCE 100 /* change the problem message below if this is changed */
#define ASSERTION_MATRIX_DIM 12
#define NAME_DESCRIPTION_CLASH_NOTE \
"Sometimes this happens because I've read too much into a name - for instance, "\
"'A dark room is a room' makes me read 'dark room' as 'dark' (an adjective I know) "\
"plus 'room', but maybe the writer actually meant a photographer's workshop. "\
"If you need to call something by a name which confuses me, one way is to use "\
"'called': for instance, 'West is a room called the dark room.' Another way is "\
"to call it something else here, and set the 'printed name' property to what you "\
"want the player to see - for instance, 'The photo lab is a room. The printed name "\
"of the photo lab is \"dark room\".'"
#define MAX_ASSEMBLY_SIZE 500
#define MAXIMUM_CACHE_SIZE 20 /* a Goldilocks value: too high slows us down, too low doesn't cache enough */
#define NUMBER_OF_CACHED_NONTERMINALS 5
#define EXACT_PM 1
#define SUBSET_PM 2
#define PARAMETRISED_PM 4
#define MAXIMAL_PM 8
#define EXACT_PARSING_BITMAP \
(MISCELLANEOUS_MC + PROPERTY_MC + ADJECTIVE_MC +\
NAMED_CONSTANT_MC + VARIABLE_MC + KIND_SLOW_MC + RULE_MC + RULEBOOK_MC +\
TABLE_MC + TABLE_COLUMN_MC + NAMED_AP_MC + ACTIVITY_MC + EQUATION_MC +\
PHRASE_CONSTANT_MC)
#define SUBSET_PARSING_BITMAP \
(NAMETAG_MC)
#define PARAMETRISED_PARSING_BITMAP \
(VOID_PHRASE_MC + VALUE_PHRASE_MC + COND_PHRASE_MC + SAY_PHRASE_MC)
#define EXCERPT_MEANING_RELEVANT(p) \
(no_meanings_tried++, ((mc_bitmap & (ParseTree__get_meaning(p)->meaning_code))!=0))
#define EXAMINE_EXCERPT_MEANING_IN_DETAIL \
LOGIF(EXCERPT_PARSING,\
"Trying $M (parsing mode %d)\n", ParseTree__get_meaning(p), parsing_mode);\
no_meanings_tried_in_detail++;
#define POW10_RANGE 8
#define CONSTANT_VAL_BITMAP (RULE_MC + RULEBOOK_MC + NAMED_CONSTANT_MC + ACTIVITY_MC +\
TABLE_MC + EQUATION_MC + PHRASE_CONSTANT_MC)
#define MAX_ATOM_ARITY 2 /* for the moment, at any rate */
#define QUANTIFIER_ATOM 1 /* any generalised quantifier */
#define PREDICATE_ATOM 10 /* a property-based unary predicate, or any predicate of higher arity */
#define KIND_ATOM 11 /* a unary predicate $K(x)$ associated with a kind $K$ */
#define ISAKIND_ATOM 12 /* a unary predicate asserting that $x$ is the world-object for a kind */
#define ISAVAR_ATOM 13 /* a unary predicate asserting that $x$ is the SP for a global variable */
#define ISACONST_ATOM 14 /* a unary predicate asserting that $x$ is the SP for a named constant */
#define EVERYWHERE_ATOM 15 /* a unary predicate asserting omnipresence */
#define NOWHERE_ATOM 16 /* a unary predicate asserting nonpresence */
#define HERE_ATOM 17 /* a unary predicate asserting presence "here" */
#define CALLED_ATOM 18 /* to keep track of "(called the intruder)"-style names */
#define NEGATION_OPEN_ATOM 20 /* logical negation $\lnot$ applied to contents of group */
#define NEGATION_CLOSE_ATOM 30 /* end of logical negation $\lnot$ */
#define DOMAIN_OPEN_ATOM 21 /* logical negation $\lnot$ applied to contents of group */
#define DOMAIN_CLOSE_ATOM 31 /* end of logical negation $\lnot$ */
#define STRUCTURAL_GROUP 10
#define PREDICATES_GROUP 20
#define OPEN_OPERATORS_GROUP 30
#define CLOSE_OPERATORS_GROUP 40
#define TRAVERSE_VARIABLE(p) \
pcalc_prop *p = NULL, *p##_prev = NULL;\
int p##_repeat = FALSE;
#define TRAVERSE_PROPOSITION(p, start)\
for (p=start, p##_prev=NULL, p##_repeat = FALSE;\
p;\
(p##_repeat == FALSE)?(p##_prev=p, p=(p)?(p->next):NULL):0, p##_repeat = FALSE)
#define PROPOSITION_EDITED(p, prop)\
if (p##_prev == NULL) p = prop; else p = p##_prev->next;\
*changed = TRUE;
#define PROPOSITION_EDITED_REPEATING_CURRENT(p, prop)\
PROPOSITION_EDITED(p, prop)\
p##_repeat = TRUE;
#define MAX_PROPOSITION_GROUP_NESTING 100 /* vastly more than could realistically be used */
#define ANY_ATOM_HERE 0 /* match any atom, but don't match beyond the end of the proposition */
#define END_PROP_HERE -1 /* a sentinel meaning "the proposition must end at this point" */
#define UNUSED_VST 1
#define FREE_VST 2
#define BOUND_VST 3
#define DISALLOW(msg) {\
if (verify_only) { *allowed = FALSE; return prop; }\
internal_error(msg);\
}
#define APPLY_SIMPLIFICATION(proposition, simp) {\
int changed = FALSE, NF = Calculus__Variables__number_free(proposition);\
if (proposition) proposition = simp(proposition, &changed);\
if (changed) LOGIF(PREDICATE_CALCULUS, "[%d] %s: $D\n", conv_log_depth, #simp, proposition);\
if ((Calculus__Variables__is_well_formed(proposition) == FALSE) ||\
(NF != Calculus__Variables__number_free(proposition))) {\
LOG("Failed after applying %s: $D", #simp, proposition);\
internal_error(#simp " simplified proposition into one which is not well-formed");\
}\
}
#define NOT_BOUND_AT_ALL 1
#define BOUND_BY_EXISTS 2
#define BOUND_BY_SOMETHING_ELSE 3
#define PROTECTED_MODEL_PROCEDURE \
if (ptim_recursion_depth == 0)\
internal_error("protected model-affecting procedure used outside proposition assert");
#define MAX_I6_SCHEMA_LENGTH 256 /* in fact 40 is plenty, but to be on the safe side */
#define MAX_I6_SCHEMA_ATTEMPT 1024 /* plenty of room for conjectural schema overruns */
#define TEST_ATOM_TASK 1
#define NOW_ATOM_TRUE_TASK 2
#define NOW_ATOM_FALSE_TASK 3
#define CONDITION_DEFER 1 /* "if S", where S is a sentence */
#define NOW_ASSERTION_DEFER 2 /* "now S" */
#define EXTREMAL_DEFER 3 /* "the heaviest X", where X is a description */
#define LOOP_DOMAIN_DEFER 4 /* "repeat with I running through X" */
#define NUMBER_OF_DEFER 5 /* "the number of X" */
#define TOTAL_DEFER 6 /* "the total P of X" */
#define RANDOM_OF_DEFER 7 /* "a random X" */
#define LIST_OF_DEFER 8 /* "the list of X" */
#define MULTIPURPOSE_DEFER 100 /* potentially any of the above */
#define CONDITION_DUSAGE -1 /* return |true| iff $\phi(v)$ */
#define LOOP_DOMAIN_DUSAGE -2 /* return the next $x$ after $v$ such that $\phi(x)$ */
#define NUMBER_OF_DUSAGE -3 /* return the number of $w$ such that $\phi(w)$ */
#define RANDOM_OF_DUSAGE -4 /* return a random $w$ such that $\phi(w)$, or 0 if none exists */
#define TOTAL_DUSAGE -5 /* return the total value of a property among $w$ such that $\phi(w)$ */
#define EXTREMAL_DUSAGE -6 /* return the maximal property value among such $w$ */
#define LIST_OF_DUSAGE -7 /* return the list of $w$ such that $\phi(w)$ */
#define FILTER_DEFER 10000 /* pseudo-reason value used only inside this routine */
#define MAX_KIND_CONSTRUCTION_ARITY 2
#define LOOP_OVER_BASE_KINDS(K) \
for (K=Kinds__first_base_k(); K; K = Kinds__next_base_k(K))
#define IDENTIFIERS_CORRESPOND(text_of_I6_name, pointer_to_I7_structure)\
if ((sn) && (strcmp(sn, text_of_I6_name) == 0)) return pointer_to_I7_structure;
#define COVARIANT 1
#define CONTRAVARIANT -1
#define MAX_KIND_VARIABLES 27 /* we number them from 1 (A) to 26 (Z) */
#define MATCH_KIND_VARIABLES_AS_SYMBOLS 0
#define MATCH_KIND_VARIABLES_INFERRING_VALUES 1
#define MATCH_KIND_VARIABLES_AS_VALUES 2
#define MATCH_KIND_VARIABLES_AS_UNIVERSAL 3
#define SIZE_OF_GRAB_BAG 11
#define KIND_VARIABLE_GRP 1 /* just |CON_KIND_VARIABLE| on its own */
#define KIND_OF_KIND_GRP 2 /* an indefinite base constructor such as "arithmetic value" */
#define BASE_CONSTRUCTOR_GRP 3 /* a definite one such as "number" */
#define PROPER_CONSTRUCTOR_GRP 4 /* with positive arity, such as "list of K" */
#define NO_TUPLING 0 /* a single kind */
#define ALLOW_NOTHING_TUPLING 1 /* a single kind, or "nothing" */
#define ARBITRARY_TUPLING 10000 /* a list of kinds of any length */
#define NO_KCA -1 /* there's no operand */
#define BOOLEAN_KCA 1 /* must be |yes| or |no| */
#define CCM_KCA 2 /* a constant compilation method */
#define TEXT_KCA 3 /* any text (no quotation marks or other delimiters are used) */
#define VOCABULARY_KCA 4 /* any single word */
#define NUMERIC_KCA 5 /* any decimal number */
#define CONSTRUCTOR_KCA 6 /* any valid kind number, such as "number" */
#define TEMPLATE_KCA 7 /* the name of a template whose definition is given in the file */
#define MACRO_KCA 8 /* the name of a macro whose definition is given in the file */
#define MAX_KIND_COMMAND_FILE_LENGTH 32768 /* the total length of all such commands combined */
#define MAX_KIND_COMMAND_LENGTH 1024 /* length of any single line */
#define MAX_KIND_MACRO_LENGTH 20 /* maximum number of commands in any one macro */
#define apply_macro_KCC 1
#define apply_template_KCC 2
#define can_coincide_with_property_KCC 5
#define can_exchange_KCC 6
#define cast_KCC 7
#define comparison_routine_KCC 8
#define comparison_schema_KCC 9
#define constant_compilation_method_KCC 10
#define constructor_arity_KCC 11
#define default_value_KCC 12
#define defined_in_source_text_KCC 13
#define description_KCC 14
#define distinguisher_KCC 15
#define documentation_reference_KCC 16
#define explicit_i6_GPR_KCC 17
#define group_KCC 18
#define has_i6_GPR_KCC 19
#define heap_size_estimate_KCC 20
#define i6_printing_routine_actions_KCC 21
#define i6_printing_routine_KCC 22
#define index_default_value_KCC 23
#define index_maximum_value_KCC 24
#define index_minimum_value_KCC 25
#define indexed_grey_if_empty_KCC 26
#define index_priority_KCC 27
#define instance_of_KCC 28
#define is_incompletely_defined_KCC 29
#define is_template_variable_KCC 30
#define loop_domain_schema_KCC 31
#define modifying_adjective_KCC 32
#define multiple_block_KCC 33
#define named_values_created_with_assertions_KCC 34
#define plural_KCC 35
#define recognition_only_GPR_KCC 36
#define singular_KCC 37
#define specification_text_KCC 38
#define small_block_size_KCC 39
#define template_variable_number_KCC 40
#define SET_BOOLEAN_FIELD(field) case field##_KCC: con->field = stc.boolean_argument; return;
#define SET_INTEGER_FIELD(field) case field##_KCC: con->field = stc.numeric_argument; return;
#define SET_TEXTUAL_FIELD(field) case field##_KCC: con->field = stc.textual_argument; return;
#define SET_CCM_FIELD(field) case field##_KCC: con->field = stc.ccm_argument; return;
#define MAX_LOOP_DOMAIN_SCHEMA_LENGTH 1000
#define NORMAL_KIND_PARSING 1
#define PHRASE_TOKEN_KIND_PARSING 2
#define MAX_BASE_UNITS_IN_SEQUENCE 16
#define NO_OPERATIONS 9
#define PLUS_OPERATION 0 /* addition */
#define MINUS_OPERATION 1 /* subtraction */
#define TIMES_OPERATION 2 /* multiplication */
#define DIVIDE_OPERATION 3 /* division */
#define REMAINDER_OPERATION 4 /* remainder after division */
#define APPROXIMATION_OPERATION 5 /* "X to the nearest Y" */
#define ROOT_OPERATION 6 /* square root -- a unary operation */
#define REALROOT_OPERATION 7 /* real-valued square root -- a unary operation */
#define CUBEROOT_OPERATION 8 /* cube root -- similarly unary */
#define EQUALS_OPERATION 9 /* set equal -- used only in equations */
#define POWER_OPERATION 10 /* raise to integer power -- used only in equations */
#define UNARY_MINUS_OPERATION 11 /* unary minus -- used only in equations */
#define TOTAL_OPERATION 12 /* not really one of the above */
#define LOOP_OVER_MULTIPLICATIONS(left_operand, right_operand, outcome_type, wn)\
dimensional_rules *dimrs;\
dimensional_rule *dimr;\
LOOP_OVER_BASE_KINDS(left_operand)\
for (dimrs = Kinds__Behaviour__get_dim_rules(left_operand),\
dimr = (dimrs)?(dimrs->multiplications):NULL,\
wn = (dimr)?(Wordings__first_wn(dimr->name)):-1,\
right_operand = (dimr)?(dimr->right):0,\
outcome_type = (dimr)?(dimr->outcome):0;\
dimr;\
dimr = dimr->next,\
wn = (dimr)?(Wordings__first_wn(dimr->name)):-1,\
right_operand = (dimr)?(dimr->right):0,\
outcome_type = (dimr)?(dimr->outcome):0)
#define UNKNOWN_WEAK_ID 1
#define BLK_FLAG_MULTIPLE 0x00000001
#define BLK_FLAG_16_BIT 0x00000002
#define BLK_FLAG_WORD 0x00000004
#define BLK_FLAG_RESIDENT 0x00000008
#define BLK_FLAG_TRUNCMULT 0x00000010
#define LOWEST_INDEX_PRIORITY 100
#define KINDS_INDEX_SHADE "#808080" /* standard HTML grey colour */
#define CONV_FROM(structure, K)\
parse_node *spec = ParseTree__new(CONSTANT_VNT);\
ParseTree__set_kind_of_value(spec, K);\
ParseTree__set_constant_##structure(spec, val);\
return spec;
#define CONV_TO(structure) \
if (spec == NULL) return NULL;\
structure *val = ParseTree__get_constant_##structure(spec);\
return val;
#define COMPARE_CONSTANTS_USING(DATA, STRUCTURE, FETCH)\
if (Kinds__get_construct(K1) == DATA) {\
STRUCTURE *x1 = FETCH(spec1);\
STRUCTURE *x2 = FETCH(spec2);\
if (x1 == x2) return TRUE;\
return FALSE;\
}
#define KCOMPARE_CONSTANTS_USING(DATA, STRUCTURE, FETCH)\
if (Kinds__Compare__eq(K1, K_##DATA)) {\
STRUCTURE *x1 = FETCH(spec1);\
STRUCTURE *x2 = FETCH(spec2);\
if (x1 == x2) return TRUE;\
return FALSE;\
}
#define KKCOMPARE_CONSTANTS_USING(DATA, STRUCTURE, FETCH)\
if (Kinds__Compare__le(K1, K_##DATA)) {\
STRUCTURE *x1 = FETCH(spec1);\
STRUCTURE *x2 = FETCH(spec2);\
if (x1 == x2) return TRUE;\
return FALSE;\
}
#define KCOMPARE_CONSTANTS(DATA, STRUCTURE)\
KCOMPARE_CONSTANTS_USING(DATA, STRUCTURE, Rvalues__to_##STRUCTURE)
#define NONE_CCM 1 /* constant values of this kind cannot exist */
#define LITERAL_CCM 2 /* a numerical annotation decides the value */
#define NAMED_CONSTANT_CCM 3 /* an |instance| annotation decides the value */
#define SPECIAL_CCM 4 /* special code specific to the kind of value is needed */
#define STORE_WORD_TO_WORD 1
#define STORE_WORD_TO_POINTER 2
#define STORE_POINTER_TO_POINTER 3
#define INCREASE_BY_WORD 4
#define INCREASE_BY_REAL 5
#define INCREASE_BY_POINTER 6
#define DECREASE_BY_WORD 7
#define DECREASE_BY_REAL 8
#define DECREASE_BY_POINTER 9
#define LOOP_THROUGH_ADJECTIVE_LIST(au, au_prop, spec)\
for (au = Calculus__Propositions__first_adjective_usage(\
Descriptions__to_proposition(spec), &au_prop);\
au;\
au = Calculus__Propositions__next_adjective_usage(&au_prop))
#define BEGIN_COMPILATION_MODE \
int status_quo_ante = compilation_mode;
#define COMPILATION_MODE_ENTER(mode) \
compilation_mode |= mode;
#define COMPILATION_MODE_EXIT(mode) \
compilation_mode &= (~mode);
#define END_COMPILATION_MODE \
compilation_mode = status_quo_ante;
#define TEST_COMPILATION_MODE(mode) \
(compilation_mode & mode)
#define DEREFERENCE_POINTERS_CMODE 0x00000001 /* make an independent copy of the result if on the heap */
#define IMPLY_NEWLINES_IN_SAY_CMODE 0x00000010 /* at the end, that is */
#define PERMIT_LOCALS_IN_TEXT_CMODE 0x00000020 /* unless casting to text */
#define COMPILE_TEXT_TO_QUOT_CMODE 0x00000080 /* for the idiosyncratic I6 |box| statement */
#define COMPILE_TEXT_TO_XML_CMODE 0x00000100 /* use XML escapes and UTF-8 encoding */
#define TRUNCATE_TEXT_CMODE 0x00000200 /* into a plausible filename length */
#define COMPILE_TEXT_TO_I6_CMODE 0x00001000 /* for bibliographic text to I6 constants */
#define CONSTANT_CMODE 0x00002000 /* compiling values in a constant context */
#define SPECIFICATIONS_CMODE 0x00004000 /* compiling specifications at all */
#define BEGIN_DASH_MODE int s_dm = dash_mode; kind **s_kvc = kind_of_var_to_create; parse_node *s_invl = Dash_ambiguity_list;
#define DASH_MODE_ENTER(mode) dash_mode |= mode;
#define DASH_MODE_CREATE(K) kind_of_var_to_create = K;
#define DASH_MODE_INVL(invl) Dash_ambiguity_list = invl;
#define DASH_MODE_EXIT(mode) dash_mode &= (~mode);
#define END_DASH_MODE dash_mode = s_dm; kind_of_var_to_create = s_kvc; Dash_ambiguity_list = s_invl;
#define TEST_DASH_MODE(mode) (dash_mode & mode)
#define ISSUE_PROBLEMS_DMODE 0x00000001 /* rather than keep silent about them */
#define ISSUE_LOCAL_PROBLEMS_DMODE 0x00000002 /* at the end, that is */
#define ISSUE_GROSS_PROBLEMS_DMODE 0x00000004 /* at the end, that is */
#define ISSUE_INTERESTING_PROBLEMS_DMODE 0x00000008 /* unless casting to text */
#define ABSOLUTE_SILENCE_DMODE 0x00000010 /* say nothing at all */
#define THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM \
no_gross_problems_thrown++; /* problems this gross cannot be suppressed */
#define THIS_IS_A_GROSS_PROBLEM \
no_gross_problems_thrown++; /* this increments even if the message is suppressed */\
if ((TEST_DASH_MODE(ISSUE_PROBLEMS_DMODE) == FALSE) &&\
(TEST_DASH_MODE(ISSUE_GROSS_PROBLEMS_DMODE) == FALSE)) return NEVER_MATCH;
#define THIS_IS_AN_ORDINARY_PROBLEM \
if (TEST_DASH_MODE(ISSUE_PROBLEMS_DMODE) == FALSE) return NEVER_MATCH;
#define LOG_DASH_LEFT \
LOGIF(MATCHING, "[%d%s] ",\
unique_DR_call_identifier,\
(TEST_DASH_MODE(ISSUE_PROBLEMS_DMODE))?"":"-silent");
#define LOG_DASH(stage) \
LOGIF(MATCHING, "[%d%s] %s $P\n",\
unique_DR_call_identifier,\
(TEST_DASH_MODE(ISSUE_PROBLEMS_DMODE))?"":"-silent", stage, p);
#define ALWAYS_MATCH 2 /* provably correct at compile time */
#define SOMETIMES_MATCH 1 /* provably reduced to a check feasible at run-time */
#define NEVER_MATCH 0 /* neither of the above */
#define MAX_DASH_RECURSION 10000
#define SWITCH_CONTEXT_AND_RECURSE(p) Dash__typecheck_recursive(p->down, p, TRUE)
#define THIS_IS_AN_INTERESTING_PROBLEM \
outcome = NEVER_MATCH;\
no_interesting_problems_thrown++;\
if (TEST_DASH_MODE(ISSUE_INTERESTING_PROBLEMS_DMODE))
#define SAY_UTSHAPE 1
#define LIST_UTSHAPE 2
#define NO_UTSHAPE 3
#define INVALID_CP_BIT 1
#define WHENWHILE_CP_BIT 2
#define PASSED_DASHFLAG 0x00000001 /* once type-checked: did this pass type checking? */
#define UNPROVEN_DASHFLAG 0x00000002 /* once type-checked: will this need run-time checking? */
#define GROSSLY_FAILED_DASHFLAG 0x00000004 /* once type-checked: oh, this one failed big time */
#define TESTED_DASHFLAG 0x00000008 /* has been type-checked */
#define INTERESTINGLY_FAILED_DASHFLAG 0x00000010 /* an interesting problem message could be produced about the way this failed */
#define UNSET_TABLE_OFFSET -654321
#define MEASURE_T_OR_LESS -1
#define MEASURE_T_EXACTLY 0
#define MEASURE_T_OR_MORE 1
#define ATTRIBUTE_SLOTS_TO_GIVE_AWAY 11
#define FIRST_IN_COMPILATION_SEQUENCE first_object_in_compilation_list
#define NEXT_IN_COMPILATION_SEQUENCE(I) objects_in_compilation_list[I->allocation_id]
#define LOOP_OVER_OBJECTS_IN_COMPILATION_SEQUENCE(I) \
for (I=FIRST_IN_COMPILATION_SEQUENCE; I; I=NEXT_IN_COMPILATION_SEQUENCE(I))
#define COL_HSIZE 2
#define TRAVERSE_PERMITTED_COMPILABLE_PROPERTIES(prn, pp, K)\
Properties__begin_traverse();\
instance *I_of;\
inference_subject *infs;\
if (Kinds__Behaviour__definite(K))\
LOOP_OVER_INSTANCES(I_of, K)\
for (infs = Instances__as_subject(I_of); infs; infs = InferenceSubjects__narrowest_broader_subject(infs))\
LOOP_OVER_PERMISSIONS_FOR_INFS(pp, infs)\
if (((prn = World__Permissions__get_property(pp))) &&\
(Properties__visited_in_traverse(prn) == FALSE) &&\
(Properties__can_be_compiled(prn)))
#define FUND_SUB 1 /* one of a few fixed and fundamental subjects (see below) */
#define KIND_SUB 2 /* a kind (number, thing, etc.) */
#define INST_SUB 3 /* an instance (specific objects, scenes, etc.) */
#define VARI_SUB 4 /* a non-local variable */
#define RELN_SUB 5 /* a binary predicate, i.e., a relation */
#define MAX_SUB 5 /* must be the largest of the values above */
#define PF_S(name, S)\
((name##_data *) S->plugin_subj[name##_plugin->allocation_id])
#define PF_I(name, I)\
((name##_data *) (Instances__as_subject(I))->plugin_subj[name##_plugin->allocation_id])
#define CREATE_PF_DATA(name, S, creator)\
(S)->plugin_subj[name##_plugin->allocation_id] = (void *) (creator(S));
#define PLUGIN_PP(id, pp)\
((id##_pp_data *) pp->plugin_pp[id##_plugin->allocation_id])
#define CREATE_PLUGIN_PP_DATA(id, pp, creator)\
(pp)->plugin_pp[id##_plugin->allocation_id] = (void *) (creator(pp));
#define LOOP_OVER_PERMISSIONS_FOR_PROPERTY(pp, prn)\
for (pp = Properties__permission_list(prn); pp; pp = pp->next_for_this_property)
#define LOOP_OVER_PERMISSIONS_FOR_INFS(pp, infs)\
for (pp = *(InferenceSubjects__get_permissions(infs)); pp; pp = pp->next_for_this_owner)
#define ARBITRARY_RELATION_INF 1 /* fact about an "arbitrary" relation */
#define PROPERTY_INF 2 /* fact about a property */
#define IMPOSSIBLE_CE -2
#define UNLIKELY_CE -1
#define UNKNOWN_CE 0
#define LIKELY_CE 1
#define CERTAIN_CE 2
#define INITIALLY_CE 3
#define POSITIVE_KNOWLEDGE_LOOP(inf, infs, type)\
for (inf = (infs)?(InferenceSubjects__get_inferences(World__Inferences__divert_infs(infs))):NULL; inf; inf = inf->next)\
if ((inf->inference_type == type) && (inf->certainty > 0))
#define KNOWLEDGE_LOOP(inf, infs, type)\
for (inf = (infs)?(InferenceSubjects__get_inferences(World__Inferences__divert_infs(infs))):NULL; inf; inf = inf->next)\
if (inf->inference_type == type)
#define CI_DIFFER_IN_EXISTENCE 1
#define CI_DIFFER_IN_TYPE 2
#define CI_DIFFER_IN_PROPERTY 3
#define CI_DIFFER_IN_INFS2 4
#define CI_DIFFER_IN_INFS1 5
#define CI_DIFFER_IN_PROPERTY_VALUE 6
#define CI_DIFFER_IN_COPY_ONLY 7
#define CI_IDENTICAL 0
#define RED_NODE 1
#define BLACK_NODE 2
#define EXISTING_TC 1 /* one seen before in another table */
#define NEW_TC_WITH_KIND 2 /* never seen before, with a kind explicitly given */
#define NEW_TC_WITHOUT_KIND 3 /* never seen before, with no specified kind */
#define NEW_TC_TOPIC 4 /* a topic column, a specialised form of text */
#define NEW_TC_PROBLEM 5 /* (something went wrong, so Inform can ignore this) */
#define MAX_COLUMNS_PER_TABLE 99
#define TABLE_IS_NEW 1
#define TABLE_IS_CONTINUED 2
#define TABLE_IS_AMENDED 3
#define TABLE_IS_REPLACED 4
#define TABLE_HAS_ONLY_NUMBER 1
#define TABLE_HAS_ONLY_NAME 2
#define TABLE_HAS_NUMBER_AND_NAME 3
#define TABLE_NAMES_MATCH(t1, t2)\
((t1 != t2) && (Wordings__nonempty(t1->table_name_text)) && (Wordings__nonempty(t2->table_name_text)) &&\
(Wordings__match(t2->table_name_text, t1->table_name_text)))
#define TABLE_NUMBERS_MATCH(t1, t2)\
((t1 != t2) && (Wordings__nonempty(t1->table_no_text)) && (Wordings__nonempty(t2->table_no_text)) &&\
(Wordings__match(t2->table_no_text, t1->table_no_text)))
#define BLANK_TABLE_ENTRY 1
#define SPEC_TABLE_ENTRY 2
#define ACTION_TABLE_ENTRY 3
#define TOPIC_TABLE_ENTRY 4
#define INSTANCE_TABLE_ENTRY 5
#define KIND_TABLE_ENTRY 6
#define NAMED_CONSTANT_ENTRY 7
#define PROBLEMATIC_TABLE_ENTRY -1
#define TB_COLUMN_REAL 0x8000
#define TB_COLUMN_SIGNED 0x4000
#define TB_COLUMN_TOPIC 0x2000
#define TB_COLUMN_DONTSORTME 0x1000
#define TB_COLUMN_NOBLANKBITS 0x0800
#define TB_COLUMN_CANEXCHANGE 0x0400
#define TB_COLUMN_ALLOCATED 0x0200
#define CONSTANT_EQN 1 /* a leaf, representing a quasinumerical constant not given a symbol */
#define SYMBOL_EQN 2 /* a leaf, representing a symbol */
#define OPERATION_EQN 3 /* a non-leaf, representing an operation */
#define OPEN_BRACKET_EQN 4
#define CLOSE_BRACKET_EQN 5
#define END_EQN 6 /* the end (left or right edge, really) of the equation */
#define IMPLICIT_TIMES_OPERATION 100
#define IMPLICIT_APPLICATION_OPERATION 101
#define MAX_EQN_ARITY 2 /* at present all operations are at most binary */
#define EQW_IDENTIFIES_KIND 1
#define EQW_IDENTIFIES_VALUE 2
#define EQW_IDENTIFIES_NOTHING 3
#define EQW_IDENTIFIES_PROBLEM 4
#define MAX_ENODES_IN_EXPRESSION 100
#define MAX_PASTEABLE_RULE_NAME_LENGTH 500
#define MIDDLE_PLACEMENT 0 /* most rules are somewhere in the middle */
#define FIRST_PLACEMENT 1
#define LAST_PLACEMENT 2
#define BEFORE_SIDE -1 /* before a reference rule */
#define IN_SIDE 0 /* without reference to any other rule */
#define AFTER_SIDE 1 /* after a reference rule */
#define INSTEAD_SIDE 2 /* in place of reference rule */
#define ARRAY_RBF 1 /* format as an array simply listing the rules */
#define GROUPED_ARRAY_RBF 2 /* format as a grouped array, for quicker action testing */
#define ROUTINE_RBF 3 /* format as a routine which runs the rulebook */
#define RULE_OPTIMISATION_THRESHOLD 20 /* group arrays when larger than this number of rules */
#define MAX_BUILT_IN_RULEBOOKS 32
#define STARTUP_RB 0 /* Startup rules */
#define TURN_SEQUENCE_RB 1 /* Turn sequence rules */
#define SHUTDOWN_RB 2 /* Shutdown rules */
#define SCENE_CHANGING_RB 3 /* Scene changing rules */
#define WHEN_PLAY_BEGINS_RB 4 /* When play begins */
#define WHEN_PLAY_ENDS_RB 5 /* When play ends */
#define WHEN_SCENE_BEGINS_RB 6 /* When play begins */
#define WHEN_SCENE_ENDS_RB 7 /* When play ends */
#define EVERY_TURN_RB 8 /* Every turn */
#define ACTION_PROCESSING_RB 9 /* Action-processing rules */
#define SETTING_ACTION_VARIABLES_RB 10 /* Setting action variables rules */
#define SPECIFIC_ACTION_PROCESSING_RB 11 /* Specific action-processing rules */
#define PLAYERS_ACTION_AWARENESS_RB 12 /* Player's action awareness rules */
#define ACCESSIBILITY_RB 13 /* Accessibility rules */
#define REACHING_INSIDE_RB 14 /* Reaching inside rules */
#define REACHING_OUTSIDE_RB 15 /* Reaching outside rules */
#define VISIBILITY_RB 16 /* Visibility rules */
#define PERSUASION_RB 17 /* Persuasion rules */
#define UNSUCCESSFUL_ATTEMPT_BY_RB 18 /* Unsuccessful attempt by */
#define BEFORE_RB 19 /* Before rules */
#define INSTEAD_RB 20 /* Instead rules */
#define CHECK_RB 21 /* Check */
#define CARRY_OUT_RB 22 /* Carry out rules */
#define AFTER_RB 23 /* After rules */
#define REPORT_RB 24 /* Report */
#define DOES_THE_PLAYER_MEAN_RB 25 /* Does the player mean...? rules */
#define MULTIPLE_ACTION_PROCESSING_RB 26 /* For changing or reordering multiple actions */
#define ACTION_FOCUS 0
#define PARAMETER_FOCUS 1
#define UNRECOGNISED_OUTCOME -1 /* used in parsing only */
#define NO_OUTCOME 0
#define SUCCESS_OUTCOME 1
#define FAILURE_OUTCOME 2
#define ANY_RULE_PLACEMENT 1000001
#define BAD_RULE_PLACEMENT 1000000
#define PRINTING_THE_NAME_ACT 0
#define PRINTING_THE_PLURAL_NAME_ACT 1
#define PRINTING_A_NUMBER_OF_ACT 2
#define PRINTING_ROOM_DESC_DETAILS_ACT 3
#define PRINTING_INVENTORY_DETAILS_ACT 4
#define LISTING_CONTENTS_ACT 5
#define GROUPING_TOGETHER_ACT 6
#define WRITING_A_PARAGRAPH_ABOUT_ACT 7
#define LISTING_NONDESCRIPT_ITEMS_ACT 8
#define PRINTING_NAME_OF_DARK_ROOM_ACT 9
#define PRINTING_DESC_OF_DARK_ROOM_ACT 10
#define PRINTING_NEWS_OF_DARKNESS_ACT 11
#define PRINTING_NEWS_OF_LIGHT_ACT 12
#define REFUSAL_TO_ACT_IN_DARK_ACT 13
#define CONSTRUCTING_STATUS_LINE_ACT 14
#define PRINTING_BANNER_TEXT_ACT 15
#define READING_A_COMMAND_ACT 16
#define DECIDING_SCOPE_ACT 17
#define DECIDING_CONCEALED_POSSESS_ACT 18
#define DECIDING_WHETHER_ALL_INC_ACT 19
#define CLARIFYING_PARSERS_CHOICE_ACT 20
#define ASKING_WHICH_DO_YOU_MEAN_ACT 21
#define PRINTING_A_PARSER_ERROR_ACT 22
#define SUPPLYING_A_MISSING_NOUN_ACT 23
#define SUPPLYING_A_MISSING_SECOND_ACT 24
#define IMPLICITLY_TAKING_ACT 25
#define STARTING_VIRTUAL_MACHINE_ACT 26
#define AMUSING_A_VICTORIOUS_PLAYER_ACT 27
#define PRINTING_PLAYERS_OBITUARY_ACT 28
#define DEALING_WITH_FINAL_QUESTION_ACT 29
#define PRINTING_LOCALE_DESCRIPTION_ACT 30
#define CHOOSING_NOTABLE_LOCALE_OBJ_ACT 31
#define PRINTING_LOCALE_PARAGRAPH_ACT 32
#define PRINTING_RESPONSE_ACT 33
#define DAWN_PHT 0
#define EARLY_MORNING_PHT 1
#define LATE_MORNING_PHT 2
#define PRE_NOON_PHT 3
#define EARLY_AFTERNOON_PHT 4
#define MID_AFTERNOON_PHT 5
#define LATE_AFTERNOON_PHT 6
#define EVENING_PHT 7
#define TO_PHRASE_EFF 1 /* "To award (some - number) points: ..." */
#define RULE_IN_RULEBOOK_EFF 2 /* "Before taking a container, ..." */
#define RULE_NOT_IN_RULEBOOK_EFF 3 /* "At 9 PM: ...", "This is the zap rule: ..." */
#define DEFINITIONAL_PHRASE_EFF 4 /* "Definition: a container is roomy if: ..." */
#define DONT_KNOW_MOR 1 /* but ask me later */
#define DECIDES_NOTHING_MOR 2 /* e.g., "award 4 points" */
#define DECIDES_VALUE_MOR 3 /* e.g., "square root of 16" */
#define DECIDES_CONDITION_MOR 4 /* e.g., "a random chance of 1 in 3 succeeds" */
#define DECIDES_NOTHING_AND_RETURNS_MOR 5 /* e.g., "continue the action" */
#define AS_YET_UNKNOWN_EFF 0 /* used only temporarily during header parsing */
#define MAX_TOKENS_PER_PHRASE 10
#define MAX_WORDS_PER_PHRASE 32 /* the most the excerpt parser can hold anyway */
#define STANDARD_PT_CONSTRUCT 1 /* e.g., |12|, |number|, |open door| */
#define NEW_LOCAL_PT_CONSTRUCT 2 /* e.g., |nonexisting number variable| */
#define EXISTING_LOCAL_PT_CONSTRUCT 3 /* e.g., |existing number variable| */
#define CONDITION_PT_CONSTRUCT 4 /* e.g., |a condition| */
#define STORAGE_PT_CONSTRUCT 5 /* e.g., |storage| */
#define TABLE_REFERENCE_PT_CONSTRUCT 6 /* e.g., |table-reference| */
#define KIND_NAME_PT_CONSTRUCT 7 /* e.g., |name of kind| */
#define VOID_PT_CONSTRUCT 8 /* e.g., or in fact only, |phrase| */
#define NO_SAY_CS 0
#define IF_SAY_CS 1
#define OTHERWISE_SAY_CS 2
#define OTHERWISE_IF_SAY_CS 3
#define END_IF_SAY_CS 4
#define SSP_NONE 0
#define SSP_START 1
#define SSP_MIDDLE 2
#define SSP_END 3
#define NOT_A_LET_PHRASE 0 /* needs to be 0 so that |let_phrase| can be a C condition */
#define ASSIGNMENT_LET_PHRASE 1 /* the regular "let" */
#define EQUATION_LET_PHRASE 2 /* "let" inviting Inform to solve an equation */
#define NOT_A_SAY_PHRASE 0 /* needs to be 0 so that |sd.say_phrase| can be a C condition */
#define A_MISCELLANEOUS_SAY_PHRASE 1
#define THE_PRIMORDIAL_SAY_PHRASE 2
#define NO_BLOCK_FOLLOWS 0 /* this needs to be 0, to make if conditions work */
#define MISCELLANEOUS_BLOCK_FOLLOWS 1
#define CONDITIONAL_BLOCK_FOLLOWS 2
#define LOOP_BODY_BLOCK_FOLLOWS 3
#define PASTE_PHRASE_FORMAT 1 /* in the insert-to-source text pasted by a button in the Index */
#define INDEX_PHRASE_FORMAT 2 /* a simpler version good enough for most purposes */
#define NO_ANN 0
#define SAY_ANN 1
#define LET_ANN 2
#define BLOCK_ANN 3
#define IN_LOOP_ANN 4
#define IN_ANN 5
#define CONDITIONAL_ANN 6
#define LOOP_ANN 7
#define NO_SANN 1
#define CONTROL_SANN 2
#define BEGIN_SANN 3
#define CONTINUE_SANN 4
#define ENDM_SANN 5
#define END_SANN 6
#define DEC_RANN 1
#define DEV_RANN 2
#define TOC_RANN 3
#define TOV_RANN 4
#define TO_RANN 5
#define MAX_OPTIONS_PER_PHRASE 16 /* because held in a 16-bit Z-machine bitmap */
#define BEFORE_PH -3
#define SUBSCHEMA_PH -1
#define EQUAL_PH 0
#define SUPERSCHEMA_PH 1
#define INCOMPARABLE_PH 2
#define AFTER_PH 3
#define CONFLICTED_PH 4
#define NOT_A_TIMED_EVENT -1 /* as for the vast majority of phrases */
#define NO_FIXED_TIME -2 /* for phrases like "When the clock strikes: ..." */
#define NOT_AN_EVENT -3 /* not even syntactically */
#define DEFINED_POSITIVELY 1
#define DEFINED_NEGATIVELY -1
#define DEFINED_PHRASALLY 0
#define DEFINED_IN_SOME_WAY_NOT_YET_KNOWN -2
#define TOKEN_CALL_PARAMETER_LV 1 /* values for the tokens of the phrase being invoked */
#define OTHER_CALL_PARAMETER_LV 2 /* other implied parameters passed during invocation: I6-level only */
#define LET_VALUE_LV 3 /* variables created by "let", "while" or "repeat" */
#define INTERNAL_USE_LV 4 /* workspace needed by our compiled code: I6-level only */
#define MAX_CALLINGS_IN_MATCH 128
#define MAX_BLOCK_NESTING 50 /* which frankly seems plenty */
#define LOOP_THROUGH_TOKENS_PARSED_IN_INV(inv, spec)\
int lttpii_counter, lttpii_upto = Invocations__get_no_tokens(inv);\
for (lttpii_counter=0,\
spec = (lttpii_counter < lttpii_upto)?\
Invocations__get_token_as_parsed(inv, lttpii_counter):NULL;\
lttpii_counter < lttpii_upto;\
lttpii_counter++,\
spec = (lttpii_counter < lttpii_upto)?\
Invocations__get_token_as_parsed(inv, lttpii_counter):NULL)
#define MAX_INVOCATIONS_PER_PHRASE 4096
#define LOOP_THROUGH_INVOCATION_LIST(inv, invl)\
LOOP_THROUGH_ALTERNATIVES(inv, invl)
#define MAX_INLINE_DEFN_LENGTH 1024
#define OPTS_INSUB 1 /* the text "phrase options" */
#define OPT_INSUB 2 /* the name of a specific phrase option */
#define LOCAL_INSUB 3 /* the name of a token */
#define PROBLEM_INSUB 4 /* the syntax was wrong, so do nothing */
#define MAX_COMPLEX_SAY_DEPTH 32 /* and it would be terrible coding style to approach this */
#define VMULT 10000
#define MAX_USAGE_COLUMN_WIDTH 200
#define Z_VM 1 /* Joel Berez and Marc Blank, 1979, and later hands */
#define GLULX_VM 2 /* Andrew Plotkin, 2000 */
#define DEFAULT_TARGET_VM 3 /* if no -extension is supplied, target row 3: Z-machine v8 */
#define THROW_VM_MATCHING_ERROR_AND_RETURN { VM_matching_error_thrown = TRUE; return TRUE; }
#define NOTEWORTHY_USAGE_THRESHOLD 50 /* don't mention arrays smaller than this, in bytes */
#define SEGMENT_LEVEL_INC 1 /* before, instead of, or after a segment of I6 template */
#define SECTION_LEVEL_INC 2 /* before, instead of, or after a section of I6 template */
#define WHEN_DEFINING_INC 3 /* as part of an Object or Class definition */
#define AS_PREFORM_INC 4 /* include it not as I6, but as Preform grammar */
#define AUTHORIAL_MODESTY_UO 0
#define DYNAMIC_MEMORY_ALLOCATION_UO 1
#define MEMORY_ECONOMY_UO 2
#define NO_DEPRECATED_FEATURES_UO 3
#define NUMBERED_RULES_UO 4
#define TELEMETRY_RECORDING_UO 5
#define SCORING_UO 6
#define NO_SCORING_UO 7
#define ENGINEERING_NOTATION_UO 8
#define UNABBREVIATED_OBJECT_NAMES_UO 9
#define INDEX_FIGURE_THUMBNAILS_UO 10
#define GN_TESTING_VERSION_UO 11
#define MAIN_TEXT_UO_ORIGIN 1
#define OPTIONS_FILE_UO_ORIGIN 2
#define EXTENSION_UO_ORIGIN 3
#define MAX_NAMESPACE_PREFIX_LENGTH 20 /* when |L_| and a number are added, we are within 31 chars */
#define CT_CAPITALISE 1 /* capitalise first letter of text */
#define CT_EXPAND_APOSTROPHES 2 /* sometimes regard |'| as |"| */
#define CT_RECOGNISE_APOSTROPHE_SUBSTITUTION 4 /* recognise |[']| as a literal |'| */
#define CT_RECOGNISE_UNICODE_SUBSTITUTION 8 /* recognise |[unicode N]| as a literal char */
#define CT_DEQUOTE 16 /* ignore initial and terminal |"| pair, e.g., render |"fish"| as |fish| */
#define CT_FOR_ARRAY 32 /* force use of |@{xx}| form not |@@ddd| */
#define CT_BOX_QUOTATION 64 /* format line breaks into text for an I6 |box| statement */
#define CT_RAW 128 /* ignore everything except capitalisation and dequoting */
#define MAX_UNISUB_LENGTH 128
#define MAX_UUID_LENGTH 128 /* the UUID is truncated to this if necessary */
#define STORY_TITLE_BIBV 0
#define STORY_AUTHOR_BIBV 1
#define STORY_HEADLINE_BIBV 2
#define STORY_GENRE_BIBV 3
#define STORY_DESCRIPTION_BIBV 4
#define STORY_CREATION_YEAR_BIBV 5
#define RELEASE_NUMBER_BIBV 6
#define SOLUTION_PAYLOAD 0
#define SOURCE_TEXT_PAYLOAD 1
#define LIBRARY_CARD_PAYLOAD 2
#define COVER_ART_PAYLOAD 3
#define EXISTING_STORY_FILE_PAYLOAD 4
#define AUXILIARY_FILE_PAYLOAD 5
#define BOOKLET_PAYLOAD 6
#define POSTCARD_PAYLOAD 7
#define WEBSITE_PAYLOAD 8
#define THEMED_WEBSITE_PAYLOAD 9
#define INTERPRETER_PAYLOAD 10
#define THEMED_INTERPRETER_PAYLOAD 11
#define HIDDEN_FILE_PAYLOAD 12
#define HIDDEN_FILE_IN_PAYLOAD 13
#define SEPARATE_FIGURES_PAYLOAD 14
#define SEPARATE_SOUNDS_PAYLOAD 15
#define CSS_PAYLOAD 16
#define JAVASCRIPT_PAYLOAD 17
#define NAMED_EXISTING_STORY_FILE_PAYLOAD 18
#define LENGTH_OF_STORY_FILE_HEADER 0x40
#define BIBLIOGRAPHIC_TEXT_TRUNCATION 31
#define INSTANCE_COUNT(I, K)\
kind_instance_counts[(I)->allocation_id*max_kind_instance_count +\
Kinds__Behaviour__I6_classnumber(K)]
#define IS_ROOM_INF 50 /* is O a room? */
#define CONTAINS_THINGS_INF 51 /* does O contain things? */
#define PARENTAGE_INF 52 /* where is O located? */
#define PARENTAGE_HERE_INF 53 /* located vaguely as "here"? */
#define PARENTAGE_NOWHERE_INF 54 /* located vaguely as "nowhere"? */
#define PART_OF_INF 55 /* is O a part of another object? */
#define FOUND_IN_INF 56 /* for backdrop things in many places */
#define FOUND_EVERYWHERE_INF 57 /* ditto */
#define LOOP_OVER_BACKDROPS_IN(B, P, I)\
LOOP_OVER_OBJECT_INSTANCES(B)\
if (PL__Backdrops__object_is_a_backdrop(B))\
POSITIVE_KNOWLEDGE_LOOP(I, Instances__as_subject(B), FOUND_IN_INF)\
if (World__Inferences__get_reference_as_object(I) == P)
#define LOOP_OVER_BACKDROPS_EVERYWHERE(B, I)\
LOOP_OVER_OBJECT_INSTANCES(B)\
if (PL__Backdrops__object_is_a_backdrop(B))\
POSITIVE_KNOWLEDGE_LOOP(I, Instances__as_subject(B), FOUND_EVERYWHERE_INF)
#define DIRECTION_INF 100 /* where do map connections from O lead? */
#define MAX_WORDS_IN_DIRECTION (MAX_WORDS_IN_ASSEMBLAGE - 2)
#define MAP_EXIT(X, Y) PF_I(map, X)->exits[Y]
#define LOOP_OVER_ROOMS(R) \
LOOP_OVER_OBJECT_INSTANCES(R)\
if (PL__Spatial__object_is_a_room(R))
#define LOOP_OVER_SUBMAP(R, sub)\
for (R = sub->first_room_in_submap; R; R = PF_I(map, R)->next_room_in_submap)
#define Room_position(R) PF_I(map, R)->position
#define LOOP_OVER_DIRECTIONS(i) \
for (i=0; i<12; i++)
#define LOOP_OVER_STORY_DIRECTIONS(i) \
for (i=0; i<registered_directions; i++)
#define LOOP_OVER_LATTICE_DIRECTIONS(i) \
for (i=0; i<10; i++)
#define LOOP_OVER_NONLATTICE_DIRECTIONS(i) \
for (i=10; i<12; i++)
#define OVERLYING_HEAT 20
#define COLLISION_HEAT 50000
#define FUSION_POINT 1000000000
#define ANGULAR_MULTIPLIER 50
#define CAP_ON_SLIDE_LENGTHS 10
#define EXPLORATION_RECORDS 3 /* how much we keep track of */
#define BEST_ONECUT_ER 0 /* what's the best-known single link to cut? */
#define BEST_PARALLEL_TWOCUT_ER 1 /* what's the best-known pair of links equal in direction? */
#define BEST_TWOCUT_ER 2 /* and in general? */
#define CLIPBOARD_SIZE 3 /* a term to be explained below */
#define MIN_ONECUT_ZONE_SIZE 2
#define MIN_TWOCUT_ZONE_SIZE 3
#define MAX_RADIATION_DISTANCE 5
#define MAX_EXPLOSION_DISTANCE 3
#define MAX_OFFSET 1
#define ROOM_GRID_POS(P) Geometry__cuboid_index(P, Universe)
#define ICON_GRID_POS(P, i1, i2) (25*ROOM_GRID_POS(P) + 5*(i1) + (i2))
#define EXIT_MAPBIT 0x00000001 /* An exit leads this way */
#define DOOR1_MAPBIT 0x00000002 /* Into a 1-sided door */
#define DOOR2_MAPBIT 0x00000004 /* Into a 2-sided door */
#define CONNECTIVE_BITMAP (EXIT_MAPBIT+DOOR1_MAPBIT+DOOR2_MAPBIT)
#define ADJACENT_MAPBIT 0x00000008 /* Into the room adjacent in space */
#define ALIGNED_MAPBIT 0x00000010 /* Into a room in correct direction */
#define FADING_MAPBIT 0x00000020 /* There's a broken exit on ... */
#define MEET_MAPBIT 0x00000040 /* This door should meet the adjacent one */
#define CROSSDOOR_MAPBIT 0x00000080 /* There's a door on the diagonal athwart */
#define CROSSDOT_MAPBIT 0x00000100 /* There's a plain exit on ... */
#define LONGEW_MAPBIT 0x00000200
#define LONGNS_MAPBIT 0x00000400
#define LONGSWNE_MAPBIT 0x00000800
#define LONGNWSE_MAPBIT 0x00001000
#define OCCUPIED_MAPBIT 0x10000000
#define LONGS_BITMAP (LONGEW_MAPBIT+LONGNS_MAPBIT+LONGSWNE_MAPBIT+LONGNWSE_MAPBIT)
#define NO_REGION_COLOURS 20
#define MAP_CELL_OUTER_SIZE 13 /* i.e., $x_o$ */
#define MAP_CELL_INNER_SIZE 27 /* i.e., $x_i$ */
#define MAP_CELL_SIZE (MAP_CELL_OUTER_SIZE + MAP_CELL_INNER_SIZE + MAP_CELL_OUTER_SIZE)
#define MAP_DISLOCATION_HEIGHT 19 /* the reduced height */
#define NUMBERING_TEXT_COLOUR "c0c0c0"
#define ROOM_BORDER_SIZE 1
#define B_ROOM_BORDER_SIZE 2
#define ROOM_BORDER_COLOUR "000000"
#define ROOM_TEXT_COLOUR "000000"
#define ABBREV_ROOMS_TO 2
#define INT_MDT 1 /* an integer */
#define BOOL_MDT 2 /* true or false */
#define TEXT_MDT 3 /* quoted text */
#define COL_MDT 4 /* an HTML-safe colour */
#define FONT_MDT 5 /* the name of a font */
#define OFF_MDT 6 /* a positional offset in an $(x,y)$ grid */
#define NO_MAP_PARAMETERS 35
#define NO_IMW 0
#define EPSFILE_IMW 1
#define MAPPED_AS_IMW 2
#define MAPPED_IMW 3
#define SETTING_IMW 4
#define RUBRIC_IMW 5
#define RUBRIC_SIZE 1
#define RUBRIC_FONT 2
#define RUBRIC_COLOUR 3
#define RUBRIC_OFFSET 4
#define RUBRIC_POSITION 5
#define FIRST_ROOM_MAP_SCOPE 1
#define LEVEL_MAP_SCOPE 2
#define KIND_MAP_SCOPE 3
#define INSTANCE_MAP_SCOPE 4
#define ENTIRE_MAP_SCOPE 5
#define ERRONEOUS_OFFSET_VALUE 100000000
#define MAX_EPS_TEXT_LENGTH 1000
#define MAX_EPS_ABBREVIATED_LENGTH MAX_EPS_TEXT_LENGTH
#define MAX_SCENE_ENDS 32 /* this must exceed 31 */
#define MAX_SCENE_CHANGE_ITERATION 20
#define START_OF_PLAY_END -1
#define NEVER_HAPPENS_END -2
#define UNRESTRICTED_ACCESS 0 /* question not meaningful, e.g. for a number */
#define IMPOSSIBLE_ACCESS 1 /* action doesn't take a noun, so no question of access */
#define DOESNT_REQUIRE_ACCESS 2 /* actor need not be able to touch this object */
#define REQUIRES_ACCESS 3 /* actor must be able to touch this object */
#define REQUIRES_POSSESSION 4 /* actor must be carrying this object */
#define OOW_ACT_CLAUSE 1
#define PP_ACT_CLAUSE 2
#define APPLYING_ACT_CLAUSE 3
#define LIGHT_ACT_CLAUSE 4
#define ABBREV_ACT_CLAUSE 5
#define MISC_PAPF 1
#define NOPARTICIPLE_PAPF 2
#define MIXEDNOUNS_PAPF 3
#define WHEN_PAPF 4
#define WHENOKAY_PAPF 5
#define IMMISCIBLE_PAPF 6
#define ACTOR_REQUESTED 0
#define ACTOR_NAMED 1
#define ACTOR_EXPLICITLY_UNIVERSAL 2
#define ACTOR_EXPLICITLY_PLAYER 3
#define ACTOR_IMPLICITLY_PLAYER 4
#define MAX_AP_POSITIONS 100
#define UNTHINKABLE_POSITION -1
#define NORMAL_COMMAND 1
#define ALIAS_COMMAND 2
#define OUT_OF_WORLD_COMMAND 3
#define TESTING_COMMAND 4
#define BARE_DIRECTION_COMMAND 5
#define COMMAND_UNDERSTAND_FORM 1
#define PROPERTY_UNDERSTAND_FORM 2
#define GRAMMAR_UNDERSTAND_FORM 3
#define NOTHING_UNDERSTAND_FORM 4
#define NO_UNDERSTAND_FORM 5
#define GV_IS_COMMAND 1 /* an imperative verbal command at run-time */
#define GV_IS_TOKEN 2 /* a square-bracketed token in other grammar */
#define GV_IS_OBJECT 3 /* a noun phrase at run time: a name for an object */
#define GV_IS_VALUE 4 /* a noun phrase at run time: a name for a value */
#define GV_IS_CONSULT 5 /* a pattern to match in part of a command (such as "consult") */
#define GV_IS_PROPERTY_NAME 6 /* a noun phrase at run time: a name for an either/or pval */
#define MAX_ALIASED_COMMANDS 32
#define MAX_LINES_PER_COMMAND 32
#define UNCALCULATED_BONUS -1000000
#define NAMED_TOKEN_GTC 1 /* these positive values are used only in parsing */
#define RELATED_GTC 2
#define STUFF_GTC 3
#define ANY_STUFF_GTC 4
#define ANY_THINGS_GTC 5
#define NOUN_TOKEN_GTC -1 /* I6 |noun| */
#define MULTI_TOKEN_GTC -2 /* I6 |multi| */
#define MULTIINSIDE_TOKEN_GTC -3 /* I6 |multiinside| */
#define MULTIHELD_TOKEN_GTC -4 /* I6 |multiheld| */
#define HELD_TOKEN_GTC -5 /* I6 |held| */
#define CREATURE_TOKEN_GTC -6 /* I6 |creature| */
#define TOPIC_TOKEN_GTC -7 /* I6 |topic| */
#define MULTIEXCEPT_TOKEN_GTC -8 /* I6 |multiexcept| */
#define GRAMMAR_PUNCTUATION_MARKS ".,:;?!(){}[]/" /* note the slash... */
#define MAX_LENGTH_OF_SCRIPT 10000 /* including length byte, so the max no of chars is one less */
#define MAX_LENGTH_OF_COMMAND 100 /* any single command must be this long or shorter */
#define MAX_POSSESSIONS_PER_SCENARIO 16
#define NO_INTT -2
#define EXTERNAL_INTT -1
#define HEADLINE_INTT 0
#define SENTENCE_INTT 1
#define DESCRIPTION_INTT 2
#define DIMENSIONS_INTT 3
#define EVALUATION_INTT 4
#define EQUATION_INTT 5
#define ARTICLE_INTT 6
#define VERB_INTT 7
#define ADJECTIVE_INTT 8
#define ING_INTT 9
#define KIND_INTT 10
#define MAP_INTT 11
#define DASH_INTT 12
#define DASHLOG_INTT 13
#define THUMBNAIL_WIDTH 80
#define OWNED_BY_THIS_PROJECT 1
#define OWNED_BY_ANOTHER_PROJECT 2
#define OWNED_BY_SPECIFIC_PROJECT 3
#define INVALID_I6TR -1
#define PROPERTY_I6TR 0 /* "The open property translates into I6 as "open"." */
#define NAMETAG_I6TR 1 /* "The north object translates into I6 as "n\_obj"." */
#define RULE_I6TR 2 /* "The baffling rule translates into I6 as "BAFFLING\_R"." */
#define VARIABLE_I6TR 3 /* "The sludge count variable translates into I6 as "sldgc". */
#define ACTION_I6TR 4 /* "The taking action translates into I6 as "Take". */
#define GRAMMAR_TOKEN_I6TR 5 /* "The grammar token "[whatever]" translates into I6 as "WHATEVER". */
#define MAX_I6T_LINE_LENGTH 1024
#define MAX_I6T_COMMAND_LENGTH 128
#define INWEB_PARAGRAPH_SYNTAX 1
#define INWEB_CODE_SYNTAX 2
#define INWEB_DASH_SYNTAX 3
#define INWEB_PURPOSE_SYNTAX 4
#define ALLOW_VALUE(val) \
if (strcmp(argument, #val)==0) { WRITE("%d", val); continue; }
#define ALLOW_CALLV(routine) \
if (strcmp(argument, #routine)==0) {\
routine();\
if ((problem_count > 0) && (closed == FALSE)) active = FALSE;\
continue;\
}
#define ALLOW_CALL(routine) \
if (strcmp(argument, #routine)==0) { routine(OUT); continue; }
#define ALLOW_ARRAY(array) \
if (strcmp(argument, #array)==0) { array##_array(OUT); continue; }
#define ALLOW_ROUTINE(routine) \
if (strcmp(argument, #routine)==0) { routine##_routine(OUT); continue; }
#define MAX_PLUGINS 18
#define CREATE_PLUGIN(P, starter, mem, NA, NA2)\
P = CREATE(plugin);\
P->starter_routine = (void *) (&starter);\
P->now_plugged_in = FALSE;\
P->stores_data = mem;\
P->plugin_name = Plugins__Manage__wording(NA);\
P->plugin_number = NA;\
P->set_name = Plugins__Manage__wording(NA2);\
P->set_number = NA2;\
P->has_template_file = NULL;\
P->IFDEF_symbol = NULL;\
P->has_been_set_explicitly = FALSE;\
registered_plugins[NA] = P;\
if (P->allocation_id >= MAX_PLUGINS) internal_error("Too many plugins");
#define CORE_PLUGIN_NAME 0
#define INTERACTIVE_FICTION_PLUGIN_NAME 1
#define NAMING_PLUGIN_NAME 2
#define INSTANCE_COUNTING_PLUGIN_NAME 3
#define COMMAND_PLUGIN_NAME 4
#define ACTIONS_PLUGIN_NAME 5
#define SPATIAL_MODEL_PLUGIN_NAME 6
#define MAPPING_PLUGIN_NAME 7
#define PLAYER_PLUGIN_NAME 8
#define REGIONS_PLUGIN_NAME 9
#define BACKDROPS_PLUGIN_NAME 10
#define SHOWME_PLUGIN_NAME 11
#define TIMES_OF_DAY_PLUGIN_NAME 12
#define SCENES_PLUGIN_NAME 13
#define FIGURES_PLUGIN_NAME 14
#define SOUNDS_PLUGIN_NAME 15
#define GLULX_EXTERNAL_FILES_PLUGIN_NAME 16
#define BIBLIOGRAPHIC_DATA_PLUGIN_NAME 17
#define PLUGIN_REMOVAL_OFFSET MAX_PLUGINS+1
#define PLUGIN_NEW_VARIABLE_NOTIFY 1
#define PLUGIN_IRREGULAR_GENITIVE 4
#define PLUGIN_SET_KIND_NOTIFY 6
#define PLUGIN_COMPLETE_MODEL 11
#define PLUGIN_PARSE_COMPOSITE_NQS 12
#define PLUGIN_REFINE_IMPLICIT_NOUN 14
#define PLUGIN_ACT_ON_SPECIAL_NPS 15
#define PLUGIN_NEW_PROPERTY_NOTIFY 16
#define PLUGIN_PROPERTY_VALUE_NOTIFY 17
#define PLUGIN_MORE_SPECIFIC 18
#define PLUGIN_INFERENCES_CONTRADICT 19
#define PLUGIN_INTERVENE_IN_ASSERTION 20
#define PLUGIN_LOG_INFERENCE_TYPE 21
#define PLUGIN_COMPILE_OBJECT_HEADER 22
#define PLUGIN_ESTIMATE_PROPERTY_USAGE 23
#define PLUGIN_CHECK_GOING 24
#define PLUGIN_COMPILE_MODEL_TABLES 25
#define PLUGIN_DEFAULT_APPEARANCE 26
#define PLUGIN_NEW_PERMISSION_NOTIFY 27
#define PLUGIN_NAME_TO_EARLY_INFS 28
#define PLUGIN_NEW_BASE_KIND_NOTIFY 29
#define PLUGIN_COMPILE_CONSTANT 30
#define PLUGIN_NEW_INSTANCE_NOTIFY 31
#define PLUGIN_OFFERED_PROPERTY 32
#define PLUGIN_OFFERED_SPECIFICATION 33
#define PLUGIN_TYPECHECK_EQUALITY 34
#define PLUGIN_FORBID_SETTING 35
#define PLUGIN_VARIABLE_SET_WARNING 36
#define PLUGIN_DETECT_BODYSNATCHING 37
#define PLUGIN_NEW_SUBJECT_NOTIFY 38
#define PLUGIN_EXPLAIN_CONTRADICTION 39
#define PLUGIN_ADD_TO_WORLD_INDEX 40
#define PLUGIN_ANNOTATE_IN_WORLD_INDEX 41
#define PLUGIN_SET_SUBKIND_NOTIFY 42
#define MAX_PLUGS 100
#define PLUGINS_CALL(code, args...) {\
plugin_call *pc = plugins_stack[code];\
while (pc) {\
int (*R)() = (int (*)()) pc->routine;\
int Q = (*R)(args);\
if (Q) return Q;\
pc = pc->next;\
}\
return FALSE;\
}
#define PLUGIN_REGISTER(code, R) {\
plugin_call *new = CREATE(plugin_call);\
new->routine = (void *) (&R);\
new->next = NULL;\
if (plugins_stack[code] == NULL) plugins_stack[code] = new;\
else {\
plugin_call *PC = plugins_stack[code];\
while ((PC) && (PC->next)) PC = PC->next;\
PC->next = new;\
}\
}
#line 72 "inform7/Chapter 2/Memory.w"
typedef struct simple_memory_claim {
void *memory_claimed; /* position in memory of the array allocated */
int extent_of_claim; /* total number of bytes making it up */
MEMORY_MANAGEMENT
} simple_memory_claim;
#line 259 "inform7/Chapter 2/Memory.w"
typedef struct allocation_status_structure {
/* actually needed for allocation purposes: */
int objects_allocated; /* total number of objects (or arrays) ever allocated */
void *first_in_memory; /* head of doubly linked list */
void *last_in_memory; /* tail of doubly linked list */
/* used only to provide statistics for the debugging log: */
char *name_of_type; /* e.g., |"lexicon_entry_MT"| */
int bytes_allocated; /* total allocation for this type of object, not counting overhead */
int objects_count; /* total number currently in existence (i.e., undeleted) */
int no_allocated_together; /* number of objects in each array of this type of object */
} allocation_status_structure;
#line 349 "inform7/Chapter 2/Memory.w"
typedef struct memblock_header {
int block_number;
struct memblock_header *next;
char *the_memory;
} memblock_header;
#line 438 "inform7/Chapter 2/Memory.w"
typedef struct memory_frame {
int integrity_check; /* this should always contain the |INTEGRITY_NUMBER| */
struct memory_frame *next_frame; /* next frame in the list of memory frames */
int mem_type; /* type of object stored in this frame */
int allocation_id; /* allocation ID number of object stored in this frame */
} memory_frame;
#line 1152 "inform7/Chapter 2/Memory.w"
typedef struct general_pointer {
void *pointer_to_data;
int run_time_type_code;
} general_pointer;
#line 227 "inform7/Chapter 2/Streams.w"
typedef struct text_stream {
FILE *write_to_file; /* for an open stream, exactly one of these is |NULL| */
char *write_to_memory;
int encoding_to_write_to_file; /* relevant only for file streams */
int use_xml_escapes; /* see above */
int allocated_by_malloc; /* was the |write_to_memory| pointer claimed by |malloc|? */
int chars_written; /* number of characters sent, counting |\n| as 1 */
int chars_capacity; /* maximum number the stream can accept without claiming more resources */
struct text_stream *stream_continues; /* if one memory stream is extended by another */
int indentation_level; /* number of tab stops in from the left margin */
int indentation_pending; /* we have just ended a line, so further text should indent */
unsigned int unicode_buffer[2]; /* relevant mainly for UTF-8 files */
int unicode_buffer_pos;
} text_stream;
#line 110 "inform7/Chapter 2/Debugging Log.w"
typedef struct debugging_aspect {
char *da_word1; /* first word of name */
char *da_word2; /* second word, or |""| if there is none */
char *da_word3; /* third word, or |""| if there is none */
int on_or_off; /* whether or not active when writing to debugging log */
int alternate; /* whether or not active when writing in trace mode */
} debugging_aspect;
#line 44 "inform7/Chapter 3/Pathnames.w"
typedef struct pathname {
char *intermediate;
struct pathname *pathname_of_parent;
int known_to_exist; /* corresponds to a directory in the filing system */
MEMORY_MANAGEMENT
} pathname;
#line 18 "inform7/Chapter 3/Filenames.w"
typedef struct filename {
struct pathname *pathname_of_location;
char *leafname;
MEMORY_MANAGEMENT
} filename;
#line 1058 "inform7/Chapter 4/HTML Files.w"
typedef struct colour_translation {
char *chip_name;
char *html_colour;
} colour_translation;
#line 24 "inform7/Chapter 5/Index File Services.w"
typedef struct index_page {
int no_elements;
char key_colour[7];
char page_title[MAX_FILENAME_LENGTH];
char page_explanation[MAX_FILENAME_LENGTH];
char page_leafname[MAX_FILENAME_LENGTH];
MEMORY_MANAGEMENT
} index_page;
#line 36 "inform7/Chapter 5/Index File Services.w"
typedef struct index_element {
int atomic_number; /* 1, 2, 3, ..., within its page */
char chemical_symbol[3];
char element_name[32];
char explanatory_note[MAX_FILENAME_LENGTH];
struct index_page *owning_page;
MEMORY_MANAGEMENT
} index_element;
#line 32 "inform7/Chapter 5/Documentation References.w"
typedef struct documentation_ref {
int symbol; /* Word number in source where the symbol is */
int section; /* HTML page number */
int used_already; /* Has this been used in a problem message already? */
int usage_count; /* For statistical purposes */
char *fragment_at; /* Pointer to HTML documentation fragment in memory */
int fragment_length; /* Number of bytes of fragment */
int sr_usage_count;
int ext_usage_count;
char *chapter_reference; /* Or |NULL| if no chapter name supplied */
char *section_reference; /* Or |NULL| if no section name supplied */
MEMORY_MANAGEMENT
} documentation_ref;
#line 23 "inform7/Chapter 12/Wordings.w"
typedef struct wording {
int word_A, word_B;
} wording;
#line 18 "inform7/Chapter 7/Word Assemblages.w"
typedef struct word_assemblage {
int no_indiv_words; /* should be between 0 and |MAX_WORDS_IN_ASSEMBLAGE| */
struct vocabulary_entry *indiv_words[MAX_WORDS_IN_ASSEMBLAGE]; /* some may be null */
} word_assemblage;
#line 35 "inform7/Chapter 5/Lexicon Index.w"
typedef struct lexicon_entry {
struct wording wording_of_entry; /* either the text of the entry, or empty, in which case... */
struct word_assemblage text_of_entry;
int part_of_speech; /* one of those above */
char *category; /* textual description of said, e.g., |"adjective"| */
struct general_pointer entry_refers_to; /* depending on which part of speech */
struct parse_node *verb_defined_at; /* sentence where defined (verbs only) */
char *gloss_note; /* gloss on the definition, or |NULL| if none is provided */
char reduced_to_lower_case[32]; /* text converted to lower case for sorting */
struct lexicon_entry *sorted_next; /* next in lexicographic order */
MEMORY_MANAGEMENT
} lexicon_entry;
#line 148 "inform7/Chapter 6/Problems, Level 2.w"
typedef struct problem_quotation {
char quotation_type; /* one of the above */
void *structure_quoted; /* except for S and W, when this is null */
struct wording text_quoted; /* for S and W only */
} problem_quotation;
#line 35 "inform7/Chapter 7/Vocabulary.w"
typedef struct vocabulary_entry {
unsigned int flags; /* bitmap of "meaning codes" indicating possible usages */
int literal_number_value; /* evaluation as a literal number, if any */
struct kind *one_word_kind; /* ditto as a kind with single-word name */
char *exemplar; /* text of one instance of this word */
char *raw_exemplar; /* text of one instance in its raw untreated form */
struct parse_node *start_list; /* meanings starting with this */
struct parse_node *end_list; /* meanings ending with this */
struct parse_node *middle_list; /* meanings with this inside but at neither end */
struct parse_node *subset_list; /* meanings allowing subsets which include this */
int subset_list_length; /* number of meanings in the subset list */
int hash; /* hash code derived from text of word */
struct vocabulary_entry *next_in_vocab_hash; /* next in list with this hash */
struct vocabulary_entry *lower_case_form; /* or null if none exists */
struct vocabulary_entry *upper_case_form; /* or null if none exists */
int nt_incidence; /* bitmap hashing which Preform nonterminals it occurs in */
} vocabulary_entry;
#line 25 "inform7/Chapter 7/Tries and Inflections.w"
typedef struct match_trie {
int match_character; /* or one of the special cases above */
char group_characters[MAX_TRIE_GROUP_SIZE+1];
char *match_outcome;
struct match_trie *on_success;
struct match_trie *next;
} match_trie;
#line 41 "inform7/Chapter 7/Tries and Inflections.w"
typedef struct match_avinue {
struct match_trie *the_trie;
struct match_avinue *next;
} match_avinue;
#line 23 "inform7/Chapter 7/Clusters.w"
typedef struct cluster {
struct individual_name *first_name;
MEMORY_MANAGEMENT
} cluster;
#line 28 "inform7/Chapter 7/Clusters.w"
typedef struct individual_name {
struct wording name; /* text of name */
int name_number; /* 1 for singular, 2 for plural */
int name_gender; /* 1 is neuter, 2 is masculine, 3 is feminine */
struct natural_language *name_language; /* always non-null */
struct excerpt_meaning *principal_meaning; /* main singular excerpt meaning this */
struct individual_name *next; /* within its cluster */
MEMORY_MANAGEMENT
} individual_name;
#line 21 "inform7/Chapter 7/Plurals Dictionary.w"
typedef struct plural_dictionary_entry {
struct wording singular_form; /* words of singular form */
struct wording plural_form; /* words of plural form */
MEMORY_MANAGEMENT
} plural_dictionary_entry;
#line 38 "inform7/Chapter 7/Natural Languages.w"
typedef struct natural_language {
struct pathname *nl_bundle_path; /* pathname of the bundle folder */
struct wording instance_name; /* instance name, e.g., "German language" */
struct instance *nl_instance; /* instance, e.g., "German language" */
struct wording language_field[MAX_LANGUAGE_FIELDS]; /* contents of the |about.txt| fields */
int extension_required; /* do we need to Include the extension for this language? */
int adaptive_person; /* which person (one of constants below) text subs are written from */
MEMORY_MANAGEMENT
} natural_language;
#line 348 "inform7/Chapter 7/Preform.w"
typedef struct range_requirement {
int no_requirements;
int ditto_flag;
int DW_req;
int DS_req;
int CW_req;
int CS_req;
int FW_req;
int FS_req;
} range_requirement;
#line 148 "inform7/Chapter 7/Preform.w"
typedef struct nonterminal {
struct vocabulary_entry *nonterminal_id; /* e.g. |"<cardinal-number>"| */
int voracious; /* if true, scans whole rest of word range */
int multiplicitous;
int marked_internal; /* has, or will be given, an internal definition... */
int (*internal_definition)(wording W, int *result, void **result_p); /* ...this one */
struct production_list *first_production_list; /* if not internal, this defines it */
int (*result_compositor)(int *r, void **rp, int *inters, void **inter_ps, wording W);
struct wording range_result[MAX_RANGES_PER_PRODUCTION]; /* storage for word ranges matched */
int optimised_in_this_pass; /* have the following been worked out yet? */
int min_nt_words, max_nt_words; /* for speed */
struct range_requirement nonterminal_req;
int nt_req_bit; /* which hashing category the words belong to, or $-1$ if none */
int number_words_by_production;
unsigned int flag_words_in_production;
int watched; /* watch goings-on to the debugging log */
int nonterminal_tries; /* used only in instrumented mode */
int nonterminal_matches; /* ditto */
MEMORY_MANAGEMENT
} nonterminal;
#line 181 "inform7/Chapter 7/Preform.w"
typedef struct production_list {
struct natural_language *definition_language;
struct production *first_production;
struct production_list *next_production_list;
struct match_avinue *as_avinue; /* when compiled to a trie rather than for Preform */
MEMORY_MANAGEMENT
} production_list;
#line 229 "inform7/Chapter 7/Preform.w"
typedef struct production {
struct ptoken *first_ptoken; /* the linked list of ptokens */
int match_number; /* 0 for |/a/|, 1 for |/b/| and so on */
int no_ranges; /* actually one more, since range 0 is reserved (see above) */
int min_pr_words, max_pr_words; /* for speed */
struct range_requirement production_req;
int no_struts; /* the actual number, this time */
struct ptoken *struts[MAX_STRUTS_PER_PRODUCTION]; /* first ptoken in strut */
int strut_lengths[MAX_STRUTS_PER_PRODUCTION]; /* length of the strut in words */
int production_tries; /* used only in instrumented mode */
int production_matches; /* ditto */
struct parse_node *sample_sentence; /* ditto */
struct wording sample_text; /* ditto */
struct production *next_production; /* within its production list */
MEMORY_MANAGEMENT
} production;
#line 283 "inform7/Chapter 7/Preform.w"
typedef struct ptoken {
int ptoken_category; /* one of the |*_PTC| values */
int negated_ptoken; /* the |^| modifier applies */
int disallow_unexpected_upper; /* the |_| modifier applies */
struct nonterminal *nt_pt; /* for |NONTERMINAL_PTC| ptokens */
struct vocabulary_entry *ve_pt; /* for |FIXED_WORD_PTC| ptokens */
struct ptoken *alternative_ptoken; /* linked list of other vocabulary ptokens */
int balanced_wildcard; /* for |MULTIPLE_WILDCARD_PTC| ptokens: brackets balanced? */
int result_index; /* for |NONTERMINAL_PTC| ptokens: what result number, counting from 1? */
int range_starts; /* 1, 2, 3, ... if word range 1, 2, 3, ... starts with this */
int range_ends; /* 1, 2, 3, ... if word range 1, 2, 3, ... ends with this */
int ptoken_position; /* fixed position in range: 1, 2, ... for left, $-1$, $-2$, ... for right */
int strut_number; /* if this is part of a strut, what number? or $-1$ if not */
int ptoken_is_fast; /* can be checked in the fast pass of the parser */
struct range_requirement token_req;
struct ptoken *next_ptoken; /* within its production list */
MEMORY_MANAGEMENT
} ptoken;
#line 60 "inform7/Chapter 7/Non-Parsing Preform.w"
typedef struct verb_tabulation {
struct word_assemblage to_be_auxiliary; /* use this if non-empty */
struct word_assemblage vc_text[NO_KNOWN_TENSES][2][6];
int modal_auxiliary_usage[NO_KNOWN_TENSES][2][6];
} verb_tabulation;
#line 46 "inform7/Chapter 7/Non-Parsing Preform.w"
typedef struct verb_conjugation {
struct word_assemblage infinitive; /* not counting the "to", in English */
struct word_assemblage past_participle;
struct word_assemblage present_participle;
struct verb_tabulation active_tabulation;
struct verb_tabulation passive_tabulation;
struct natural_language *defined_in;
struct binary_predicate *vc_meaning; /* the BP is the root meaning of the verb */
struct parse_node *where_vc_created;
int auxiliary_only; /* used only as an auxiliary, e.g. the "have" in "I have gone" */
int instance_of_verb; /* defines an instance of kind "verb" at run-time */
MEMORY_MANAGEMENT
} verb_conjugation;
#line 52 "inform7/Chapter 8/Determiners and Quantifiers.w"
typedef struct quantifier {
char *operator; /* I6 operator to compare successes against the threshold */
int T_coefficient; /* see above */
int is_complementary; /* tests the complement of the set, not the set of matches */
int can_be_used_in_now; /* can be asserted true or false using "now" */
int can_be_used_in_assertions; /* can be used in assertion sentences */
struct quantifier *negated_quant; /* the logically converse determiner */
char *log_text; /* to be used in the debugging log when logging propositions */
MEMORY_MANAGEMENT
} quantifier;
#line 94 "inform7/Chapter 8/Determiners and Quantifiers.w"
typedef struct determiner {
int allows_prefixed_not; /* can the word "not" come before this? */
struct word_assemblage text_of_det; /* which is allowed to be empty */
int takes_number; /* does a number follow? (e.g. for "at least N" */
struct quantifier *quantifier_meant; /* meaning of this quantifier */
char *index_text; /* used in the Phrasebook index lexicon */
MEMORY_MANAGEMENT
} determiner;
#line 28 "inform7/Chapter 8/Time Periods.w"
typedef struct time_period {
int valid_tp; /* flag distinguishing validly and invalidly parsed periods */
int units; /* one of the two above */
int length; /* the duration or else the lower limit of an interval */
int until; /* |-1| or else the upper limit of an interval */
char *inform6_operator; /* |<=|, |==|, |>|, and so forth */
int tense; /* one of the four above */
} time_period;
#line 49 "inform7/Chapter 9/Adjectives.w"
typedef struct adjectival_phrase {
struct cluster *adjective_names;
struct adjective_meaning *possible_meanings; /* list of definitions in order given */
struct adjective_meaning *sorted_meanings; /* the same list sorted into logical order */
MEMORY_MANAGEMENT
} adjectival_phrase;
#line 63 "inform7/Chapter 18/I6 Schemas.w"
typedef struct i6_schema {
char prototype[MAX_I6_SCHEMA_LENGTH];
} i6_schema;
#line 38 "inform7/Chapter 9/Adjective Meanings.w"
typedef struct adjective_meaning {
struct wording adjective_index_text; /* text to use in the Phrasebook index */
struct parse_node *defined_at; /* from what sentence this came (if it did) */
struct adjectival_phrase *owning_adjective; /* of which this is a definition */
struct adjective_meaning *next_meaning; /* next in order of definition */
struct adjective_meaning *next_sorted; /* next in logically sorted order */
struct wording domain_text; /* domain to which defn applies */
struct inference_subject *domain_infs; /* what domain the defn applies to */
int setting_domain; /* are we currently working this out? */
struct kind *domain_kind; /* what kind of values */
int problems_thrown; /* complaining about the domain of this adjective */
int meaning_parity; /* meaning understood positively? */
struct adjective_meaning *am_negated_from; /* if explicitly constructed as such */
int adjective_form; /* one of the |*_KADJ| constants: see below */
general_pointer detailed_meaning; /* to the relevant structure */
int task_via_support_routine[NO_ADJECTIVE_TASKS + 1];
struct i6_schema i6s_to_transfer_to_SR[NO_ADJECTIVE_TASKS + 1]; /* where |TRUE| */
struct i6_schema i6s_for_runtime_task[NO_ADJECTIVE_TASKS + 1]; /* where |TRUE| */
int am_ready_flag; /* optional flag to mark whether schemas prepared yet */
int defined_already; /* temporary workspace used when compiling support routines */
MEMORY_MANAGEMENT
} adjective_meaning;
#line 15 "inform7/Chapter 9/Adjective Usages.w"
typedef struct adjective_usage {
adjectival_phrase *ref_to;
int ref_positive; /* used positively? */
} adjective_usage;
#line 107 "inform7/Chapter 10/Literal Patterns.w"
typedef struct literal_pattern_token {
int new_word_at; /* does token start a new word? */
int lpt_type; /* one of the three constants defined above */
char token_char; /* |CHARACTER_LPT| only; the character to match */
int token_wn; /* |WORD_LPT| only; word number in source text of the prototype */
} literal_pattern_token;
#line 135 "inform7/Chapter 10/Literal Patterns.w"
typedef struct literal_pattern_element {
int element_index; /* the value $i$ placing this within its LP, where $0\leq i<n$ */
int element_range; /* the value $r_i$ for this LP */
int element_multiplier; /* the value $m_i$ for this LP */
struct wording element_name; /* if we define a name for the element */
int is_real; /* store as a real number, not an integer? */
int without_leading_zeros; /* normally without? */
int element_optional; /* can we truncate the LP here? */
int preamble_optional; /* if so, can we lose the preamble as well? */
} literal_pattern_element;
#line 61 "inform7/Chapter 19/Scaled Arithmetic Values.w"
typedef struct scaling_transformation {
int use_integer_scaling; /* or if not, use real */
int int_O; /* the $O$ value described above, if integers used */
int int_M; /* the $M$ value described above */
double real_O; /* the $O$ value described above, if real numbers used */
double real_M; /* the $M$ value described above */
/* used only in the definition process */
int scaling_mode; /* one of the |LP_SCALED_*| constants */
int int_scalar; /* whichever of these is relevant according to the integer/real mode */
double real_scalar;
} scaling_transformation;
#line 65 "inform7/Chapter 10/Literal Patterns.w"
typedef struct literal_pattern {
struct kind *kind_specified; /* the kind of the result: i.e., what it specifies */
struct literal_pattern *next_for_this_kind; /* continuing list for this kind */
struct wording prototype_text; /* where the prototype specification is */
int no_lp_tokens; /* number of tokens in parse_node */
struct literal_pattern_token lp_tokens[MAX_TOKENS_PER_LITERAL];
int no_lp_elements; /* how many tokens are numbers */
struct literal_pattern_element lp_elements[MAX_ELEMENTS_PER_LITERAL];
int number_signed; /* for instance -10 cm would be allowed if this is set */
/* used when we have a sequence of alternative notations for the same unit */
int primary_alternative; /* first of a set of alternatives? */
struct literal_pattern *next_alternative_lp; /* continuing list of alternatives */
int singular_form_only; /* print using this notation only for 1 unit */
int plural_form_only; /* print using this notation for 2 units, 0.5 units, etc. */
/* used when printing and calculating values */
struct scaling_transformation scaling; /* how to convert apparent to actual values */
int equivalent_unit; /* is this just an equivalent to another LP? */
int benchmark; /* is this the benchmark LP for its kind? */
int last_resort; /* is this the last possible LP to use when printing a value of the kind? */
int marked_for_printing; /* used in compiling printing routines */
MEMORY_MANAGEMENT
} literal_pattern;
#line 163 "inform7/Chapter 10/Literal Patterns.w"
typedef struct literal_pattern_name {
struct wording notation_name; /* name for this notation, if any; e.g. "in centimetres" */
struct literal_pattern *can_use_this_lp; /* list of LPs used under this name */
struct literal_pattern_name *next; /* other names for the same kind */
struct literal_pattern_name *next_with_rp; /* used in parsing only: list applied to one notation */
int lpn_compiled_already;
MEMORY_MANAGEMENT
} literal_pattern_name;
#line 62 "inform7/Chapter 10/Excerpt Meanings.w"
typedef struct excerpt_meaning {
unsigned int meaning_code; /* what kind of meaning: a single MC, not a bitmap */
struct general_pointer data; /* data structure being referred to */
int no_em_tokens; /* length of token list */
struct vocabulary_entry *em_tokens[MAX_TOKENS_PER_EXCERPT_MEANING]; /* token list */
int excerpt_hash; /* hash code generated from the token list */
int registered_as_noun;
MEMORY_MANAGEMENT
} excerpt_meaning;
#line 170 "inform7/Chapter 13/Headings.w"
typedef struct name_resolution_data {
int heading_count; /* used when tallying up objects under their headings */
struct nametag *next_under_heading; /* next in the list under that */
int search_score; /* used when searching nametags to parse names */
struct nametag *next_to_search; /* similarly */
} name_resolution_data;
#line 41 "inform7/Chapter 10/Nametags.w"
typedef struct nametag {
struct cluster *names;
char nt_I6_identifier[32]; /* Name to be used in Inform 6 output */
struct name_resolution_data name_resolution; /* see the Headings section on this */
struct general_pointer tagged_to;
int search_priority; /* in the range 1 up to |MAX_NAMETAG_PRIORITY| */
int match_exactly; /* do not allow subset parsing matches, e.g., "bottle" for "glass bottle" */
int range_number; /* used to enumerate */
unsigned int registration_category;
struct general_pointer registration_to;
MEMORY_MANAGEMENT
} nametag;
#line 33 "inform7/Chapter 10/Instances.w"
typedef struct instance {
struct nametag *tag;
struct parse_node *creating_sentence; /* sentence creating the instance */
struct parse_node *instance_of_set_at; /* and identifying its kind */
struct inference_subject *as_subject;
int enumeration_index; /* within each kind, named constants are counted from 1 */
struct general_pointer connection; /* to the data structure for a constant of a kind significant to Inform */
struct adjectival_phrase *usage_as_aph; /* if this is a noun used adjectivally, like "red" */
int index_appearances; /* how many times have I appeared thus far in the World index? */
struct instance_usage *first_noted_usage;
struct instance_usage *last_noted_usage;
MEMORY_MANAGEMENT
} instance;
#line 52 "inform7/Chapter 10/Instances.w"
typedef struct instance_usage {
struct parse_node *where_instance_used;
struct instance_usage *next;
} instance_usage;
#line 19 "inform7/Chapter 10/Nonlocal Variables.w"
typedef struct nonlocal_variable {
struct wording name; /* text of the name */
struct parse_node *nlv_created_at; /* sentence creating the variable */
struct wording var_documentation_symbol; /* reference to manual, if any */
struct stacked_variable *scope; /* where it exists, or |NULL| for everywhere */
struct kind *nlv_kind; /* what kind of value it holds */
struct inference_subject *nlv_knowledge; /* what we know about its initial value */
int constant_at_run_time; /* for instance, for "story title" */
struct inference_subject *alias_to_infs; /* like "player" to "yourself" */
int position_in_variables_array; /* or negative if stored elsewhere */
int var_is_initialisable_anyway; /* despite being stored elsewhere, that is */
int var_is_bibliographic; /* one of the bibliographic constants set at the end */
int nlv_name_translated; /* has this been given storage as an I6 variable? */
char nlv_as_rvalue[32], nlv_as_lvalue[32]; /* I6 forms to use in compiled code */
char *nlv_write_schema; /* or |NULL| to assign to the L-value form */
int substitution_marker; /* to prevent infinite regress when substituting */
MEMORY_MANAGEMENT
} nonlocal_variable;
#line 132 "inform7/Chapter 11/Binary Predicates.w"
typedef struct bp_term_details {
struct wording called_name; /* "(called...)" name, if any exists */
struct inference_subject *implies_infs; /* the domain of values allowed */
struct kind *implies_kind; /* the kind of these values */
struct i6_schema *function_of_other; /* the function $f_0$ or $f_1$ as above */
char *index_term_as; /* usually null, but if not, used in Phrasebook index */
} bp_term_details;
#line 199 "inform7/Chapter 11/Binary Predicates.w"
typedef struct binary_predicate {
int relation_family; /* one of the |*_KBP| constants defined below */
int form_of_relation; /* one of the |Relation_*| constants defined below */
struct word_assemblage relation_name; /* (which might have length 0) */
struct parse_node *bp_created_at; /* where declared in the source text */
char debugging_log_name[MAX_WORD_LENGTH+10]; /* used when printing propositions to the debug log */
struct bp_term_details term_details[2]; /* term 0 is the left term, 1 is the right */
struct binary_predicate *reversal; /* the $R$ such that $R(x,y)$ iff $B(y,x)$ */
int right_way_round; /* was this BP created directly? or is it a reversal of another? */
/* how to compile code which tests or forces this BP to be true or false: */
struct i6_schema *test_function; /* I6 schema for (a) testing $B(x, y)$... */
struct wording condition_defn_text; /* ...unless this I7 condition is used instead */
struct i6_schema *make_true_function; /* I6 schema for (b) "now $B(x, y)$" */
struct i6_schema *make_false_function; /* I6 schema for (c) "now ${\rm not}(B(x, y))$" */
/* for use in the A-parser: */
int arbitrary; /* allow source to assert $B(x, y)$ for any arbitrary pairs $x, y$ */
struct property *set_property; /* asserting $B(x, v)$ sets this prop. of $x$ to $v$ */
struct wording property_pending_text; /* temp. version used until props created */
int relates_values_not_objects; /* true if either term is necessarily a value... */
struct inference_subject *knowledge_about_bp; /* ...and if so, here's the list of known assertions */
/* for optimisation of run-time code: */
int dynamic_memory; /* stored in dynamically allocated memory */
struct property *i6_storage_property; /* provides run-time storage */
struct kind *storage_kind; /* kind of property owner */
int allow_function_simplification; /* allow Inform to make use of any $f_i$ functions? */
int fast_route_finding; /* use fast rather than slow route-finding algorithm? */
char *loop_parent_optimisation_proviso; /* if not NULL, optimise loops using object tree */
char *loop_parent_optimisation_ranger; /* if not NULL, routine iterating through contents */
int record_needed; /* we need to compile a small array of details in readable memory */
/* details, filled in for right-way-round BPs only, for particular kinds of BP: */
int a_listed_in_predicate; /* (if right way) was this generated from a table column? */
struct property *same_property; /* (if right way) if a "same property as..." */
struct property *comparative_property; /* (if right way) if a comparative adjective */
int comparison_sign; /* ...and |+1| or |-1| according to sign of definition */
int *equivalence_partition; /* (if right way) partition array of equivalence classes */
MEMORY_MANAGEMENT
} binary_predicate;
#line 19 "inform7/Chapter 11/Relations.w"
typedef struct relation_guard {
struct binary_predicate *guarding; /* which one is being defended */
struct kind *check_L; /* or null if no check needed */
struct kind *check_R; /* or null if no check needed */
struct i6_schema *inner_test; /* schemas for the relation if check passes */
struct i6_schema *inner_make_true;
struct i6_schema *inner_make_false;
struct i6_schema *f0; /* schemas for the relation's function */
struct i6_schema *f1;
MEMORY_MANAGEMENT
} relation_guard;
#line 25 "inform7/Chapter 11/Conjugation of Verbs.w"
typedef struct verb_usage {
struct word_assemblage vu_text;
int negated_form_of_verb; /* is this a negated form? */
int tensed; /* one of the four tense values */
struct binary_predicate *vu_meaning; /* the BP is the root meaning of the verb */
struct lexicon_entry *vu_lex_entry; /* for use when indexing */
struct parse_node *where_vu_created; /* for use if problem messages needed */
struct verb_conjugation *conjugated_from;
struct verb_usage *next_in_search_list;
int vu_allow_unexpected_upper_case; /* for verbs like "to Hoover" */
MEMORY_MANAGEMENT
} verb_usage;
#line 25 "inform7/Chapter 11/Prepositions.w"
typedef struct preposition_usage {
struct word_assemblage pu_text;
int player_implied; /* for prepositions used adjectivally */
struct property *is_same_property_as; /* for "is the same P as" preps */
struct binary_predicate *pu_meaning; /* again, the root meaning */
struct lexicon_entry *pu_lex_entry; /* for use when indexing */
struct parse_node *where_pu_created; /* for use if problem messages needed */
int negated_sense; /* if the sense of the sentence is implicitly negated */
int allow_unexpected_upper_case; /* for preps like "in Cahoots With" */
MEMORY_MANAGEMENT
} preposition_usage;
#line 41 "inform7/Chapter 12/Lexer.w"
typedef struct source_location {
struct source_file *file_of_origin; /* or |NULL| if internally written and not from a file */
int line_number; /* counting upwards from 1 within file (if any) */
} source_location;
#line 199 "inform7/Chapter 12/Lexer.w"
typedef struct lexer_details {
char *lw_text; /* text of word after treatment to normalise */
char *lw_rawtext; /* original untouched text of word */
struct source_location lw_source; /* where it was read from */
char lw_break; /* the divider (space, tab, etc.) preceding it */
struct vocabulary_entry *lw_identity; /* which distinct word */
} lexer_details;
#line 39 "inform7/Chapter 12/Read Source Text.w"
typedef struct source_file {
struct filename *name;
int words_of_source; /* word count, omitting comments and verbatim matter */
int last_lexed_word; /* number of final word lexed */
int words_of_quoted_text; /* word count for text in double-quotes */
FILE *handle; /* file handle while open */
struct extension_file *extension_provided; /* meets this extension request */
MEMORY_MANAGEMENT
} source_file;
#line 195 "inform7/Chapter 13/Parse Tree.w"
typedef struct parse_node {
struct wording text_parsed; /* the text being interpreted by this node */
node_type_t node_type; /* what the node basically represents */
struct parse_node_annotation *annotations; /* linked list of miscellaneous annotations */
struct parse_node *down; /* pointers within the current interpretation */
struct parse_node *next;
int score; /* used to choose most likely interpretation */
struct parse_node *next_alternative; /* fork to alternative interpretation */
int log_time; /* used purely as a defensive measure when writing debugging log */
MEMORY_MANAGEMENT
} parse_node;
#line 230 "inform7/Chapter 13/Parse Tree.w"
typedef struct parse_node_annotation {
int kind_of_annotation;
int annotation_integer;
general_pointer annotation_pointer;
struct parse_node_annotation *next_annotation;
} parse_node_annotation;
#line 437 "inform7/Chapter 13/Parse Tree.w"
typedef struct parse_tree_node_type {
node_type_t identity;
char *node_type_name; /* text of name of type, such as |"INVOCATION_LIST_NT"| */
int min_children; /* minimum legal number of child nodes */
int max_children; /* maximum legal number of child nodes */
int category; /* one of the |*_NCAT| values below */
int node_flags; /* bitmap of node flags */
} parse_tree_node_type;
#line 23 "inform7/Chapter 14/Extension Identifiers.w"
typedef struct extension_identifier {
char author_name[MAX_EXTENSION_AUTHOR_LENGTH];
char raw_author_name[MAX_EXTENSION_AUTHOR_LENGTH];
char title[MAX_EXTENSION_TITLE_LENGTH];
char raw_title[MAX_EXTENSION_TITLE_LENGTH];
int extension_id_hash_code; /* hash code derived from the above */
} extension_identifier;
#line 56 "inform7/Chapter 13/Headings.w"
typedef struct heading {
struct parse_node *sentence_declaring; /* if any: file starts are undeclared */
struct source_location start_location; /* first word under this heading is here */
int level; /* 0 for Volume (highest) to 5 for Section (lowest) */
int indentation; /* in a hierarchical listing */
int index_definitions_made_under_this; /* for instance, global variables made here? */
int for_release; /* include this material in a release version? */
int omit_material; /* if set, simply ignore all of this */
int use_with_or_without; /* if TRUE, use with the extension; if FALSE, without */
struct extension_identifier for_use_with; /* e.g. "for use with ... by ..." */
struct wording in_place_of_text; /* e.g. "in place of ... in ... by ..." */
struct nametag *list_of_contents; /* tagged names defined under this */
struct nametag *last_in_list_of_contents;
struct heading *parent_heading;
struct heading *child_heading;
struct heading *next_heading;
MEMORY_MANAGEMENT
} heading;
#line 180 "inform7/Chapter 13/Headings.w"
typedef struct contents_entry {
struct heading *heading_entered;
struct contents_entry *next;
MEMORY_MANAGEMENT
} contents_entry;
#line 30 "inform7/Chapter 13/Rule Subtrees.w"
typedef struct control_structure_phrase {
struct control_structure_phrase *subordinate_to;
int indent_subblocks;
int body_empty_except_for_subordinates;
int used_at_stage;
int is_a_loop;
int requires_new_syntax;
int allow_run_on;
char *keyword;
MEMORY_MANAGEMENT
} control_structure_phrase;
#line 160 "inform7/Chapter 14/Extension Files.w"
typedef struct extension_file {
struct extension_identifier ef_id; /* Texts of title and author with hash code */
struct wording author_text; /* Author's name */
struct wording title_text; /* Extension name */
struct wording body_text; /* Body of source text supplied in extension, if any */
int body_text_unbroken; /* Does this contain text waiting to be sentence-broken? */
struct wording documentation_text; /* Documentation supplied in extension, if any */
struct wording VM_restriction_text; /* Restricting use to certain VMs */
int min_version_needed; /* As stipulated by source */
int version_loaded; /* As actually loaded */
int loaded_from_built_in_area; /* Located within Inform application */
int authorial_modesty; /* Do not credit in the compiled game */
struct parse_node *inclusion_sentence; /* Where the source called for this */
struct source_file *read_into_file; /* Which source file loaded this */
char rubric_as_lexed[MAX_RUBRIC_LENGTH+1];
char extra_credit_as_lexed[MAX_RUBRIC_LENGTH+1];
MEMORY_MANAGEMENT
} extension_file;
#line 46 "inform7/Chapter 14/Extension Identifiers.w"
typedef struct extension_identifier_database_entry {
struct extension_identifier *eide_id;
struct extension_identifier_database_entry *hash_next; /* next one in hashed EID database */
int incidence_count[NO_EIDB_CONTEXTS];
char last_usage_date[64];
char sort_usage_date[64];
char word_count_text[64];
} extension_identifier_database_entry;
#line 22 "inform7/Chapter 14/Extension Census.w"
typedef struct extension_census_datum {
struct extension_identifier ecd_id; /* title, author, hash code */
char version_text[MAX_VERSION_NUMBER_LENGTH+1]; /* such as |23| or |14/060527| */
char VM_requirement[512]; /* such as "(for Z-machine only)" */
int built_in; /* found in the Inform 7 application's private stock */
int project_specific; /* found in the Materials folder for the current project */
int overriding_a_built_in_extension; /* not built in, but overriding one which is */
pathname *domain; /* pathname of the stock in which this was found */
char rubric[MAX_RUBRIC_LENGTH+1]; /* brief description found in opening lines */
struct extension_census_datum *next; /* next one in lexicographic order */
MEMORY_MANAGEMENT
} extension_census_datum;
#line 29 "inform7/Chapter 14/Extension Dictionary.w"
typedef struct extension_dictionary_entry {
struct extension_identifier ede_id; /* author name and title, with hash code */
char entry_text[MAX_ED_HEADWORD_LENGTH]; /* text of the dictionary entry */
char sorting[MAX_ED_HEADWORD_LENGTH + 10]; /* text reprocessed for sorting purposes */
char type[MAX_ED_CATEGORY_LENGTH]; /* grammatical category, such as "kind" */
int erased; /* marked to be erased */
struct extension_dictionary_entry *next_in_sorted_dictionary; /* link in linked list */
MEMORY_MANAGEMENT
} extension_dictionary_entry;
#line 52 "inform7/Chapter 14/Extension Dictionary.w"
typedef struct known_extension_clash {
int first_known; /* heads a linked list of clashes with a given |ede1| */
struct known_extension_clash *next; /* next in linked list of clashes */
struct extension_dictionary_entry *leftx; /* clash is between this entry... */
struct extension_dictionary_entry *rightx; /* ...and this one */
int number_clashes; /* number of entries clashing between |ede1| and |ede2| */
MEMORY_MANAGEMENT
} known_extension_clash;
#line 53 "inform7/Chapter 15/Traverse for Assertions.w"
typedef struct sentence_handler {
node_type_t sentence_node_type; /* usually but not always |SENTENCE_NT| */
int verb_type; /* for those which are indeed |SENTENCE_NT| */
int handle_on_traverse; /* 1 or 2 to restrict to that pass, or 0 for both */
void (*handling_routine)(struct parse_node *PN); /* or NULL not to handle */
} sentence_handler;
#line 42 "inform7/Chapter 15/Make Assertions.w"
typedef struct matrix_entry {
node_type_t row_node_type;
int cases[ASSERTION_MATRIX_DIM];
} matrix_entry;
#line 39 "inform7/Chapter 15/Assemblies.w"
typedef struct generalisation {
struct parse_node *look_for; /* prototype situation to look for */
struct parse_node *what_to_make; /* subtree for what to assemble */
struct parse_node *substitute_at; /* position under |look_for| of the EVERY node */
struct generalisation *next; /* next in list of generalisations about kind */
MEMORY_MANAGEMENT
} generalisation;
#line 53 "inform7/Chapter 15/Assemblies.w"
typedef struct application {
struct inference_subject *generalisation_owner;
struct generalisation *latest_applied;
struct application *next;
} application;
#line 63 "inform7/Chapter 15/Assemblies.w"
typedef struct assemblies_data {
struct generalisation *generalisation_list; /* kinds only: assembly instructions, if any */
struct application *applications_so_far; /* instances only: progress */
struct inference_subject *named_after; /* name derived from another: e.g. "Jane's nose" */
struct wording named_after_text; /* text of the derived part, e.g. "nose" */
} assemblies_data;
#line 22 "inform7/Chapter 15/Implications.w"
typedef struct implication {
struct pcalc_prop *if_spec; /* which objects are affected */
struct parse_node *then_pn; /* what assertion is implied about them */
int implied_likelihood; /* with what certainty level */
struct implication *next_implication; /* in list of implications */
MEMORY_MANAGEMENT
} implication;
#line 33 "inform7/Chapter 15/Implications.w"
typedef struct possession_marker {
int possessed; /* temporary use when checking implications about objects */
int possession_certainty; /* ditto */
} possession_marker;
#line 196 "inform7/Chapter 16/Architecture of the S-Parser.w"
typedef struct expression_cache_entry {
struct wording cached_query; /* the word range whose parsing this is */
struct parse_node *cached_result; /* and the result (quite possibly |UNKNOWN_VNT|) */
} expression_cache_entry;
#line 190 "inform7/Chapter 16/Architecture of the S-Parser.w"
typedef struct expression_cache {
struct expression_cache_entry pe_cache[MAXIMUM_CACHE_SIZE];
int pe_cache_size; /* number of entries used, 0 to |MAXIMUM_CACHE_SIZE| */
int pe_cache_posn; /* next write position, 0 to |pe_cache_size| minus 1 */
} expression_cache;
#line 38 "inform7/Chapter 17/Terms.w"
typedef struct pcalc_term {
int variable; /* 0 to 25, or |-1| for "not a variable" */
struct parse_node *constant; /* or |NULL| for "not a constant" */
struct pcalc_func *function; /* or |NULL| for "not a function of another term" */
int cinder; /* complicated, this: used to worry about scope of I6 local variables */
struct kind *term_checked_as_kind; /* or |NULL| if unchecked */
} pcalc_term;
#line 62 "inform7/Chapter 17/Terms.w"
typedef struct pcalc_func {
struct binary_predicate *bp; /* the predicate $B$ such that this is $f_B(t)$ */
struct pcalc_term fn_of; /* the term $t$ such that this is $f_B(t)$ */
int from_term; /* whether $t$ is term 0 or 1 of $B$ */
} pcalc_func;
#line 25 "inform7/Chapter 17/Atomic Propositions.w"
typedef struct pcalc_prop {
int element; /* one of the constants below: always 1 or greater */
int arity; /* 1 for quantifiers and unary predicates; 2 for BPs; 0 otherwise */
struct general_pointer predicate; /* usually indicates which predicate structure is meant */
struct pcalc_term terms[MAX_ATOM_ARITY]; /* terms to which the predicate applies */
struct kind *assert_kind; /* |KIND_ATOM|: the kind of value of a variable */
int composited; /* |KIND_ATOM|: arises from a composite determiner/noun like "somewhere" */
int unarticled; /* |KIND_ATOM|: arises from an unarticled usage like "vehicle", not "a vehicle" */
struct wording calling_name; /* |CALLED_ATOM|: text of the name this is called */
int quantification_parameter; /* |QUANTIFIER_ATOM|: e.g., the 3 in "all three" */
struct pcalc_prop *next; /* next atom in the list for this proposition */
} pcalc_prop;
#line 27 "inform7/Chapter 17/Type Check Propositions.w"
typedef struct variable_type_assignment {
struct kind *assigned_kinds[26]; /* one for each of the 26 variables */
} variable_type_assignment;
#line 34 "inform7/Chapter 17/Type Check Propositions.w"
typedef struct tc_problem_kit {
int issue_error;
struct wording ew_text;
char *intention;
int log_to_I6_text;
int flag_problem;
} tc_problem_kit;
#line 22 "inform7/Chapter 18/Compile Atoms.w"
typedef struct annotated_i6_schema {
struct i6_schema *schema;
int negate_schema; /* true if atom is to be tested with the opposite parity */
struct pcalc_term pt0; /* terms on which the I6 schema is to be expanded */
struct pcalc_term pt1;
int involves_action_variables;
} annotated_i6_schema;
#line 33 "inform7/Chapter 18/Deciding to Defer.w"
typedef struct pcalc_prop_deferral {
int reason; /* what we intend to do with it: one of the reasons above */
struct pcalc_prop *proposition_to_defer; /* the proposition */
struct parse_node *deferred_from; /* remember where it came from, for Problem reports */
struct general_pointer defn_ref; /* sometimes we must remember other things too */
struct kind *cinder_kinds[16]; /* the kinds of value being cindered (see below) */
int rtp_constant_needed; /* compile a string of the origin text for run-time problems? */
MEMORY_MANAGEMENT
} pcalc_prop_deferral;
#line 259 "inform7/Chapter 19/Kinds.w"
typedef struct kind {
struct kind_constructor *construct; /* which can never be |NULL| */
int kind_variable_number; /* only used if construct is |CON_KIND_VARIABLE| */
struct unit_sequence *intermediate_result; /* only used if construct is |CON_INTERMEDIATE| */
struct kind *kc_args[MAX_KIND_CONSTRUCTION_ARITY]; /* used if arity positive, or for |CON_KIND_VARIABLE| */
} kind;
#line 100 "inform7/Chapter 19/Kind Checking.w"
typedef struct kind_variable_declaration {
int kv_number; /* must be from 1 to 26 */
struct kind *kv_value; /* must be a definite non-|NULL| kind */
struct kind_variable_declaration *next;
MEMORY_MANAGEMENT
} kind_variable_declaration;
#line 65 "inform7/Chapter 19/Dimensions.w"
typedef struct dimensional_rules {
struct dimensional_rule *multiplications;
} dimensional_rules;
#line 176 "inform7/Chapter 19/Dimensions.w"
typedef struct unit_pair {
struct kind *fund_unit; /* and this really must be a fundamental kind */
int power; /* a non-zero integer */
} unit_pair;
#line 191 "inform7/Chapter 19/Dimensions.w"
typedef struct unit_sequence {
int no_unit_pairs; /* in range 0 to |MAX_BASE_UNITS_IN_SEQUENCE| */
struct unit_pair unit_pairs[MAX_BASE_UNITS_IN_SEQUENCE];
int scaling_factor; /* see discussion of scaling below */
} unit_sequence;
#line 34 "inform7/Chapter 19/Kind Constructors.w"
typedef struct kind_constructor {
struct nametag *dt_tag; /* text of name */
int group; /* one of the four values above */
/* A: how this came into being */
int defined_in_source_text; /* rather than by I6 template files, i.e., by being built-in */
int is_incompletely_defined; /* newly defined and ambiguous as yet */
struct parse_node *where_defined_in_source_text; /* if so */
struct kind *stored_as; /* currently unused: if this is a typedef for some construction */
/* B: constructing kinds */
int constructor_arity; /* 0 for base, 1 for unary, 2 for binary */
int variance[MAX_KIND_CONSTRUCTION_ARITY]; /* must be |COVARIANT| or |CONTRAVARIANT| */
int tupling[MAX_KIND_CONSTRUCTION_ARITY]; /* extent to which tupling is permitted */
struct kind *cached_kind; /* cached result of |Kinds::base_construction| */
/* C: compatibility with other kinds */
struct parse_node *superkind_set_at; /* where it says, e.g., "A rabbit is a kind of animal" */
struct kind_constructor_casting_rule *first_casting_rule; /* list of these */
struct kind_constructor_instance *first_instance_rule; /* list of these */
/* D: how constant values of this kind are expressed */
struct literal_pattern *ways_to_write_literals; /* list of ways to write this */
int named_values_created_with_assertions; /* such as "Train Arrival is a scene." */
struct table *named_values_created_with_table; /* alternatively... */
int next_free_value; /* to make distinguishable instances of this kind */
int constant_compilation_method; /* one of the |*_CCM| values */
/* E: knowledge about values of this kind */
struct inference_subject *dt_knowledge; /* inferences about properties */
char *default_value; /* used for built-in types only */
/* F: behaviour as a property as well */
int can_coincide_with_property; /* allowed to coincide in name with a property */
struct property *coinciding_property; /* property of the same name, if any */
/* G: performing arithmetic */
char comparison_routine[32]; /* for instance, when sorting table or list entries */
struct dimensional_rules dim_rules; /* how arithmetic operations work here */
struct unit_sequence dimensional_form; /* dimensions of this kind */
int dimensional_form_fixed; /* whether they are derived */
/* H: representing this kind at run-time */
int weak_kind_ID; /* as used at run-time by the I6 template */
char name_in_template_code[32]; /* an I6 identifier */
int small_block_size; /* if stored as a block value, size in words of the SB */
/* I: storing values at run-time */
int multiple_block; /* TRUE for flexible-size values stored on the heap */
int heap_size_estimate; /* typical number of bytes used */
int can_exchange; /* with external files and therefore other story files */
char *distinguisher; /* I6 routine to see if values distinguishable */
struct kind_constructor_comparison_schema *first_comparison_schema; /* list of these */
char *loop_domain_schema; /* how to compile an I6 loop over the instances */
/* J: printing and parsing values at run-time */
char dt_I6_identifier[32]; /* an I6 identifier used for compiling printing rules */
char name_of_printing_rule_ACTIONS[32]; /* ditto but for ACTIONS testing command */
struct grammar_verb *understand_as_values; /* used when parsing such values */
int has_i6_GPR; /* a general parsing routine exists in the I6 code for this */
int I6_GPR_needed; /* and is actually required */
char *explicit_i6_GPR; /* routine name, when not compiled automatically */
char *recognition_only_GPR; /* for recognising an explicit value as preposition */
/* K: indexing and documentation */
char *specification_text; /* text for parse_node */
char *constructor_description; /* text used in index pages */
char *index_default_value; /* and its description in the Kinds index */
char *index_maximum_value; /* ditto */
char *index_minimum_value; /* ditto */
int index_priority; /* from 1 (highest) to |LOWEST_INDEX_PRIORITY| (lowest) */
int linguistic; /* divide off as having linguistics content */
int indexed_grey_if_empty; /* shaded grey in the Kinds index */
char *documentation_reference; /* documentation symbol, if any */
MEMORY_MANAGEMENT
} kind_constructor;
#line 66 "inform7/Chapter 19/Kind Interpreter.w"
typedef struct single_kind_command {
struct kind_command_definition *which_kind_command;
int boolean_argument; /* where appropriate */
int numeric_argument; /* where appropriate */
char *textual_argument; /* where appropriate */
int ccm_argument; /* where appropriate */
struct word_assemblage vocabulary_argument; /* where appropriate */
char constructor_argument[32]; /* where appropriate */
struct kind_template_definition *template_argument; /* where appropriate */
struct kind_macro_definition *macro_argument; /* where appropriate */
} single_kind_command;
#line 89 "inform7/Chapter 19/Kind Interpreter.w"
typedef struct kind_constructor_casting_rule {
char cast_from_kind_unparsed[32]; /* to the one which has the rule */
struct kind_constructor *cast_from_kind; /* to the one which has the rule */
struct kind_constructor_casting_rule *next_casting_rule;
} kind_constructor_casting_rule;
#line 99 "inform7/Chapter 19/Kind Interpreter.w"
typedef struct kind_constructor_comparison_schema {
char comparator_unparsed[32];
struct kind_constructor *comparator;
char *comparison_schema;
struct kind_constructor_comparison_schema *next_comparison_schema;
} kind_constructor_comparison_schema;
#line 110 "inform7/Chapter 19/Kind Interpreter.w"
typedef struct kind_constructor_instance {
char instance_of_this_unparsed[32];
struct kind_constructor *instance_of_this;
struct kind_constructor_instance *next_instance_rule;
} kind_constructor_instance;
#line 173 "inform7/Chapter 19/Kind Interpreter.w"
typedef struct kind_command_definition {
char *text_of_command;
int opcode_number;
int operand_type;
} kind_command_definition;
#line 182 "inform7/Chapter 19/Kind Interpreter.w"
typedef struct kind_template_definition {
char *template_name; /* including the asterisk, e.g., |"*PRINTING-ROUTINE"| */
char *template_text;
MEMORY_MANAGEMENT
} kind_template_definition;
#line 188 "inform7/Chapter 19/Kind Interpreter.w"
typedef struct kind_macro_definition {
char *kind_macro_name; /* including the sharp, e.g., |"#UNIT"| */
int kind_macro_line_count;
struct single_kind_command kind_macro_line[MAX_KIND_MACRO_LENGTH];
MEMORY_MANAGEMENT
} kind_macro_definition;
#line 200 "inform7/Chapter 19/Kind Interpreter.w"
typedef struct kind_template_obligation {
struct kind_template_definition *remembered_template; /* I7 source to insert... */
struct kind_constructor *remembered_constructor; /* ...concerning this kind */
MEMORY_MANAGEMENT
} kind_template_obligation;
#line 69 "inform7/Chapter 19/Dimensions.w"
typedef struct dimensional_rule {
struct wording name;
struct kind *right;
struct kind *outcome;
struct dimensional_rule *next;
} dimensional_rule;
#line 17 "inform7/Chapter 19/Floating-Point Values.w"
typedef struct generalised_kind {
struct kind *valid_kind; /* must be non-null */
int promotion; /* |0| for no change, |1| for "a real version", |-1| for "an int version" */
} generalised_kind;
#line 22 "inform7/Chapter 19/Runtime Support for Kinds.w"
typedef struct runtime_kind_structure {
struct kind *kind_described;
struct parse_node *default_requested_here;
int make_default;
char rks_identifier[32];
MEMORY_MANAGEMENT
} runtime_kind_structure;
#line 53 "inform7/Chapter 20/Dash.w"
typedef struct inv_token_problem_token {
struct wording problematic_text;
struct parse_node *as_parsed;
int already_described;
int new_name; /* found in context of a name not yet defined */
MEMORY_MANAGEMENT
} inv_token_problem_token;
#line 31 "inform7/Chapter 21/Properties.w"
typedef struct property {
struct wording name; /* name of property */
int ambiguous_name; /* does this look like a property test, e.g., "point of view"? */
/* the basic nature of this property */
int either_or; /* is this an either/or property? if not, it is a valued one */
struct property_permission *applicable_to; /* lists who has permission to have this */
int do_not_compile; /* for e.g. the "specification" pseudo-property */
int include_in_index; /* is this property shown in the indexes? */
/* runtime implementation */
int metadata_table_offset; /* position in the |property_metadata| word array at run-time */
int translated; /* has this been given an explicit translation? */
char original_name[32]; /* the identifier we would like to use at run-time for this property */
char translated_name[32]; /* the identifier we actually use at run-time for this property */
/* temporary use only */
int indexed_already; /* and has it been, thus far in index construction? */
int visited_on_traverse; /* for temporary use when compiling objects */
struct possession_marker pom; /* for temporary use when checking implications */
/* used only for either-or properties */
int implemented_as_attribute; /* if so: is it an I6 attribute at run-time? */
struct property *negation; /* and which property name (if any) negates it? */
int stored_in_negation; /* this is the dummy half of an either/or pair */
struct adjective_meaning *adjectival_meaning_registered; /* and has it been made an adjective yet? */
struct adjectival_phrase *adjectival_phrase_registered; /* similarly */
struct grammar_verb *eo_parsing_grammar; /* exotic forms used in parsing */
/* used only for valued properties */
struct kind *property_value_kind; /* if not either/or, what kind of value does it hold? */
struct binary_predicate *setting_bp; /* and which relation sets it? */
struct binary_predicate *stored_bp; /* does it store the content of a relation? */
int used_for_non_typesafe_relation; /* expressing, e.g., a 1-1 relation to a kind */
int also_a_type; /* and is its name the same as that of the kind of value? */
/* used only for condition properties, a special kind of valued properties */
struct inference_subject *condition_of; /* or is it a condition of an object? */
int condition_anonymously_named; /* if so, is it named just "... condition"? */
MEMORY_MANAGEMENT
} property;
#line 59 "inform7/Chapter 21/Measurement Adjectives.w"
typedef struct measurement_definition {
struct parse_node *measurement_node; /* where the actual definition is */
struct wording headword; /* adjective being defined (must be single word) */
struct adjective_meaning *headword_as_adjective; /* which adjective meaning */
struct wording superlative; /* its superlative form */
struct property *prop; /* the property being compared, if any */
struct wording name_of_property_to_compare; /* text of the name of the property to compare */
int region_shape; /* one of the |MEASURE_T_*| constants */
int region_threshold; /* numerical value of threshold (if any) */
struct kind *region_kind; /* of this value */
int region_threshold_evaluated; /* have we evaluated this one yet? */
struct wording region_threshold_text; /* text of threshold value */
int property_schema_written; /* I6 schema for testing written yet? */
MEMORY_MANAGEMENT
} measurement_definition;
#line 20 "inform7/Chapter 21/Properties of Values.w"
typedef struct property_of_value_storage {
int storage_table_id, storage_column_id; /* the table and column reference */
MEMORY_MANAGEMENT
} property_of_value_storage;
#line 59 "inform7/Chapter 22/Inference Subjects.w"
typedef struct inference_subject {
int kind_of_infs; /* one of the |*_SUB| constants above */
struct general_pointer represents; /* the individual instance, kind, etc. in question */
struct parse_node *infs_created_at; /* which sentence created this */
struct inference *inf_list; /* contingently true: inferences drawn about this subject */
struct implication *imp_list; /* necessarily true: implications applying to this */
int default_certainty; /* by default, how certain are inferences about this? */
struct property_permission *permissions_list; /* what properties this can have, if any */
struct assemblies_data assemblies; /* what generalisations have been made about this? */
struct inference_subject *broader_than; /* see below */
char *infs_name_in_log; /* solely to make the debugging log more legible */
struct nonlocal_variable *alias_variable; /* alias to this variable, like "yourself" to "player" */
void *plugin_subj[MAX_PLUGINS];
MEMORY_MANAGEMENT
} inference_subject;
#line 70 "inform7/Chapter 22/Property Permissions.w"
typedef struct property_permission {
struct inference_subject *property_owner; /* to whom permission is granted */
struct property_permission *next_for_this_owner; /* in list of permissions */
struct property *property_granted; /* which property is permitted */
struct property_permission *next_for_this_property; /* in list of permissions */
struct parse_node *where_granted; /* sentence granting the permission */
struct general_pointer pp_storage_data; /* how we'll compile this at run-time */
void *plugin_pp[MAX_PLUGINS]; /* storage for plugins to attach, if they want to */
MEMORY_MANAGEMENT
} property_permission;
#line 70 "inform7/Chapter 22/Inferences.w"
typedef struct inference {
int inference_type; /* see above */
int certainty; /* see above */
struct parse_node *inferred_from; /* from what sentence was this drawn? */
int added_in_construction; /* or was this drawn during the model completion stage? */
int inference_timestamp;
struct inference_subject *infs_ref1; /* from 0 to 2 other INFSs are connected by this inference */
struct inference_subject *infs_ref2;
struct parse_node *spec_ref1; /* used by dynamic relations between non-subjects */
struct parse_node *spec_ref2;
struct property *inferred_property; /* property referred to, if any */
struct parse_node *inferred_property_value; /* and its value, if any */
struct inference *next; /* next in list of inferences on same subject */
MEMORY_MANAGEMENT
} inference;
#line 52 "inform7/Chapter 23/Text Literals.w"
typedef struct literal_text {
int lt_position; /* position in the source of quoted text */
int as_boxed_quotation; /* formatted for the Inform 6 |box| statement */
int bibliographic_conventions; /* mostly for apostrophes */
int unescaped; /* completely so */
int unexpanded; /* don't expand single quotes to double */
int node_colour; /* red or black: see above */
struct literal_text *left_node; /* within their red-black tree */
struct literal_text *right_node;
int small_block_array_needed;
MEMORY_MANAGEMENT
} literal_text;
#line 23 "inform7/Chapter 23/Text Substitutions.w"
typedef struct text_substitution {
struct wording unsubstituted_text; /* including the substitutions in squares */
int dont_need_after_all; /* in case replaced as a response */
int tr_done_already; /* has been compiled */
struct rule *responding_to_rule;
int responding_to_marker;
struct parse_node *sentence_using_this; /* where this occurs in source */
int local_names_existed_at_usage_time; /* remember in case of problems */
struct ph_stack_frame *parked_stack_frame; /* for cases where possible */
char ts_identifier[32]; /* the I6 routine for this */
int ts_sb_needed; /* reference copy of small block needed as a constant? */
MEMORY_MANAGEMENT
} text_substitution;
#line 17 "inform7/Chapter 23/Responses.w"
typedef struct response_message {
struct rule *responding_rule; /* named rule in which this response occurs */
int response_marker; /* 0 for A, 1 for B, and so on up */
struct text_substitution *original_text;
struct ph_stack_frame *original_stack_frame;
int launcher_compiled;
int via_I6; /* if responding to a rule defined by I6 code, not source text */
int via_I6_routine_compiled;
MEMORY_MANAGEMENT
} response_message;
#line 25 "inform7/Chapter 24/List Constants.w"
typedef struct literal_list {
struct wording unbraced_text; /* position in the source of quoted text, excluding braces */
struct parse_node *list_text; /* used for problem reporting only */
int listed_within_code; /* appears within a phrase, rather than (say) a table entry? */
struct kind *entry_kind; /* i.e., of the entries, not the list */
int kinds_known_to_be_inconsistent; /* problem(s) thrown when parsing these */
struct llist_entry *first_llist_entry; /* linked list of contents */
int list_compiled; /* lists are compiled at several different points: has this one been done? */
MEMORY_MANAGEMENT
} literal_list;
#line 42 "inform7/Chapter 24/List Constants.w"
typedef struct llist_entry {
struct parse_node *llist_entry_value;
struct llist_entry *next_llist_entry;
MEMORY_MANAGEMENT
} llist_entry;
#line 28 "inform7/Chapter 25/Table Columns.w"
typedef struct table_column {
struct wording name; /* name of column (without "entry" suffix) */
struct kind *kind_stored_in_column; /* what kind of value is stored in this column */
struct table *table_from_which_kind_inferred; /* usually the earliest use */
struct binary_predicate *listed_in_predicate; /* see above */
MEMORY_MANAGEMENT
} table_column;
#line 47 "inform7/Chapter 25/Table Columns.w"
typedef struct table_column_usage {
struct table_column *column_identity;
struct parse_node *entries; /* initial contents of this column in the table */
struct wording kind_declaration_text; /* if specified */
int actual_constant_entries; /* how many entries have explicitly been given */
struct parse_node *observed_constant_cell; /* first one spotted */
int kind_name_entries; /* how many entries read, say, "a rulebook" */
struct parse_node *observed_kind_cell; /* first one spotted */
} table_column_usage;
#line 24 "inform7/Chapter 25/Tables.w"
typedef struct table {
struct wording table_no_text; /* the table number (if any) */
struct wording table_name_text; /* the table name (if any) */
struct table_contribution *table_created_at; /* where created in source */
struct parse_node *headline_fragment; /* a pseudo-sentence formed by the heading line */
int blank_rows; /* number of entirely blank rows to be appended (may be 0) */
struct wording blank_rows_for_each_text; /* add one blank for each instance */
struct wording blank_rows_text; /* text of blank rows specification */
int fill_in_blanks; /* if set, fill any blank entries with default values */
int first_column_by_definition; /* if set, first column defines new value names */
struct kind *kind_defined_in_this_table; /* ...of this kind */
int contains_property_values_at_run_time;
struct parse_node *where_used_to_define;
int preserve_row_order_at_run_time; /* if set, don't sort this table */
struct table *amendment_of; /* if amendment of earlier table */
int has_been_amended; /* if there exists an amendment of this */
char tab_I6_identifier[32]; /* an I6 identifier */
int approximate_array_space_needed; /* at run-time, in words */
int disable_block_constant_correction; /* if set, don't translate block constant entries */
int no_columns; /* must be at least 1 */
struct table_column_usage columns[MAX_COLUMNS_PER_TABLE];
MEMORY_MANAGEMENT
} table;
#line 53 "inform7/Chapter 25/Tables.w"
typedef struct table_contribution {
struct parse_node *source_table;
struct table_contribution *next;
} table_contribution;
#line 22 "inform7/Chapter 26/Equations.w"
typedef struct equation {
struct wording equation_text; /* the text of the actual equation */
struct wording equation_no_text; /* the equation number (if any) */
struct wording equation_name_text; /* the equation name (if any) */
struct wording where_text; /* declaration of symbols */
struct wording usage_text; /* usage notes */
struct parse_node *equation_created_at; /* where created in source */
int examined_already;
struct equation_node *parsed_equation; /* and the equation itself (when eventually parsed) */
char eqn_I6_identifier[32]; /* an I6 identifier */
struct equation_symbol *symbol_list; /* the symbols used */
MEMORY_MANAGEMENT
} equation;
#line 48 "inform7/Chapter 26/Equations.w"
typedef struct equation_symbol {
struct wording name; /* always just one word, in fact */
struct kind *var_kind; /* if a variable -- must be quasinumerical */
struct phrase *function_notated; /* if a phrase QN to QN */
struct parse_node *var_const; /* if a symbol for a constant value */
int temp_constant; /* is this constant a substitution for one usage only? */
struct equation_symbol *next; /* in the list belonging to the equation */
struct local_variable *local_map; /* when being solved in a given stack frame */
int promote_local_to_real; /* from integer, if necessary */
MEMORY_MANAGEMENT
} equation_symbol;
#line 110 "inform7/Chapter 26/Equations.w"
typedef struct equation_node {
int eqn_type; /* one of the |*_EQN| values */
int eqn_operation; /* one of the |*_OPERATION| values (see "Dimensions.w") */
int enode_arity; /* 0 for a leaf */
struct equation_node *enode_operands[MAX_EQN_ARITY]; /* the operands */
struct parse_node *leaf_constant; /* if e.g. "21" */
struct equation_symbol *leaf_symbol; /* if e.g. "G" */
struct generalised_kind gK_before; /* result of the node as it is */
struct generalised_kind gK_after; /* result of the node as we need it to be */
int enode_promotion; /* promote this from an integer to a real number? */
int rational_n; /* represents the rational number |n/m|... */
int rational_m; /* ...unless |m| is zero */
MEMORY_MANAGEMENT
} equation_node;
#line 46 "inform7/Chapter 27/Rules.w"
typedef struct rule {
struct wording name; /* name of the rule being booked */
int explicitly_named; /* was this rule explicitly named when created? */
struct wording italicised_text; /* when indexing a rulebook */
struct stacked_variable_owner_list *listed_stv_owners; /* making vars visible here */
struct phrase *defn_as_phrase; /* the rule being booked */
char defn_as_I6_routine[32]; /* an I6 identifier */
int defn_compiled; /* has the definition of this rule, if needed, been compiled yet? */
struct booking *automatic_booking; /* how this is placed in rulebooks */
struct applicability_condition *first_applicability_condition; /* see below */
struct response_message *lettered_responses[26]; /* responses (A), (B), ... */
struct parse_node *lettered_responses_used[26]; /* responses (A), (B), ... */
struct kind *kind_of_rule; /* determined from its rulebook(s) */
struct rulebook *kind_of_rule_set_from;
struct wording lettered_responses_value[26];
MEMORY_MANAGEMENT
} rule;
#line 83 "inform7/Chapter 27/Rules.w"
typedef struct applicability_condition {
struct wording text_of_condition;
int sense_of_applicability; /* |TRUE| if condition must hold for rule to have effect */
struct rule *substituted_rule; /* rule to use instead if not, or |NULL| to do nothing */
struct parse_node *where_imposed;
struct applicability_condition *next_applicability_condition;
MEMORY_MANAGEMENT
} applicability_condition;
#line 18 "inform7/Chapter 27/Rule Bookings.w"
typedef struct booking {
struct booking *next_rule; /* in the linked list of pages for the rulebook */
struct rule *rule_being_booked; /* what appears on this page */
int placement; /* one of three placement values: see below */
int automatic_placement; /* should this be inserted automatically? */
/* used only to show how the page was added to its rulebook, for the index: */
int next_rule_specificity; /* $1$ more specific than following, $0$ equal, $-1$ less */
char *next_rule_specificity_law; /* description of reason */
char *next_rule_specificity_lawname; /* name of Law used to sort */
MEMORY_MANAGEMENT
} booking;
#line 33 "inform7/Chapter 27/Focus and Outcome.w"
typedef struct focus {
int rulebook_focus; /* always |ACTION_FOCUS| or |PARAMETER_FOCUS| */
struct kind *kind_of_parameter; /* if created as |NO_FOCUS|, this is |NULL| */
int rules_always_test_actor; /* for action-tied check, carry out, report */
} focus;
#line 61 "inform7/Chapter 27/Focus and Outcome.w"
typedef struct outcomes {
int default_outcome_declared; /* flag: whether author has declared this */
int default_rule_outcome; /* success, failure or none: see above */
struct rulebook_outcome *default_named_outcome; /* alternative to the above */
struct rulebook_outcome *named_outcomes;
struct kind *value_outcome_kind;
} outcomes;
#line 50 "inform7/Chapter 27/Rulebooks.w"
typedef struct rulebook {
struct wording primary_name; /* name in source text */
struct wording alternative_name; /* alternative form of name */
int fragmentation_stem_length; /* to do with parsing, but 0 for most rulebooks */
struct focus my_focus;
struct outcomes my_outcomes;
int automatically_generated; /* so that the index can omit these */
int runs_during_activities; /* allow "while..." clauses to name these */
int used_by_future_action_activity; /* like "deciding the scope of something..." */
struct booking *rule_list; /* linked list of booked rules */
struct placement_affecting *placement_list; /* linked list of explicit placements */
struct stacked_variable_owner *owned_by_rb; /* rulebook variables owned here */
struct stacked_variable_owner_list *accessible_from_rb; /* and which can be named here */
char rb_I6_identifier[32]; /* I6 identifier name for array holding contents */
MEMORY_MANAGEMENT
} rulebook;
#line 77 "inform7/Chapter 27/Rulebooks.w"
typedef struct rulebook_match {
struct rulebook *matched_rulebook;
int match_from;
int match_length;
int advance_words;
int tail_words;
int article_used;
int placement_requested;
} rulebook_match;
#line 93 "inform7/Chapter 27/Rulebooks.w"
typedef struct placement_affecting {
struct parse_node *placement_sentence;
struct placement_affecting *next;
MEMORY_MANAGEMENT
} placement_affecting;
#line 73 "inform7/Chapter 27/Focus and Outcome.w"
typedef struct named_rulebook_outcome {
struct wording name; /* Name in source text */
MEMORY_MANAGEMENT
} named_rulebook_outcome;
#line 78 "inform7/Chapter 27/Focus and Outcome.w"
typedef struct rulebook_outcome {
struct rulebook_outcome *next;
struct named_rulebook_outcome *outcome_name;
int kind_of_outcome; /* one of the three values above */
MEMORY_MANAGEMENT
} rulebook_outcome;
#line 16 "inform7/Chapter 27/Stacked Variables.w"
typedef struct stacked_variable {
struct wording name; /* text of the name */
struct parse_node *assigned_at; /* sentence assigning it */
struct nonlocal_variable *underlying_var; /* the variable in question */
int owner_id; /* who owns this */
int offset_in_owning_frame; /* word offset of storage (counts from 0) */
struct wording match_wording_text; /* matching text (relevant for action variables only) */
MEMORY_MANAGEMENT
} stacked_variable;
#line 26 "inform7/Chapter 27/Stacked Variables.w"
typedef struct stacked_variable_list {
struct stacked_variable *the_stv; /* the STV */
struct stacked_variable_list *next; /* in linked list */
MEMORY_MANAGEMENT
} stacked_variable_list;
#line 32 "inform7/Chapter 27/Stacked Variables.w"
typedef struct stacked_variable_owner {
int no_stvs;
int recognition_id;
struct stacked_variable_list *list_of_stvs;
MEMORY_MANAGEMENT
} stacked_variable_owner;
#line 39 "inform7/Chapter 27/Stacked Variables.w"
typedef struct stacked_variable_owner_list {
struct stacked_variable_owner *stvo; /* the STO */
struct stacked_variable_owner_list *next; /* in linked list */
MEMORY_MANAGEMENT
} stacked_variable_owner_list;
#line 23 "inform7/Chapter 27/Activities.w"
typedef struct activity {
struct wording name; /* text of the name of the activity */
struct rulebook *before_rules; /* rulebooks for when this is followed */
struct rulebook *for_rules;
struct rulebook *after_rules;
struct kind *activity_on_what_kind; /* or null */
struct stacked_variable_owner *owned_by_av; /* activity variables owned here */
char av_I6_identifier[32]; /* an I6 identifier for a constant identifying this */
struct wording av_documentation_symbol; /* cross-reference to HTML documentation, if any */
int activity_indexed; /* has this been indexed yet? */
struct activity_crossref *cross_references;
MEMORY_MANAGEMENT
} activity;
#line 37 "inform7/Chapter 27/Activities.w"
typedef struct activity_list {
struct activity *activity; /* what activity */
struct parse_node *acting_on; /* the parameter */
struct parse_node *only_when; /* condition for when this applies */
int ACL_parity; /* |+1| if meant positively, |-1| if negatively */
struct activity_list *next; /* next in activity list */
} activity_list;
#line 45 "inform7/Chapter 27/Activities.w"
typedef struct activity_crossref {
struct phrase *rule_dependent;
struct activity_crossref *next;
} activity_crossref;
#line 73 "inform7/Chapter 28/Phrase Type Data.w"
typedef struct phrase_token {
struct wording token_name; /* name */
struct parse_node *to_match; /* what we expect to find here */
struct kind *token_kind;
int construct; /* one of the above values */
} phrase_token;
#line 139 "inform7/Chapter 28/Phrase Type Data.w"
typedef struct say_details {
int say_phrase; /* one of the three |*_SAY_PHRASE| values */
int say_phrase_running_on; /* ignore implied newlines in previous invocation */
int say_phrase_stream_position; /* one of the |SSP_*| values above */
int say_phrase_stream_token_at; /* word number of say stream token name */
int say_phrase_stream_closing_token_at; /* ditto for choice of ending */
int say_control_structure; /* one of the four |*_SAY_CS| values below */
} say_details;
#line 174 "inform7/Chapter 28/Phrase Type Data.w"
typedef struct inline_details {
int invoked_inline_not_as_call; /* if |FALSE|, none of the rest applies */
int let_phrase; /* one of the |*_LET_PHRASE| values below */
int assignment_phrase; /* |TRUE| if this has to be typechecked as an assignment */
int arithmetical_operation; /* |-1|, or one of the |*_OPERATION| constants */
int block_follows; /* for inline phrases only: followed by a begin... end block? */
char *only_in_loop; /* if not null, the phrase can only be used in this block */
} inline_details;
#line 44 "inform7/Chapter 28/Phrase Type Data.w"
typedef struct ph_type_data {
struct wording registration_text; /* words used to register the excerpt meaning */
int word_sequence[MAX_WORDS_PER_PHRASE]; /* the "word sequence": see above */
int no_words; /* length of the word sequence */
struct phrase_token token_sequence[MAX_TOKENS_PER_PHRASE];
int no_tokens;
int manner_of_return; /* one of the |*_MOR| values */
struct kind *return_kind; /* |NULL| except in the |DECIDES_VALUE_MOR| case */
struct say_details as_say; /* used only for "say" phrases, that is, text substitutions */
struct inline_details as_inline; /* side effects for phrases like C keywords */
int now_deprecated; /* is this a phrase likely to be withdrawn in future? */
} ph_type_data;
#line 21 "inform7/Chapter 28/Phrase Usage.w"
typedef struct ph_usage_data {
struct wording full_preamble; /* e.g. to identify nameless rules in the log */
struct constant_phrase *constant_phrase_holder; /* for named To... phrases */
int phrase_effect; /* see below: basically, how the phrase is invoked */
int timing_of_event; /* one of two values defined below; or a specific time */
struct use_as_event *uses_as_event;
struct wording explicit_name; /* if a named rule, this is its name */
int explicit_name_used_in_maths; /* if so, this flag means it's like |log()| or |sin()| */
struct wording explicit_name_for_inverse; /* e.g. |exp| for |log| */
struct wording whenwhile; /* when/while for action/activity rulebooks */
struct wording rule_preamble;
struct wording rule_parameter; /* text of object or action parameter */
struct parse_node *during_scene_spec; /* what scene is currently under way */
struct wording event_name;
struct rulebook *owning_rulebook; /* the primary booking for the phrase will be here */
int owning_rulebook_placement; /* ...and with this placement value: see Rulebooks */
} ph_usage_data;
#line 31 "inform7/Chapter 35/Action Patterns.w"
typedef struct action_pattern {
struct wording text_of_pattern; /* text giving rise to this AP */
struct action_name_list *action; /* what the behaviour is */
int test_anl; /* actually test the action when compiled */
int applies_to_any_actor; /* treat player and other people equally */
int request; /* a request from the player for someone to do this? */
struct parse_node *actor_spec;
struct parse_node *noun_spec;
int noun_any;
struct parse_node *second_spec;
int second_any;
struct parse_node *presence_spec; /* in the presence of... */
struct parse_node *room_spec; /* in... */
int room_any;
struct parse_node *when; /* when... (any condition here) */
struct parse_node *from_spec; /* for the "going" action only */
struct parse_node *to_spec; /* ditto */
struct parse_node *by_spec; /* ditto */
struct parse_node *through_spec; /* ditto */
struct parse_node *pushing_spec; /* ditto */
int nowhere_flag; /* ditto: a flag for "going nowhere" */
struct ap_optional_clause *optional_clauses;
int chief_action_owner_id; /* stacked variable ID number of main action */
struct time_period duration; /* to hold "for the third time", etc. */
struct parse_node *parameter_spec; /* alternatively, just this */
struct kind *parameter_kind; /* of this expected kind */
int valid; /* recording success or failure in parsing to an AP */
struct parse_node *entered_into_NAP_here; /* sentence adding it to named behaviour */
struct action_pattern *next; /* for forming APs into linked lists */
} action_pattern;
#line 27 "inform7/Chapter 28/Phrase Runtime Context Data.w"
typedef struct ph_runtime_context_data {
struct wording activity_context; /* happens only while any activities go on? */
struct parse_node *activity_where; /* and who says? */
struct activity_list *avl;
struct parse_node *during_scene; /* ...happens only during a scene matching this? */
struct action_pattern ap; /* happens only if the action matches this pattern? */
int always_test_actor; /* ...even if no AP was given, test that actor is player? */
int never_test_actor; /* ...for instance, for a parametrised rather than action rulebook */
int marked_for_anyone; /* any actor is allowed to perform this action */
struct rulebook **compile_for_rulebook; /* ...used for the default outcome */
int permit_all_outcomes; /* waive the usual restrictions on rule outcomes */
} ph_runtime_context_data;
#line 37 "inform7/Chapter 30/Local Variables.w"
typedef struct locals_slate {
struct local_variable *local_variable_allocation; /* linked list of valid locals */
int it_variable_exists; /* it, he, she, or they, used for adjective definitions */
int its_form_allowed; /* its, his, her or their, ditto */
struct wording it_pseudonym; /* a further variation on the same variable */
} locals_slate;
#line 23 "inform7/Chapter 30/Stack Frames.w"
typedef struct ph_stack_frame {
struct locals_slate local_value_variables; /* those in scope here */
struct stacked_variable_owner_list *local_stvol; /* those in scope here */
struct pointer_allocation *allocated_pointers;
int no_formal_parameters_needed; /* usually 0, unless there are ambiguities */
struct kind *kind_returned; /* or |NULL| for no return value */
struct kind **local_kind_variables; /* points to an array indexed 1 to 26 */
int determines_past_conditions; /* or rather, in the present, but for future use */
} ph_stack_frame;
#line 27 "inform7/Chapter 28/Phrase Options.w"
typedef struct ph_options_data {
struct phrase_option *options_permitted[MAX_OPTIONS_PER_PHRASE]; /* see below */
int no_options_permitted;
struct wording options_declaration; /* the text declaring the whole set of options */
int multiple_options_permitted; /* can be combined, or mutually exclusive? */
} ph_options_data;
#line 49 "inform7/Chapter 28/Phrases.w"
typedef struct phrase {
struct parse_node *declaration_node; /* |ROUTINE_NT| node where declared */
int inline_wn; /* word number of inline I6 definition, or |-1| if not inline */
int inline_mor; /* manner of return for inline I6 definition, or |UNKNOWN_VNT| */
struct wording ph_documentation_symbol; /* cross-reference with documentation */
struct ph_type_data type_data;
struct ph_usage_data usage_data;
struct ph_runtime_context_data runtime_context_data;
struct ph_stack_frame stack_frame;
struct ph_options_data options_data;
int at_least_one_compiled_form_needed; /* do we still need to compile this? */
int compile_with_run_time_debugging; /* in the RULES command */
char ph_I6_identifier[32]; /* name of I6 routine, or empty string for inline phrases */
struct phrase *next_in_logical_order; /* for "to..." phrases only */
int sequence_count; /* within the logical order list, from 0 */
MEMORY_MANAGEMENT
} phrase;
#line 37 "inform7/Chapter 28/Phrase Options.w"
typedef struct phrase_option {
struct wording name; /* text of name */
} phrase_option;
#line 20 "inform7/Chapter 28/Phrases as Values.w"
typedef struct constant_phrase {
struct wording name;
struct phrase *phrase_meant; /* if known at this point */
struct kind *cphr_kind; /* ditto */
struct wording associated_preamble_text;
MEMORY_MANAGEMENT
} constant_phrase;
#line 17 "inform7/Chapter 28/To Phrases.w"
typedef struct to_phrase_request {
struct phrase *requested_phrase;
struct kind *requested_exact_kind;
struct kind *kind_variables_interpretation[27];
MEMORY_MANAGEMENT
} to_phrase_request;
#line 26 "inform7/Chapter 28/Timed Phrases.w"
typedef struct use_as_event {
struct parse_node *where_triggered; /* sentence which specifies when this occurs */
struct use_as_event *next;
MEMORY_MANAGEMENT
} use_as_event;
#line 30 "inform7/Chapter 29/Adjectival Definitions.w"
typedef struct definition {
struct parse_node *definition_node; /* current sentence: where the word "Definition" is */
struct parse_node *node; /* where the actual definition is */
int format; /* |+1| to go by condition, |-1| to negate it, |0| to use routine */
struct wording condition_to_match; /* text of condition to match, if |+1| or |-1| */
struct wording domain_calling; /* what if anything the term is called */
struct adjective_meaning *am_of_def; /* which adjective meaning */
MEMORY_MANAGEMENT
} definition;
#line 52 "inform7/Chapter 30/Local Variables.w"
typedef struct local_variable {
int lv_purpose; /* one of the |*_LV| values above */
char lv_lvalue[32]; /* an Inform lvalue for the variable's run-time storage */
int index_with_this_purpose; /* what index count it has, within locals of its type */
char *comment_on_use; /* purely to make the output more legible */
int allocated; /* in existence at this point in the routine? */
struct wording varname; /* name of local variable */
int name_hash; /* hash code for this name */
int block_scope; /* scope of a local - block depth */
int free_at_end_of_scope; /* whether it holds temporary data on heap */
struct kind *kind_as_declared; /* data type for the contents */
int protected; /* from alteration using "let"? */
int parsed_recently; /* name recognised since this was last wiped? */
struct local_variable *next; /* on the same slate */
MEMORY_MANAGEMENT
} local_variable;
#line 35 "inform7/Chapter 30/Phrase Blocks.w"
typedef struct phrase_block {
struct control_structure_phrase *from_structure; /* e.g., "if" or "while" */
struct parse_node *block_location; /* where block begins */
struct kind *switch_kind; /* for a switch statement */
struct text_stream *tail_stream; /* code to add when the block closes */
int label_following; /* or -1 if none is used */
} phrase_block;
#line 30 "inform7/Chapter 30/Phrase Blocks.w"
typedef struct block_stack {
int pb_sp; /* stack pointer for the block stack which follows: */
struct phrase_block pb_stack[MAX_BLOCK_NESTING+1];
} block_stack;
#line 41 "inform7/Chapter 30/Stack Frames.w"
typedef struct ph_stack_frame_box {
struct ph_stack_frame boxed_phsf;
MEMORY_MANAGEMENT
} ph_stack_frame_box;
#line 50 "inform7/Chapter 30/Stack Frames.w"
typedef struct pointer_allocation {
char allocation_code[128]; /* a function call returning a pointer to a new value */
char local_reference_code[128]; /* an I6 lvalue for the storage holding the pointer */
char escaped_local_reference_code[128]; /* the same, but suitable for schema use */
char schema_for_promotion[128]; /* an I6 schema for promoting this value */
int offset_index; /* start of small block wrt current stack frame */
int offset_past; /* just past the end of the small block */
struct pointer_allocation *next_in_frame; /* within the linked list */
MEMORY_MANAGEMENT
} pointer_allocation;
#line 22 "inform7/Chapter 30/Chronology.w"
typedef struct past_tense_condition_record {
struct parse_node *condition; /* condition to be evaluated */
struct action_pattern *ap_to_test; /* condition to be evaluated */
struct parse_node *where_ptc_tested; /* sentence in which condition is found */
MEMORY_MANAGEMENT
} past_tense_condition_record;
#line 29 "inform7/Chapter 30/Chronology.w"
typedef struct past_tense_action_record {
struct action_pattern historic_action; /* action pattern to be matched */
struct parse_node *where_pta_tested; /* sentence in which AP is found */
MEMORY_MANAGEMENT
} past_tense_action_record;
#line 66 "inform7/Chapter 31/Invocations.w"
typedef struct invocation_options {
int options; /* bitmap of any phrase options appended */
struct wording options_invoked_text; /* text of any phrase options appended */
} invocation_options;
#line 134 "inform7/Chapter 31/Invocations.w"
typedef struct invocation_sort_block {
struct parse_node *inv_data;
int unsorted_position;
} invocation_sort_block;
#line 15 "inform7/Chapter 31/Compile Invocations.w"
typedef struct tokens_packet {
int tokens_count; /* number of arguments to phrase */
struct parse_node *args[32]; /* what they are */
struct kind *kind_required[32]; /* what pointer kinds of value, if they are */
struct kind *as_requested; /* kind for the function call */
} tokens_packet;
#line 38 "inform7/Chapter 32/Virtual Machines.w"
typedef struct VM_identifier {
int VM_code; /* one of the values above */
int VM_version; /* times the |VMULT|, or -1 to mean generic versionless VM */
char *VM_major_name; /* or NULL if not a major VM name */
char *VM_extension; /* canonical filename extension */
char *VM_blorbed_extension; /* when blorbed up */
char *VM_name; /* text to use with author */
char *VM_image; /* filename of image for icon denoting VM */
int VM_is_32_bit; /* true or false: false means 16-bit */
int max_locals; /* upper limit on local variables per stack frame */
int VM_matches; /* true or false: computed */
char *default_browser_interpreter; /* e.g., "Parchment" */
} VM_identifier;
#line 59 "inform7/Chapter 32/Virtual Machines.w"
typedef struct VM_usage_note {
struct wording structure_name; /* name of the structure using this array space... */
char usage_explained[MAX_USAGE_COLUMN_WIDTH]; /* ...or an explanation instead */
char *usage_category; /* e.g., "relation" */
int bytes_used; /* number of bytes (not words) given over to this */
int each_flag; /* is this a count of how many bytes per usage of something? */
MEMORY_MANAGEMENT
} VM_usage_note;
#line 21 "inform7/Chapter 32/Inform 6 Inclusions.w"
typedef struct i6_inclusion_matter {
struct parse_node *material_to_include; /* normally an I6 escape |(- ... -)| */
struct inference_subject *infs_to_include_with; /* typically an object or class definition */
MEMORY_MANAGEMENT
} i6_inclusion_matter;
#line 35 "inform7/Chapter 32/Use Options.w"
typedef struct use_option {
struct wording name; /* word range where name is stored */
struct parse_node *option_expansion; /* definition as given in source */
struct parse_node *where_used; /* where the option is taken in the source */
int option_used; /* set if this option has been taken */
int source_file_scoped; /* scope is the current source file only? */
int minimum_setting_value; /* for those which are numeric */
MEMORY_MANAGEMENT
} use_option;
#line 61 "inform7/Chapter 32/Use Options.w"
typedef struct i6_memory_setting {
char ICL_identifier[64]; /* see the DM4 for the I6 memory setting names */
int number; /* e.g., |50000| means "at least 50,000" */
MEMORY_MANAGEMENT
} i6_memory_setting;
#line 23 "inform7/Chapter 32/List Together.w"
typedef struct list_together_routine {
int articles_bit; /* if false, add |NOARTICLE_BIT| to the I6 listing style */
MEMORY_MANAGEMENT
} list_together_routine;
#line 29 "inform7/Chapter 32/Jump Labels.w"
typedef struct label_namespace {
char label_prefix[MAX_NAMESPACE_PREFIX_LENGTH + 1];
int label_counter; /* next free ID number for this label namespace */
int allocate_storage; /* number of words of memory to reserve for each label */
MEMORY_MANAGEMENT
} label_namespace;
#line 48 "inform7/Chapter 33/Release Instructions.w"
typedef struct auxiliary_file {
struct filename *name_of_original_file; /* e.g., "Collegio.pdf" */
struct pathname *folder_to_release_to; /* e.g., "Sounds" */
char *brief_description; /* e.g., "Collegio Magazine" */
int from_payload;
MEMORY_MANAGEMENT
} auxiliary_file;
#line 18 "inform7/Chapter 34/Instance Counting.w"
typedef struct counting_data {
struct property *instance_count_prop; /* the (|I6| only) IK-Count property for this kind */
struct property *instance_link_prop; /* the (|I6| only) IK-Link property for this kind */
int has_instances; /* are there any instances of this kind? */
MEMORY_MANAGEMENT
} counting_data;
#line 34 "inform7/Chapter 34/Spatial Model.w"
typedef struct spatial_data {
/* fundamental spatial information about an object's location */
struct instance *progenitor;
struct parse_node *progenitor_set_at;
int part_flag; /* is this a component part of something else? */
int here_flag; /* was this declared simply as being "here"? */
/* temporary storage needed when compiling spatial data to I6 code */
struct instance *object_tree_parent; /* in/on/worn by/carried by tree structure */
struct instance *object_tree_child;
struct instance *object_tree_sibling;
struct instance *incorp_tree_parent; /* part-of tree structure */
struct instance *incorp_tree_child;
struct instance *incorp_tree_sibling;
int I6_definition_depth; /* i.e., how many arrows |->| appear in its I6 header */
MEMORY_MANAGEMENT
} spatial_data;
#line 32 "inform7/Chapter 34/Regions.w"
typedef struct regions_data {
struct instance *in_region; /* smallest region containing me (rooms only) */
struct parse_node *in_region_set_at; /* where this is decided */
MEMORY_MANAGEMENT
} regions_data;
#line 16 "inform7/Chapter 34/Spatial Geometry.w"
typedef struct vector {
int x, y, z;
} vector;
#line 40 "inform7/Chapter 34/EPS Map.w"
typedef struct plotting_parameter {
int specified; /* is it explicitly specified at this scope? */
char *name; /* name (used only in global scope) */
int parameter_data_type; /* one of the above types (used only in global scope) */
char *string_value; /* string value, if appropriate to this type; */
int numeric_value; /* or numeric value, if appropriate to this type */
} plotting_parameter;
#line 55 "inform7/Chapter 34/EPS Map.w"
typedef struct map_parameter_scope {
struct map_parameter_scope *wider_scope; /* that is, the scope above this */
struct plotting_parameter values[NO_MAP_PARAMETERS];
} map_parameter_scope;
#line 25 "inform7/Chapter 34/The Map.w"
typedef struct map_data {
/* these are meaningful for doors only */
struct instance *map_connection_a;
struct instance *map_connection_b;
struct instance *map_direction_a;
struct instance *map_direction_b;
/* these are meaningful for directions only */
int direction_index; /* counts 0, 1, 2, ..., in order of creation */
struct binary_predicate *direction_relation; /* the corresponding "mapped D of" relation */
/* these are meaningful for rooms only, and are used in making the World index */
struct instance *exits[MAX_DIRECTIONS];
struct parse_node *exits_set_at[MAX_DIRECTIONS];
struct instance *spatial_relationship[12];
int exit_lengths[MAX_DIRECTIONS];
struct instance *lock_exits[MAX_DIRECTIONS];
struct vector position;
struct vector saved_gridpos;
int cooled, shifted, zone;
struct connected_submap *submap;
struct instance *next_room_in_submap;
char *world_index_colour; /* an HTML colour for the room square (rooms only) */
char *world_index_text_colour; /* an HTML colour for the room text (rooms only) */
struct map_parameter_scope local_map_parameters; /* temporary: used in EPS mapping */
int eps_x, eps_y;
MEMORY_MANAGEMENT
} map_data;
#line 44 "inform7/Chapter 34/Spatial Geometry.w"
typedef struct cuboid {
int population;
struct vector corner0;
struct vector corner1;
} cuboid;
#line 72 "inform7/Chapter 34/Spatial Map.w"
typedef struct connected_submap {
struct instance *first_room_in_submap; /* double-headed linked list of rooms */
struct instance *last_room_in_submap;
struct cuboid bounds;
int heat; /* current penalty score for bad placement of rooms */
int positioned; /* already placed within the global map grid? */
int *incidence_cache; /* how many of our rooms occupy each grid position? */
struct cuboid incidence_cache_bounds; /* bounds of the incidence cache array */
int superpositions; /* number of pairs of rooms which share the same grid location */
MEMORY_MANAGEMENT
} connected_submap;
#line 106 "inform7/Chapter 34/EPS Map.w"
typedef struct rubric_holder {
char *annotation;
int point_size;
char *font;
char *colour;
int at_offset;
struct instance *offset_from;
MEMORY_MANAGEMENT
} rubric_holder;
#line 120 "inform7/Chapter 34/EPS Map.w"
typedef struct EPS_map_level {
int width;
int actual_height;
int height;
char titling[128];
int titling_point_size;
int map_level;
int y_max;
int y_min;
int contains_rooms;
int contains_titling;
int eps_origin;
struct map_parameter_scope map_parameters;
MEMORY_MANAGEMENT
} EPS_map_level;
#line 28 "inform7/Chapter 34/Scenes.w"
typedef struct scene_connector {
struct scene *connect_to; /* scene connected to */
int end; /* end number: see above */
struct scene_connector *next; /* next in list of connectors for a scene end */
struct parse_node *where_said; /* where this linkage was specified in source */
} scene_connector;
#line 35 "inform7/Chapter 34/Scenes.w"
typedef struct scene {
struct instance *as_instance; /* the constant for the name of the scene */
int once_only; /* cannot repeat during play */
int start_of_play; /* if begins when play begins */
int marker; /* used to detect potentially infinite recursion when scene changes occur */
int no_ends; /* how many ends the scene has */
struct wording end_names[MAX_SCENE_ENDS]; /* for ends 2, 3, ...: e.g. "badly" */
struct rulebook *end_rulebook[MAX_SCENE_ENDS]; /* rules to apply then */
struct parse_node *anchor_condition[MAX_SCENE_ENDS];
struct scene_connector *anchor_scene[MAX_SCENE_ENDS]; /* linked list */
int indexed; /* temporary storage during Scenes index creation */
struct parse_node *scene_declared_at; /* where defined */
struct parse_node *anchor_condition_set[MAX_SCENE_ENDS]; /* where set */
MEMORY_MANAGEMENT
} scene;
#line 38 "inform7/Chapter 35/Actions.w"
typedef struct action_name {
struct wording present_name; /* such as "drop" or "take" */
struct wording past_name; /* such as "dropped" or "taken" */
int it_optional; /* noun optional when describing the second noun? */
int abbreviable; /* preposition optional when describing the second noun? */
char an_I6_identifier[32]; /* compile to this action name in I6 */
int out_of_world; /* action is declared as out of world? */
int use_verb_routine_in_I6_library; /* rather than compiling our own? */
struct rulebook *check_rules; /* rulebooks private to this action */
struct rulebook *carry_out_rules;
struct rulebook *report_rules;
struct stacked_variable_owner *owned_by_an; /* action variables owned here */
struct parse_node *designers_specification; /* where created */
int requires_light; /* does this action require light to be carried out? */
int min_parameters, max_parameters; /* in the range 0 to 2 */
int noun_access; /* one of the possibilities below */
int second_access;
struct kind *noun_kind; /* if there is at least 1 parameter */
struct kind *second_kind; /* if there are 2 parameters */
struct grammar_line *list_with_action; /* list of grammar producing this */
int an_specification_text_word; /* description used in index */
int an_index_group; /* paragraph number it belongs to (1, 2, 3, ...) */
MEMORY_MANAGEMENT
} action_name;
#line 15 "inform7/Chapter 35/Action Name Lists.w"
typedef struct action_name_list {
struct action_name *action_listed; /* the action in this ANL list entry */
struct named_action_pattern *nap_listed; /* or a named pattern instead */
struct action_name_list *next; /* next in this ANL list */
int word_position; /* and some values used temporarily during parsing */
int negate_pattern; /* parity of the entire list which this heads */
int parity; /* parity of just this individual item */
int parc;
struct wording parameter[2];
struct wording in_clause;
int abbreviation_level; /* number of words missing */
int anyone_specified;
int delete_this_link; /* used temporarily during parsing */
} action_name_list;
#line 67 "inform7/Chapter 35/Action Patterns.w"
typedef struct ap_optional_clause {
struct stacked_variable *stv_to_match;
struct parse_node *clause_spec;
int allow_region_as_room;
struct ap_optional_clause *next;
MEMORY_MANAGEMENT
} ap_optional_clause;
#line 14 "inform7/Chapter 35/Looping Over Scope.w"
typedef struct loop_over_scope {
struct parse_node *what_to_find;
MEMORY_MANAGEMENT
} loop_over_scope;
#line 15 "inform7/Chapter 35/Named Action Patterns.w"
typedef struct named_action_pattern {
struct action_pattern *first; /* list of APs defining this NAP */
struct wording text_of_declaration;
char nap_I6_identifier[32]; /* for an I6 routine to test this NAP */
MEMORY_MANAGEMENT
} named_action_pattern;
#line 24 "inform7/Chapter 35/Actions Index.w"
typedef struct command_index_entry {
int nature; /* one of the above values */
char *command_headword; /* text of command headword, such as "REMOVE" */
struct grammar_verb *gv_indexed; /* ...leading to... */
struct command_index_entry *next_alphabetically; /* next in linked list */
MEMORY_MANAGEMENT
} command_index_entry;
#line 18 "inform7/Chapter 36/Traverse for Grammar.w"
typedef struct cached_understanding {
struct wording understanding_text; /* word range of the understanding text */
int consult_grammar_no; /* the |N| for this |Consult_Grammar_N| routine */
MEMORY_MANAGEMENT
} cached_understanding;
#line 27 "inform7/Chapter 36/Traverse for Grammar.w"
typedef struct understanding_item {
struct wording quoted_text;
struct property *quoted_property;
struct understanding_item *next;
} understanding_item;
#line 33 "inform7/Chapter 36/Traverse for Grammar.w"
typedef struct understanding_reference {
struct wording reference_text;
int gv_result;
int mword;
int mistaken;
int pluralised_reference;
int reversed_reference;
action_name *an_reference;
parse_node *spec_reference;
struct understanding_reference *next;
} understanding_reference;
#line 32 "inform7/Chapter 36/Grammar Properties.w"
typedef struct parsing_data {
struct grammar_verb *understand_as_this_object; /* grammar for parsing the name at run-time */
MEMORY_MANAGEMENT
} parsing_data;
#line 40 "inform7/Chapter 36/Grammar Properties.w"
typedef struct parsing_pp_data {
int visibility_level_in_parser; /* if so, does the run-time I6 parser recognise it? */
struct wording visibility_condition; /* (at least if...?) */
struct parse_node *visibility_sentence; /* where this is specified */
MEMORY_MANAGEMENT
} parsing_pp_data;
#line 14 "inform7/Chapter 36/Grammar Types.w"
typedef struct grammar_type {
int no_resulting_values; /* number of resulting values: 0, 1 or 2; or |-1| */
struct parse_node *first_type; /* and their types */
struct parse_node *second_type;
int first_multiplicity; /* lines only: allow a multiple object here? */
int second_multiplicity; /* lines only: allow a multiple object here? */
} grammar_type;
#line 43 "inform7/Chapter 36/Grammar Verbs.w"
typedef struct grammar_verb {
int gv_is; /* one of the five values above */
struct grammar_type gv_type;
struct grammar_line *first_line; /* linked list in creation order */
struct grammar_line *sorted_first_line; /* and in logical applicability order */
struct wording command; /* |GV_IS_COMMAND|: word number at which command found */
struct wording aliased_command[MAX_ALIASED_COMMANDS]; /* ...and other commands synonymous */
int no_aliased_commands; /* ...and how many of them there are */
struct wording name; /* |GV_IS_TOKEN|: name of this token */
struct inference_subject *subj_understood; /* |GV_IS_OBJECT|: what this provides names for */
struct kind *kind_understood; /* |GV_IS_VALUE|: for which type it names an instance of */
struct property *prn_understood; /* |GV_IS_PROPERTY_NAME|: which prn this names */
struct parse_node *where_gv_created; /* for problem message reports */
char gv_I6_identifier[32]; /* when a token is delegated to an I6 routine */
int slashed; /* slashing has been done */
int determined; /* determination has been done */
MEMORY_MANAGEMENT
} grammar_verb;
#line 79 "inform7/Chapter 36/Grammar Verbs.w"
typedef struct reserved_command_verb {
char reserved_text[32];
MEMORY_MANAGEMENT
} reserved_command_verb;
#line 36 "inform7/Chapter 36/Grammar Lines.w"
typedef struct grammar_line {
struct grammar_line *next_line; /* linked list in creation order */
struct grammar_line *sorted_next_line; /* and in applicability order */
struct parse_node *where_grammar_specified; /* where found in source */
int original_text; /* the word number of the double-quoted grammar text... */
struct parse_node *tokens; /* ...which is parsed into this list of tokens */
int lexeme_count; /* number of lexemes, or |-1| if not yet counted */
struct wording understand_when_text; /* only when this condition holds */
struct pcalc_prop *understand_when_prop; /* and when this condition holds */
int pluralised; /* |GV_IS_OBJECT|: refers in the plural */
struct action_name *resulting_action; /* |GV_IS_COMMAND|: the action */
int reversed; /* |GV_IS_COMMAND|: the two arguments are in reverse order */
int mistaken; /* |GV_IS_COMMAND|: is this understood as a mistake? */
struct wording mistake_response_text; /* if so, reply thus */
struct grammar_type gl_type;
int suppress_compilation; /* has been compiled in a single I6 grammar token already? */
struct grammar_line *next_with_action; /* used when indexing actions */
struct grammar_verb *belongs_to_gv; /* similarly, used only in indexing */
int general_sort_bonus; /* temporary values used in grammar line sorting */
int understanding_sort_bonus;
MEMORY_MANAGEMENT
} grammar_line;
#line 69 "inform7/Chapter 36/Grammar Lines.w"
typedef struct slash_gpr {
struct parse_node *first_choice;
struct parse_node *last_choice;
MEMORY_MANAGEMENT
} slash_gpr;
#line 16 "inform7/Chapter 36/Noun Filter Tokens.w"
typedef struct noun_filter_token {
struct parse_node *the_filter;
struct parse_node *nft_created_at;
int global_scope_flag;
int any_things_flag;
int parse_using_gpr;
int nft_compiled;
char nft_routine_name[32];
MEMORY_MANAGEMENT
} noun_filter_token;
#line 28 "inform7/Chapter 36/Test Scripts.w"
typedef struct test_scenario {
struct wording name; /* in fact a single word identifying the test */
char text_of_script[MAX_LENGTH_OF_SCRIPT];
struct instance *place; /* room we need to be in to perform test */
int no_possessions; /* number of required possessions of player */
struct instance *possessions[MAX_POSSESSIONS_PER_SCENARIO]; /* what they are */
struct parse_node *sentence_test_declared_at;
MEMORY_MANAGEMENT
} test_scenario;
#line 41 "inform7/Chapter 36/Test Scripts.w"
typedef struct internal_test_case {
int itc_code; /* one of the above |*_INTT| values */
struct wording text_supplying_the_case;
struct parse_node *itc_defined_at;
MEMORY_MANAGEMENT
} internal_test_case;
#line 19 "inform7/Chapter 37/Figures.w"
typedef struct blorb_figure {
struct wording name; /* text of name */
struct filename *filename_of_image_file;
int figure_number; /* resource number of this picture inside Blorb */
int alt_description; /* word number of double-quoted description */
MEMORY_MANAGEMENT
} blorb_figure;
#line 20 "inform7/Chapter 37/Sound Effects.w"
typedef struct blorb_sound {
struct wording name; /* text of name */
struct filename *filename_of_sound_file; /* relative to the Resources folder */
int sound_number; /* resource number of this picture inside Blorb */
int alt_description; /* word number of double-quoted description */
MEMORY_MANAGEMENT
} blorb_sound;
#line 22 "inform7/Chapter 37/External Files.w"
typedef struct external_file {
struct wording name; /* text of name */
int unextended_filename; /* word number of text like |"bones"| */
char exf_I6_identifier[32]; /* an I6 identifier */
int file_is_binary; /* true or false */
int file_ownership; /* one of the above */
char IFID_of_owner[48]; /* an I6 identifier */
MEMORY_MANAGEMENT
} external_file;
#line 24 "inform7/Chapter 38/I6 Template Interpreter.w"
typedef struct I6T_intervention {
int intervention_stage; /* $-1$ for before, 0 for instead, 1 for after */
char *segment_name;
char *part_name; /* or NULL to mean the entire segment */
unsigned char *I6T_matter; /* to be used at the given position, or NULL */
char *alternative_segment; /* to be used at the given position, or NULL */
int segment_found; /* did the segment name match one actually read? */
int part_found; /* did the part name? */
struct parse_node *where_intervention_requested; /* at what sentence? */
MEMORY_MANAGEMENT
} I6T_intervention;
#line 19 "inform7/Chapter 38/Plugins.w"
typedef struct plugin {
struct word_assemblage plugin_name;
int plugin_number;
struct word_assemblage set_name;
int set_number;
void *starter_routine;
int now_plugged_in;
int stores_data;
int has_been_set_explicitly;
char *has_template_file;
char *IFDEF_symbol;
MEMORY_MANAGEMENT
} plugin;
#line 53 "inform7/Chapter 38/Plugin Calls.w"
typedef struct plugin_call {
void *routine;
struct plugin_call *next;
} plugin_call;
#line 120 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__Windows_isdigit(int c) ;
#line 189 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__mkdir(char *path_to_folder) ;
#line 201 "inform7/Chapter 1/Platform-Specific Definitions.w"
void * Platform__opendir(char *path_to_folder) ;
#line 206 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__readdir(void *folder, char *path_to_folder, char *leafname) ;
#line 225 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__closedir(void *folder) ;
#line 243 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__mkdir(char *path_to_folder) ;
#line 255 "inform7/Chapter 1/Platform-Specific Definitions.w"
void * Platform__opendir(char *path_to_folder) ;
#line 260 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__readdir(void *folder, char *path_to_folder, char *leafname) ;
#line 280 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__closedir(void *folder) ;
#line 312 "inform7/Chapter 1/Platform-Specific Definitions.w"
FILE * Platform__iso_fopen(filename *F, char *usage) ;
#line 320 "inform7/Chapter 1/Platform-Specific Definitions.w"
FILE * Platform__iso_fopen_caseless(filename *F, char *usage) ;
#line 332 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__transcode_ISO_string_to_locale(char *from, char *to) ;
#line 338 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__transcode_ISO_string_to_locale(char *from, char *to) ;
#line 359 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__truncated_locale_fgets(FILE *F, char *buffer, int limit) ;
#line 365 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__truncated_locale_fgets(FILE *F, char *buffer, int limit) ;
#line 386 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__truncated_locale_arg(char *arg, char *buffer, int limit) ;
#line 392 "inform7/Chapter 1/Platform-Specific Definitions.w"
void Platform__truncated_locale_arg(char *arg, char *buffer, int limit) ;
#line 409 "inform7/Chapter 1/Platform-Specific Definitions.w"
char Platform__tolower(char c) ;
#line 412 "inform7/Chapter 1/Platform-Specific Definitions.w"
char Platform__toupper(char c) ;
#line 415 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__isalpha(char c) ;
#line 418 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__isdigit(char c) ;
#line 421 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__strlen(const char *p) ;
#line 432 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__truncated_iso_fgets(FILE *F, char *buffer, int limit) ;
#line 279 "inform7/Chapter 2/Memory.w"
void Memory__start(void) ;
#line 364 "inform7/Chapter 2/Memory.w"
void Memory__allocate_another_block(void) ;
#line 415 "inform7/Chapter 2/Memory.w"
void Memory__free_memory(void) ;
#line 462 "inform7/Chapter 2/Memory.w"
void Memory__check_integrity(void) ;
#line 479 "inform7/Chapter 2/Memory.w"
void Memory__debug_frames(int from, int to) ;
#line 498 "inform7/Chapter 2/Memory.w"
void * Memory__allocate(int mem_type, int extent) ;
#line 916 "inform7/Chapter 2/Memory.w"
void * Memory__I7_calloc(int how_many, int size_in_bytes, int reason) ;
#line 919 "inform7/Chapter 2/Memory.w"
void * Memory__I7_malloc(int size_in_bytes, int reason) ;
#line 926 "inform7/Chapter 2/Memory.w"
void * Memory__I7_alloc(int N, int S, int R) ;
#line 983 "inform7/Chapter 2/Memory.w"
void Memory__I7_free(void *pointer, int R) ;
#line 1005 "inform7/Chapter 2/Memory.w"
void Memory__I7_free_remaining(void) ;
#line 1019 "inform7/Chapter 2/Memory.w"
int Memory__log_usage(int total) ;
#line 1038 "inform7/Chapter 2/Memory.w"
void Memory__log_statistics(void) ;
#line 1114 "inform7/Chapter 2/Memory.w"
int Memory__compare_usage(const void *ent1, const void *ent2) ;
#line 1124 "inform7/Chapter 2/Memory.w"
int Memory__proportion(int bytes, int total) ;
#line 1157 "inform7/Chapter 2/Memory.w"
general_pointer Memory__store_gp_null(void) ;
#line 1163 "inform7/Chapter 2/Memory.w"
int Memory__test_gp_null(general_pointer gp) ;
#line 268 "inform7/Chapter 2/Streams.w"
void Streams__initialise(text_stream *stream) ;
#line 289 "inform7/Chapter 2/Streams.w"
text_stream * Streams__get_stdout(void) ;
#line 301 "inform7/Chapter 2/Streams.w"
text_stream * Streams__get_stderr(void) ;
#line 314 "inform7/Chapter 2/Streams.w"
int Streams__open_to_file(text_stream *stream, filename *name, int encoding) ;
#line 328 "inform7/Chapter 2/Streams.w"
int Streams__open_to_file_append(text_stream *stream, filename *name, int encoding) ;
#line 345 "inform7/Chapter 2/Streams.w"
int Streams__open_to_memory(text_stream *stream, int capacity) ;
#line 363 "inform7/Chapter 2/Streams.w"
text_stream Streams__new_buffer(int capacity, char *at) ;
#line 380 "inform7/Chapter 2/Streams.w"
void Streams__flush(text_stream *stream) ;
#line 388 "inform7/Chapter 2/Streams.w"
void Streams__close(text_stream *stream) ;
#line 436 "inform7/Chapter 2/Streams.w"
void Streams__printf(text_stream *stream, char *fmt, ...) ;
#line 525 "inform7/Chapter 2/Streams.w"
void Streams__putc(int c_int, text_stream *stream) ;
#line 641 "inform7/Chapter 2/Streams.w"
void Streams__literal(text_stream *stream, char *p) ;
#line 656 "inform7/Chapter 2/Streams.w"
void Streams__indent(text_stream *stream) ;
#line 661 "inform7/Chapter 2/Streams.w"
void Streams__outdent(text_stream *stream) ;
#line 668 "inform7/Chapter 2/Streams.w"
void Streams__set_indentation(text_stream *stream, int N) ;
#line 680 "inform7/Chapter 2/Streams.w"
int Streams__get_position(text_stream *stream) ;
#line 694 "inform7/Chapter 2/Streams.w"
int Streams__latest(text_stream *stream) ;
#line 713 "inform7/Chapter 2/Streams.w"
void Streams__set_position(text_stream *stream, int position) ;
#line 740 "inform7/Chapter 2/Streams.w"
char * Streams__get_text(text_stream *stream) ;
#line 746 "inform7/Chapter 2/Streams.w"
int Streams__all_text_accessible(text_stream *stream) ;
#line 757 "inform7/Chapter 2/Streams.w"
void Streams__copy(text_stream *to, text_stream *from) ;
#line 268 "inform7/Chapter 2/Debugging Log.w"
void Log__open(void) ;
#line 278 "inform7/Chapter 2/Debugging Log.w"
void Log__close(void) ;
#line 295 "inform7/Chapter 2/Debugging Log.w"
void Log__ensure_telemetry_file(void) ;
#line 311 "inform7/Chapter 2/Debugging Log.w"
void Log__write_to_telemetry_file(char *m) ;
#line 321 "inform7/Chapter 2/Debugging Log.w"
void Log__read_further_mandatory_text(void) ;
#line 346 "inform7/Chapter 2/Debugging Log.w"
void Log__new_phase_of_Informs_run(char *p, char *q) ;
#line 355 "inform7/Chapter 2/Debugging Log.w"
void Log__new_stage_of_Informs_run(char *p) ;
#line 369 "inform7/Chapter 2/Debugging Log.w"
int Log__aspect_switched_on(int aspect) ;
#line 376 "inform7/Chapter 2/Debugging Log.w"
void Log__set_aspect(int aspect, int state) ;
#line 383 "inform7/Chapter 2/Debugging Log.w"
void Log__set_all_aspects(int new_state) ;
#line 426 "inform7/Chapter 2/Debugging Log.w"
void Log__set_aspect_from_text(wording W, int new_state) ;
#line 501 "inform7/Chapter 2/Debugging Log.w"
void Log__set_aspect_from_command_line(char *text) ;
#line 542 "inform7/Chapter 2/Debugging Log.w"
void Log__tracing_on(int starred, char *heading) ;
#line 563 "inform7/Chapter 2/Debugging Log.w"
void Log__tracing_phrases(char *text) ;
#line 598 "inform7/Chapter 2/Debugging Log.w"
void Log__show_debugging_settings_with_state(int state) ;
#line 613 "inform7/Chapter 2/Debugging Log.w"
void Log__show_debugging_contents(void) ;
#line 626 "inform7/Chapter 2/Debugging Log.w"
void Log__paste_icons(void) ;
#line 651 "inform7/Chapter 2/Debugging Log.w"
void Log__dlprintf(char *fmt, ...) ;
#line 40 "inform7/Chapter 2/Progress Percentages.w"
void ProgressBar__update_progress_bar(int stage, float proportion) ;
#line 50 "inform7/Chapter 2/Progress Percentages.w"
void ProgressBar__final_state_of_progress_bar(void) ;
#line 61 "inform7/Chapter 2/Progress Percentages.w"
text_stream * ProgressBar__begin_outcome(void) ;
#line 67 "inform7/Chapter 2/Progress Percentages.w"
void ProgressBar__end_outcome(void) ;
#line 63 "inform7/Chapter 3/Pathnames.w"
pathname * Pathnames__subfolder(pathname *P, char *folder_name) ;
#line 67 "inform7/Chapter 3/Pathnames.w"
pathname * Pathnames__primitive(char *c_string, int from, int to, pathname *par) ;
#line 89 "inform7/Chapter 3/Pathnames.w"
pathname * Pathnames__from_string(char *path) ;
#line 93 "inform7/Chapter 3/Pathnames.w"
pathname * Pathnames__from_string_relative(pathname *P, char *path) ;
#line 110 "inform7/Chapter 3/Pathnames.w"
void Pathnames__to_string(char *to, pathname *P) ;
#line 115 "inform7/Chapter 3/Pathnames.w"
int Pathnames__to_string_r(char *to, pathname *P, int room_left) ;
#line 142 "inform7/Chapter 3/Pathnames.w"
void Pathnames__to_string_relative(char *to, pathname *P, pathname *R) ;
#line 161 "inform7/Chapter 3/Pathnames.w"
void Pathnames__start(void) ;
#line 174 "inform7/Chapter 3/Pathnames.w"
int Pathnames__create_in_file_system(pathname *P) ;
#line 198 "inform7/Chapter 3/Pathnames.w"
int Pathnames__write_contents_to_file(filename *writeto, pathname *P) ;
#line 221 "inform7/Chapter 3/Pathnames.w"
int Pathnames__write_contents_to_stream(OUTPUT_STREAM, pathname *P) ;
#line 30 "inform7/Chapter 3/Filenames.w"
filename * Filenames__in_folder(pathname *P, char *file_name) ;
#line 34 "inform7/Chapter 3/Filenames.w"
filename * Filenames__primitive(char *c_string, int from, int to, pathname *par) ;
#line 51 "inform7/Chapter 3/Filenames.w"
filename * Filenames__from_string(pathname *F, char *path) ;
#line 67 "inform7/Chapter 3/Filenames.w"
void Filenames__to_string(char *to, filename *F) ;
#line 80 "inform7/Chapter 3/Filenames.w"
void Filenames__to_string_relative(char *to, filename *F, pathname *P) ;
#line 96 "inform7/Chapter 3/Filenames.w"
char * Filenames__get_leafname(filename *F) ;
#line 86 "inform7/Chapter 3/Where Everything Lives.w"
int Locations__command_line_setting(char *option, char *arg) ;
#line 121 "inform7/Chapter 3/Where Everything Lives.w"
int Locations__set_defaults(int census_mode) ;
#line 448 "inform7/Chapter 3/Where Everything Lives.w"
void Locations__EILT_at(int area, pathname *P) ;
#line 472 "inform7/Chapter 3/Where Everything Lives.w"
filename * Locations__of_extension(pathname *E, char *title, char *author, int i7x_flag) ;
#line 482 "inform7/Chapter 3/Where Everything Lives.w"
filename * Locations__of_extension_documentation(char *title, char *author) ;
#line 496 "inform7/Chapter 3/Where Everything Lives.w"
filename * Locations__in_index(char *leafname, int sub) ;
#line 58 "inform7/Chapter 3/Case-Insensitive Filenames.w"
FILE * CIFilingSystem__fopen(const char *path, const char *mode) ;
#line 232 "inform7/Chapter 3/Case-Insensitive Filenames.w"
int CIFilingSystem__match_in_directory(void *vd, char *name, char *last_match) ;
#line 257 "inform7/Chapter 3/Case-Insensitive Filenames.w"
FILE * CIFilingSystem__fopen(const char *path, const char *mode) ;
#line 11 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_int8(FILE *binary_file, unsigned int *result) ;
#line 19 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_int16(FILE *binary_file, unsigned int *result) ;
#line 30 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_int32(FILE *binary_file, unsigned int *result) ;
#line 45 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_int64(FILE *binary_file, unsigned long long *result) ;
#line 74 "inform7/Chapter 3/Binary Files.w"
void BinaryFiles__swap_bytes32(unsigned int *value) ;
#line 82 "inform7/Chapter 3/Binary Files.w"
void BinaryFiles__swap_bytes64(unsigned long long *value) ;
#line 100 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_variable_length_integer(FILE *binary_file, unsigned int *result) ;
#line 117 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_float80(FILE *binary_file, unsigned int *result) ;
#line 142 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_string(FILE *binary_file, char *string, unsigned int length) ;
#line 27 "inform7/Chapter 3/Image Dimensions.w"
int ImageFiles__get_JPEG_dimensions(FILE *JPEG_file, unsigned int *width, unsigned int *height) ;
#line 80 "inform7/Chapter 3/Image Dimensions.w"
int ImageFiles__get_PNG_dimensions(FILE *PNG_file, unsigned int *width, unsigned int *height) ;
#line 15 "inform7/Chapter 3/Sound Durations.w"
int SoundFiles__get_AIFF_duration(FILE *pFile, unsigned int *pDuration, unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) ;
#line 62 "inform7/Chapter 3/Sound Durations.w"
int SoundFiles__get_OggVorbis_duration(FILE *pFile, unsigned int *pDuration, unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) ;
#line 184 "inform7/Chapter 3/Sound Durations.w"
int SoundFiles__get_MIDI_information(FILE *pFile, unsigned int *pType, unsigned int *pNumTracks) ;
#line 105 "inform7/Chapter 4/HTML Files.w"
void HTML__set_source_link_case(char *p) ;
#line 109 "inform7/Chapter 4/HTML Files.w"
void HTML__html_source_link(OUTPUT_STREAM, source_location sl, int nonbreaking_space) ;
#line 139 "inform7/Chapter 4/HTML Files.w"
void HTML__html_icon_with_tooltip(OUTPUT_STREAM, char *icon_name, char *tip, char *tip2) ;
#line 195 "inform7/Chapter 4/HTML Files.w"
void HTML__html_outcome_image(OUTPUT_STREAM, char *image, char *verdict) ;
#line 248 "inform7/Chapter 4/HTML Files.w"
void HTML__outcome_image_tail(OUTPUT_STREAM) ;
#line 267 "inform7/Chapter 4/HTML Files.w"
void HTML__html_header(OUTPUT_STREAM, char *title, char *thumbnail, char *caption) ;
#line 441 "inform7/Chapter 4/HTML Files.w"
void HTML__html_header_complete(OUTPUT_STREAM, char *title, char *thumbnail) ;
#line 450 "inform7/Chapter 4/HTML Files.w"
void HTML__html_footer(OUTPUT_STREAM) ;
#line 459 "inform7/Chapter 4/HTML Files.w"
void HTML__open_para(OUTPUT_STREAM, int depth, char *class) ;
#line 470 "inform7/Chapter 4/HTML Files.w"
void HTML__test_html_paragraphs(void) ;
#line 520 "inform7/Chapter 4/HTML Files.w"
void HTML__html_char_out(OUTPUT_STREAM, char c) ;
#line 568 "inform7/Chapter 4/HTML Files.w"
void HTML__begin_plain_html_table(OUTPUT_STREAM) ;
#line 572 "inform7/Chapter 4/HTML Files.w"
void HTML__begin_wide_html_table(OUTPUT_STREAM) ;
#line 581 "inform7/Chapter 4/HTML Files.w"
void HTML__begin_html_table(OUTPUT_STREAM, char *colour, int full_width, int border, int cellspacing, int cellpadding, int height, int width) ;
#line 594 "inform7/Chapter 4/HTML Files.w"
void HTML__begin_html_table_bg(OUTPUT_STREAM, char *colour, int full_width, int border, int cellspacing, int cellpadding, int height, int width, char *bg) ;
#line 605 "inform7/Chapter 4/HTML Files.w"
void HTML__first_html_column(OUTPUT_STREAM, int width) ;
#line 610 "inform7/Chapter 4/HTML Files.w"
void HTML__first_html_column_nowrap(OUTPUT_STREAM, int width, char *colour) ;
#line 616 "inform7/Chapter 4/HTML Files.w"
void HTML__first_html_column_spaced(OUTPUT_STREAM, int width) ;
#line 621 "inform7/Chapter 4/HTML Files.w"
void HTML__first_html_column_coloured(OUTPUT_STREAM, int width, char *col, int cs) ;
#line 629 "inform7/Chapter 4/HTML Files.w"
void HTML__next_html_column(OUTPUT_STREAM, int width) ;
#line 635 "inform7/Chapter 4/HTML Files.w"
void HTML__next_html_column_centred(OUTPUT_STREAM, int width) ;
#line 641 "inform7/Chapter 4/HTML Files.w"
void HTML__next_html_column_spanning(OUTPUT_STREAM, int width, int sp) ;
#line 647 "inform7/Chapter 4/HTML Files.w"
void HTML__next_html_column_nowrap(OUTPUT_STREAM, int width) ;
#line 653 "inform7/Chapter 4/HTML Files.w"
void HTML__next_html_column_spaced(OUTPUT_STREAM, int width) ;
#line 659 "inform7/Chapter 4/HTML Files.w"
void HTML__next_html_column_nw(OUTPUT_STREAM, int width) ;
#line 665 "inform7/Chapter 4/HTML Files.w"
void HTML__next_html_column_w(OUTPUT_STREAM, int width) ;
#line 670 "inform7/Chapter 4/HTML Files.w"
void HTML__next_html_column_right_justified(OUTPUT_STREAM, int width) ;
#line 675 "inform7/Chapter 4/HTML Files.w"
void HTML__end_html_row(OUTPUT_STREAM) ;
#line 678 "inform7/Chapter 4/HTML Files.w"
void HTML__end_html_table(OUTPUT_STREAM) ;
#line 689 "inform7/Chapter 4/HTML Files.w"
void HTML__open_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) ;
#line 702 "inform7/Chapter 4/HTML Files.w"
void HTML__close_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) ;
#line 713 "inform7/Chapter 4/HTML Files.w"
void HTML__box_corner(OUTPUT_STREAM, char *html_colour, char *corner) ;
#line 724 "inform7/Chapter 4/HTML Files.w"
void HTML__write_xml_safe_text(OUTPUT_STREAM, char *txt) ;
#line 748 "inform7/Chapter 4/HTML Files.w"
void HTML__compile_bibliographic_text(OUTPUT_STREAM, char *p) ;
#line 932 "inform7/Chapter 4/HTML Files.w"
int HTML__iso_remove_accents(int charcode) ;
#line 967 "inform7/Chapter 4/HTML Files.w"
int HTML__combining_accent(int accent, int letter) ;
#line 1020 "inform7/Chapter 4/HTML Files.w"
int HTML__without_accent(int letter) ;
#line 1048 "inform7/Chapter 4/HTML Files.w"
int HTML__is_babel_whitespace(char c) ;
#line 1214 "inform7/Chapter 4/HTML Files.w"
char * HTML__translate_colour_name(char *original) ;
#line 93 "inform7/Chapter 4/Javascript Pastes.w"
void HTML__Javascript__paste_W(OUTPUT_STREAM, wording W) ;
#line 96 "inform7/Chapter 4/Javascript Pastes.w"
void HTML__Javascript__paste(OUTPUT_STREAM, char *alt_text) ;
#line 99 "inform7/Chapter 4/Javascript Pastes.w"
void HTML__Javascript__paste_inner(OUTPUT_STREAM, int from, int to, char *alt_text) ;
#line 126 "inform7/Chapter 4/Javascript Pastes.w"
void HTML__Javascript__open_file(OUTPUT_STREAM, pathname *P, char *leaf, char *contents) ;
#line 148 "inform7/Chapter 4/Javascript Pastes.w"
void HTML__Javascript__javascript_string_out(OUTPUT_STREAM, int from, int to, char *C_string) ;
#line 253 "inform7/Chapter 4/Javascript Pastes.w"
void HTML__Javascript__javascript_char_out(OUTPUT_STREAM, char c) ;
#line 46 "inform7/Chapter 4/HTML Documentation.w"
void HTML__Documentation__href_of_example(OUTPUT_STREAM, char *base_leafname, int to_example_variant, int to_example_anchor) ;
#line 76 "inform7/Chapter 4/HTML Documentation.w"
int HTML__Documentation__extension_documentation_heading(wording W, int *level, wording *HW) ;
#line 112 "inform7/Chapter 4/HTML Documentation.w"
int HTML__Documentation__extension_documentation_example(wording W, int *asterisks, wording *egn, wording *egr) ;
#line 148 "inform7/Chapter 4/HTML Documentation.w"
void HTML__Documentation__set_table_of_contents(wording W, OUTPUT_STREAM, char *base_leafname) ;
#line 230 "inform7/Chapter 4/HTML Documentation.w"
int HTML__Documentation__set_body_text(wording W, OUTPUT_STREAM, int example_which_is_open, char *base_leafname) ;
#line 57 "inform7/Chapter 5/Index File Services.w"
void Index__set_thumbnail_image(char *image, char *caption) ;
#line 65 "inform7/Chapter 5/Index File Services.w"
void Index__new_page(char *col) ;
#line 93 "inform7/Chapter 5/Index File Services.w"
void Index__new_segment(char *abb, char *title, char *explanation) ;
#line 111 "inform7/Chapter 5/Index File Services.w"
void Index__open_file(char *index_leaf, char *title, int sub, char *explanation) ;
#line 290 "inform7/Chapter 5/Index File Services.w"
void Index__index_banner_line(int N, char *sym, char *name, char *exp, char *link) ;
#line 324 "inform7/Chapter 5/Index File Services.w"
void Index__scripting(void) ;
#line 597 "inform7/Chapter 5/Index File Services.w"
void Index__index_actual_element(char *elt) ;
#line 713 "inform7/Chapter 5/Index File Services.w"
void Index__explain(char *explanation) ;
#line 749 "inform7/Chapter 5/Index File Services.w"
void Index__complete(void) ;
#line 754 "inform7/Chapter 5/Index File Services.w"
void Index__close_index_file(void) ;
#line 775 "inform7/Chapter 5/Index File Services.w"
void Index__link(int wn) ;
#line 779 "inform7/Chapter 5/Index File Services.w"
void Index__link_location(source_location sl) ;
#line 783 "inform7/Chapter 5/Index File Services.w"
void Index__link_to(OUTPUT_STREAM, int wn, int nonbreaking_space) ;
#line 787 "inform7/Chapter 5/Index File Services.w"
void Index__link_to_location(OUTPUT_STREAM, source_location sl, int nonbreaking_space) ;
#line 807 "inform7/Chapter 5/Index File Services.w"
void Index__detail_link(char *stub, int sub, int down) ;
#line 819 "inform7/Chapter 5/Index File Services.w"
void Index__below_link(char *p) ;
#line 824 "inform7/Chapter 5/Index File Services.w"
void Index__anchor(char *p) ;
#line 828 "inform7/Chapter 5/Index File Services.w"
void Index__below_link_numbered(int n) ;
#line 833 "inform7/Chapter 5/Index File Services.w"
void Index__anchor_numbered(int n) ;
#line 840 "inform7/Chapter 5/Index File Services.w"
void Index__extra_link(int id) ;
#line 846 "inform7/Chapter 5/Index File Services.w"
void Index__extra_link_with(int id, char *icon) ;
#line 858 "inform7/Chapter 5/Index File Services.w"
void Index__noextra_link(void) ;
#line 865 "inform7/Chapter 5/Index File Services.w"
void Index__extra_div_open(int id, int indent, char *colour) ;
#line 871 "inform7/Chapter 5/Index File Services.w"
void Index__extra_div_close(char *colour) ;
#line 876 "inform7/Chapter 5/Index File Services.w"
void Index__extra_div_open_nested(int id, int indent) ;
#line 881 "inform7/Chapter 5/Index File Services.w"
void Index__extra_div_close_nested(void) ;
#line 888 "inform7/Chapter 5/Index File Services.w"
void Index__deprecation_icon(int id) ;
#line 899 "inform7/Chapter 5/Index File Services.w"
void Index__dequote(char *p) ;
#line 58 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__dref_new(parse_node *p) ;
#line 93 "inform7/Chapter 5/Documentation References.w"
char * Index__DocReferences__validate_if_possible(char *temp) ;
#line 105 "inform7/Chapter 5/Documentation References.w"
char * Index__DocReferences__link_if_possible_once(char *temp, char **chap, char **sec) ;
#line 140 "inform7/Chapter 5/Documentation References.w"
wording Index__DocReferences__position_of_symbol(wording *W) ;
#line 153 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__doc_mark_used(char *symb, int at_word) ;
#line 179 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__log_statistics(void) ;
#line 195 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__link(char *fn) ;
#line 199 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__fully_link(char *fn) ;
#line 203 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__link_to(OUTPUT_STREAM, char *fn, int full) ;
#line 222 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__doc_fragment(char *fn) ;
#line 227 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__doc_fragment_to(OUTPUT_STREAM, char *fn) ;
#line 295 "inform7/Chapter 5/Documentation References.w"
documentation_ref * Index__DocReferences__name_to_dr(char *fn) ;
#line 58 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry * Index__Lexicon__lexicon_new_entry(wording W) ;
#line 73 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry * Index__Lexicon__new_entry_with_details(wording W, int pos, word_assemblage wa, char *category, char *gloss) ;
#line 82 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry * Index__Lexicon__new_main_verb(word_assemblage infinitive, int part) ;
#line 99 "inform7/Chapter 5/Lexicon Index.w"
void Index__Lexicon__lexicon_copy_to_string(lexicon_entry *lex, char *str) ;
#line 112 "inform7/Chapter 5/Lexicon Index.w"
void Index__Lexicon__index(void) ;
#line 133 "inform7/Chapter 5/Lexicon Index.w"
void Index__Lexicon__index_common_nouns(void) ;
#line 445 "inform7/Chapter 5/Lexicon Index.w"
void Index__Lexicon__index_verbs(void) ;
#line 483 "inform7/Chapter 5/Lexicon Index.w"
void Index__Lexicon__list_verbs_in_file(OUTPUT_STREAM, source_file *sf, extension_file *ef) ;
#line 14 "inform7/Chapter 6/Problems, Level 0.w"
void Problems__Fatal__issue(char *message) ;
#line 22 "inform7/Chapter 6/Problems, Level 0.w"
void Problems__Fatal__issue_t(char *message, char *fn) ;
#line 30 "inform7/Chapter 6/Problems, Level 0.w"
void Problems__Fatal__filename_related(char *message, filename *F) ;
#line 44 "inform7/Chapter 6/Problems, Level 0.w"
void Problems__Fatal__force_crash(void) ;
#line 33 "inform7/Chapter 6/Problems, Level 1.w"
void Problems__Buffer__copy_text_into_problem_buffer(wording W) ;
#line 44 "inform7/Chapter 6/Problems, Level 1.w"
void Problems__Buffer__redirect_problem_sentence(parse_node *from, parse_node *A, parse_node *B) ;
#line 54 "inform7/Chapter 6/Problems, Level 1.w"
void Problems__Buffer__copy_source_reference_into_problem_buffer(wording W) ;
#line 105 "inform7/Chapter 6/Problems, Level 1.w"
int Problems__Buffer__is_problem_buffer_whitespace(char c) ;
#line 121 "inform7/Chapter 6/Problems, Level 1.w"
void Problems__Buffer__output_problem_buffer_to(OUTPUT_STREAM, int indentation) ;
#line 282 "inform7/Chapter 6/Problems, Level 1.w"
void Problems__Buffer__output_problem_buffer(int indentation) ;
#line 31 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__find_headings_at(parse_node *sentence, parse_node **problem_headings) ;
#line 43 "inform7/Chapter 6/Problems, Level 2.w"
int Problems__visit_for_headings(parse_node *p, parse_node *from, parse_node **sentence) ;
#line 78 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__show_problem_location(void) ;
#line 163 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__problem_quote(int t, char type, void *v) ;
#line 170 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__problem_quote_textual(int t, char type, wording W) ;
#line 181 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_source(int t, parse_node *p) ;
#line 185 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_source_eliding_begin(int t, parse_node *p) ;
#line 193 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_wording(int t, wording W) ;
#line 194 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_wording_tinted_green(int t, wording W) ;
#line 195 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_wording_tinted_red(int t, wording W) ;
#line 196 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_wording_as_source(int t, wording W) ;
#line 201 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_relation(int t, binary_predicate *bp) ;
#line 202 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_extension(int t, extension_file *ef) ;
#line 203 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_phrase(int t, phrase *p) ;
#line 204 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_invocation(int t, parse_node *inv) ;
#line 205 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_number(int t, int *num) ;
#line 206 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_object(int t, instance *I) ;
#line 207 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_subject(int t, inference_subject *infs) ;
#line 215 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_table(int t, table *tab) ;
#line 218 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_property(int t, property *p) ;
#line 219 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_text(int t, char *message) ;
#line 220 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_wa(int t, word_assemblage *wa) ;
#line 221 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_spec(int t, parse_node *spec) ;
#line 222 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_extension_id(int t, extension_identifier *eid) ;
#line 229 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_kind_of(int t, parse_node *spec) ;
#line 251 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_kind(int t, kind *K) ;
#line 279 "inform7/Chapter 6/Problems, Level 2.w"
int Problems__explained_before(char *explanation) ;
#line 300 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__issue_problem_begin(char *message) ;
#line 323 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__issue_problem_end(void) ;
#line 348 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__issue_problem_segment(char *message) ;
#line 579 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__write_reports(int disaster_struck) ;
#line 31 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__internal_error_end(void) ;
#line 46 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__internal_error_fn(char *p, char *filename, int linenum) ;
#line 64 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__internal_error_tu_fn(char *p, char *filename, int linenum) ;
#line 85 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__nodal_error_fn(parse_node *pn, char *p, char *filename, int linenum) ;
#line 94 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__nodal_check(parse_node *pn, node_type_t node_type_required, char *filename, int linenum) ;
#line 113 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__internal_error_on_node_type_fn(parse_node *pn, char *filename, int linenum) ;
#line 129 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__s_subtree_error_set_position(parse_node *p) ;
#line 132 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__s_subtree_error(char *mess) ;
#line 198 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__problem_documentation_links(OUTPUT_STREAM) ;
#line 217 "inform7/Chapter 6/Problems, Level 3.w"
char * Problems__Issue__latest_sigil(void) ;
#line 234 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__handmade_problem(SIGIL_ARGUMENTS) ;
#line 244 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__limit_problem(SIGIL_ARGUMENTS, char *what_has_run_out, int how_many) ;
#line 259 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__memory_allocation_problem(SIGIL_ARGUMENTS, char *what_has_run_out) ;
#line 279 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__lexical_problem(SIGIL_ARGUMENTS, char *message, char *concerning, char *exp) ;
#line 300 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__unlocated_problem(SIGIL_ARGUMENTS, char *message) ;
#line 309 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__unlocated_problem_on_file(SIGIL_ARGUMENTS, char *message, char *fn) ;
#line 326 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__sentence_problem(SIGIL_ARGUMENTS, char *message, char *explanation) ;
#line 339 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__sentence_problem_with_note(SIGIL_ARGUMENTS, char *message, char *explanation, char *note) ;
#line 355 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__sentence_in_detail_problem(SIGIL_ARGUMENTS, wording W, char *message, char *explanation) ;
#line 372 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__negative_sentence_problem(SIGIL_ARGUMENTS) ;
#line 392 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__assertion_problem(SIGIL_ARGUMENTS, char *message, char *explanation) ;
#line 427 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__diagnose_further(void) ;
#line 457 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__definition_problem(SIGIL_ARGUMENTS, parse_node *q, char *message, char *explanation) ;
#line 468 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__adjective_problem(SIGIL_ARGUMENTS, wording IX, wording D, char *message, char *explanation) ;
#line 487 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__two_sentences_problem(SIGIL_ARGUMENTS, parse_node *other_sentence, char *message, char *explanation) ;
#line 508 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__contradiction_problem(SIGIL_ARGUMENTS, parse_node *A, parse_node *B, instance *I, char *message, char *explanation) ;
#line 525 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__infs_contradiction_problem(SIGIL_ARGUMENTS, parse_node *A, parse_node *B, inference_subject *infs, char *message, char *explanation) ;
#line 547 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__table_problem(SIGIL_ARGUMENTS, table *t, table_column *tc, parse_node *data, char *message) ;
#line 563 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__equation_problem(SIGIL_ARGUMENTS, equation *eqn, char *p, char *text) ;
#line 576 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__equation_symbol_problem(SIGIL_ARGUMENTS, equation *eqn, wording W, char *text) ;
#line 590 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__inline_problem(SIGIL_ARGUMENTS, phrase *ph, char *definition, char *message) ;
#line 611 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__tcp_problem(SIGIL_ARGUMENTS, tc_problem_kit *tck, char *prototype) ;
#line 633 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__object_problem(SIGIL_ARGUMENTS, instance *I, char *message, char *explanation) ;
#line 644 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__object_problem_at_sentence(SIGIL_ARGUMENTS, instance *I, char *message, char *explanation) ;
#line 656 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__subject_problem_at_sentence(SIGIL_ARGUMENTS, inference_subject *infs, char *message, char *explanation) ;
#line 674 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__subject_creation_problem(SIGIL_ARGUMENTS, inference_subject *subj, char *message, char *explanation) ;
#line 702 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__inference_problem(SIGIL_ARGUMENTS, inference_subject *infs, inference *inf, char *message, char *explanation) ;
#line 721 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__property_problem(SIGIL_ARGUMENTS, property *prn, char *message, char *explanation) ;
#line 735 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__extension_problem(SIGIL_ARGUMENTS, extension_file *ef, char *message) ;
#line 751 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__release_problem(SIGIL_ARGUMENTS, char *message, filename *name) ;
#line 763 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__release_problem_path(SIGIL_ARGUMENTS, char *message, pathname *path) ;
#line 775 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__release_problem_at_sentence(SIGIL_ARGUMENTS, char *message, filename *name) ;
#line 793 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__map_problem(SIGIL_ARGUMENTS, parse_node *q, char *message) ;
#line 802 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__map_problem_wanted_but(SIGIL_ARGUMENTS, parse_node *q, char *i_wanted_a, int vw1) ;
#line 819 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__start_problems_report(void) ;
#line 825 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__issue_problems_banner(OUTPUT_STREAM, char *verdict) ;
#line 76 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__identify_word(int wn) ;
#line 82 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__identify_word_range(wording W) ;
#line 91 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__change_text_of_word(int wn, char *new) ;
#line 101 "inform7/Chapter 7/Vocabulary.w"
vocabulary_entry * Vocabulary__vocab_entry_new(char *text, int hash_code, unsigned int flags, int val) ;
#line 130 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__log(vocabulary_entry *ve) ;
#line 154 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__set_raw_exemplar_to_text(int wn) ;
#line 162 "inform7/Chapter 7/Vocabulary.w"
char * Vocabulary__get_exemplar(vocabulary_entry *ve, int raw) ;
#line 171 "inform7/Chapter 7/Vocabulary.w"
int Vocabulary__get_literal_number_value(vocabulary_entry *ve) ;
#line 174 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__set_literal_number_value(vocabulary_entry *ve, int val) ;
#line 181 "inform7/Chapter 7/Vocabulary.w"
kind * Vocabulary__get_kind(vocabulary_entry *ve) ;
#line 184 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__set_kind(vocabulary_entry *ve, kind *K) ;
#line 198 "inform7/Chapter 7/Vocabulary.w"
int Vocabulary__used_case_sensitively(vocabulary_entry *ve) ;
#line 202 "inform7/Chapter 7/Vocabulary.w"
vocabulary_entry * Vocabulary__get_lower_case_form(vocabulary_entry *ve) ;
#line 205 "inform7/Chapter 7/Vocabulary.w"
vocabulary_entry * Vocabulary__make_case_sensitive(vocabulary_entry *ve) ;
#line 217 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__set_flags(vocabulary_entry *ve, unsigned int t) ;
#line 220 "inform7/Chapter 7/Vocabulary.w"
unsigned int Vocabulary__test_vflags(vocabulary_entry *ve, unsigned int t) ;
#line 223 "inform7/Chapter 7/Vocabulary.w"
unsigned int Vocabulary__test_flags(int wn, unsigned int t) ;
#line 233 "inform7/Chapter 7/Vocabulary.w"
unsigned int Vocabulary__disjunction_of_flags(wording W) ;
#line 243 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__set_ntb(vocabulary_entry *ve, int R) ;
#line 246 "inform7/Chapter 7/Vocabulary.w"
int Vocabulary__get_ntb(vocabulary_entry *ve) ;
#line 295 "inform7/Chapter 7/Vocabulary.w"
int Vocabulary__hash_code_from_word(char *text) ;
#line 326 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__start_hash_table(void) ;
#line 342 "inform7/Chapter 7/Vocabulary.w"
vocabulary_entry * Vocabulary__entry_for_text(char *text) ;
#line 406 "inform7/Chapter 7/Vocabulary.w"
vocabulary_entry * Vocabulary__entry_for_partial_text(char *str, int from, int to) ;
#line 423 "inform7/Chapter 7/Vocabulary.w"
int Vocabulary__an_ordinal_number(char *fw) ;
#line 69 "inform7/Chapter 7/Tries and Inflections.w"
match_trie * Inflections__new_trie_node(int mc) ;
#line 84 "inform7/Chapter 7/Tries and Inflections.w"
match_avinue * Inflections__new_avinue(int from_start) ;
#line 91 "inform7/Chapter 7/Tries and Inflections.w"
match_avinue * Inflections__fresh_avinue(match_avinue *A) ;
#line 132 "inform7/Chapter 7/Tries and Inflections.w"
char * Inflections__search_trie(match_trie *T, char *p, char *add_outcome) ;
#line 300 "inform7/Chapter 7/Tries and Inflections.w"
int Inflections__trie_node_matches(match_trie *pos, int c) ;
#line 320 "inform7/Chapter 7/Tries and Inflections.w"
int Inflections__trie_node_ambiguous(match_trie *pos) ;
#line 330 "inform7/Chapter 7/Tries and Inflections.w"
char * Inflections__search_avinue(match_avinue *T, char *p) ;
#line 343 "inform7/Chapter 7/Tries and Inflections.w"
void Inflections__log_avinue(match_avinue *A) ;
#line 355 "inform7/Chapter 7/Tries and Inflections.w"
void Inflections__log_trie_recursively(match_trie *T) ;
#line 383 "inform7/Chapter 7/Tries and Inflections.w"
int Inflections__suffix_inflection(match_avinue *T, char *to, char *from, int max_length) ;
#line 413 "inform7/Chapter 7/Tries and Inflections.w"
word_assemblage Inflections__apply_trie_to_wa(word_assemblage wa, match_avinue *mt) ;
#line 434 "inform7/Chapter 7/Tries and Inflections.w"
void Inflections__preface_by_article(OUTPUT_STREAM, text_stream *TEMP) ;
#line 450 "inform7/Chapter 7/Tries and Inflections.w"
int Inflections__pluralize(char *to, char *from, int max_length, natural_language *nl) ;
#line 464 "inform7/Chapter 7/Tries and Inflections.w"
int Inflections__pasturise_participle(char *to, char *from, int max_length) ;
#line 474 "inform7/Chapter 7/Tries and Inflections.w"
void Inflections__test_tries(OUTPUT_STREAM, char *p) ;
#line 490 "inform7/Chapter 7/Tries and Inflections.w"
void Inflections__add_to_avinue(match_avinue *mt, char *from, char *to) ;
#line 501 "inform7/Chapter 7/Tries and Inflections.w"
wording Inflections__make_past_of_participle(wording W) ;
#line 521 "inform7/Chapter 7/Tries and Inflections.w"
wording Inflections__set_past_participle(wording W, int irregular_pp) ;
#line 534 "inform7/Chapter 7/Tries and Inflections.w"
wording Inflections__make_comparative(wording W) ;
#line 554 "inform7/Chapter 7/Tries and Inflections.w"
wording Inflections__make_superlative(wording W) ;
#line 576 "inform7/Chapter 7/Tries and Inflections.w"
wording Inflections__make_quiddity(wording W) ;
#line 593 "inform7/Chapter 7/Tries and Inflections.w"
void Inflections__test_trie_cases(OUTPUT_STREAM) ;
#line 608 "inform7/Chapter 7/Tries and Inflections.w"
void Inflections__test_trie_case(char *t) ;
#line 32 "inform7/Chapter 7/Word Assemblages.w"
word_assemblage WordAssemblages__new_assemblage(void) ;
#line 43 "inform7/Chapter 7/Word Assemblages.w"
word_assemblage WordAssemblages__from_wording(wording W) ;
#line 55 "inform7/Chapter 7/Word Assemblages.w"
word_assemblage WordAssemblages__lit_0(void) ;
#line 59 "inform7/Chapter 7/Word Assemblages.w"
word_assemblage WordAssemblages__lit_1(vocabulary_entry *ve1) ;
#line 68 "inform7/Chapter 7/Word Assemblages.w"
word_assemblage WordAssemblages__join(word_assemblage wa1, word_assemblage wa2) ;
#line 84 "inform7/Chapter 7/Word Assemblages.w"
wording WordAssemblages__to_wording(word_assemblage *wa) ;
#line 100 "inform7/Chapter 7/Word Assemblages.w"
void WordAssemblages__truncate(word_assemblage *wa, int n) ;
#line 108 "inform7/Chapter 7/Word Assemblages.w"
void WordAssemblages__truncate_to(word_assemblage *wa, int n) ;
#line 117 "inform7/Chapter 7/Word Assemblages.w"
int WordAssemblages__nonempty(word_assemblage wa1) ;
#line 122 "inform7/Chapter 7/Word Assemblages.w"
void WordAssemblages__copy_to_stream(OUTPUT_STREAM, word_assemblage *wa) ;
#line 129 "inform7/Chapter 7/Word Assemblages.w"
void WordAssemblages__copy_to_string(word_assemblage *wa, char *str) ;
#line 137 "inform7/Chapter 7/Word Assemblages.w"
vocabulary_entry * WordAssemblages__hyphenated(word_assemblage *wa) ;
#line 151 "inform7/Chapter 7/Word Assemblages.w"
void WordAssemblages__as_array(word_assemblage *wa, vocabulary_entry ***array, int *len) ;
#line 159 "inform7/Chapter 7/Word Assemblages.w"
int WordAssemblages__compare(word_assemblage *wa1, word_assemblage *wa2) ;
#line 169 "inform7/Chapter 7/Word Assemblages.w"
int WordAssemblages__compare_with_wording(word_assemblage *wa, wording W) ;
#line 182 "inform7/Chapter 7/Word Assemblages.w"
int WordAssemblages__parse_as_strictly_initial_text(wording W, word_assemblage *wa) ;
#line 186 "inform7/Chapter 7/Word Assemblages.w"
int WordAssemblages__parse_as_weakly_initial_text(wording W, word_assemblage *wa, wording S, int allow_uuc, int allow_to_fill) ;
#line 205 "inform7/Chapter 7/Word Assemblages.w"
vocabulary_entry * WordAssemblages__last_word(word_assemblage *wa) ;
#line 210 "inform7/Chapter 7/Word Assemblages.w"
vocabulary_entry * WordAssemblages__first_word(word_assemblage *wa) ;
#line 215 "inform7/Chapter 7/Word Assemblages.w"
int WordAssemblages__longer(word_assemblage *wa1, word_assemblage *wa2) ;
#line 226 "inform7/Chapter 7/Word Assemblages.w"
void WordAssemblages__log(word_assemblage *wa) ;
#line 236 "inform7/Chapter 7/Word Assemblages.w"
void WordAssemblages__index(word_assemblage *wa) ;
#line 44 "inform7/Chapter 7/Clusters.w"
cluster * Clusters__new(void) ;
#line 53 "inform7/Chapter 7/Clusters.w"
individual_name * Clusters__add(cluster *names, wording W, natural_language *foreign_language, int gender, int number, int pluralise) ;
#line 104 "inform7/Chapter 7/Clusters.w"
void Clusters__add_with_agreements(cluster *cl, wording W, natural_language *nl) ;
#line 162 "inform7/Chapter 7/Clusters.w"
void Clusters__set_plural_name(cluster *cl, wording W) ;
#line 180 "inform7/Chapter 7/Clusters.w"
wording Clusters__get_name(cluster *cl, int plural_flag) ;
#line 194 "inform7/Chapter 7/Clusters.w"
wording Clusters__get_name_in_play(cluster *cl, int plural_flag) ;
#line 208 "inform7/Chapter 7/Clusters.w"
wording Clusters__get_name_general(cluster *cl, natural_language *nl, int number_sought, int gender_sought) ;
#line 225 "inform7/Chapter 7/Clusters.w"
void Clusters__set_principal_meaning(individual_name *in, excerpt_meaning *em) ;
#line 230 "inform7/Chapter 7/Clusters.w"
excerpt_meaning * Clusters__get_principal_meaning(cluster *cl) ;
#line 42 "inform7/Chapter 7/Plurals Dictionary.w"
void Plurals__handle_definition(parse_node *p) ;
#line 46 "inform7/Chapter 7/Plurals Dictionary.w"
void Plurals__traverse_for_definitions(void) ;
#line 50 "inform7/Chapter 7/Plurals Dictionary.w"
void Plurals__visit_for_definitions(parse_node *p) ;
#line 63 "inform7/Chapter 7/Plurals Dictionary.w"
void Plurals__register(wording S, wording P) ;
#line 107 "inform7/Chapter 7/Plurals Dictionary.w"
plural_dictionary_entry * Plurals__make(wording W, wording *PW, plural_dictionary_entry *search_from, natural_language *nl) ;
#line 97 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__scan(void) ;
#line 118 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__scan_bundles_from(pathname *P, char *origin) ;
#line 230 "inform7/Chapter 7/Natural Languages.w"
natural_language * NaturalLanguages__get_nl(char *name) ;
#line 247 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__log(natural_language *nl) ;
#line 255 "inform7/Chapter 7/Natural Languages.w"
char * NaturalLanguages__get_name(natural_language *nl) ;
#line 286 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__stock_nl_kind(kind *K) ;
#line 307 "inform7/Chapter 7/Natural Languages.w"
int NaturalLanguages__adaptive_person(natural_language *nl) ;
#line 325 "inform7/Chapter 7/Natural Languages.w"
natural_language * NaturalLanguages__English(void) ;
#line 333 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__set_language_of_play(natural_language *nl) ;
#line 344 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__write_language_code(OUTPUT_STREAM, natural_language *nl) ;
#line 363 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__include_required(void) ;
#line 391 "inform7/Chapter 7/Natural Languages.w"
wording NaturalLanguages__load_preform(natural_language *nl) ;
#line 367 "inform7/Chapter 7/Preform.w"
void Preform__log_language(void) ;
#line 405 "inform7/Chapter 7/Preform.w"
void Preform__log_production(production *pr, int detailed) ;
#line 417 "inform7/Chapter 7/Preform.w"
void Preform__log_ptoken(ptoken *pt, int detailed) ;
#line 439 "inform7/Chapter 7/Preform.w"
void Preform__write_ptoken(OUTPUT_STREAM, ptoken *pt) ;
#line 469 "inform7/Chapter 7/Preform.w"
void Preform__watch(nonterminal *nt, int state) ;
#line 495 "inform7/Chapter 7/Preform.w"
void Preform__read_definition(void) ;
#line 587 "inform7/Chapter 7/Preform.w"
int Preform__parse_preform(wording W, int break_first) ;
#line 692 "inform7/Chapter 7/Preform.w"
nonterminal * Preform__detect_nonterminal(vocabulary_entry *ve) ;
#line 700 "inform7/Chapter 7/Preform.w"
nonterminal * Preform__find_nonterminal(vocabulary_entry *ve) ;
#line 733 "inform7/Chapter 7/Preform.w"
production * Preform__new_production(wording W, nonterminal *nt, int pc) ;
#line 856 "inform7/Chapter 7/Preform.w"
ptoken * Preform__parse_slashed_chain(nonterminal *nt, production *pr, int wn, int unescaped) ;
#line 906 "inform7/Chapter 7/Preform.w"
ptoken * Preform__new_ptoken(vocabulary_entry *ve, int unescaped, nonterminal *nt, int pc) ;
#line 959 "inform7/Chapter 7/Preform.w"
void Preform__optimise_counts(void) ;
#line 1002 "inform7/Chapter 7/Preform.w"
void Preform__optimise_nt(nonterminal *nt) ;
#line 1212 "inform7/Chapter 7/Preform.w"
void Preform__optimise_nt_reqs(nonterminal *nt) ;
#line 1225 "inform7/Chapter 7/Preform.w"
void Preform__optimise_req(range_requirement *req, range_requirement *prev) ;
#line 1253 "inform7/Chapter 7/Preform.w"
void Preform__mark_as_preposition(vocabulary_entry *ve) ;
#line 1259 "inform7/Chapter 7/Preform.w"
void Preform__mark_as_verb(vocabulary_entry *ve) ;
#line 1272 "inform7/Chapter 7/Preform.w"
void Preform__mark_as_cardinal(vocabulary_entry *ve) ;
#line 1276 "inform7/Chapter 7/Preform.w"
void Preform__mark_as_ordinal(vocabulary_entry *ve) ;
#line 1280 "inform7/Chapter 7/Preform.w"
void Preform__mark_nt_as_requiring_itself(nonterminal *nt) ;
#line 1285 "inform7/Chapter 7/Preform.w"
void Preform__mark_nt_as_requiring_itself_first(nonterminal *nt) ;
#line 1292 "inform7/Chapter 7/Preform.w"
void Preform__mark_nt_as_requiring_itself_conj(nonterminal *nt) ;
#line 1301 "inform7/Chapter 7/Preform.w"
void Preform__mark_nt_as_requiring_itself_articled(nonterminal *nt) ;
#line 1308 "inform7/Chapter 7/Preform.w"
void Preform__set_nt_incidence(vocabulary_entry *ve, nonterminal *nt) ;
#line 1319 "inform7/Chapter 7/Preform.w"
int Preform__nt_bitmap_bit(nonterminal *nt) ;
#line 1348 "inform7/Chapter 7/Preform.w"
int Preform__test_word(int wn, nonterminal *nt) ;
#line 1354 "inform7/Chapter 7/Preform.w"
void Preform__mark_word(int wn, nonterminal *nt) ;
#line 1358 "inform7/Chapter 7/Preform.w"
void Preform__mark_vocabulary(vocabulary_entry *ve, nonterminal *nt) ;
#line 1362 "inform7/Chapter 7/Preform.w"
int Preform__test_vocabulary(vocabulary_entry *ve, nonterminal *nt) ;
#line 1368 "inform7/Chapter 7/Preform.w"
int Preform__get_range_disjunction(wording W) ;
#line 1375 "inform7/Chapter 7/Preform.w"
int Preform__get_range_conjunction(wording W) ;
#line 1387 "inform7/Chapter 7/Preform.w"
int Preform__nt_bitmap_violates(wording W, range_requirement *req) ;
#line 1450 "inform7/Chapter 7/Preform.w"
void Preform__concatenate_rreq(range_requirement *req, range_requirement *with) ;
#line 1465 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_ds(int m1, int m2) ;
#line 1474 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_cs(int m1, int m2) ;
#line 1485 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_dw(int m1, int m2) ;
#line 1496 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_cw(int m1, int m2) ;
#line 1505 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_fs(int m1, int m2) ;
#line 1509 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_fw(int m1, int m2) ;
#line 1518 "inform7/Chapter 7/Preform.w"
void Preform__disjoin_rreq(range_requirement *req, range_requirement *with) ;
#line 1533 "inform7/Chapter 7/Preform.w"
int Preform__disjoin_ds(int m1, int m2) ;
#line 1542 "inform7/Chapter 7/Preform.w"
int Preform__disjoin_cs(int m1, int m2) ;
#line 1551 "inform7/Chapter 7/Preform.w"
int Preform__disjoin_dw(int m1, int m2) ;
#line 1560 "inform7/Chapter 7/Preform.w"
int Preform__disjoin_cw(int m1, int m2) ;
#line 1566 "inform7/Chapter 7/Preform.w"
int Preform__disjoin_fw(int m1, int m2) ;
#line 1570 "inform7/Chapter 7/Preform.w"
int Preform__disjoin_fs(int m1, int m2) ;
#line 1574 "inform7/Chapter 7/Preform.w"
void Preform__clear_rreq(range_requirement *req) ;
#line 1580 "inform7/Chapter 7/Preform.w"
void Preform__atomic_rreq(range_requirement *req, nonterminal *nt) ;
#line 1587 "inform7/Chapter 7/Preform.w"
void Preform__log_range_requirement(range_requirement *req) ;
#line 1601 "inform7/Chapter 7/Preform.w"
int Preform__ptoken_width(ptoken *pt) ;
#line 1615 "inform7/Chapter 7/Preform.w"
void Preform__ptoken_extrema(ptoken *pt, int *min_t, int *max_t) ;
#line 1677 "inform7/Chapter 7/Preform.w"
int Preform__parse_nt_against_word_range(nonterminal *nt, wording W, int *result, void **result_p) ;
#line 2180 "inform7/Chapter 7/Preform.w"
int Preform__next_strut_posn_after(wording W, ptoken *start, int len, int from) ;
#line 2207 "inform7/Chapter 7/Preform.w"
int Preform__parse_fixed_word_ptoken(int wn, ptoken *pt) ;
#line 83 "inform7/Chapter 7/Non-Parsing Preform.w"
word_assemblage Preform__Nonparsing__merge(nonterminal *nt, int pnum, word_assemblage ingredient) ;
#line 111 "inform7/Chapter 7/Non-Parsing Preform.w"
word_assemblage Preform__Nonparsing__wording(nonterminal *nt, int pnum) ;
#line 118 "inform7/Chapter 7/Non-Parsing Preform.w"
vocabulary_entry * Preform__Nonparsing__word(nonterminal *nt, int pnum) ;
#line 132 "inform7/Chapter 7/Non-Parsing Preform.w"
vocabulary_entry * Preform__Nonparsing__replace_word(vocabulary_entry *ve, nonterminal *nt_from, nonterminal *nt_to) ;
#line 166 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__enter_lexicon(nonterminal *nt_from, int pos, char *category, char *gloss) ;
#line 194 "inform7/Chapter 7/Non-Parsing Preform.w"
match_avinue * Preform__Nonparsing__define_trie(nonterminal *nt, int end, natural_language *nl) ;
#line 298 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__log_avinues(void) ;
#line 327 "inform7/Chapter 7/Non-Parsing Preform.w"
verb_conjugation * Preform__Nonparsing__conjugate_verb(word_assemblage base_text, word_assemblage *overrides, int no_overrides, natural_language *nl) ;
#line 494 "inform7/Chapter 7/Non-Parsing Preform.w"
nonterminal * Preform__Nonparsing__follow_conjugation_instructions(word_assemblage *verb_forms, int *highest_form_written, int *aux_len, int *avo_flag, int *niv_flag, natural_language *nl) ;
#line 669 "inform7/Chapter 7/Non-Parsing Preform.w"
word_assemblage Preform__Nonparsing__merge_verb_material(ptoken *row, int sense, int tense, int person, int num_ingredients, word_assemblage *ingredients, natural_language *nl, int *modal_following) ;
#line 803 "inform7/Chapter 7/Non-Parsing Preform.w"
word_assemblage Preform__Nonparsing__expand_wa_with_endings(vocabulary_entry *ve, word_assemblage *verb_forms) ;
#line 854 "inform7/Chapter 7/Non-Parsing Preform.w"
word_assemblage Preform__Nonparsing__shorten_wa_with_contractions(word_assemblage wa) ;
#line 904 "inform7/Chapter 7/Non-Parsing Preform.w"
int Preform__Nonparsing__ptoken_to_verb_form_number(ptoken *pt) ;
#line 910 "inform7/Chapter 7/Non-Parsing Preform.w"
int Preform__Nonparsing__ve_to_verb_form_number(vocabulary_entry *ve) ;
#line 922 "inform7/Chapter 7/Non-Parsing Preform.w"
int Preform__Nonparsing__ptoken_to_tense_indicator(ptoken *pt, int *set_sense) ;
#line 949 "inform7/Chapter 7/Non-Parsing Preform.w"
int Preform__Nonparsing__ptoken_as_bracket(ptoken *pt) ;
#line 962 "inform7/Chapter 7/Non-Parsing Preform.w"
int Preform__Nonparsing__compare_ve_with_tails(vocabulary_entry *ve, vocabulary_entry *pattern) ;
#line 983 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__trie_definition_error(nonterminal *nt, production *pr, char *message) ;
#line 990 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__conjugation_error(word_assemblage base_text, nonterminal *nt, production *pr, char *message) ;
#line 999 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__general_npp_error(word_assemblage base_text, nonterminal *nt, production *pr, char *message) ;
#line 1047 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__test_conjugation(OUTPUT_STREAM, wording W) ;
#line 1055 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__write_conjugation(OUTPUT_STREAM, verb_conjugation *vc) ;
#line 1098 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__test_participle(OUTPUT_STREAM, wording W) ;
#line 1106 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__write_participle(OUTPUT_STREAM, verb_conjugation *vc) ;
#line 97 "inform7/Chapter 8/Articles and Pronouns.w"
wording Articles__remove_the(wording W) ;
#line 103 "inform7/Chapter 8/Articles and Pronouns.w"
wording Articles__remove_article(wording W) ;
#line 111 "inform7/Chapter 8/Determiners and Quantifiers.w"
quantifier * Quantifiers__quant_new(char *op, int T, int is_comp, char *text) ;
#line 162 "inform7/Chapter 8/Determiners and Quantifiers.w"
void Quantifiers__quants_negate_each_other(quantifier *qx, quantifier *qy) ;
#line 165 "inform7/Chapter 8/Determiners and Quantifiers.w"
quantifier * Quantifiers__get_negation(quantifier *quant) ;
#line 172 "inform7/Chapter 8/Determiners and Quantifiers.w"
void Quantifiers__log(quantifier *quant, int parameter) ;
#line 204 "inform7/Chapter 8/Determiners and Quantifiers.w"
void Quantifiers__compile_test(OUTPUT_STREAM, quantifier *quant, int index, int quantification_parameter) ;
#line 240 "inform7/Chapter 8/Determiners and Quantifiers.w"
int Quantifiers__is_now_assertable(quantifier *quant) ;
#line 250 "inform7/Chapter 8/Determiners and Quantifiers.w"
int Quantifiers__can_be_used_in_assertions(quantifier *quant) ;
#line 281 "inform7/Chapter 8/Determiners and Quantifiers.w"
determiner * Quantifiers__det_new(int not, int pr, int num, quantifier *quant, char *text) ;
#line 339 "inform7/Chapter 8/Determiners and Quantifiers.w"
int Quantifiers__parse_against_text(wording W, int *which_P, quantifier **which_quant) ;
#line 401 "inform7/Chapter 8/Determiners and Quantifiers.w"
wording Quantifiers__det_parse_against_text(wording W, determiner *det, int *which_P) ;
#line 429 "inform7/Chapter 8/Determiners and Quantifiers.w"
void Quantifiers__make_built_in(void) ;
#line 595 "inform7/Chapter 8/Determiners and Quantifiers.w"
int Quantifiers__quant_requires_at_least_one_true_case(quantifier *quant, int parameter) ;
#line 44 "inform7/Chapter 8/Time Periods.w"
time_period TimePeriods__new(void) ;
#line 55 "inform7/Chapter 8/Time Periods.w"
time_period TimePeriods__new_tense_marker(int t) ;
#line 61 "inform7/Chapter 8/Time Periods.w"
time_period * TimePeriods__store(time_period tp) ;
#line 67 "inform7/Chapter 8/Time Periods.w"
void TimePeriods__log_tense_number(int t) ;
#line 77 "inform7/Chapter 8/Time Periods.w"
void TimePeriods__log(time_period *tp) ;
#line 93 "inform7/Chapter 8/Time Periods.w"
int TimePeriods__is_valid(time_period *tp) ;
#line 96 "inform7/Chapter 8/Time Periods.w"
void TimePeriods__make_invalid(time_period *tp) ;
#line 100 "inform7/Chapter 8/Time Periods.w"
int TimePeriods__get_tense(time_period *tp) ;
#line 104 "inform7/Chapter 8/Time Periods.w"
void TimePeriods__set_tense(time_period *tp, int t) ;
#line 108 "inform7/Chapter 8/Time Periods.w"
int TimePeriods__duration_count(time_period *tp) ;
#line 124 "inform7/Chapter 8/Time Periods.w"
int TimePeriods__compare_specificity(time_period *tp1, time_period *tp2) ;
#line 205 "inform7/Chapter 8/Time Periods.w"
time_period TimePeriods__parse(wording W) ;
#line 79 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase * Adjectives__Phrases__parse(wording W) ;
#line 88 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase * Adjectives__Phrases__from_word_range(wording W, natural_language *nl) ;
#line 127 "inform7/Chapter 9/Adjectives.w"
wording Adjectives__Phrases__get_text(adjectival_phrase *aph, int plural) ;
#line 140 "inform7/Chapter 9/Adjectives.w"
void Adjectives__Phrases__declare_meaningless(parse_node *p) ;
#line 145 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase * Adjectives__Phrases__declare_textually(wording W) ;
#line 154 "inform7/Chapter 9/Adjectives.w"
void Adjectives__Phrases__test_adjective(OUTPUT_STREAM, wording W) ;
#line 180 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase * Adjectives__Phrases__declare(adjective_meaning *am, wording W) ;
#line 199 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase * Adjectives__Phrases__get_aph_from_am(adjective_meaning *am) ;
#line 208 "inform7/Chapter 9/Adjectives.w"
void Adjectives__Phrases__sortrandom_meanings(adjectival_phrase *aph) ;
#line 216 "inform7/Chapter 9/Adjectives.w"
adjective_meaning * Adjectives__Phrases__get_sorted_definition_list(adjectival_phrase *aph) ;
#line 223 "inform7/Chapter 9/Adjectives.w"
adjective_meaning * Adjectives__Phrases__first_meaning(adjectival_phrase *aph) ;
#line 231 "inform7/Chapter 9/Adjectives.w"
void Adjectives__Phrases__log(adjectival_phrase *aph) ;
#line 241 "inform7/Chapter 9/Adjectives.w"
void Adjectives__Phrases__log_meanings(adjectival_phrase *aph) ;
#line 280 "inform7/Chapter 9/Adjectives.w"
int Adjectives__Phrases__applicable_to(adjectival_phrase *aph, kind *K) ;
#line 324 "inform7/Chapter 9/Adjectives.w"
instance * Adjectives__Phrases__has_ENUMERATIVE_meaning(adjectival_phrase *aph) ;
#line 332 "inform7/Chapter 9/Adjectives.w"
property * Adjectives__Phrases__has_EORP_meaning(adjectival_phrase *aph, int *sense) ;
#line 372 "inform7/Chapter 9/Adjectives.w"
int Adjectives__Phrases__assert(adjectival_phrase *aph, kind *kind_domain, inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) ;
#line 120 "inform7/Chapter 9/Adjective Meanings.w"
adjective_meaning * Adjectives__Meanings__list_sort(adjective_meaning *unsorted_head) ;
#line 169 "inform7/Chapter 9/Adjective Meanings.w"
adjective_meaning * Adjectives__Meanings__new(int form, general_pointer details, wording W) ;
#line 202 "inform7/Chapter 9/Adjective Meanings.w"
adjective_meaning * Adjectives__Meanings__negate(adjective_meaning *am) ;
#line 229 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__get_form(adjective_meaning *am) ;
#line 257 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__domain_weak_match(kind *K1, kind *K2) ;
#line 267 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__domain_subj_compare(inference_subject *infs, adjective_meaning *am) ;
#line 296 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__set_domain_text(adjective_meaning *am, wording W) ;
#line 302 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__set_domain_from_instance(adjective_meaning *am, instance *I) ;
#line 319 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__set_domain_from_kind(adjective_meaning *am, kind *K) ;
#line 329 "inform7/Chapter 9/Adjective Meanings.w"
kind * Adjectives__Meanings__get_domain(adjective_meaning *am) ;
#line 334 "inform7/Chapter 9/Adjective Meanings.w"
kind * Adjectives__Meanings__get_domain_forcing(adjective_meaning *am) ;
#line 346 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__set_definition_domain(adjective_meaning *am, int early) ;
#line 474 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__compare(adjective_meaning *am1, adjective_meaning *am2) ;
#line 579 "inform7/Chapter 9/Adjective Meanings.w"
i6_schema * Adjectives__Meanings__set_i6_schema(adjective_meaning *am, int T, int via_support) ;
#line 599 "inform7/Chapter 9/Adjective Meanings.w"
i6_schema * Adjectives__Meanings__get_i6_schema(adjectival_phrase *aph, kind *kind_domain, int T) ;
#line 644 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__write_adjective_test_routine(OUTPUT_STREAM, adjectival_phrase *aph) ;
#line 665 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__pass_task_to_support_routine(adjective_meaning *am, int T) ;
#line 674 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__get_ready_flag(adjective_meaning *am) ;
#line 677 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__set_ready_flag(adjective_meaning *am) ;
#line 688 "inform7/Chapter 9/Adjective Meanings.w"
adjective_meaning * Adjectives__Meanings__list_next_domain_kind(adjective_meaning *am, kind **K, int T) ;
#line 704 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__compile_support_code(OUTPUT_STREAM) ;
#line 805 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__list_compile(adjective_meaning *list_head, OUTPUT_STREAM, ph_stack_frame *phsf, kind *K, int T) ;
#line 851 "inform7/Chapter 9/Adjective Meanings.w"
adjective_meaning * Adjectives__Meanings__parse(parse_node *q, int sense, wording AW, wording DNW, wording CONW, wording CALLW) ;
#line 870 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__compiling_soon(adjective_meaning *am, int T) ;
#line 898 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__compile(adjective_meaning *am, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 942 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__assert(adjective_meaning *am, inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) ;
#line 983 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__print_to_index(adjective_meaning *am) ;
#line 1047 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__agreements(OUTPUT_STREAM) ;
#line 1085 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__invoke(OUTPUT_STREAM, adjectival_phrase *aph) ;
#line 25 "inform7/Chapter 9/Adjective Usages.w"
adjective_usage * Adjectives__Usages__new(adjectival_phrase *aph, int pos) ;
#line 32 "inform7/Chapter 9/Adjective Usages.w"
void Adjectives__Usages__log(adjective_usage *au) ;
#line 39 "inform7/Chapter 9/Adjective Usages.w"
adjective_usage * Adjectives__Usages__copy(adjective_usage *au_from) ;
#line 43 "inform7/Chapter 9/Adjective Usages.w"
adjectival_phrase * Adjectives__Usages__get_aph(adjective_usage *au) ;
#line 48 "inform7/Chapter 9/Adjective Usages.w"
int Adjectives__Usages__get_parity(adjective_usage *au) ;
#line 53 "inform7/Chapter 9/Adjective Usages.w"
void Adjectives__Usages__flip_parity(adjective_usage *au) ;
#line 177 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * LiteralPatterns__lp_new(kind *K, wording W) ;
#line 198 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_token LiteralPatterns__lpt_new(int t, int nw) ;
#line 210 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_element LiteralPatterns__lpe_new(int i, int r, int sgn) ;
#line 231 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * LiteralPatterns__list_add(literal_pattern *list_head, literal_pattern *new_lp, int using_integer_scaling) ;
#line 317 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * LiteralPatterns__lp_list_add_inner(literal_pattern *list_head, literal_pattern *new_lp) ;
#line 341 "inform7/Chapter 10/Literal Patterns.w"
int LiteralPatterns__lp_precedes(literal_pattern *A, literal_pattern *B) ;
#line 358 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * LiteralPatterns__get_benchmark(kind *K) ;
#line 370 "inform7/Chapter 10/Literal Patterns.w"
int LiteralPatterns__scale_factor(kind *K) ;
#line 381 "inform7/Chapter 10/Literal Patterns.w"
int LiteralPatterns__at_optional_break_point(literal_pattern *lp, int ec, int tc) ;
#line 400 "inform7/Chapter 10/Literal Patterns.w"
kind * LiteralPatterns__match(literal_pattern *lp, wording W, int *found) ;
#line 685 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__gpr_locals(void) ;
#line 703 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__gpr(OUTPUT_STREAM, literal_pattern *lp) ;
#line 881 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__index_all(kind *K) ;
#line 954 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__index_lp_possibilities(literal_pattern *lp, literal_pattern *benchmark_lp) ;
#line 982 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__index_lp_possibility(literal_pattern *lp, literal_pattern *benchmark_lp) ;
#line 1001 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__index_value(literal_pattern *lp_list, int v) ;
#line 1032 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__index_benchmark_value(kind *K) ;
#line 1046 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__lp_index_quantum_value(literal_pattern *lp, scaling_transformation sc) ;
#line 1056 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__lp_index_value_specific(literal_pattern *lp, double alt_value) ;
#line 1062 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__lp_index_value_specific_inner(literal_pattern *lp, int v, double real_v) ;
#line 1125 "inform7/Chapter 10/Literal Patterns.w"
char * LiteralPatterns__leading_zero_prototype(int range) ;
#line 1141 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__printing_routine(OUTPUT_STREAM, literal_pattern *lp_list) ;
#line 1310 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__comment_use_of_lp(OUTPUT_STREAM, literal_pattern *lp) ;
#line 1321 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__log_lp_debugging_data(OUTPUT_STREAM, literal_pattern *lp) ;
#line 1346 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__new_literal_specification(parse_node *pn) ;
#line 1360 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * LiteralPatterns__new_literal_specification_list(parse_node *p, parse_node *q, literal_pattern *lp_main) ;
#line 1389 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern * LiteralPatterns__new_literal_specification_inner(parse_node *p, parse_node *q, literal_pattern *owner) ;
#line 1966 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_name * LiteralPatterns__new_lpn(wording W, literal_pattern_name *existing) ;
#line 1986 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__define_named_phrases(void) ;
#line 2046 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__define_packing_phrases(literal_pattern *lp, kind *K) ;
#line 44 "inform7/Chapter 10/Times of Day.w"
void PL__TimesOfDay__start(void) ;
#line 51 "inform7/Chapter 10/Times of Day.w"
int PL__TimesOfDay__times_new_base_kind_notify(kind *new_base, char *name, wording W) ;
#line 61 "inform7/Chapter 10/Times of Day.w"
kind * PL__TimesOfDay__kind(void) ;
#line 138 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning * Semantics__Nouns__ExcerptMeanings__new(unsigned int mc, general_pointer data) ;
#line 151 "inform7/Chapter 10/Excerpt Meanings.w"
general_pointer Semantics__Nouns__ExcerptMeanings__data(excerpt_meaning *em) ;
#line 159 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__log_meaning_code(unsigned int mc) ;
#line 202 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__log(excerpt_meaning *em) ;
#line 217 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__log_all(void) ;
#line 248 "inform7/Chapter 10/Excerpt Meanings.w"
int Semantics__Nouns__ExcerptMeanings__hash_code(int w1, int w2) ;
#line 275 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__hash_code_from_token_list(excerpt_meaning *em) ;
#line 369 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__register_em(unsigned int meaning_code, excerpt_meaning *em) ;
#line 479 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning * Semantics__Nouns__ExcerptMeanings__register( unsigned int meaning_code, wording W, general_pointer data) ;
#line 598 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning * Semantics__Nouns__ExcerptMeanings__register_assemblage( unsigned int meaning_code, word_assemblage wa, general_pointer data) ;
#line 634 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning * Semantics__Nouns__ExcerptMeanings__register_noun( unsigned int meaning_code, wording W, parse_node *value) ;
#line 641 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning * Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage( unsigned int meaning_code, word_assemblage wa, parse_node *value) ;
#line 15 "inform7/Chapter 10/Unicode Translations.w"
void UnicodeTranslations__unicode_translates(parse_node *pn) ;
#line 93 "inform7/Chapter 10/Unicode Translations.w"
int UnicodeTranslations__char_in_range(int cc) ;
#line 61 "inform7/Chapter 10/Nametags.w"
individual_name * Nametags__add_to_nametag_and_reg(nametag *t, wording W, natural_language *foreign_language, int gender, int number, int options) ;
#line 91 "inform7/Chapter 10/Nametags.w"
nametag * Nametags__new(wording W, general_pointer owner, int p, int options, unsigned int mc, natural_language *foreign_language, int gender) ;
#line 123 "inform7/Chapter 10/Nametags.w"
excerpt_meaning * Nametags__register_nametag(wording W, nametag *t, natural_language *foreign_language) ;
#line 135 "inform7/Chapter 10/Nametags.w"
void Nametags__log(nametag *t) ;
#line 151 "inform7/Chapter 10/Nametags.w"
wording Nametags__get_name(nametag *t, int plural_flag) ;
#line 155 "inform7/Chapter 10/Nametags.w"
wording Nametags__get_name_in_play(nametag *t, int plural_flag) ;
#line 159 "inform7/Chapter 10/Nametags.w"
void Nametags__set_plural_name(nametag *t, wording W) ;
#line 163 "inform7/Chapter 10/Nametags.w"
int Nametags__full_name_includes(nametag *t, vocabulary_entry *wd) ;
#line 175 "inform7/Chapter 10/Nametags.w"
general_pointer Nametags__tag_holder(nametag *t) ;
#line 180 "inform7/Chapter 10/Nametags.w"
int Nametags__priority(nametag *t) ;
#line 185 "inform7/Chapter 10/Nametags.w"
int Nametags__range_number(nametag *t) ;
#line 190 "inform7/Chapter 10/Nametags.w"
void Nametags__set_range_number(nametag *t, int r) ;
#line 195 "inform7/Chapter 10/Nametags.w"
int Nametags__exactitude(nametag *t) ;
#line 201 "inform7/Chapter 10/Nametags.w"
excerpt_meaning * Nametags__get_principal_meaning(nametag *t) ;
#line 205 "inform7/Chapter 10/Nametags.w"
name_resolution_data * Nametags__name_resolution_data(nametag *t) ;
#line 216 "inform7/Chapter 10/Nametags.w"
char * Nametags__identifier(nametag *t) ;
#line 221 "inform7/Chapter 10/Nametags.w"
void Nametags__nametag_compose_identifier(nametag *t, char C, int N) ;
#line 231 "inform7/Chapter 10/Nametags.w"
void Nametags__nametag_set_I6_representation(nametag *t, char *new) ;
#line 245 "inform7/Chapter 10/Nametags.w"
void Nametags__name_all(void) ;
#line 253 "inform7/Chapter 10/Nametags.w"
void Nametags__visit_to_name(parse_node *p) ;
#line 290 "inform7/Chapter 10/Nametags.w"
nametag * Nametags__disambiguate(parse_node *p, int priority) ;
#line 342 "inform7/Chapter 10/Nametags.w"
void Nametags__nl_translates(parse_node *pn) ;
#line 85 "inform7/Chapter 10/Instances.w"
instance * Instances__new(wording W, kind *K) ;
#line 187 "inform7/Chapter 10/Instances.w"
parse_node * Instances__get_creating_sentence(instance *I) ;
#line 195 "inform7/Chapter 10/Instances.w"
source_file * Instances__get_creating_file(instance *I) ;
#line 209 "inform7/Chapter 10/Instances.w"
void Instances__make_kind_coincident(kind *K, property *P) ;
#line 223 "inform7/Chapter 10/Instances.w"
void Instances__update_adjectival_forms(property *P) ;
#line 240 "inform7/Chapter 10/Instances.w"
void Instances__register_as_adjectival_constant(instance *I, property *P) ;
#line 251 "inform7/Chapter 10/Instances.w"
void Instances__log(instance *I) ;
#line 263 "inform7/Chapter 10/Instances.w"
int Instances__get_numerical_value(instance *I) ;
#line 267 "inform7/Chapter 10/Instances.w"
inference_subject * Instances__as_subject(instance *I) ;
#line 275 "inform7/Chapter 10/Instances.w"
wording Instances__get_name(instance *I, int plural) ;
#line 280 "inform7/Chapter 10/Instances.w"
wording Instances__get_name_in_play(instance *I, int plural) ;
#line 285 "inform7/Chapter 10/Instances.w"
int Instances__full_name_includes(instance *I, vocabulary_entry *wd) ;
#line 290 "inform7/Chapter 10/Instances.w"
nametag * Instances__get_nametag(instance *I) ;
#line 294 "inform7/Chapter 10/Instances.w"
char * Instances__identifier(instance *I) ;
#line 302 "inform7/Chapter 10/Instances.w"
void Instances__write_name_for_index(OUTPUT_STREAM, instance *I) ;
#line 321 "inform7/Chapter 10/Instances.w"
instance * Instances__parse_object(wording W) ;
#line 381 "inform7/Chapter 10/Instances.w"
kind * Instances__to_kind(instance *I) ;
#line 387 "inform7/Chapter 10/Instances.w"
int Instances__of_kind(instance *I, kind *match) ;
#line 398 "inform7/Chapter 10/Instances.w"
void Instances__set_kind(instance *I, kind *new) ;
#line 450 "inform7/Chapter 10/Instances.w"
parse_node * Instances__get_kind_set_sentence(instance *I) ;
#line 470 "inform7/Chapter 10/Instances.w"
int Instances__count(kind *K) ;
#line 489 "inform7/Chapter 10/Instances.w"
void Instances__set_connection(instance *I, general_pointer gp) ;
#line 493 "inform7/Chapter 10/Instances.w"
general_pointer Instances__get_connection(instance *I) ;
#line 501 "inform7/Chapter 10/Instances.w"
void Instances__increment_indexing_count(instance *I) ;
#line 505 "inform7/Chapter 10/Instances.w"
int Instances__indexed_yet(instance *I) ;
#line 513 "inform7/Chapter 10/Instances.w"
void Instances__index_name(instance *I) ;
#line 531 "inform7/Chapter 10/Instances.w"
void Instances__note_usage(instance *I, parse_node *NB) ;
#line 547 "inform7/Chapter 10/Instances.w"
void Instances__index_usages(instance *I) ;
#line 571 "inform7/Chapter 10/Instances.w"
wording Instances__SUBJ_get_name_text(inference_subject *from) ;
#line 576 "inform7/Chapter 10/Instances.w"
general_pointer Instances__SUBJ_new_permission_granted(inference_subject *from) ;
#line 581 "inform7/Chapter 10/Instances.w"
void Instances__SUBJ_complete_model(inference_subject *infs) ;
#line 584 "inform7/Chapter 10/Instances.w"
void Instances__SUBJ_check_model(inference_subject *infs) ;
#line 590 "inform7/Chapter 10/Instances.w"
void Instances__SUBJ_make_adj_const_domain(inference_subject *S, instance *I, property *P) ;
#line 599 "inform7/Chapter 10/Instances.w"
void Instances__SUBJ_write_element_of_condition(inference_subject *infs, char *cond) ;
#line 612 "inform7/Chapter 10/Instances.w"
int Instances__SUBJ_compile_all(OUTPUT_STREAM) ;
#line 624 "inform7/Chapter 10/Instances.w"
void Instances__SUBJ_compile(OUTPUT_STREAM, inference_subject *infs) ;
#line 647 "inform7/Chapter 10/Instances.w"
adjectival_phrase * Instances__get_adjectival_phrase(instance *I) ;
#line 651 "inform7/Chapter 10/Instances.w"
adjective_meaning * Instances__ADJ_parse(parse_node *pn, int sense, wording AW, wording DNW, wording CONW, wording CALLW) ;
#line 656 "inform7/Chapter 10/Instances.w"
void Instances__ADJ_compiling_soon(adjective_meaning *am, instance *I, int T) ;
#line 659 "inform7/Chapter 10/Instances.w"
int Instances__ADJ_compile(instance *I, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 669 "inform7/Chapter 10/Instances.w"
int Instances__ADJ_assert(instance *I, inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) ;
#line 681 "inform7/Chapter 10/Instances.w"
int Instances__ADJ_index(instance *I) ;
#line 721 "inform7/Chapter 10/Instances.w"
void Instances__make_adj_const_domain(instance *I, property *P, kind *set, instance *singleton) ;
#line 73 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable * NonlocalVariables__new_global(wording W, kind *K) ;
#line 78 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable * NonlocalVariables__new_stacked(wording W, kind *K, stacked_variable *scope) ;
#line 87 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable * NonlocalVariables__new(wording W, kind *K, stacked_variable *scope) ;
#line 158 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__log(nonlocal_variable *nlv) ;
#line 169 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable * NonlocalVariables__parse(wording W) ;
#line 184 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__translates(wording W, parse_node *p2) ;
#line 213 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__set_I6_identifier(nonlocal_variable *nlv, char *rvalue, char *lvalue) ;
#line 225 "inform7/Chapter 10/Nonlocal Variables.w"
char * NonlocalVariables__identifier(nonlocal_variable *nlv) ;
#line 231 "inform7/Chapter 10/Nonlocal Variables.w"
char * NonlocalVariables__lvalue_identifier(nonlocal_variable *nlv) ;
#line 253 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__allocate_storage(void) ;
#line 273 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__set_write_schema(nonlocal_variable *nlv, char *sch) ;
#line 277 "inform7/Chapter 10/Nonlocal Variables.w"
char * NonlocalVariables__get_write_schema(nonlocal_variable *nlv) ;
#line 283 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__warn_about_change(nonlocal_variable *nlv) ;
#line 303 "inform7/Chapter 10/Nonlocal Variables.w"
wording NonlocalVariables__SUBJ_get_name_text(inference_subject *from) ;
#line 308 "inform7/Chapter 10/Nonlocal Variables.w"
general_pointer NonlocalVariables__SUBJ_new_permission_granted(inference_subject *from) ;
#line 312 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__SUBJ_make_adj_const_domain(inference_subject *infs, instance *nc, property *prn) ;
#line 316 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__SUBJ_complete_model(inference_subject *infs) ;
#line 319 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__SUBJ_check_model(inference_subject *infs) ;
#line 322 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__SUBJ_write_element_of_condition(inference_subject *infs, char *cond) ;
#line 326 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__SUBJ_compile(OUTPUT_STREAM, inference_subject *infs) ;
#line 329 "inform7/Chapter 10/Nonlocal Variables.w"
inference_subject * NonlocalVariables__get_knowledge(nonlocal_variable *nlv) ;
#line 337 "inform7/Chapter 10/Nonlocal Variables.w"
int NonlocalVariables__SUBJ_compile_all(OUTPUT_STREAM) ;
#line 399 "inform7/Chapter 10/Nonlocal Variables.w"
parse_node * NonlocalVariables__get_initial_value(nonlocal_variable *nlv) ;
#line 408 "inform7/Chapter 10/Nonlocal Variables.w"
parse_node * NonlocalVariables__origin_of_initial_value(nonlocal_variable *nlv) ;
#line 417 "inform7/Chapter 10/Nonlocal Variables.w"
int NonlocalVariables__has_initial_value_set(nonlocal_variable *nlv) ;
#line 425 "inform7/Chapter 10/Nonlocal Variables.w"
int NonlocalVariables__is_global(nonlocal_variable *nlv) ;
#line 435 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__set_kind(nonlocal_variable *nlv, kind *K) ;
#line 440 "inform7/Chapter 10/Nonlocal Variables.w"
kind * NonlocalVariables__kind(nonlocal_variable *nlv) ;
#line 448 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable * NonlocalVariables__temporary(char *I6_form, kind *K) ;
#line 456 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable * NonlocalVariables__temporary_formal(int i) ;
#line 475 "inform7/Chapter 10/Nonlocal Variables.w"
wording NonlocalVariables__treat_as_plain_text_word(nonlocal_variable *nlv) ;
#line 489 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__make_constant(nonlocal_variable *nlv, int bib) ;
#line 496 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__make_initalisable(nonlocal_variable *nlv) ;
#line 500 "inform7/Chapter 10/Nonlocal Variables.w"
int NonlocalVariables__is_constant(nonlocal_variable *nlv) ;
#line 505 "inform7/Chapter 10/Nonlocal Variables.w"
int NonlocalVariables__must_be_constant(nonlocal_variable *nlv) ;
#line 520 "inform7/Chapter 10/Nonlocal Variables.w"
parse_node * NonlocalVariables__substitute_constants(parse_node *spec) ;
#line 554 "inform7/Chapter 10/Nonlocal Variables.w"
inference_subject * NonlocalVariables__get_alias(nonlocal_variable *nlv) ;
#line 564 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__set_alias(nonlocal_variable *nlv, inference_subject *infs) ;
#line 580 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__compile_initial_value(OUTPUT_STREAM, nonlocal_variable *nlv) ;
#line 587 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__compile_initial_value_inner(OUTPUT_STREAM, nonlocal_variable *nlv) ;
#line 664 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__index_all(void) ;
#line 704 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__index_single(nonlocal_variable *nlv) ;
#line 18 "inform7/Chapter 10/Index Physical World.w"
void Data__Objects__page_Kinds(void) ;
#line 48 "inform7/Chapter 10/Index Physical World.w"
void Data__Objects__page_World(void) ;
#line 170 "inform7/Chapter 10/Index Physical World.w"
void Data__Objects__index(instance *I, kind *K, int depth, int details) ;
#line 359 "inform7/Chapter 10/Index Physical World.w"
void Data__Objects__index_instances(kind *K, int depth) ;
#line 333 "inform7/Chapter 11/Binary Predicates.w"
bp_term_details BinaryPredicates__new_term(inference_subject *infs) ;
#line 346 "inform7/Chapter 11/Binary Predicates.w"
bp_term_details BinaryPredicates__full_new_term(inference_subject *infs, kind *K, wording CW, i6_schema *f) ;
#line 359 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__set_term_domain(bp_term_details *bptd, kind *K) ;
#line 368 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__set_term_function(bp_term_details *bptd, i6_schema *f) ;
#line 373 "inform7/Chapter 11/Binary Predicates.w"
i6_schema * BinaryPredicates__get_term_function(bp_term_details *bptd) ;
#line 381 "inform7/Chapter 11/Binary Predicates.w"
kind * BinaryPredicates__kind(binary_predicate *bp) ;
#line 393 "inform7/Chapter 11/Binary Predicates.w"
kind * BinaryPredicates__kind_of_term(bp_term_details *bptd) ;
#line 402 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__index_term_details(bp_term_details *bptd) ;
#line 415 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__add_term_as_call_parameter(OUTPUT_STREAM, ph_stack_frame *phsf, bp_term_details bptd) ;
#line 429 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__set_index_details(binary_predicate *bp, char *left, char *right) ;
#line 457 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate * BinaryPredicates__make_equality(void) ;
#line 478 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate * BinaryPredicates__make_pair(int family, bp_term_details left_term, bp_term_details right_term, char *name, char *namer, property *pn, i6_schema *mtf, i6_schema *tf, word_assemblage source_name) ;
#line 511 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate * BinaryPredicates__make_pair_sketchily(word_assemblage wa, int f) ;
#line 534 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate * BinaryPredicates__make_single(int family, bp_term_details left_term, bp_term_details right_term, char *name, property *pn, i6_schema *mtf, i6_schema *tf, word_assemblage rn) ;
#line 588 "inform7/Chapter 11/Binary Predicates.w"
wording BinaryPredicates__SUBJ_get_name_text(inference_subject *from) ;
#line 592 "inform7/Chapter 11/Binary Predicates.w"
general_pointer BinaryPredicates__SUBJ_new_permission_granted(inference_subject *from) ;
#line 596 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__SUBJ_make_adj_const_domain(inference_subject *infs, instance *nc, property *prn) ;
#line 600 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__SUBJ_complete_model(inference_subject *infs) ;
#line 618 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__SUBJ_check_model(inference_subject *infs) ;
#line 630 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__SUBJ_write_element_of_condition(inference_subject *infs, char *cond) ;
#line 634 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__SUBJ_compile_all(OUTPUT_STREAM) ;
#line 638 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__SUBJ_compile(OUTPUT_STREAM, inference_subject *infs) ;
#line 668 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__log_term_details(bp_term_details *bptd, int i) ;
#line 677 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__log(binary_predicate *bp) ;
#line 709 "inform7/Chapter 11/Binary Predicates.w"
char * BinaryPredicates__get_log_name(binary_predicate *bp) ;
#line 716 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__get_form_of_relation(binary_predicate *bp) ;
#line 719 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__is_explicit_with_runtime_storage(binary_predicate *bp) ;
#line 725 "inform7/Chapter 11/Binary Predicates.w"
char * BinaryPredicates__form_to_text(binary_predicate *bp) ;
#line 740 "inform7/Chapter 11/Binary Predicates.w"
parse_node * BinaryPredicates__get_bp_created_at(binary_predicate *bp) ;
#line 747 "inform7/Chapter 11/Binary Predicates.w"
kind * BinaryPredicates__term_kind(binary_predicate *bp, int t) ;
#line 750 "inform7/Chapter 11/Binary Predicates.w"
i6_schema * BinaryPredicates__get_term_as_function_of_other(binary_predicate *bp, int t) ;
#line 757 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate * BinaryPredicates__get_reversal(binary_predicate *bp) ;
#line 760 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__is_the_wrong_way_round(binary_predicate *bp) ;
#line 768 "inform7/Chapter 11/Binary Predicates.w"
i6_schema * BinaryPredicates__get_test_function(binary_predicate *bp) ;
#line 771 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__can_be_made_true_at_runtime(binary_predicate *bp) ;
#line 785 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__allow_arbitrary_assertions(binary_predicate *bp) ;
#line 788 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__store_dynamically(binary_predicate *bp) ;
#line 791 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__relates_values_not_objects(binary_predicate *bp) ;
#line 794 "inform7/Chapter 11/Binary Predicates.w"
inference_subject * BinaryPredicates__as_subject(binary_predicate *bp) ;
#line 801 "inform7/Chapter 11/Binary Predicates.w"
property * BinaryPredicates__get_i6_storage_property(binary_predicate *bp) ;
#line 804 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__allows_function_simplification(binary_predicate *bp) ;
#line 807 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__mark_as_needed(binary_predicate *bp) ;
#line 814 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__set_comparison_details(binary_predicate *bp, int sign, property *prn) ;
#line 831 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__write_optimised_loop_schema(i6_schema *sch, binary_predicate *bp) ;
#line 874 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__make_built_in(void) ;
#line 891 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__make_built_in_further(void) ;
#line 911 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 931 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__assert(binary_predicate *bp, inference_subject *subj0, parse_node *spec0, inference_subject *subj1, parse_node *spec1) ;
#line 951 "inform7/Chapter 11/Binary Predicates.w"
i6_schema * BinaryPredicates__get_i6_schema(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 979 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 124 "inform7/Chapter 11/Relations.w"
void Relations__parse_new(parse_node *PN) ;
#line 150 "inform7/Chapter 11/Relations.w"
void Relations__parse_new_relation_further(parse_node *PN) ;
#line 749 "inform7/Chapter 11/Relations.w"
int Relations__parse_relation_term_type(wording W, kind **set_K, char *side) ;
#line 768 "inform7/Chapter 11/Relations.w"
int Relations__check_finite_range(kind *K) ;
#line 792 "inform7/Chapter 11/Relations.w"
void Relations__compile_defined_relation_constants(OUTPUT_STREAM) ;
#line 817 "inform7/Chapter 11/Relations.w"
void Relations__compile_relation_records(OUTPUT_STREAM) ;
#line 1135 "inform7/Chapter 11/Relations.w"
void Relations__write_rels_lookup(OUTPUT_STREAM, binary_predicate *bp, int t) ;
#line 1165 "inform7/Chapter 11/Relations.w"
void Relations__write_rels_lookup_list(OUTPUT_STREAM, binary_predicate *bp, int t) ;
#line 1187 "inform7/Chapter 11/Relations.w"
void Relations__write_rels_lookup_list_all(OUTPUT_STREAM, binary_predicate *bp, int t) ;
#line 1215 "inform7/Chapter 11/Relations.w"
void Relations__compile_default_relation(OUTPUT_STREAM, char *identifier, kind *K) ;
#line 1230 "inform7/Chapter 11/Relations.w"
void Relations__compile_blank_relation(OUTPUT_STREAM, kind *K) ;
#line 1251 "inform7/Chapter 11/Relations.w"
void Relations__relations_command(OUTPUT_STREAM) ;
#line 1279 "inform7/Chapter 11/Relations.w"
void Relations__begin_bit_stream(OUTPUT_STREAM) ;
#line 1283 "inform7/Chapter 11/Relations.w"
void Relations__compile_bit(OUTPUT_STREAM, int b) ;
#line 1293 "inform7/Chapter 11/Relations.w"
void Relations__end_bit_stream(OUTPUT_STREAM) ;
#line 1302 "inform7/Chapter 11/Relations.w"
void Relations__compile_vtov_storage(OUTPUT_STREAM, binary_predicate *bp) ;
#line 1407 "inform7/Chapter 11/Relations.w"
int Relations__infs_in_domain(inference_subject *infs, binary_predicate *bp, int index) ;
#line 1461 "inform7/Chapter 11/Relations.w"
int Relations__relation_range(binary_predicate *bp, int index) ;
#line 1475 "inform7/Chapter 11/Relations.w"
void Relations__allocate_index_storage(void) ;
#line 1480 "inform7/Chapter 11/Relations.w"
void Relations__set_relation_index(inference_subject *infs, int i, int v) ;
#line 1485 "inform7/Chapter 11/Relations.w"
int Relations__get_relation_index(inference_subject *infs, int i) ;
#line 1490 "inform7/Chapter 11/Relations.w"
void Relations__free_index_storage(void) ;
#line 1559 "inform7/Chapter 11/Relations.w"
void Relations__equivalence_relation_make_singleton_partitions(binary_predicate *bp, int domain_size) ;
#line 1598 "inform7/Chapter 11/Relations.w"
void Relations__equivalence_relation_merge_classes(binary_predicate *bp, int domain_size, int ix1, int ix2) ;
#line 1622 "inform7/Chapter 11/Relations.w"
void Relations__equivalence_relation_add_properties(binary_predicate *bp) ;
#line 1649 "inform7/Chapter 11/Relations.w"
int Relations__equivalence_relation_get_class(binary_predicate *bp, int ix) ;
#line 1668 "inform7/Chapter 11/Relations.w"
void Relations__check_OtoO_relation(binary_predicate *bp) ;
#line 1721 "inform7/Chapter 11/Relations.w"
void Relations__check_OtoV_relation(binary_predicate *bp) ;
#line 1804 "inform7/Chapter 11/Relations.w"
void Relations__compile_defined_relations(OUTPUT_STREAM) ;
#line 1900 "inform7/Chapter 11/Relations.w"
void Relations__compile_routine_to_decide(OUTPUT_STREAM, char *rname, wording W, bp_term_details par1, bp_term_details par2) ;
#line 1929 "inform7/Chapter 11/Relations.w"
void Relations__index_table(void) ;
#line 1979 "inform7/Chapter 11/Relations.w"
void Relations__index_for_verbs(binary_predicate *bp) ;
#line 14 "inform7/Chapter 11/Explicit Relations.w"
void Relations__Explicit__REL_create_initial_stock(void) ;
#line 16 "inform7/Chapter 11/Explicit Relations.w"
void Relations__Explicit__REL_create_second_stock(void) ;
#line 22 "inform7/Chapter 11/Explicit Relations.w"
int Relations__Explicit__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 32 "inform7/Chapter 11/Explicit Relations.w"
int Relations__Explicit__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 91 "inform7/Chapter 11/Explicit Relations.w"
void Relations__Explicit__infer_property_based_relation(binary_predicate *relation, inference_subject *infs0, inference_subject *infs1) ;
#line 103 "inform7/Chapter 11/Explicit Relations.w"
int Relations__Explicit__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 110 "inform7/Chapter 11/Explicit Relations.w"
int Relations__Explicit__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 20 "inform7/Chapter 11/The Universal Relation.w"
void Relations__Universal__REL_create_initial_stock(void) ;
#line 37 "inform7/Chapter 11/The Universal Relation.w"
void Relations__Universal__REL_create_second_stock(void) ;
#line 44 "inform7/Chapter 11/The Universal Relation.w"
int Relations__Universal__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 109 "inform7/Chapter 11/The Universal Relation.w"
int Relations__Universal__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 120 "inform7/Chapter 11/The Universal Relation.w"
int Relations__Universal__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 148 "inform7/Chapter 11/The Universal Relation.w"
int Relations__Universal__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 60 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage * Verbs__register_vu(word_assemblage wa, int negated, int tensed, binary_predicate *root, verb_conjugation *vc, int unexpected_upper_casing_used) ;
#line 96 "inform7/Chapter 11/Conjugation of Verbs.w"
int Verbs__vu_foreign(verb_usage *vu) ;
#line 109 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage * Verbs__find_vu(word_assemblage against) ;
#line 120 "inform7/Chapter 11/Conjugation of Verbs.w"
binary_predicate * Verbs__get_meaning(verb_usage *vu) ;
#line 123 "inform7/Chapter 11/Conjugation of Verbs.w"
int Verbs__get_tense_used(verb_usage *vu) ;
#line 126 "inform7/Chapter 11/Conjugation of Verbs.w"
int Verbs__is_used_negatively(verb_usage *vu) ;
#line 141 "inform7/Chapter 11/Conjugation of Verbs.w"
int Verbs__parse_against_verb(wording W, verb_usage *vu) ;
#line 378 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__log(verb_usage *vu) ;
#line 386 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__log_all(void) ;
#line 404 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__tabulate(lexicon_entry *lex, int tense, char *tensename) ;
#line 426 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__tabulate_meaning(lexicon_entry *lex) ;
#line 467 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__stock(void) ;
#line 496 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__register_regular_verb(verb_conjugation *vc, binary_predicate *root, int unexpected_upper_casing_used) ;
#line 514 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__register_main_forms_of_verb(verb_conjugation *vc, verb_tabulation *vt, binary_predicate *root, int unexpected_upper_casing_used) ;
#line 695 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__parse_new(parse_node *PN) ;
#line 989 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__ConjugateVerb_invoke(OUTPUT_STREAM, verb_conjugation *vc, verb_conjugation *modal, int negated) ;
#line 1014 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__ConjugateVerb_routine(OUTPUT_STREAM) ;
#line 1152 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__conj_from_wa(OUTPUT_STREAM, word_assemblage *wa, verb_conjugation *vc, int mau) ;
#line 1182 "inform7/Chapter 11/Conjugation of Verbs.w"
int Verbs__takes_contraction_form(word_assemblage *wa) ;
#line 1190 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_conjugation * Verbs__find_vc_by_infinitive(word_assemblage infinitive) ;
#line 50 "inform7/Chapter 11/Prepositions.w"
preposition_usage * Prepositions__register(word_assemblage wa, int assumes_player, binary_predicate *root, int stroked, int unexpected_upper_casing_used) ;
#line 80 "inform7/Chapter 11/Prepositions.w"
preposition_usage * Prepositions__find_pu(word_assemblage against) ;
#line 91 "inform7/Chapter 11/Prepositions.w"
int Prepositions__implicitly_negates(preposition_usage *pu) ;
#line 95 "inform7/Chapter 11/Prepositions.w"
binary_predicate * Prepositions__get_meaning(preposition_usage *pu) ;
#line 99 "inform7/Chapter 11/Prepositions.w"
parse_node * Prepositions__get_where_pu_created(preposition_usage *pu) ;
#line 115 "inform7/Chapter 11/Prepositions.w"
int Prepositions__parse_prep_against(wording W, preposition_usage *pu, int fill) ;
#line 164 "inform7/Chapter 11/Prepositions.w"
void Prepositions__log(preposition_usage *pu) ;
#line 177 "inform7/Chapter 11/Prepositions.w"
void Prepositions__register_comparative(wording W, binary_predicate *root) ;
#line 185 "inform7/Chapter 11/Prepositions.w"
void Prepositions__register_same_property_as(binary_predicate *root) ;
#line 238 "inform7/Chapter 12/Lexer.w"
void Lexer__start(void) ;
#line 254 "inform7/Chapter 12/Lexer.w"
void Lexer__ensure_space_up_to(int n) ;
#line 290 "inform7/Chapter 12/Lexer.w"
void Lexer__ensure_lexer_hwm_can_be_raised_by(int n, int transfer_partial_word) ;
#line 312 "inform7/Chapter 12/Lexer.w"
void Lexer__allocate_lexer_workspace_chunk(int multiplier) ;
#line 327 "inform7/Chapter 12/Lexer.w"
char * Lexer__copy_to_memory(char *p) ;
#line 376 "inform7/Chapter 12/Lexer.w"
int Lexer__is_punctuation(char c) ;
#line 393 "inform7/Chapter 12/Lexer.w"
int Lexer__indentation_level(int wn) ;
#line 399 "inform7/Chapter 12/Lexer.w"
char Lexer__break_char_for_indents(int t) ;
#line 408 "inform7/Chapter 12/Lexer.w"
vocabulary_entry * Lexer__word(int wn) ;
#line 412 "inform7/Chapter 12/Lexer.w"
void Lexer__set_word(int wn, vocabulary_entry *ve) ;
#line 416 "inform7/Chapter 12/Lexer.w"
int Lexer__break_before(int wn) ;
#line 420 "inform7/Chapter 12/Lexer.w"
source_file * Lexer__file_of_origin(int wn) ;
#line 424 "inform7/Chapter 12/Lexer.w"
source_location Lexer__word_location(int wn) ;
#line 434 "inform7/Chapter 12/Lexer.w"
char * Lexer__word_raw_text(int wn) ;
#line 438 "inform7/Chapter 12/Lexer.w"
void Lexer__set_word_raw_text(int wn, char *rt) ;
#line 442 "inform7/Chapter 12/Lexer.w"
char * Lexer__word_text(int wn) ;
#line 446 "inform7/Chapter 12/Lexer.w"
void Lexer__set_word_text(int wn, char *rt) ;
#line 450 "inform7/Chapter 12/Lexer.w"
void Lexer__word_copy(int to, int from) ;
#line 519 "inform7/Chapter 12/Lexer.w"
void Lexer__reset_lexer(void) ;
#line 560 "inform7/Chapter 12/Lexer.w"
void Lexer__feed_begins(source_location sl) ;
#line 568 "inform7/Chapter 12/Lexer.w"
wording Lexer__feed_ends(int extra_padding, char *problem_source_description) ;
#line 684 "inform7/Chapter 12/Lexer.w"
void Lexer__feed_triplet(int last_cr, int cr, int next_cr) ;
#line 741 "inform7/Chapter 12/Lexer.w"
void Lexer__feed_char_into_lexer(char c) ;
#line 1122 "inform7/Chapter 12/Lexer.w"
wording Lexer__splice_words(wording W) ;
#line 60 "inform7/Chapter 12/Read Source Text.w"
int SourceFiles__read_extension_source_text(extension_file *EF, char *synopsis, int documentation_only) ;
#line 67 "inform7/Chapter 12/Read Source Text.w"
void SourceFiles__read_primary_source_text(void) ;
#line 86 "inform7/Chapter 12/Read Source Text.w"
int SourceFiles__read_file(filename *F, char *synopsis, extension_file *EF, int documentation_only) ;
#line 193 "inform7/Chapter 12/Read Source Text.w"
void SourceFiles__feed_file_into_lexer(source_file *sf, char *leaf, int documentation_only) ;
#line 245 "inform7/Chapter 12/Read Source Text.w"
int SourceFiles__word_count(int wc) ;
#line 274 "inform7/Chapter 12/Read Source Text.w"
int SourceFiles__total_word_count(source_file *sf) ;
#line 278 "inform7/Chapter 12/Read Source Text.w"
int SourceFiles__last_lexed_word(source_file *sf) ;
#line 288 "inform7/Chapter 12/Read Source Text.w"
filename * SourceFiles__get_filename(source_file *sf) ;
#line 293 "inform7/Chapter 12/Read Source Text.w"
extension_file * SourceFiles__get_extension_corresponding(source_file *sf) ;
#line 298 "inform7/Chapter 12/Read Source Text.w"
source_file * SourceFiles__filename_to_source_file(char *name2) ;
#line 340 "inform7/Chapter 12/Read Source Text.w"
int SourceFiles__utf8_fgetc(FILE *from, char **or_from, int escape_oddities) ;
#line 27 "inform7/Chapter 12/Lexical Services.w"
int Text__compare_word_by_strcmp(int w, char *t) ;
#line 30 "inform7/Chapter 12/Lexical Services.w"
int Text__compare_raw_word_by_strcmp(int w, char *t) ;
#line 42 "inform7/Chapter 12/Lexical Services.w"
int Text__unexpectedly_upper_case(int wn) ;
#line 57 "inform7/Chapter 12/Lexical Services.w"
int Text__singly_quoted(int wn) ;
#line 70 "inform7/Chapter 12/Lexical Services.w"
int Text__text_ending_sentence(int wn) ;
#line 128 "inform7/Chapter 12/Lexical Services.w"
void Text__dequote_word(int wn) ;
#line 158 "inform7/Chapter 12/Lexical Services.w"
int Text__well_formed_text_routine(char *fw) ;
#line 175 "inform7/Chapter 12/Lexical Services.w"
int Text__perhaps_ill_formed_text_routine(char *fw) ;
#line 189 "inform7/Chapter 12/Lexical Services.w"
void Text__to_stream(OUTPUT_STREAM, char *p) ;
#line 199 "inform7/Chapter 12/Lexical Services.w"
void Text__transcode_ISO_string_to_UTF8(char *p, char *dest) ;
#line 216 "inform7/Chapter 12/Lexical Services.w"
void Text__log_lexer_output(void) ;
#line 54 "inform7/Chapter 12/Wordings.w"
wording Wordings__new(int A, int B) ;
#line 58 "inform7/Chapter 12/Wordings.w"
wording Wordings__one_word(int A) ;
#line 66 "inform7/Chapter 12/Wordings.w"
wording Wordings__up_to(wording W, int last_wn) ;
#line 72 "inform7/Chapter 12/Wordings.w"
wording Wordings__from(wording W, int first_wn) ;
#line 81 "inform7/Chapter 12/Wordings.w"
int Wordings__length(wording W) ;
#line 86 "inform7/Chapter 12/Wordings.w"
int Wordings__phrasual_length(wording W) ;
#line 97 "inform7/Chapter 12/Wordings.w"
int Wordings__first_wn(wording W) ;
#line 101 "inform7/Chapter 12/Wordings.w"
int Wordings__last_wn(wording W) ;
#line 110 "inform7/Chapter 12/Wordings.w"
wording Wordings__truncate(wording W, int max) ;
#line 115 "inform7/Chapter 12/Wordings.w"
wording Wordings__first_word(wording W) ;
#line 121 "inform7/Chapter 12/Wordings.w"
wording Wordings__last_word(wording W) ;
#line 127 "inform7/Chapter 12/Wordings.w"
wording Wordings__trim_first_word(wording W) ;
#line 134 "inform7/Chapter 12/Wordings.w"
wording Wordings__trim_last_word(wording W) ;
#line 141 "inform7/Chapter 12/Wordings.w"
wording Wordings__trim_both_ends(wording W) ;
#line 151 "inform7/Chapter 12/Wordings.w"
wording Wordings__union(wording W1, wording W2) ;
#line 162 "inform7/Chapter 12/Wordings.w"
int Wordings__within(wording SMALL, wording BIG) ;
#line 169 "inform7/Chapter 12/Wordings.w"
source_location Wordings__location(wording W) ;
#line 173 "inform7/Chapter 12/Wordings.w"
heading * Wordings__heading_of(wording W) ;
#line 181 "inform7/Chapter 12/Wordings.w"
int Wordings__empty(wording W) ;
#line 186 "inform7/Chapter 12/Wordings.w"
int Wordings__nonempty(wording W) ;
#line 196 "inform7/Chapter 12/Wordings.w"
int Wordings__eq(wording W1, wording W2) ;
#line 209 "inform7/Chapter 12/Wordings.w"
int Wordings__match(wording W1, wording W2) ;
#line 216 "inform7/Chapter 12/Wordings.w"
int Wordings__starts_with(wording W, wording S) ;
#line 224 "inform7/Chapter 12/Wordings.w"
int Wordings__match_inner(int w1, int w2, int w3, int w4) ;
#line 235 "inform7/Chapter 12/Wordings.w"
int Wordings__match_cs(wording W1, wording W2) ;
#line 242 "inform7/Chapter 12/Wordings.w"
int Wordings__match_cs_inner(int w1, int w2, int w3, int w4) ;
#line 255 "inform7/Chapter 12/Wordings.w"
int Wordings__match_perhaps_quoted(wording W1, wording W2) ;
#line 275 "inform7/Chapter 12/Wordings.w"
int Wordings__strcmp(wording X, wording Y) ;
#line 293 "inform7/Chapter 12/Wordings.w"
int Wordings__hash_code(wording W) ;
#line 303 "inform7/Chapter 12/Wordings.w"
int Wordings__paired_brackets(wording W) ;
#line 314 "inform7/Chapter 12/Wordings.w"
int Wordings__mismatched_brackets(wording W) ;
#line 328 "inform7/Chapter 12/Wordings.w"
int Wordings__top_level_comma(wording W) ;
#line 356 "inform7/Chapter 12/Wordings.w"
int Wordings__last_word_of_formatted_text(wording W, int tab_flag) ;
#line 378 "inform7/Chapter 12/Wordings.w"
void Wordings__to_stream(OUTPUT_STREAM, wording W) ;
#line 388 "inform7/Chapter 12/Wordings.w"
void Wordings__to_string(char *str, wording W) ;
#line 396 "inform7/Chapter 12/Wordings.w"
void Wordings__to_string_truncated(char *str, int max, wording W) ;
#line 421 "inform7/Chapter 12/Wordings.w"
void Wordings__to_string_abbreviated(int extent, char *str, wording W) ;
#line 489 "inform7/Chapter 12/Wordings.w"
void Wordings__to_stream_raw(OUTPUT_STREAM, wording W) ;
#line 511 "inform7/Chapter 12/Wordings.w"
void Wordings__to_stream_raw_within_i6_literal(OUTPUT_STREAM, wording W) ;
#line 531 "inform7/Chapter 12/Wordings.w"
void Wordings__to_string_raw(char *str, wording W) ;
#line 547 "inform7/Chapter 12/Wordings.w"
void Wordings__to_string_raw_truncated(char *str, int max, wording W) ;
#line 568 "inform7/Chapter 12/Wordings.w"
void Wordings__index(wording W) ;
#line 572 "inform7/Chapter 12/Wordings.w"
void Wordings__index_raw(wording W) ;
#line 580 "inform7/Chapter 12/Wordings.w"
void Wordings__log(wording W) ;
#line 584 "inform7/Chapter 12/Wordings.w"
void Wordings__log_raw(wording W) ;
#line 592 "inform7/Chapter 12/Wordings.w"
void Wordings__log_with_whitespace(wording W) ;
#line 609 "inform7/Chapter 12/Wordings.w"
void Wordings__log_spaceless(wording W) ;
#line 30 "inform7/Chapter 12/Feeds.w"
feed_t Feeds__begin(void) ;
#line 33 "inform7/Chapter 12/Feeds.w"
wording Feeds__end(feed_t id) ;
#line 42 "inform7/Chapter 12/Feeds.w"
wording Feeds__feed_text(char *text) ;
#line 46 "inform7/Chapter 12/Feeds.w"
wording Feeds__feed_text_expanding_strings(char *text) ;
#line 50 "inform7/Chapter 12/Feeds.w"
wording Feeds__feed_text_for_preform(char *text) ;
#line 58 "inform7/Chapter 12/Feeds.w"
wording Feeds__feed_text_full(char *text, int expand_strings, char *nonstandard) ;
#line 89 "inform7/Chapter 12/Feeds.w"
wording Feeds__feed_wording(wording W) ;
#line 553 "inform7/Chapter 13/Parse Tree.w"
parse_tree_node_type * ParseTree__node_metadata(node_type_t t) ;
#line 566 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__valid_type(node_type_t t) ;
#line 571 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__cat(node_type_t t) ;
#line 577 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__top_level(node_type_t t) ;
#line 583 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__second_level(node_type_t t) ;
#line 589 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__is_specification_node_type(node_type_t t) ;
#line 599 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__visitable(node_type_t t) ;
#line 604 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__test_flag(node_type_t t, int f) ;
#line 613 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__is_lvalue(parse_node *pn) ;
#line 619 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__is_rvalue(parse_node *pn) ;
#line 625 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__is_value(parse_node *pn) ;
#line 633 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__is_condition(parse_node *pn) ;
#line 639 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__is_phrasal(parse_node *pn) ;
#line 650 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__log_type(node_type_t t) ;
#line 657 "inform7/Chapter 13/Parse Tree.w"
char * ParseTree__get_type_name(node_type_t t) ;
#line 666 "inform7/Chapter 13/Parse Tree.w"
parse_node * ParseTree__new(node_type_t t) ;
#line 681 "inform7/Chapter 13/Parse Tree.w"
parse_node * ParseTree__new_with_words(node_type_t code_number, wording W) ;
#line 691 "inform7/Chapter 13/Parse Tree.w"
parse_node * ParseTree__new_from_em(excerpt_meaning *em) ;
#line 700 "inform7/Chapter 13/Parse Tree.w"
wording ParseTree__get_text(parse_node *pn) ;
#line 705 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__set_text(parse_node *pn, wording W) ;
#line 715 "inform7/Chapter 13/Parse Tree.w"
node_type_t ParseTree__get_type(parse_node *pn) ;
#line 719 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__is(parse_node *pn, node_type_t t) ;
#line 728 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__set_type(parse_node *pn, node_type_t nt) ;
#line 745 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__set_type_and_clear_annotations(parse_node *pn, node_type_t nt) ;
#line 752 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__get_score(parse_node *pn) ;
#line 753 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__set_score(parse_node *pn, int s) ;
#line 759 "inform7/Chapter 13/Parse Tree.w"
parse_node_annotation * ParseTree__pna_new(int koa) ;
#line 775 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__has_annotation(parse_node *PN, int koa) ;
#line 789 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__int_annotation(parse_node *PN, int koa) ;
#line 798 "inform7/Chapter 13/Parse Tree.w"
general_pointer ParseTree__pn_pointer_annotation(parse_node *PN, int koa) ;
#line 812 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__annotate_int(parse_node *PN, int koa, int v) ;
#line 831 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__pn_annotate_pointer(parse_node *PN, int koa, general_pointer data) ;
#line 935 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__copy(parse_node *to, parse_node *from) ;
#line 955 "inform7/Chapter 13/Parse Tree.w"
parse_node * ParseTree__duplicate(parse_node *p) ;
#line 964 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__copy_in_place(parse_node *to, parse_node *from) ;
#line 977 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__copy_subtree(parse_node *from, parse_node *to, int level) ;
#line 997 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__no_children(parse_node *pn) ;
#line 1012 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__contains(parse_node *PN, parse_node *to_find) ;
#line 1033 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__left_edge_of(parse_node *PN) ;
#line 1047 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__right_edge_of(parse_node *PN) ;
#line 1063 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__plant_parse_tree(void) ;
#line 1083 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__enable_last_sentence_cacheing(void) ;
#line 1088 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__disable_last_sentence_cacheing(void) ;
#line 1106 "inform7/Chapter 13/Parse Tree.w"
parse_node * ParseTree__graft(parse_node *newborn, parse_node *parent) ;
#line 1132 "inform7/Chapter 13/Parse Tree.w"
parse_node * ParseTree__graft_alternative(parse_node *newborn, parse_node *parent) ;
#line 1162 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__push_attachment_point(parse_node *to) ;
#line 1169 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__pop_attachment_point(int l) ;
#line 1177 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__set_attachment_point_one_off(parse_node *to) ;
#line 1185 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__insert_sentence(parse_node *new) ;
#line 1226 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__log_tree(parse_node *pn) ;
#line 1231 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__log_subtree(parse_node *pn) ;
#line 1246 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__log_subtree_recursively(parse_node *pn, int num, int of, int gen, int ltime) ;
#line 1289 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__log_node(parse_node *pn) ;
#line 1378 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__log_with_annotations(parse_node *pn) ;
#line 1389 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__write_to_file(void) ;
#line 1407 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__write_main_source_to_log(void) ;
#line 1420 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse(void (*visitor)(parse_node *)) ;
#line 1423 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_from(parse_node *pn, void (*visitor)(parse_node *)) ;
#line 1434 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_dfirst(void (*visitor)(parse_node *)) ;
#line 1437 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_dfirst_from(parse_node *pn, void (*visitor)(parse_node *)) ;
#line 1446 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_wfirst(void (*visitor)(parse_node *)) ;
#line 1449 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_wfirst_from(parse_node *pn, void (*visitor)(parse_node *)) ;
#line 1458 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_with_stream(text_stream *OUT, void (*visitor)(text_stream *, parse_node *)) ;
#line 1461 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_from_with_stream(text_stream *OUT, parse_node *pn, void (*visitor)(text_stream *, parse_node *)) ;
#line 1473 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_int(void (*visitor)(parse_node *, int *), int *X) ;
#line 1476 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_from_int(parse_node *pn, void (*visitor)(parse_node *, int *), int *X) ;
#line 1487 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_int_int(void (*visitor)(parse_node *, int *, int *), int *X, int *Y) ;
#line 1490 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_from_int_int(parse_node *pn, void (*visitor)(parse_node *, int *, int *), int *X, int *Y) ;
#line 1501 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_ppn(void (*visitor)(parse_node *, parse_node **), parse_node **X) ;
#line 1504 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_from_ppn(parse_node *pn, void (*visitor)(parse_node *, parse_node **), parse_node **X) ;
#line 1515 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_ppni(void (*visitor)(parse_node *, parse_node **, int *), parse_node **X, int *N) ;
#line 1518 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_from_ppni(parse_node *pn, void (*visitor)(parse_node *, parse_node **, int *), parse_node **X, int *N) ;
#line 1529 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse_up_to_ip(parse_node *end, void (*visitor)(parse_node *, instance **), instance **X) ;
#line 1532 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__traverse_from_up_to_ip(parse_node *end, parse_node *pn, void (*visitor)(parse_node *, instance **), instance **X) ;
#line 1549 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__traverse_ppn_nocs(int (*visitor)(parse_node *, parse_node *, parse_node **), parse_node **X) ;
#line 1552 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__traverse_from_ppn_nocs(parse_node *pn, int (*visitor)(parse_node *, parse_node *, parse_node **), parse_node *from, parse_node **X) ;
#line 1576 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__verify_integrity(parse_node *p, int worth_logging) ;
#line 1589 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__verify_tree_integrity_recursively(parse_node *p, parse_node *from, char *way, int depth, int ltime) ;
#line 1640 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__verify(void) ;
#line 1648 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__verify_structure(parse_node *p) ;
#line 1666 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__verify_structure_recursively(parse_node *p, parse_node *parent, parse_node *latest_routine) ;
#line 1751 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__make_parentage_allowed_table(void) ;
#line 1789 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__parentage_allowed(node_type_t t_parent, int cat_parent, node_type_t t_child, int cat_child) ;
#line 1813 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__allow_annotation(node_type_t t, int annot) ;
#line 1816 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__allow_annotation_to_category(int cat, int annot) ;
#line 1821 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__allow_annotation_to_specification(int annot) ;
#line 1834 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__make_annotation_allowed_table(void) ;
#line 1983 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__annotation_allowed(node_type_t t, int annot) ;
#line 1999 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__allow_in_assertions(parse_node *p) ;
#line 2008 "inform7/Chapter 13/Parse Tree.w"
parse_node * ParseTree__add_possible_reading(parse_node *existing, parse_node *reading, wording W) ;
#line 2038 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__add_pr_inv(parse_node *E, parse_node *reading) ;
#line 2044 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__add_single_pr_inv(parse_node *E, parse_node *N) ;
#line 34 "inform7/Chapter 13/Sentences.w"
void Sentences__declare_source_loaded(void) ;
#line 46 "inform7/Chapter 13/Sentences.w"
void Sentences__break_source(void) ;
#line 93 "inform7/Chapter 13/Sentences.w"
void Sentences__break(wording W, extension_file *from_extension) ;
#line 352 "inform7/Chapter 13/Sentences.w"
void Sentences__make_node(wording W, char stop_character) ;
#line 210 "inform7/Chapter 13/Headings.w"
heading * Sentences__Headings__declare(parse_node *PN) ;
#line 364 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__make_tree(void) ;
#line 431 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__make_child_heading(heading *ch, heading *pa) ;
#line 480 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__verify_heading_tree(void) ;
#line 485 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__verify_heading_tree_recursively(heading *h, int depth) ;
#line 503 "inform7/Chapter 13/Headings.w"
int Sentences__Headings__include_material(heading *h) ;
#line 510 "inform7/Chapter 13/Headings.w"
int Sentences__Headings__indexed(heading *h) ;
#line 518 "inform7/Chapter 13/Headings.w"
extension_file * Sentences__Headings__get_extension_containing(heading *h) ;
#line 529 "inform7/Chapter 13/Headings.w"
wording Sentences__Headings__get_text(heading *h) ;
#line 546 "inform7/Chapter 13/Headings.w"
heading * Sentences__Headings__heading_of(source_location sl) ;
#line 565 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__satisfy_dependencies(void) ;
#line 577 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__satisfy_individual_heading_dependency(heading *h) ;
#line 644 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__excise_material_under(heading *h, parse_node *transfer_to) ;
#line 659 "inform7/Chapter 13/Headings.w"
heading * Sentences__Headings__find_dependent_heading(parse_node *pn) ;
#line 671 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__suppress_dependencies(parse_node *pn) ;
#line 737 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__attach_nametag(nametag *new_tag) ;
#line 758 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__verify_divisions(void) ;
#line 855 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__disturb(void) ;
#line 864 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__construct_nametag_search_list(void) ;
#line 949 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__build_search_list_from(heading *within, heading *way_we_came, int p) ;
#line 986 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__set_nametag_search_score(nametag *nt, int v) ;
#line 990 "inform7/Chapter 13/Headings.w"
nametag * Sentences__Headings__highest_scoring_nametag_searched(void) ;
#line 1010 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__handle_heading(parse_node *PN) ;
#line 1019 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__log(heading *h) ;
#line 1035 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__log_all_headings(void) ;
#line 1042 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__log_headings_recursively(heading *h, int depth) ;
#line 1056 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__index(void) ;
#line 1122 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__index_heading_recursively(heading *h) ;
#line 1183 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__write_as_xml(void) ;
#line 1191 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__write_headings_as_xml_inner(OUTPUT_STREAM) ;
#line 150 "inform7/Chapter 13/Verb Phrases.w"
void Sentences__VPs__traverse(void) ;
#line 153 "inform7/Chapter 13/Verb Phrases.w"
void Sentences__VPs__visit(parse_node *p) ;
#line 196 "inform7/Chapter 13/Verb Phrases.w"
void Sentences__VPs__seek(parse_node *PN) ;
#line 228 "inform7/Chapter 13/Verb Phrases.w"
void Sentences__VPs__switch_dl_mode(parse_node *PN, int sense) ;
#line 443 "inform7/Chapter 13/Verb Phrases.w"
int Sentences__VPs__nss_tree1(int t, wording VW, parse_node *np1) ;
#line 452 "inform7/Chapter 13/Verb Phrases.w"
int Sentences__VPs__nss_tree2(int t, wording VW, parse_node *np1, parse_node *np2) ;
#line 462 "inform7/Chapter 13/Verb Phrases.w"
int Sentences__VPs__nss_tree3(int t, wording VW, parse_node *np1, parse_node *np2, parse_node *np3) ;
#line 875 "inform7/Chapter 13/Verb Phrases.w"
void Sentences__VPs__log(int verb_number) ;
#line 41 "inform7/Chapter 13/Noun Phrases.w"
parse_node * Sentences__NPs__new_raw(wording W) ;
#line 47 "inform7/Chapter 13/Noun Phrases.w"
parse_node * Sentences__NPs__new_raw_empty(void) ;
#line 117 "inform7/Chapter 13/Noun Phrases.w"
parse_node * Sentences__NPs__annotate_by_articles(parse_node *RAW_NP) ;
#line 473 "inform7/Chapter 13/Noun Phrases.w"
parse_node * Sentences__NPs__PN_void(node_type_t t, wording W) ;
#line 480 "inform7/Chapter 13/Noun Phrases.w"
parse_node * Sentences__NPs__PN_single(node_type_t t, wording W, parse_node *A) ;
#line 488 "inform7/Chapter 13/Noun Phrases.w"
parse_node * Sentences__NPs__PN_pair(node_type_t t, wording W, parse_node *A, parse_node *B) ;
#line 504 "inform7/Chapter 13/Noun Phrases.w"
parse_node * Sentences__NPs__PN_rel(wording W, binary_predicate *R, int reln_type, parse_node *referent) ;
#line 531 "inform7/Chapter 13/Noun Phrases.w"
int Sentences__NPs__turn_player_to_yourself(parse_node *pn) ;
#line 62 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__expunge_X_OF_Y_subtree(parse_node *pn) ;
#line 68 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__expunge_FROM_subtree(parse_node *pn) ;
#line 85 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__convert_clause_to_RELATIONSHIP(parse_node *pn) ;
#line 114 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__tidy_up_ofs_and_froms(void) ;
#line 140 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__traverse_for_property_names(parse_node *pn) ;
#line 148 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__check_sentence_for_direction_creation(parse_node *pn) ;
#line 171 "inform7/Chapter 13/Of and From.w"
binary_predicate * Sentences__Rearrangement__relation_noticed(int i) ;
#line 334 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__traverse_for_nonbreaking_ofs(parse_node *pn) ;
#line 368 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__traverse_for_FROM_NT_subtrees(parse_node *pn) ;
#line 65 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__register_recently_lexed_phrases(void) ;
#line 74 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__demote_command_nodes(parse_node *p) ;
#line 91 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__detect_loose_command_nodes(parse_node *p) ;
#line 114 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__parse_routine_structure(parse_node *routine_node) ;
#line 841 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__police_code_block(parse_node *block, control_structure_phrase *context) ;
#line 1002 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__purge_otherwise_if(parse_node *block) ;
#line 1044 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__purge_end_markers(parse_node *block) ;
#line 1062 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__purge_begin_markers(parse_node *block) ;
#line 1084 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__insert_cb_nodes(parse_node *block) ;
#line 1110 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__read_instead_markers(parse_node *block) ;
#line 1131 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__break_up_says(parse_node *block) ;
#line 1165 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__unroll_says(parse_node *cb_node, wording W, int depth) ;
#line 1320 "inform7/Chapter 13/Rule Subtrees.w"
parse_node * Sentences__RuleSubtrees__end_node(parse_node *opening) ;
#line 1335 "inform7/Chapter 13/Rule Subtrees.w"
control_structure_phrase * Sentences__RuleSubtrees__csp_new(void) ;
#line 1348 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__create_standard_csps(void) ;
#line 1397 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__log_control_structure(control_structure_phrase *csp) ;
#line 1413 "inform7/Chapter 13/Rule Subtrees.w"
int Sentences__RuleSubtrees__comma_possible(control_structure_phrase *csp) ;
#line 1419 "inform7/Chapter 13/Rule Subtrees.w"
int Sentences__RuleSubtrees__is_a_loop(control_structure_phrase *csp) ;
#line 1424 "inform7/Chapter 13/Rule Subtrees.w"
int Sentences__RuleSubtrees__opens_block(control_structure_phrase *csp) ;
#line 1429 "inform7/Chapter 13/Rule Subtrees.w"
int Sentences__RuleSubtrees__permits_break(control_structure_phrase *csp) ;
#line 1434 "inform7/Chapter 13/Rule Subtrees.w"
char * Sentences__RuleSubtrees__incipit(control_structure_phrase *csp) ;
#line 1439 "inform7/Chapter 13/Rule Subtrees.w"
control_structure_phrase * Sentences__RuleSubtrees__detect_control_structure(wording W) ;
#line 1447 "inform7/Chapter 13/Rule Subtrees.w"
int Sentences__RuleSubtrees__abbreviated_otherwise(wording W) ;
#line 1454 "inform7/Chapter 13/Rule Subtrees.w"
control_structure_phrase * Sentences__RuleSubtrees__detect_end_control_structure(wording W) ;
#line 187 "inform7/Chapter 14/Extension Files.w"
extension_file * Extensions__Files__new(wording AW, wording NW, wording VMW, int version_word) ;
#line 252 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__set_rubric(extension_file *ef, char *text) ;
#line 257 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__set_extra_credit(extension_file *ef, char *text) ;
#line 267 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__set_corresponding_source_file(extension_file *ef, source_file *sf) ;
#line 271 "inform7/Chapter 14/Extension Files.w"
source_file * Extensions__Files__get_corresponding_source_file(extension_file *ef) ;
#line 278 "inform7/Chapter 14/Extension Files.w"
extension_identifier * Extensions__Files__get_eid(extension_file *ef) ;
#line 285 "inform7/Chapter 14/Extension Files.w"
int Extensions__Files__get_version_wn(extension_file *ef) ;
#line 296 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__set_authorial_modesty(extension_file *ef) ;
#line 297 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__set_general_authorial_modesty(void) ;
#line 305 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_name_to_file(extension_file *ef, OUTPUT_STREAM) ;
#line 309 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_author_to_file(extension_file *ef, OUTPUT_STREAM) ;
#line 316 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__log(extension_file *ef) ;
#line 325 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_I6_comment_describing(extension_file *ef, OUTPUT_STREAM) ;
#line 340 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_full_title_to_stream(OUTPUT_STREAM, extension_file *ef) ;
#line 357 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__check_versions(void) ;
#line 405 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__ShowExtensionVersions_routine(OUTPUT_STREAM) ;
#line 435 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__credit_ef(OUTPUT_STREAM, extension_file *ef, int with_newline) ;
#line 452 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__index(void) ;
#line 463 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__index_extensions_from(extension_file *from) ;
#line 527 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__handle_census_mode(void) ;
#line 537 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__update_census(void) ;
#line 553 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_sketchy_documentation_for_extensions_found(void) ;
#line 588 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_top_level_of_extensions_documentation(void) ;
#line 596 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_top_level_extensions_page(char *leaf, int content) ;
#line 31 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__traverse(void) ;
#line 41 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__visit(parse_node *pn, parse_node **elder, int *includes_cleared) ;
#line 107 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__fulfill_request_to_include_extension(parse_node *p, parse_node *auth_p) ;
#line 149 "inform7/Chapter 14/Including Extensions.w"
extension_file * Extensions__Inclusion__load(wording A, wording T, int version_word, wording VMW) ;
#line 278 "inform7/Chapter 14/Including Extensions.w"
int Extensions__Inclusion__parse_version(int vwn) ;
#line 366 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__check_begins_here(parse_node *PN, extension_file *ef) ;
#line 458 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__check_ends_here(parse_node *PN, extension_file *ef) ;
#line 495 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__handle_extension_begins(parse_node *PN) ;
#line 499 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__handle_extension_ends(parse_node *PN) ;
#line 76 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__new(extension_identifier *eid, char *an, char *ti, int context) ;
#line 98 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__set_raw(extension_identifier *eid, char *raw_an, char *raw_ti) ;
#line 103 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__write_to_HTML_file(OUTPUT_STREAM, extension_identifier *eid, int fancy) ;
#line 111 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__write_to_I6_file(OUTPUT_STREAM, extension_identifier *eid) ;
#line 119 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__write_to_C_string(char *p, extension_identifier *eid) ;
#line 123 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__write_link_to_HTML_file(OUTPUT_STREAM, extension_identifier *eid) ;
#line 145 "inform7/Chapter 14/Extension Identifiers.w"
int Extensions__IDs__match(extension_identifier *eid1, extension_identifier *eid2) ;
#line 156 "inform7/Chapter 14/Extension Identifiers.w"
int Extensions__IDs__compare(extension_identifier *eid1, extension_identifier *eid2) ;
#line 164 "inform7/Chapter 14/Extension Identifiers.w"
int Extensions__IDs__compare_by_title(extension_identifier *eid1, extension_identifier *eid2) ;
#line 172 "inform7/Chapter 14/Extension Identifiers.w"
int Extensions__IDs__compare_by_date(extension_identifier *eid1, extension_identifier *eid2) ;
#line 182 "inform7/Chapter 14/Extension Identifiers.w"
int Extensions__IDs__compare_by_length(extension_identifier *eid1, extension_identifier *eid2) ;
#line 199 "inform7/Chapter 14/Extension Identifiers.w"
int Extensions__IDs__is_standard_rules(extension_identifier *eid) ;
#line 226 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__add_EID_to_database(extension_identifier *eid, int context) ;
#line 253 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__set_usage_date(extension_identifier *eid, char *date) ;
#line 263 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__set_sort_date(extension_identifier *eid, char *date) ;
#line 273 "inform7/Chapter 14/Extension Identifiers.w"
char * Extensions__IDs__get_usage_date(extension_identifier *eid) ;
#line 287 "inform7/Chapter 14/Extension Identifiers.w"
char * Extensions__IDs__get_sort_date(extension_identifier *eid) ;
#line 301 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__set_word_count(extension_identifier *eid, int wc) ;
#line 311 "inform7/Chapter 14/Extension Identifiers.w"
char * Extensions__IDs__get_sort_word_count(extension_identifier *eid) ;
#line 325 "inform7/Chapter 14/Extension Identifiers.w"
char * Extensions__IDs__get_word_count(extension_identifier *eid) ;
#line 335 "inform7/Chapter 14/Extension Identifiers.w"
int Extensions__IDs__no_times_used_in_context(extension_identifier *eid, int context) ;
#line 345 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__log_EID_hash_table(void) ;
#line 368 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__truncated_strcpy(char *to, char *from, int max) ;
#line 380 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__normalise_casing(char *p) ;
#line 397 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__begin_extension_link(OUTPUT_STREAM, extension_identifier *eid, char *rubric) ;
#line 411 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__escape_apostrophes(OUTPUT_STREAM, char *p) ;
#line 421 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__end_extension_link(OUTPUT_STREAM, extension_identifier *eid) ;
#line 54 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__perform(void) ;
#line 70 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__take_census_of_domain(pathname *P, int origin) ;
#line 96 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__census_from(pathname *P, int top_level, int origin, char *parent) ;
#line 514 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__begin_recording_census_errors(void) ;
#line 519 "inform7/Chapter 14/Extension Census.w"
int Extensions__Census__currently_recording_errors(void) ;
#line 524 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__end_recording_census_errors(void) ;
#line 534 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__census_error(char *message, char *auth, char *title, char *claimed_author, char *claimed_title) ;
#line 557 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__warn_about_census_errors(OUTPUT_STREAM) ;
#line 572 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__transcribe_census_errors(OUTPUT_STREAM) ;
#line 619 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__write_results(OUTPUT_STREAM) ;
#line 998 "inform7/Chapter 14/Extension Census.w"
int Extensions__Census__installation_region(extension_census_datum *ecd) ;
#line 1005 "inform7/Chapter 14/Extension Census.w"
int Extensions__Census__ecd_used(extension_census_datum *ecd) ;
#line 1017 "inform7/Chapter 14/Extension Census.w"
int Extensions__Census__compare_ecd_by_title(const void *ecd1, const void *ecd2) ;
#line 1023 "inform7/Chapter 14/Extension Census.w"
int Extensions__Census__compare_ecd_by_author(const void *ecd1, const void *ecd2) ;
#line 1029 "inform7/Chapter 14/Extension Census.w"
int Extensions__Census__compare_ecd_by_installation(const void *ecd1, const void *ecd2) ;
#line 1037 "inform7/Chapter 14/Extension Census.w"
int Extensions__Census__compare_ecd_by_date(const void *ecd1, const void *ecd2) ;
#line 1043 "inform7/Chapter 14/Extension Census.w"
int Extensions__Census__compare_ecd_by_length(const void *ecd1, const void *ecd2) ;
#line 109 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__log_entry(extension_dictionary_entry *ede) ;
#line 115 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__log_extension_dictionary(void) ;
#line 137 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__erase_entries_of_uninstalled_extensions(void) ;
#line 156 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__erase_entries(extension_file *ef) ;
#line 171 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__new_entry(char *category, extension_file *ef, wording W) ;
#line 179 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__new_entry_from_string(char *category, extension_file *ef, char *headword) ;
#line 183 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__new_dictionary_entry_raw(char *category, char *author, char *title, char *headword) ;
#line 222 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__load(void) ;
#line 287 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__time_stamp(extension_file *ef) ;
#line 307 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__write_back(void) ;
#line 356 "inform7/Chapter 14/Extension Dictionary.w"
int Extensions__Dictionary__sort_extension_dictionary(void) ;
#line 451 "inform7/Chapter 14/Extension Dictionary.w"
int Extensions__Dictionary__compare_ed_entries(const void *elem1, const void *elem2) ;
#line 467 "inform7/Chapter 14/Extension Dictionary.w"
known_extension_clash * Extensions__Dictionary__kec_new(extension_dictionary_entry *L, extension_dictionary_entry *R, int first_known_flag) ;
#line 531 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__extension_clash(extension_dictionary_entry *ede1, extension_dictionary_entry *ede2) ;
#line 588 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__list_known_extension_clashes(OUTPUT_STREAM) ;
#line 636 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__write_to_HTML(OUTPUT_STREAM) ;
#line 14 "inform7/Chapter 14/Extension Documentation.w"
void Extensions__Documentation__write_detailed(extension_file *ef) ;
#line 17 "inform7/Chapter 14/Extension Documentation.w"
void Extensions__Documentation__write_sketchy(extension_census_datum *ecd) ;
#line 40 "inform7/Chapter 14/Extension Documentation.w"
void Extensions__Documentation__write_extension_documentation(extension_census_datum *ecd, extension_file *ef) ;
#line 61 "inform7/Chapter 14/Extension Documentation.w"
int Extensions__Documentation__write_extension_documentation_page(extension_census_datum *ecd, extension_file *ef, int eg_number) ;
#line 407 "inform7/Chapter 14/Extension Documentation.w"
int Extensions__Documentation__document_headword(OUTPUT_STREAM, int kc, extension_file *ef, char *par_heading, char *category, wording W) ;
#line 102 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__traverse(int pass) ;
#line 145 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__visit(parse_node *p, parse_node **last) ;
#line 230 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__switch_sentence_trace(parse_node *PN) ;
#line 256 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__handle_sentence_with_primary_verb(parse_node *p) ;
#line 399 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__set_appearance(int wn) ;
#line 467 "inform7/Chapter 15/Traverse for Assertions.w"
inference_subject * Assertions__Traverse__get_current_subject(void) ;
#line 471 "inform7/Chapter 15/Traverse for Assertions.w"
inference_subject * Assertions__Traverse__get_current_object(void) ;
#line 475 "inform7/Chapter 15/Traverse for Assertions.w"
int Assertions__Traverse__get_current_subject_plurality(void) ;
#line 494 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__new_discussion(void) ;
#line 502 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__change_discussion_topic(inference_subject *infsx, inference_subject *infsy, inference_subject *infsy_full) ;
#line 529 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__subject_of_discussion_a_list(void) ;
#line 41 "inform7/Chapter 15/To Be and To Have.w"
void Assertions__Copular__to_be(parse_node *pv) ;
#line 77 "inform7/Chapter 15/To Be and To Have.w"
void Assertions__Copular__to_have(parse_node *pv) ;
#line 186 "inform7/Chapter 15/To Be and To Have.w"
void Assertions__Copular__make_assertion(parse_node *px, parse_node *py) ;
#line 233 "inform7/Chapter 15/To Be and To Have.w"
inference_subject * Assertions__Copular__discussed_at_node(parse_node *pn) ;
#line 248 "inform7/Chapter 15/To Be and To Have.w"
void Assertions__Copular__make_existential_assertion(parse_node *py) ;
#line 20 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__noun_from_infs(parse_node *p, inference_subject *infs) ;
#line 25 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__noun_from_value(parse_node *p, parse_node *spec) ;
#line 51 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__pn_noun_details_from_spec(parse_node *p, parse_node *spec) ;
#line 70 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__pn_make_COMMON_or_PROPER(parse_node *p, inference_subject *infs) ;
#line 82 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__copy_noun_details(parse_node *to, parse_node *from) ;
#line 104 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__pn_make_adjective(parse_node *p, adjective_usage *ale, parse_node *spec) ;
#line 118 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__coerce_adjectival_usage_to_noun(parse_node *leaf) ;
#line 138 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__refine(parse_node *p, int creation_rule) ;
#line 158 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__refine_parse_tree_inner(parse_node *p, int creation_rule) ;
#line 619 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__refine_from_simple_description(parse_node *p, parse_node *spec) ;
#line 745 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__perform_and_surgery(parse_node *p) ;
#line 792 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__perform_with_surgery(parse_node *p) ;
#line 825 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__perform_location_surgery(parse_node *p) ;
#line 864 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__perform_called_surgery(parse_node *p) ;
#line 38 "inform7/Chapter 15/The Creator.w"
int Assertions__Creator__consult_the_creator(parse_node *px, parse_node *py) ;
#line 150 "inform7/Chapter 15/The Creator.w"
int Assertions__Creator__actionlike(parse_node *p) ;
#line 160 "inform7/Chapter 15/The Creator.w"
void Assertions__Creator__to_action_node(parse_node *p) ;
#line 177 "inform7/Chapter 15/The Creator.w"
binary_predicate * Assertions__Creator__bp_of_subtree(parse_node *p) ;
#line 185 "inform7/Chapter 15/The Creator.w"
kind * Assertions__Creator__kind_of_subtree(parse_node *p, parse_node **governing) ;
#line 287 "inform7/Chapter 15/The Creator.w"
void Assertions__Creator__tabular_definitions(table *t) ;
#line 291 "inform7/Chapter 15/The Creator.w"
void Assertions__Creator__noun_creator(parse_node *p, kind *create_as, parse_node *governor) ;
#line 825 "inform7/Chapter 15/The Creator.w"
int Assertions__Creator__vet_name(wording W) ;
#line 852 "inform7/Chapter 15/The Creator.w"
void Assertions__Creator__convert_instance_to_nounphrase(parse_node *p, binary_predicate *hinge_relation) ;
#line 1094 "inform7/Chapter 15/The Creator.w"
int Assertions__Creator__vet_name_for_noun(wording W) ;
#line 66 "inform7/Chapter 15/Make Assertions.w"
int Assertions__Maker__which_assertion_case(parse_node *px, parse_node *py) ;
#line 92 "inform7/Chapter 15/Make Assertions.w"
void Assertions__Maker__make_assertion_recursive(parse_node *px, parse_node *py) ;
#line 98 "inform7/Chapter 15/Make Assertions.w"
void Assertions__Maker__make_assertion_recursive_inner(parse_node *px, parse_node *py) ;
#line 1755 "inform7/Chapter 15/Make Assertions.w"
int Assertions__Maker__convert_adjective_to_noun(parse_node *p) ;
#line 1768 "inform7/Chapter 15/Make Assertions.w"
void Assertions__Maker__issue_value_equation_problem(parse_node *px, parse_node *py) ;
#line 1823 "inform7/Chapter 15/Make Assertions.w"
void Assertions__Maker__instantiate_related_common_nouns(parse_node *p) ;
#line 1827 "inform7/Chapter 15/Make Assertions.w"
void Assertions__Maker__instantiate_related_common_nouns_r(parse_node *from, parse_node *at) ;
#line 1845 "inform7/Chapter 15/Make Assertions.w"
int Assertions__Maker__is_adjlist(parse_node *p) ;
#line 13 "inform7/Chapter 15/Property Knowledge.w"
void Assertions__PropertyKnowledge__initialise_global_variable(nonlocal_variable *q, parse_node *val) ;
#line 17 "inform7/Chapter 15/Property Knowledge.w"
void Assertions__PropertyKnowledge__verify_global_variable(nonlocal_variable *q) ;
#line 25 "inform7/Chapter 15/Property Knowledge.w"
void Assertions__PropertyKnowledge__igv_dash(nonlocal_variable *q, parse_node *val, int verification_stage) ;
#line 105 "inform7/Chapter 15/Property Knowledge.w"
void Assertions__PropertyKnowledge__assert_property_value_from_property_subtree_infs(property *prn, inference_subject *owner, parse_node *val_subtree) ;
#line 112 "inform7/Chapter 15/Property Knowledge.w"
void Assertions__PropertyKnowledge__assert_property_list(parse_node *owner_subtree, parse_node *list_subtree) ;
#line 191 "inform7/Chapter 15/Property Knowledge.w"
parse_node * Assertions__PropertyKnowledge__property_value_from_property_subtree(property *prn, parse_node *py) ;
#line 16 "inform7/Chapter 15/Relation Knowledge.w"
void Assertions__Relational__assert_subtree_in_relationship(parse_node *value, parse_node *relationship_subtree) ;
#line 120 "inform7/Chapter 15/Relation Knowledge.w"
void Assertions__Relational__substitute_at_node(parse_node *p) ;
#line 131 "inform7/Chapter 15/Relation Knowledge.w"
void Assertions__Relational__assert_relation_between_subtrees(parse_node *px, binary_predicate *bp, parse_node *py) ;
#line 75 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__initialise_assemblies_data(assemblies_data *ad) ;
#line 85 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__name_object_after(inference_subject *infs, inference_subject *after, wording W) ;
#line 94 "inform7/Chapter 15/Assemblies.w"
inference_subject * Assertions__Assemblies__what_this_is_named_after(inference_subject *infs) ;
#line 99 "inform7/Chapter 15/Assemblies.w"
wording Assertions__Assemblies__get_named_after_text(inference_subject *infs) ;
#line 118 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__make_generalisation(parse_node *look_for, parse_node *what_to_make) ;
#line 219 "inform7/Chapter 15/Assemblies.w"
int Assertions__Assemblies__subtree_mentions_kind(parse_node *subtree, inference_subject *k, int level) ;
#line 235 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__ensure_all_generalisations_made(inference_subject *k) ;
#line 249 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__satisfies_generalisations(inference_subject *infs) ;
#line 317 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__satisfies_generalisation(inference_subject *infs, generalisation *g) ;
#line 44 "inform7/Chapter 15/Implications.w"
void Assertions__Implications__new(parse_node *px, parse_node *py) ;
#line 139 "inform7/Chapter 15/Implications.w"
void Assertions__Implications__consider_all(inference_subject *infs) ;
#line 166 "inform7/Chapter 15/Implications.w"
void Assertions__Implications__set_possessed_flags(inference_subject *infs) ;
#line 214 "inform7/Chapter 15/Implications.w"
int Assertions__Implications__check_implications_of(inference_subject *domain, inference_subject *candidate) ;
#line 65 "inform7/Chapter 15/Property Declarations.w"
void Assertions__Property__declare_property_can_be(parse_node *p) ;
#line 110 "inform7/Chapter 15/Property Declarations.w"
int Assertions__Property__list_length(parse_node *P) ;
#line 474 "inform7/Chapter 15/Property Declarations.w"
property * Assertions__Property__recursively_declare_properties(parse_node *owner_ref, parse_node *p) ;
#line 545 "inform7/Chapter 15/Property Declarations.w"
void Assertions__Property__recursively_call_properties(parse_node *owner_ref, parse_node *kind_ref, parse_node *prn_ref) ;
#line 207 "inform7/Chapter 16/Architecture of the S-Parser.w"
parse_node * SParser__parse_with_cache(wording W, int context, nonterminal *nt) ;
#line 276 "inform7/Chapter 16/Architecture of the S-Parser.w"
void SParser__warn_expression_cache(void) ;
#line 292 "inform7/Chapter 16/Architecture of the S-Parser.w"
void SParser__parse_void_phrase(parse_node *p) ;
#line 295 "inform7/Chapter 16/Architecture of the S-Parser.w"
void SParser__parse_say_term(parse_node *p) ;
#line 298 "inform7/Chapter 16/Architecture of the S-Parser.w"
void SParser__parse_phrase_inner(parse_node *p, int as_say_term) ;
#line 83 "inform7/Chapter 16/Parse Excerpts.w"
parse_node * SParser__parse_excerpt_maximal(unsigned int mc_bitmap, wording W) ;
#line 91 "inform7/Chapter 16/Parse Excerpts.w"
parse_node * SParser__parse_excerpt(unsigned int mc_bitmap, wording W) ;
#line 490 "inform7/Chapter 16/Parse Excerpts.w"
parse_node * SParser__result(excerpt_meaning *em, int score, parse_node *alternatives) ;
#line 535 "inform7/Chapter 16/Parse Excerpts.w"
void SParser__debug_parser_statistics(void) ;
#line 325 "inform7/Chapter 16/Parse Literals.w"
int Literals__ismultiplicationsign(char c) ;
#line 343 "inform7/Chapter 16/Parse Literals.w"
int Literals__construct_float(int signbit, double intv, double fracv, int expo) ;
#line 418 "inform7/Chapter 16/Parse Literals.w"
double Literals__ten_to_the(int expo) ;
#line 287 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node * ParseTree__AdjectiveLists__join_adjlist(parse_node *A, parse_node *B) ;
#line 295 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node * ParseTree__AdjectiveLists__join_adjlist_w(parse_node *A, parse_node *B) ;
#line 303 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node * ParseTree__AdjectiveLists__make_adjlist(parse_node *A, wording W) ;
#line 308 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node * ParseTree__AdjectiveLists__negate_adjlist(parse_node *A) ;
#line 319 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node * ParseTree__AdjectiveLists__add_adjlist(parse_node *spec, parse_node *adjlist) ;
#line 328 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node * ParseTree__AdjectiveLists__add_adjlist_w(parse_node *spec, parse_node *adjlist) ;
#line 340 "inform7/Chapter 16/Constants and Descriptions.w"
int ParseTree__AdjectiveLists__adjlist_applies_to_kind(parse_node *A, kind *K) ;
#line 270 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node * SParser__val(parse_node *v, wording W) ;
#line 338 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node * SParser__p_o_val(parse_node *A, parse_node *B) ;
#line 549 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node * SParser__arg(parse_node *val) ;
#line 117 "inform7/Chapter 16/Verbal and Relative Clauses.w"
parse_node * SParser__Subtrees__verb_marker(verb_usage *vu, preposition_usage *pu, parse_node *np) ;
#line 187 "inform7/Chapter 16/Verbal and Relative Clauses.w"
void SParser__Subtrees__correct_for_adjectives(parse_node *A, parse_node *B) ;
#line 303 "inform7/Chapter 16/Verbal and Relative Clauses.w"
parse_node * SParser__Subtrees__to_specification(int SV_not_SN, wording W, parse_node *A, parse_node *B) ;
#line 307 "inform7/Chapter 16/Verbal and Relative Clauses.w"
parse_node * SParser__Subtrees__to_specification_inner(int SV_not_SN, wording W, parse_node *A, parse_node *B) ;
#line 455 "inform7/Chapter 16/Verbal and Relative Clauses.w"
void SParser__Subtrees__throw_past_problem(int desc) ;
#line 269 "inform7/Chapter 16/Conditions and Phrases.w"
parse_node * SParser__say_adjective(adjectival_phrase *aph, wording W) ;
#line 283 "inform7/Chapter 16/Conditions and Phrases.w"
parse_node * SParser__say_verb(verb_conjugation *vc, int neg, verb_conjugation *mvc, wording W) ;
#line 306 "inform7/Chapter 16/Conditions and Phrases.w"
void SParser__add_ilist(parse_node *spec, parse_node *p) ;
#line 73 "inform7/Chapter 17/Terms.w"
pcalc_term Calculus__Terms__new_variable(int v) ;
#line 80 "inform7/Chapter 17/Terms.w"
pcalc_term Calculus__Terms__new_constant(parse_node *c) ;
#line 86 "inform7/Chapter 17/Terms.w"
pcalc_term Calculus__Terms__new_function(binary_predicate *bp, pcalc_term ptof, int t) ;
#line 106 "inform7/Chapter 17/Terms.w"
pcalc_term Calculus__Terms__copy(pcalc_term pt) ;
#line 140 "inform7/Chapter 17/Terms.w"
parse_node * Calculus__Terms__constant_underlying(pcalc_term *t) ;
#line 147 "inform7/Chapter 17/Terms.w"
int Calculus__Terms__variable_underlying(pcalc_term *t) ;
#line 166 "inform7/Chapter 17/Terms.w"
pcalc_term Calculus__Terms__adj_to_noun_conversion(adjective_usage *tr) ;
#line 178 "inform7/Chapter 17/Terms.w"
adjective_usage * Calculus__Terms__noun_to_adj_conversion(pcalc_term pt) ;
#line 211 "inform7/Chapter 17/Terms.w"
void Calculus__Terms__compile(OUTPUT_STREAM, pcalc_term pt) ;
#line 245 "inform7/Chapter 17/Terms.w"
void Calculus__Terms__log(pcalc_term *pt) ;
#line 75 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__element_get_group(int element) ;
#line 89 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__element_get_match(int element) ;
#line 103 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__new(int element) ;
#line 135 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__QUANTIFIER_new(quantifier *quant, int v, int parameter) ;
#line 147 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_quantifier(pcalc_prop *prop) ;
#line 152 "inform7/Chapter 17/Atomic Propositions.w"
quantifier * Calculus__Atoms__get_quantifier(pcalc_prop *prop) ;
#line 158 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__get_quantification_parameter(pcalc_prop *prop) ;
#line 164 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_existence_quantifier(pcalc_prop *prop) ;
#line 171 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_nonexistence_quantifier(pcalc_prop *prop) ;
#line 178 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_forall_quantifier(pcalc_prop *prop) ;
#line 185 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_notall_quantifier(pcalc_prop *prop) ;
#line 192 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_for_all_x(pcalc_prop *prop) ;
#line 200 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_now_assertable_quantifier(pcalc_prop *prop) ;
#line 209 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__EVERYWHERE_new(pcalc_term pt) ;
#line 219 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__NOWHERE_new(pcalc_term pt) ;
#line 229 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__HERE_new(pcalc_term pt) ;
#line 239 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__ISAKIND_new(pcalc_term pt, kind *K) ;
#line 250 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__ISAVAR_new(pcalc_term pt) ;
#line 260 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__ISACONST_new(pcalc_term pt) ;
#line 282 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__CALLED_new(wording W, pcalc_term pt, kind *K) ;
#line 291 "inform7/Chapter 17/Atomic Propositions.w"
wording Calculus__Atoms__CALLED_get_name(pcalc_prop *prop) ;
#line 320 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__KIND_new(kind *K, pcalc_term pt) ;
#line 328 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__KIND_new_composited(kind *K, pcalc_term pt) ;
#line 337 "inform7/Chapter 17/Atomic Propositions.w"
kind * Calculus__Atoms__get_asserted_kind(pcalc_prop *prop) ;
#line 342 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_composited(pcalc_prop *prop) ;
#line 347 "inform7/Chapter 17/Atomic Propositions.w"
void Calculus__Atoms__set_composited(pcalc_prop *prop, int state) ;
#line 354 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_unarticled(pcalc_prop *prop) ;
#line 359 "inform7/Chapter 17/Atomic Propositions.w"
void Calculus__Atoms__set_unarticled(pcalc_prop *prop, int state) ;
#line 368 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__unary_PREDICATE_from_aph(adjectival_phrase *aph, int negated) ;
#line 377 "inform7/Chapter 17/Atomic Propositions.w"
adjective_usage * Calculus__Atoms__au_from_unary_PREDICATE(pcalc_prop *prop) ;
#line 384 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__binary_PREDICATE_new(binary_predicate *bp, pcalc_term pt1, pcalc_term pt2) ;
#line 393 "inform7/Chapter 17/Atomic Propositions.w"
binary_predicate * Calculus__Atoms__is_binary_predicate(pcalc_prop *prop) ;
#line 400 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_equality_predicate(pcalc_prop *prop) ;
#line 409 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop * Calculus__Atoms__prop_x_is_constant(parse_node *spec) ;
#line 417 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_term * Calculus__Atoms__is_x_equals(pcalc_prop *prop) ;
#line 426 "inform7/Chapter 17/Atomic Propositions.w"
char * Calculus__Atoms__validate(pcalc_prop *prop) ;
#line 451 "inform7/Chapter 17/Atomic Propositions.w"
void Calculus__Atoms__log(pcalc_prop *prop) ;
#line 141 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__implied_conjunction_between(pcalc_prop *p1, pcalc_prop *p2) ;
#line 154 "inform7/Chapter 17/Propositions.w"
char * Calculus__Propositions__debugging_log_text_between(pcalc_prop *p1, pcalc_prop *p2) ;
#line 172 "inform7/Chapter 17/Propositions.w"
void Calculus__Propositions__log(pcalc_prop *prop) ;
#line 234 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__is_syntactically_valid(pcalc_prop *prop) ;
#line 277 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__is_complex(pcalc_prop *prop) ;
#line 299 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__copy(pcalc_prop *original) ;
#line 320 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__concatenate(pcalc_prop *existing_body, pcalc_prop *tail) ;
#line 335 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__conjoin(pcalc_prop *existing_body, pcalc_prop *tail) ;
#line 346 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__insert_atom(pcalc_prop *prop, pcalc_prop *position, pcalc_prop *new_atom) ;
#line 362 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__delete_atom(pcalc_prop *prop, pcalc_prop *position) ;
#line 380 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__length(pcalc_prop *prop) ;
#line 408 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__match(pcalc_prop *prop, int c, ...) ;
#line 434 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__prop_seek_atom(pcalc_prop *prop, int atom_req, int arity_req) ;
#line 446 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__contains_binary_predicate(pcalc_prop *prop) ;
#line 450 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__contains_quantifier(pcalc_prop *prop) ;
#line 454 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__composited_kind(pcalc_prop *prop) ;
#line 460 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__contains_nonexistence_quantifier(pcalc_prop *prop) ;
#line 469 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__contains_callings(pcalc_prop *prop) ;
#line 477 "inform7/Chapter 17/Propositions.w"
kind * Calculus__Propositions__describes_kind(pcalc_prop *prop) ;
#line 497 "inform7/Chapter 17/Propositions.w"
parse_node * Calculus__Propositions__describes_value(pcalc_prop *prop) ;
#line 522 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__contains_adjective(pcalc_prop *prop) ;
#line 527 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__count_unary_predicates(pcalc_prop *prop) ;
#line 541 "inform7/Chapter 17/Propositions.w"
pcalc_term Calculus__Propositions__get_first_cited_term(pcalc_prop *prop) ;
#line 557 "inform7/Chapter 17/Propositions.w"
pcalc_term Calculus__Propositions__convert_adj_to_noun(pcalc_prop *prop) ;
#line 579 "inform7/Chapter 17/Propositions.w"
adjective_usage * Calculus__Propositions__first_adjective_usage(pcalc_prop *prop, pcalc_prop **ppp) ;
#line 586 "inform7/Chapter 17/Propositions.w"
adjective_usage * Calculus__Propositions__next_adjective_usage(pcalc_prop **ppp) ;
#line 604 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__is_a_group(pcalc_prop *prop, int governing) ;
#line 620 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__remove_topmost_group(pcalc_prop *prop) ;
#line 635 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__unnegate(pcalc_prop *prop) ;
#line 645 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__ungroup_after(pcalc_prop *prop, pcalc_prop *position, pcalc_prop **last) ;
#line 680 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__trim_universal_quantifier(pcalc_prop *prop) ;
#line 693 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__remove_final_close_domain(pcalc_prop *prop, int *move_domain) ;
#line 708 "inform7/Chapter 17/Propositions.w"
pcalc_prop * Calculus__Propositions__from_spec(parse_node *spec) ;
#line 78 "inform7/Chapter 17/Binding and Substitution.w"
void Calculus__Variables__determine_status(pcalc_prop *prop, int *var_states, int *valid) ;
#line 115 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__is_well_formed(pcalc_prop *prop) ;
#line 126 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__status(pcalc_prop *prop, int v) ;
#line 136 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__number_free(pcalc_prop *prop) ;
#line 149 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__find_unused(pcalc_prop *prop) ;
#line 167 "inform7/Chapter 17/Binding and Substitution.w"
void Calculus__Variables__vars_map(pcalc_prop *prop, int *renumber_map, pcalc_term *preserving) ;
#line 178 "inform7/Chapter 17/Binding and Substitution.w"
void Calculus__Variables__term_map(pcalc_term *pt, int *renumber_map) ;
#line 193 "inform7/Chapter 17/Binding and Substitution.w"
void Calculus__Variables__renumber(pcalc_prop *prop, pcalc_term *preserving) ;
#line 231 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__renumber_bound(pcalc_prop *prop, pcalc_prop *not_to_overlap, int query) ;
#line 274 "inform7/Chapter 17/Binding and Substitution.w"
pcalc_prop * Calculus__Variables__bind_existential(pcalc_prop *prop, pcalc_term *preserving) ;
#line 295 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__substitute_v_in_term(pcalc_term *pt, int v, pcalc_term *t) ;
#line 301 "inform7/Chapter 17/Binding and Substitution.w"
void Calculus__Variables__substitute_nothing_in_term(pcalc_term *pt, pcalc_term *t) ;
#line 306 "inform7/Chapter 17/Binding and Substitution.w"
void Calculus__Variables__substitute_term_in_term(pcalc_term *pt, pcalc_term *t) ;
#line 331 "inform7/Chapter 17/Binding and Substitution.w"
pcalc_prop * Calculus__Variables__substitute_term(pcalc_prop *prop, int v, pcalc_term t, int verify_only, int *allowed, int *changed) ;
#line 400 "inform7/Chapter 17/Binding and Substitution.w"
kind * Calculus__Variables__kind_of_variable_0(pcalc_prop *prop) ;
#line 413 "inform7/Chapter 17/Binding and Substitution.w"
pcalc_prop * Calculus__Variables__substitute_var_0_in(pcalc_prop *prop, parse_node *spec) ;
#line 421 "inform7/Chapter 17/Binding and Substitution.w"
kind * Calculus__Variables__infer_kind_of_variable_0(pcalc_prop *prop) ;
#line 449 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__detect_locals(pcalc_prop *prop, parse_node **example) ;
#line 461 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__detect_local_in_term(pcalc_term *pt, int locals_count, parse_node **example) ;
#line 469 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__detect_local_in_spec(parse_node *spec, int locals_count, parse_node **example) ;
#line 18 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_make_a_kind(kind *K) ;
#line 22 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_make_a_var(void) ;
#line 26 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_make_a_const(void) ;
#line 30 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_create_something(kind *K, wording W) ;
#line 44 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__prop_to_set_kind(instance *I, kind *k) ;
#line 48 "inform7/Chapter 17/Tree Conversions.w"
void Calculus__Propositions__Abstract__assert_kind_of_object(instance *I, kind *k) ;
#line 53 "inform7/Chapter 17/Tree Conversions.w"
void Calculus__Propositions__Abstract__assert_kind_of_subject(inference_subject *inst, inference_subject *new, pcalc_prop *subject_to) ;
#line 64 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_set_simple_relation(binary_predicate *bp, instance *I) ;
#line 72 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_set_relation(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 88 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_provide_property(property *prn) ;
#line 93 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_set_property(property *prn, parse_node *val) ;
#line 103 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_put_everywhere(void) ;
#line 107 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_put_nowhere(void) ;
#line 111 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__to_put_here(void) ;
#line 120 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__from_property_subtree(property *prn, parse_node *py) ;
#line 130 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop * Calculus__Propositions__Abstract__from_property_list(parse_node *p, kind *K) ;
#line 33 "inform7/Chapter 17/Sentence Conversions.w"
pcalc_prop * Calculus__Propositions__FromSentences__S_subtree(int SV_not_SN, wording W, parse_node *A, parse_node *B, pcalc_term *subject_of_sentence, int verb_phrase_negated) ;
#line 433 "inform7/Chapter 17/Sentence Conversions.w"
pcalc_prop * Calculus__Propositions__FromSentences__simplify(pcalc_prop *sentence_prop) ;
#line 472 "inform7/Chapter 17/Sentence Conversions.w"
pcalc_prop * Calculus__Propositions__FromSentences__NP_subtree_to_proposition(pcalc_term *subject_of_NP, parse_node *p, kind *K) ;
#line 48 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__nothing_constant(pcalc_prop *prop, int *changed) ;
#line 163 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__use_listed_in(pcalc_prop *prop, int *changed) ;
#line 216 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__negated_determiners_nonex(pcalc_prop *prop, int *changed) ;
#line 220 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__negated_determiners(pcalc_prop *prop, int *changed, int negate_existence_too) ;
#line 261 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__prop_ungroup_and_negate_determiner(pcalc_prop *prop, pcalc_prop *after, int add_domain_brackets) ;
#line 303 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__negated_satisfiable(pcalc_prop *prop, int *changed) ;
#line 353 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__make_kinds_of_value_explicit(pcalc_prop *prop, int *changed) ;
#line 383 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__redundant_kinds(pcalc_prop *prop, int *changed) ;
#line 403 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__simp_redundant_kinds_dash(pcalc_prop *prop, pcalc_prop *start_group, int start_level, int *changed) ;
#line 674 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__turn_right_way_round(pcalc_prop *prop, int *changed) ;
#line 714 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__region_containment(pcalc_prop *prop, int *changed) ;
#line 772 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__reduce_predicates(pcalc_prop *prop, int *changed) ;
#line 804 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__eliminate_redundant_variables(pcalc_prop *prop, int *changed) ;
#line 936 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__not_related_to_something(pcalc_prop *prop, int *changed) ;
#line 983 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__convert_gerunds(pcalc_prop *prop, int *changed) ;
#line 1020 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__eliminate_to_have(pcalc_prop *prop, int *changed) ;
#line 1065 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__prop_substitute_prop_cons(pcalc_prop *prop, property *prn, parse_node *po_spec, int *count, pcalc_prop *not_this) ;
#line 1112 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__is_all_rooms(pcalc_prop *prop, int *changed) ;
#line 1179 "inform7/Chapter 17/Simplifications.w"
pcalc_prop * Calculus__Simplifications__everywhere_and_nowhere(pcalc_prop *prop, int *changed) ;
#line 49 "inform7/Chapter 17/Type Check Propositions.w"
tc_problem_kit Calculus__Propositions__Checker__tc_no_problem_reporting(void) ;
#line 55 "inform7/Chapter 17/Type Check Propositions.w"
tc_problem_kit Calculus__Propositions__Checker__tc_problem_reporting(wording W, char *intent) ;
#line 65 "inform7/Chapter 17/Type Check Propositions.w"
tc_problem_kit Calculus__Propositions__Checker__tc_problem_logging(void) ;
#line 80 "inform7/Chapter 17/Type Check Propositions.w"
int Calculus__Propositions__Checker__type_check(pcalc_prop *prop, tc_problem_kit tck_s) ;
#line 395 "inform7/Chapter 17/Type Check Propositions.w"
kind * Calculus__Propositions__Checker__kind_of_term(pcalc_term *pt, variable_type_assignment *vta, tc_problem_kit *tck) ;
#line 410 "inform7/Chapter 17/Type Check Propositions.w"
kind * Calculus__Propositions__Checker__kind_of_term_inner(pcalc_term *pt, variable_type_assignment *vta, tc_problem_kit *tck) ;
#line 441 "inform7/Chapter 17/Type Check Propositions.w"
kind * Calculus__Propositions__Checker__approximate_argument_kind(binary_predicate *bp, int i) ;
#line 453 "inform7/Chapter 17/Type Check Propositions.w"
int Calculus__Propositions__Checker__type_check_unary_predicate(pcalc_prop *pl, variable_type_assignment *vta, tc_problem_kit *tck) ;
#line 482 "inform7/Chapter 17/Type Check Propositions.w"
int Calculus__Propositions__Checker__type_check_binary_predicate(pcalc_prop *pl, variable_type_assignment *vta, tc_problem_kit *tck) ;
#line 601 "inform7/Chapter 17/Type Check Propositions.w"
void Calculus__Propositions__Checker__issue_bp_typecheck_error(binary_predicate *bp, kind *t0, kind *t1, tc_problem_kit *tck) ;
#line 611 "inform7/Chapter 17/Type Check Propositions.w"
void Calculus__Propositions__Checker__issue_kind_typecheck_error(kind *actually_find, kind *need_to_find, tc_problem_kit *tck, pcalc_prop *ka) ;
#line 20 "inform7/Chapter 18/The Equality Relation.w"
void Calculus__Equality__REL_create_initial_stock(void) ;
#line 33 "inform7/Chapter 18/The Equality Relation.w"
void Calculus__Equality__REL_create_second_stock(void) ;
#line 41 "inform7/Chapter 18/The Equality Relation.w"
int Calculus__Equality__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 115 "inform7/Chapter 18/The Equality Relation.w"
int Calculus__Equality__both_terms_of_same_construction(kind *k0, kind *k1, kind_constructor *cons) ;
#line 126 "inform7/Chapter 18/The Equality Relation.w"
int Calculus__Equality__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 180 "inform7/Chapter 18/The Equality Relation.w"
int Calculus__Equality__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 348 "inform7/Chapter 18/The Equality Relation.w"
int Calculus__Equality__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 32 "inform7/Chapter 18/Quasinumeric Relations.w"
void Calculus__QuasinumericRelations__REL_create_initial_stock(void) ;
#line 68 "inform7/Chapter 18/Quasinumeric Relations.w"
void Calculus__QuasinumericRelations__REL_create_second_stock(void) ;
#line 74 "inform7/Chapter 18/Quasinumeric Relations.w"
int Calculus__QuasinumericRelations__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 94 "inform7/Chapter 18/Quasinumeric Relations.w"
int Calculus__QuasinumericRelations__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 106 "inform7/Chapter 18/Quasinumeric Relations.w"
int Calculus__QuasinumericRelations__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 166 "inform7/Chapter 18/Quasinumeric Relations.w"
int Calculus__QuasinumericRelations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 88 "inform7/Chapter 18/Assert Propositions.w"
void Calculus__Propositions__Assert__assert_true(pcalc_prop *prop, int certitude) ;
#line 92 "inform7/Chapter 18/Assert Propositions.w"
void Calculus__Propositions__Assert__assert_true_about(pcalc_prop *prop, inference_subject *infs, int certitude) ;
#line 117 "inform7/Chapter 18/Assert Propositions.w"
void Calculus__Propositions__Assert__prop_true_in_world_model_inner(pcalc_prop *prop, inference_subject *subject, int certainty) ;
#line 166 "inform7/Chapter 18/Assert Propositions.w"
void Calculus__Propositions__Assert__prop_true_in_model(pcalc_prop *prop) ;
#line 598 "inform7/Chapter 18/Assert Propositions.w"
void Calculus__Propositions__Assert__cautiously_set_kind(inference_subject *inst, kind *k) ;
#line 620 "inform7/Chapter 18/Assert Propositions.w"
parse_node * Calculus__Propositions__Assert__spec_of_term(pcalc_term pt) ;
#line 640 "inform7/Chapter 18/Assert Propositions.w"
inference_subject * Calculus__Propositions__Assert__subject_of_term(pcalc_term pt) ;
#line 671 "inform7/Chapter 18/Assert Propositions.w"
int Calculus__Propositions__Assert__testable_at_compile_time(pcalc_prop *prop) ;
#line 699 "inform7/Chapter 18/Assert Propositions.w"
int Calculus__Propositions__Assert__test_at_compile_time(pcalc_prop *prop, inference_subject *about) ;
#line 75 "inform7/Chapter 18/I6 Schemas.w"
i6_schema * Calculus__Schemas__new(char *fmt, ...) ;
#line 90 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__modify(i6_schema *sch, char *fmt, ...) ;
#line 103 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__append(i6_schema *sch, char *fmt, ...) ;
#line 155 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__overrun(char *temp) ;
#line 168 "inform7/Chapter 18/I6 Schemas.w"
int Calculus__Schemas__empty(i6_schema *sch) ;
#line 179 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__expand(i6_schema *sch, OUTPUT_STREAM, pcalc_term *pt1, pcalc_term *pt2) ;
#line 193 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__expand_textual(i6_schema *sch, OUTPUT_STREAM, char *str1, char *str2) ;
#line 207 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__sch_expand_inner(i6_schema *sch, OUTPUT_STREAM, pcalc_term *pt1, char *str1, pcalc_term *pt2, char *str2) ;
#line 321 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__sch_expand_parameter(OUTPUT_STREAM, pcalc_term *pt, char *str, int give_kind_id, int give_comparison_routine, int dereference_property, kind *cast_to, int by_reference) ;
#line 363 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__sch_type_parameter(pcalc_term *pt) ;
#line 371 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__log(i6_schema *sch) ;
#line 376 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__log_applied(i6_schema *sch, pcalc_term *pt1) ;
#line 56 "inform7/Chapter 18/Compile Atoms.w"
void Calculus__Atoms__Compile__compile(OUTPUT_STREAM, int task, pcalc_prop *pl, int with_semicolon) ;
#line 140 "inform7/Chapter 18/Compile Atoms.w"
annotated_i6_schema Calculus__Atoms__Compile__i6_schema_of_atom(i6_schema *sch, pcalc_prop *pl, int task) ;
#line 337 "inform7/Chapter 18/Compile Atoms.w"
int Calculus__Atoms__Compile__atom_involves_action_variables(pcalc_prop *pl) ;
#line 349 "inform7/Chapter 18/Compile Atoms.w"
annotated_i6_schema Calculus__Atoms__Compile__blank_asch(void) ;
#line 51 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__allow_no_further_deferrals(void) ;
#line 59 "inform7/Chapter 18/Deciding to Defer.w"
pcalc_prop_deferral * Calculus__Deferrals__new_deferred_proposition(pcalc_prop *prop, int reason) ;
#line 77 "inform7/Chapter 18/Deciding to Defer.w"
pcalc_prop_deferral * Calculus__Deferrals__defer_loop_domain(pcalc_prop *prop) ;
#line 91 "inform7/Chapter 18/Deciding to Defer.w"
int Calculus__Deferrals__compile_deferred_description_test(parse_node *spec) ;
#line 115 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_test_of_proposition(OUTPUT_STREAM, parse_node *substitution, pcalc_prop *prop) ;
#line 229 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__retrieve_callings(OUTPUT_STREAM, pcalc_prop *prop, int condition_context) ;
#line 255 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__prepare_to_retrieve_callings(OUTPUT_STREAM, pcalc_prop *prop, int condition_context) ;
#line 272 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_test_if_var_matches_description(OUTPUT_STREAM, parse_node *var, parse_node *matches) ;
#line 317 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_now_proposition(OUTPUT_STREAM, pcalc_prop *prop, int with_semicolon) ;
#line 417 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_multiple_use_proposition(OUTPUT_STREAM, parse_node *spec, kind *K) ;
#line 487 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_number_of_S(OUTPUT_STREAM, parse_node *spec) ;
#line 502 "inform7/Chapter 18/Deciding to Defer.w"
int Calculus__Deferrals__spec_is_variable_of_kind_description(parse_node *spec) ;
#line 509 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_call_to_deferred_desc(OUTPUT_STREAM, pcalc_prop *prop, int reason, general_pointer data, kind *K) ;
#line 531 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_list_of_S(OUTPUT_STREAM, parse_node *spec, kind *K) ;
#line 550 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_random_of_S(OUTPUT_STREAM, parse_node *spec) ;
#line 587 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_total_of_S(OUTPUT_STREAM, property *prn, parse_node *spec) ;
#line 606 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_substitution_test(OUTPUT_STREAM, parse_node *in, parse_node *spec) ;
#line 623 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_substitution_now(OUTPUT_STREAM, parse_node *in, parse_node *spec) ;
#line 643 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_extremal_of_S(OUTPUT_STREAM, parse_node *spec, property *prn, int sign) ;
#line 692 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_repeat_through_domain_S(OUTPUT_STREAM, parse_node *spec, local_variable *v1) ;
#line 772 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_repeat_call(OUTPUT_STREAM, parse_node *spec, local_variable *fromv) ;
#line 785 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_repeat_domain(OUTPUT_STREAM, pcalc_prop *prop, local_variable *fromv) ;
#line 797 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_loop_over_list_S(OUTPUT_STREAM, parse_node *spec, local_variable *v1) ;
#line 853 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__prop_verify_descriptive(pcalc_prop *prop, char *billing, parse_node *constructor) ;
#line 63 "inform7/Chapter 18/Cinders and Deferrals.w"
int Calculus__Deferrals__Cinders__find(OUTPUT_STREAM, pcalc_prop *prop, pcalc_prop_deferral *pdef) ;
#line 77 "inform7/Chapter 18/Cinders and Deferrals.w"
int Calculus__Deferrals__Cinders__cind_find_in_term(OUTPUT_STREAM, pcalc_term *pt, int cinder_number, int *started) ;
#line 115 "inform7/Chapter 18/Cinders and Deferrals.w"
int Calculus__Deferrals__Cinders__spec_needs_to_be_cindered(parse_node *spec) ;
#line 131 "inform7/Chapter 18/Cinders and Deferrals.w"
void Calculus__Deferrals__Cinders__declare(pcalc_prop *prop, pcalc_prop_deferral *pdef) ;
#line 145 "inform7/Chapter 18/Cinders and Deferrals.w"
int Calculus__Deferrals__Cinders__cind_declare_in(int cinder_number, pcalc_term *pt) ;
#line 163 "inform7/Chapter 18/Cinders and Deferrals.w"
kind * Calculus__Deferrals__Cinders__kind_of_value_of_term(pcalc_term pt) ;
#line 182 "inform7/Chapter 18/Cinders and Deferrals.w"
void Calculus__Deferrals__Cinders__compile(OUTPUT_STREAM, int c) ;
#line 16 "inform7/Chapter 18/Compile Deferred Propositions.w"
void Calculus__Propositions__Deferred__compile_comment_about_deferral_reason(OUTPUT_STREAM, int reason) ;
#line 48 "inform7/Chapter 18/Compile Deferred Propositions.w"
void Calculus__Propositions__Deferred__compile_remaining_deferred(OUTPUT_STREAM) ;
#line 53 "inform7/Chapter 18/Compile Deferred Propositions.w"
int Calculus__Propositions__Deferred__compilation_coroutine(OUTPUT_STREAM) ;
#line 1215 "inform7/Chapter 18/Compile Deferred Propositions.w"
pcalc_prop * Calculus__Propositions__Deferred__compile_loop_header(OUTPUT_STREAM, int var, pcalc_prop *proposition, int avoid_parent_optimisation, int grouped, pcalc_prop_deferral *pdef) ;
#line 283 "inform7/Chapter 19/Kinds.w"
kind * Kinds__base_construction(kind_constructor *con) ;
#line 313 "inform7/Chapter 19/Kinds.w"
kind * Kinds__intermediate_construction(unit_sequence *ik) ;
#line 331 "inform7/Chapter 19/Kinds.w"
kind * Kinds__variable_construction(int N, kind *declaration) ;
#line 352 "inform7/Chapter 19/Kinds.w"
kind * Kinds__unary_construction(kind_constructor *con, kind *X) ;
#line 361 "inform7/Chapter 19/Kinds.w"
kind * Kinds__binary_construction(kind_constructor *con, kind *X, kind *Y) ;
#line 409 "inform7/Chapter 19/Kinds.w"
kind * Kinds__function_kind(int no_args, kind **args, kind *return_K) ;
#line 422 "inform7/Chapter 19/Kinds.w"
kind * Kinds__pair_kind(kind *X, kind *Y) ;
#line 443 "inform7/Chapter 19/Kinds.w"
kind * Kinds__first_base_k(void) ;
#line 451 "inform7/Chapter 19/Kinds.w"
kind * Kinds__next_base_k(kind *K) ;
#line 465 "inform7/Chapter 19/Kinds.w"
kind_constructor * Kinds__get_construct(kind *K) ;
#line 473 "inform7/Chapter 19/Kinds.w"
int Kinds__is_intermediate(kind *K) ;
#line 478 "inform7/Chapter 19/Kinds.w"
int Kinds__get_variable_number(kind *K) ;
#line 483 "inform7/Chapter 19/Kinds.w"
kind * Kinds__get_variable_stipulation(kind *K) ;
#line 491 "inform7/Chapter 19/Kinds.w"
int Kinds__is_proper_constructor(kind *K) ;
#line 496 "inform7/Chapter 19/Kinds.w"
int Kinds__arity_of_constructor(kind *K) ;
#line 504 "inform7/Chapter 19/Kinds.w"
kind * Kinds__unary_construction_material(kind *K) ;
#line 512 "inform7/Chapter 19/Kinds.w"
void Kinds__binary_construction_material(kind *K, kind **X, kind **Y) ;
#line 526 "inform7/Chapter 19/Kinds.w"
int Kinds__contains(kind *K, kind_constructor *con) ;
#line 549 "inform7/Chapter 19/Kinds.w"
kind * Kinds__substitute(kind *K, kind **meanings, int *changed) ;
#line 585 "inform7/Chapter 19/Kinds.w"
kind * Kinds__weaken(kind *K) ;
#line 607 "inform7/Chapter 19/Kinds.w"
kind * Kinds__dereference_properties(kind *K) ;
#line 650 "inform7/Chapter 19/Kinds.w"
kind * Kinds__new_base(wording W, kind *super) ;
#line 724 "inform7/Chapter 19/Kinds.w"
kind_constructor ** Kinds__known_constructor_name(char *sn) ;
#line 743 "inform7/Chapter 19/Kinds.w"
kind ** Kinds__known_kind_name(char *sn) ;
#line 769 "inform7/Chapter 19/Kinds.w"
int Kinds__known_name(char *sn) ;
#line 112 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__le(kind *from, kind *to) ;
#line 117 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__lt(kind *from, kind *to) ;
#line 141 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__eq(kind *K1, kind *K2) ;
#line 164 "inform7/Chapter 19/Kind Checking.w"
kind * Kinds__Compare__super(kind *K) ;
#line 178 "inform7/Chapter 19/Kind Checking.w"
kind * Kinds__Compare__max(kind *K1, kind *K2) ;
#line 190 "inform7/Chapter 19/Kind Checking.w"
kind * Kinds__Compare__traverse_kind_poset(kind *K1, kind *K2, int direction) ;
#line 227 "inform7/Chapter 19/Kind Checking.w"
kind * Kinds__Compare__accumulative_max(kind *K1, kind *K2) ;
#line 255 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__compatible(kind *from, kind *to) ;
#line 274 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__test_kind_relation(kind *from, kind *to, int comp) ;
#line 447 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__compatible_with_description(parse_node *from_spec, parse_node *to_spec) ;
#line 471 "inform7/Chapter 19/Kind Checking.w"
void Kinds__Compare__show_variables(void) ;
#line 482 "inform7/Chapter 19/Kind Checking.w"
void Kinds__Compare__show_frame_variables(void) ;
#line 498 "inform7/Chapter 19/Kind Checking.w"
void Kinds__Compare__make_subkind(kind *sub, kind *super) ;
#line 549 "inform7/Chapter 19/Kind Checking.w"
void Kinds__Compare__log_poset(int n) ;
#line 155 "inform7/Chapter 19/Kind Constructors.w"
kind_constructor * Kinds__Constructors__new(kind_constructor *super, char *source_name, char *initialisation_macro) ;
#line 305 "inform7/Chapter 19/Kind Constructors.w"
void Kinds__Constructors__attach_nametag(kind_constructor *con, nametag *nt) ;
#line 310 "inform7/Chapter 19/Kind Constructors.w"
wording Kinds__Constructors__get_name(kind_constructor *con, int plural_form) ;
#line 318 "inform7/Chapter 19/Kind Constructors.w"
wording Kinds__Constructors__get_name_in_play(kind_constructor *con, int plural_form) ;
#line 326 "inform7/Chapter 19/Kind Constructors.w"
nametag * Kinds__Constructors__get_nametag(kind_constructor *con) ;
#line 338 "inform7/Chapter 19/Kind Constructors.w"
void Kinds__Constructors__compile_I6_constants(OUTPUT_STREAM) ;
#line 349 "inform7/Chapter 19/Kind Constructors.w"
char * Kinds__Constructors__name_in_template_code(kind_constructor *con) ;
#line 357 "inform7/Chapter 19/Kind Constructors.w"
kind_constructor * Kinds__Constructors__parse(char *sn) ;
#line 371 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__convert_to_unit(kind_constructor *con) ;
#line 381 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__convert_to_enumeration(kind_constructor *con) ;
#line 397 "inform7/Chapter 19/Kind Constructors.w"
void Kinds__Constructors__convert_to_real(kind_constructor *con) ;
#line 406 "inform7/Chapter 19/Kind Constructors.w"
void Kinds__Constructors__mark_as_linguistic(kind_constructor *con) ;
#line 413 "inform7/Chapter 19/Kind Constructors.w"
kind ** Kinds__Constructors__cache_location(kind_constructor *con) ;
#line 418 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__arity(kind_constructor *con) ;
#line 424 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__tupling(kind_constructor *con, int b) ;
#line 428 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__variance(kind_constructor *con, int b) ;
#line 437 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__is_definite(kind_constructor *con) ;
#line 444 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__get_weak_ID(kind_constructor *con) ;
#line 449 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__is_arithmetic(kind_constructor *con) ;
#line 457 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__is_arithmetic_and_real(kind_constructor *con) ;
#line 465 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__is_enumeration(kind_constructor *con) ;
#line 478 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__find_cast(kind_constructor *from, kind_constructor *to) ;
#line 498 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__find_instance(kind_constructor *from, kind_constructor *to) ;
#line 515 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__compatible(kind_constructor *from, kind_constructor *to, int allow_casts) ;
#line 526 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__uses_pointer_values(kind_constructor *con) ;
#line 533 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__allow_word_as_pointer(kind_constructor *left, kind_constructor *right) ;
#line 247 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__start(void) ;
#line 265 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__despatch_kind_command(char *command) ;
#line 322 "inform7/Chapter 19/Kind Interpreter.w"
single_kind_command Kinds__Interpreter__parse_kind_command(char *command) ;
#line 500 "inform7/Chapter 19/Kind Interpreter.w"
kind_template_definition * Kinds__Interpreter__new_kind_template(char *name) ;
#line 506 "inform7/Chapter 19/Kind Interpreter.w"
kind_template_definition * Kinds__Interpreter__parse_kind_template_name(char *name) ;
#line 520 "inform7/Chapter 19/Kind Interpreter.w"
int Kinds__Interpreter__recording_a_kind_template(void) ;
#line 525 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__begin_kind_template(char *name) ;
#line 533 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__record_into_kind_template(char *line) ;
#line 537 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__end_kind_template(void) ;
#line 549 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__remember_to_transcribe_spec_template(kind_template_definition *ttd, kind_constructor *C) ;
#line 558 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__include_templates_for_kinds(void) ;
#line 564 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__transcribe_kind_template(kind_template_definition *ttd, kind_constructor *con) ;
#line 660 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__transcribe_constructor_name(char *buffer, kind_constructor *con, int lower_case) ;
#line 689 "inform7/Chapter 19/Kind Interpreter.w"
kind_macro_definition * Kinds__Interpreter__new_kind_macro(char *name) ;
#line 696 "inform7/Chapter 19/Kind Interpreter.w"
kind_macro_definition * Kinds__Interpreter__parse_kind_macro_name(char *name) ;
#line 706 "inform7/Chapter 19/Kind Interpreter.w"
int Kinds__Interpreter__recording_a_kind_macro(void) ;
#line 711 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__begin_kind_macro(char *name) ;
#line 717 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__record_into_kind_macro(single_kind_command stc) ;
#line 725 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__end_kind_macro(void) ;
#line 734 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__play_back_kind_macro(kind_macro_definition *macro, kind_constructor *con) ;
#line 753 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__initialise_kind_text_archiver(void) ;
#line 757 "inform7/Chapter 19/Kind Interpreter.w"
char * Kinds__Interpreter__archive_kind_text(char *original) ;
#line 768 "inform7/Chapter 19/Kind Interpreter.w"
char * Kinds__Interpreter__begin_recording_kind_text(void) ;
#line 774 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__record_kind_text(char *line) ;
#line 779 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__end_recording_kind_text(void) ;
#line 787 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__kind_command_error(char *command, char *error) ;
#line 835 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__apply_kind_command(single_kind_command stc, kind_constructor *con) ;
#line 1020 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__batch_done(void) ;
#line 11 "inform7/Chapter 19/Using Kinds.w"
wording Kinds__Behaviour__get_name(kind *K, int plural_form) ;
#line 16 "inform7/Chapter 19/Using Kinds.w"
wording Kinds__Behaviour__get_name_in_play(kind *K, int plural_form) ;
#line 21 "inform7/Chapter 19/Using Kinds.w"
nametag * Kinds__Behaviour__get_nametag(kind *K) ;
#line 31 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__is_kind_of_kind(kind *K) ;
#line 42 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__definite(kind *K) ;
#line 52 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__semidefinite(kind *K) ;
#line 63 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__involves_var(kind *K, int v) ;
#line 84 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__is_built_in(kind *K) ;
#line 90 "inform7/Chapter 19/Using Kinds.w"
parse_node * Kinds__Behaviour__get_creating_sentence(kind *K) ;
#line 103 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__is_uncertainly_defined(kind *K) ;
#line 111 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__is_an_enumeration(kind *K) ;
#line 121 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__convert_to_unit(kind *K) ;
#line 129 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__convert_to_enumeration(kind *K) ;
#line 136 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__convert_to_real(kind *K) ;
#line 145 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__new_enumerated_value(kind *K) ;
#line 154 "inform7/Chapter 19/Using Kinds.w"
kind * Kinds__Behaviour__stored_as(kind *K) ;
#line 165 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__set_superkind_set_at(kind *K, parse_node *S) ;
#line 170 "inform7/Chapter 19/Using Kinds.w"
parse_node * Kinds__Behaviour__get_superkind_set_at(kind *K) ;
#line 181 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__has_named_constant_values(kind *K) ;
#line 187 "inform7/Chapter 19/Using Kinds.w"
table * Kinds__Behaviour__defined_by_table(kind *K) ;
#line 192 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__set_defined_by_table(kind *K, table *t) ;
#line 203 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__get_constant_compilation_method(kind *K) ;
#line 214 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__add_literal_pattern(kind *K, literal_pattern *lp) ;
#line 225 "inform7/Chapter 19/Using Kinds.w"
literal_pattern * Kinds__Behaviour__list_of_literal_forms(kind *K) ;
#line 233 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__get_highest_valid_value_as_integer(kind *K) ;
#line 252 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__has_properties(kind *K) ;
#line 273 "inform7/Chapter 19/Using Kinds.w"
inference_subject * Kinds__Behaviour__as_subject(kind *K) ;
#line 278 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__set_subject(kind *K, inference_subject *infs) ;
#line 287 "inform7/Chapter 19/Using Kinds.w"
wording Kinds__Behaviour__get_name_text(inference_subject *from) ;
#line 291 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__complete_model(inference_subject *infs) ;
#line 292 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__check_model(inference_subject *infs) ;
#line 294 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__write_element_of_condition(inference_subject *infs, char *cond) ;
#line 306 "inform7/Chapter 19/Using Kinds.w"
general_pointer Kinds__Behaviour__new_permission_granted(inference_subject *from) ;
#line 316 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__make_adj_const_domain(inference_subject *infs, instance *nc, property *prn) ;
#line 326 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__compile(OUTPUT_STREAM, inference_subject *infs) ;
#line 331 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__compile_all(OUTPUT_STREAM) ;
#line 346 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__compile_default_value(OUTPUT_STREAM, kind *K, wording W, char *storage_name) ;
#line 474 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_default_value(kind *K) ;
#line 515 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__name_can_coincide_with_property(kind *K) ;
#line 520 "inform7/Chapter 19/Using Kinds.w"
property * Kinds__Behaviour__get_coinciding_property(kind *K) ;
#line 525 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__set_coinciding_property(kind *K, property *P) ;
#line 536 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__uses_signed_comparisons(kind *K) ;
#line 542 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_comparison_routine(kind *K) ;
#line 557 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__is_quasinumerical(kind *K) ;
#line 562 "inform7/Chapter 19/Using Kinds.w"
unit_sequence * Kinds__Behaviour__get_dimensional_form(kind *K) ;
#line 569 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__test_if_derived(kind *K) ;
#line 574 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__now_derived(kind *K) ;
#line 579 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__scale_factor(kind *K) ;
#line 590 "inform7/Chapter 19/Using Kinds.w"
dimensional_rules * Kinds__Behaviour__get_dim_rules(kind *K) ;
#line 598 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_name_in_template_code(kind *K) ;
#line 610 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__I6_classname(kind *K) ;
#line 617 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__I6_classnumber(kind *K) ;
#line 626 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__write_support_routine_name(OUTPUT_STREAM, kind *K) ;
#line 640 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__uses_pointer_values(kind *K) ;
#line 648 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__get_small_block_size(kind *K) ;
#line 657 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__get_heap_size_estimate(kind *K) ;
#line 665 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__cast_possible(kind *from, kind *to) ;
#line 681 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__cast_call(OUTPUT_STREAM, kind *from, kind *to) ;
#line 707 "inform7/Chapter 19/Using Kinds.w"
parse_node * Kinds__Behaviour__cast_constant(parse_node *value, kind *to) ;
#line 742 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__interpret_test_equality(kind *left, kind *right) ;
#line 783 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__interpret_store(node_type_t storage_class, kind *left, kind *right, int inc) ;
#line 816 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_distinguisher(kind *K) ;
#line 827 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__compile_domain_possible(kind *K) ;
#line 857 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__write_loop_schema(i6_schema *sch, kind *K, int use_ix) ;
#line 912 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__requires_blanks_bitmap(kind *K) ;
#line 923 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__can_exchange(kind *K) ;
#line 933 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_name_of_printing_rule(kind *K) ;
#line 944 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_name_of_printing_rule_ACTIONS(kind *K) ;
#line 958 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_explicit_I6_GPR(kind *K) ;
#line 967 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__offers_I6_GPR(kind *K) ;
#line 976 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__request_I6_GPR(kind *K) ;
#line 987 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__needs_I6_GPR(kind *K) ;
#line 1002 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__set_parsing_grammar(kind *K, grammar_verb *gv) ;
#line 1008 "inform7/Chapter 19/Using Kinds.w"
grammar_verb * Kinds__Behaviour__get_parsing_grammar(kind *K) ;
#line 1019 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_recognition_only_GPR(kind *K) ;
#line 1027 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_documentation_reference(kind *K) ;
#line 1032 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__set_documentation_reference(kind *K, char *dr) ;
#line 1041 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_index_default_value(kind *K) ;
#line 1046 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_index_minimum_value(kind *K) ;
#line 1051 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_index_maximum_value(kind *K) ;
#line 1056 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__get_index_priority(kind *K) ;
#line 1061 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__indexed_grey_if_empty(kind *K) ;
#line 1072 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__set_specification_text(kind *K, char *desc) ;
#line 1077 "inform7/Chapter 19/Using Kinds.w"
char * Kinds__Behaviour__get_specification_text(kind *K) ;
#line 1086 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__notify_of_use(kind *K) ;
#line 288 "inform7/Chapter 19/Describing Kinds.w"
int Kinds__Textual__parse_constructor_name(kind_constructor *con, wording *KW, wording *LW) ;
#line 369 "inform7/Chapter 19/Describing Kinds.w"
int Kinds__Textual__parse_variable(vocabulary_entry *ve) ;
#line 374 "inform7/Chapter 19/Describing Kinds.w"
int Kinds__Textual__parse_kind_variable_name(char *p, int allow_lower) ;
#line 383 "inform7/Chapter 19/Describing Kinds.w"
int Kinds__Textual__parse_kind_variable_name_singular(char *p) ;
#line 480 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__log(kind *K) ;
#line 487 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__write(OUTPUT_STREAM, kind *K) ;
#line 491 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__write_plural(OUTPUT_STREAM, kind *K) ;
#line 498 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__write_articled(OUTPUT_STREAM, kind *K) ;
#line 508 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__write_inner(OUTPUT_STREAM, kind *K, int plural_form, int substituting) ;
#line 660 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__desc_base(OUTPUT_STREAM, kind_constructor *con, int b, kind *K, int substituting) ;
#line 315 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__kind_prior(kind *A, kind *B) ;
#line 332 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__dim_initialise(dimensional_rules *dimrs) ;
#line 339 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__record_multiplication_rule(kind *left, kind *right, kind *outcome) ;
#line 384 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__dim_set_multiplication(kind *left, kind *right, kind *outcome) ;
#line 417 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__arithmetic_op_is_unary(int op) ;
#line 445 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__gcd(int m, int n) ;
#line 458 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__lcm(int m, int n) ;
#line 468 "inform7/Chapter 19/Dimensions.w"
unit_sequence Kinds__Dimensions__fundamental_unit_sequence(kind *B) ;
#line 484 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__compare_unit_sequences(unit_sequence *ik1, unit_sequence *ik2) ;
#line 520 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__multiply_unit_sequences(unit_sequence *us1, int s1, unit_sequence *us2, int s2, unit_sequence *result) ;
#line 620 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__root_unit_sequence(unit_sequence *us, int pow, unit_sequence *result) ;
#line 640 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__dim_substitute(unit_sequence *existing, kind *fundamental, unit_sequence *derived) ;
#line 671 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__us_get_scaling_factor(unit_sequence *us) ;
#line 679 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__index_unit_sequence(OUTPUT_STREAM, unit_sequence *deriv, int briefly) ;
#line 711 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__log_unit_sequence(unit_sequence *deriv) ;
#line 741 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__make_unit_derivation(kind *left, kind *right, kind *outcome) ;
#line 828 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__dimensionless(kind *K) ;
#line 836 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__us_dimensionless(unit_sequence *us) ;
#line 845 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__index_dimensional_rules(void) ;
#line 968 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__log_unit_analysis(void) ;
#line 988 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__kind_is_derived(kind *K) ;
#line 1029 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__kind_rescale_multiplication(OUTPUT_STREAM, kind *kindx, kind *kindy) ;
#line 1046 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__kind_rescale_division(OUTPUT_STREAM, kind *kindx, kind *kindy) ;
#line 1060 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__kind_rescale_root(OUTPUT_STREAM, kind *kindx, int power) ;
#line 1109 "inform7/Chapter 19/Dimensions.w"
kind * Kinds__Dimensions__arithmetic_on_kinds(kind *K1, kind *K2, int op) ;
#line 1246 "inform7/Chapter 19/Dimensions.w"
kind * Kinds__Dimensions__to_rational_power(kind *F, int n, int m) ;
#line 1268 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__perform_arithmetic(OUTPUT_STREAM, int op, equation *eqn, parse_node *X, equation_node *EX, kind *KX, parse_node *Y, equation_node *EY, kind *KY) ;
#line 27 "inform7/Chapter 19/Floating-Point Values.w"
generalised_kind Kinds__FloatingPoint__new_gk(kind *K) ;
#line 35 "inform7/Chapter 19/Floating-Point Values.w"
void Kinds__FloatingPoint__log_gk(generalised_kind gK) ;
#line 41 "inform7/Chapter 19/Floating-Point Values.w"
kind * Kinds__FloatingPoint__underlying(generalised_kind gK) ;
#line 45 "inform7/Chapter 19/Floating-Point Values.w"
int Kinds__FloatingPoint__is_real(generalised_kind gK) ;
#line 51 "inform7/Chapter 19/Floating-Point Values.w"
generalised_kind Kinds__FloatingPoint__to_integer(generalised_kind gK) ;
#line 65 "inform7/Chapter 19/Floating-Point Values.w"
generalised_kind Kinds__FloatingPoint__to_real(generalised_kind gK) ;
#line 82 "inform7/Chapter 19/Floating-Point Values.w"
void Kinds__FloatingPoint__begin_flotation(OUTPUT_STREAM, kind *K) ;
#line 88 "inform7/Chapter 19/Floating-Point Values.w"
void Kinds__FloatingPoint__end_flotation(OUTPUT_STREAM, kind *K) ;
#line 95 "inform7/Chapter 19/Floating-Point Values.w"
void Kinds__FloatingPoint__begin_deflotation(OUTPUT_STREAM, kind *K) ;
#line 100 "inform7/Chapter 19/Floating-Point Values.w"
void Kinds__FloatingPoint__end_deflotation(OUTPUT_STREAM, kind *K) ;
#line 107 "inform7/Chapter 19/Floating-Point Values.w"
int Kinds__FloatingPoint__uses_floating_point(kind *K) ;
#line 112 "inform7/Chapter 19/Floating-Point Values.w"
kind * Kinds__FloatingPoint__real_equivalent(kind *K) ;
#line 117 "inform7/Chapter 19/Floating-Point Values.w"
kind * Kinds__FloatingPoint__integer_equivalent(kind *K) ;
#line 81 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__describe(OUTPUT_STREAM, scaling_transformation sc) ;
#line 102 "inform7/Chapter 19/Scaled Arithmetic Values.w"
scaling_transformation Kinds__Scalings__new(int integer_valued, int scaled, int int_s, double real_s, int offset, double real_offset) ;
#line 119 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__convert_to_real(scaling_transformation *sc) ;
#line 136 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__determine_M(scaling_transformation *sc, scaling_transformation *benchmark_sc, int first, int equiv, int alt) ;
#line 262 "inform7/Chapter 19/Scaled Arithmetic Values.w"
scaling_transformation Kinds__Scalings__enlarge(scaling_transformation sc, int F) ;
#line 271 "inform7/Chapter 19/Scaled Arithmetic Values.w"
scaling_transformation Kinds__Scalings__contract(scaling_transformation sc, int F, int *loses_accuracy) ;
#line 288 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__compare(scaling_transformation A, scaling_transformation B) ;
#line 309 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__get_integer_multiplier(scaling_transformation sc) ;
#line 316 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__involves_scale_change(scaling_transformation sc) ;
#line 328 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__quantum(scaling_transformation sc) ;
#line 332 "inform7/Chapter 19/Scaled Arithmetic Values.w"
double Kinds__Scalings__real_quantum(scaling_transformation sc) ;
#line 340 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__quanta_to_value(scaling_transformation sc, int q) ;
#line 344 "inform7/Chapter 19/Scaled Arithmetic Values.w"
double Kinds__Scalings__real_quanta_to_value(scaling_transformation sc, double q) ;
#line 360 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__value_to_quanta(int v, scaling_transformation sc, int *q, int *r) ;
#line 366 "inform7/Chapter 19/Scaled Arithmetic Values.w"
double Kinds__Scalings__real_value_to_quanta(double v, scaling_transformation sc) ;
#line 376 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_quanta_to_value(OUTPUT_STREAM, scaling_transformation sc, char *V_var, int label) ;
#line 413 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_scale_and_add(OUTPUT_STREAM, char *var, int scale_factor, char *to_add, int label) ;
#line 438 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_value_to_quanta(OUTPUT_STREAM, scaling_transformation sc, char *V_var, char *R_var) ;
#line 467 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_threshold_test(OUTPUT_STREAM, scaling_transformation sc, char *V_var, char *op) ;
#line 484 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_print_in_quanta(OUTPUT_STREAM, scaling_transformation sc, char *V_var, char *R_var, char *S_var) ;
#line 563 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__I6_real_literal(OUTPUT_STREAM, double x) ;
#line 64 "inform7/Chapter 19/Runtime Support for Kinds.w"
int Kinds__RunTime__weak_id(kind *K) ;
#line 73 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_weak_id(OUTPUT_STREAM, kind *K) ;
#line 121 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_strong_id(OUTPUT_STREAM, kind *K) ;
#line 142 "inform7/Chapter 19/Runtime Support for Kinds.w"
runtime_kind_structure * Kinds__RunTime__get_rks(kind *K) ;
#line 214 "inform7/Chapter 19/Runtime Support for Kinds.w"
int Kinds__RunTime__compile_default_value(OUTPUT_STREAM, kind *K) ;
#line 222 "inform7/Chapter 19/Runtime Support for Kinds.w"
int Kinds__RunTime__precompile_default_value(kind *K) ;
#line 242 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_structures(OUTPUT_STREAM) ;
#line 367 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__ensure_basic_heap_present(void) ;
#line 376 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_heap_allocator(OUTPUT_STREAM) ;
#line 409 "inform7/Chapter 19/Runtime Support for Kinds.w"
text_stream * Kinds__RunTime__begin_block_constant(OUTPUT_STREAM, kind *K) ;
#line 422 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__end_block_constant(kind *K) ;
#line 429 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_block_constants(OUTPUT_STREAM) ;
#line 446 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_heap_allocation(OUTPUT_STREAM, kind *K, int multiplier, int stack_offset) ;
#line 472 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_block_value_header(OUTPUT_STREAM, kind *K, int individual, int size) ;
#line 495 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_data_type_support_routines(OUTPUT_STREAM) ;
#line 777 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__I7_Kind_Name_routine(OUTPUT_STREAM) ;
#line 25 "inform7/Chapter 19/Kinds Index.w"
void Kinds__Index__index_kinds(int pass) ;
#line 253 "inform7/Chapter 19/Kinds Index.w"
void Kinds__Index__index_kind_col_head(char *name, char *anchor) ;
#line 266 "inform7/Chapter 19/Kinds Index.w"
void Kinds__Index__begin_chart_row(void) ;
#line 285 "inform7/Chapter 19/Kinds Index.w"
int Kinds__Index__index_kind_name_cell(int shaded, kind *K) ;
#line 303 "inform7/Chapter 19/Kinds Index.w"
void Kinds__Index__end_chart_row(int shaded, kind *K, char *tick1, char *tick2, char *tick3) ;
#line 360 "inform7/Chapter 19/Kinds Index.w"
void Kinds__Index__index_kind(kind *K, int plural, int with_links) ;
#line 15 "inform7/Chapter 20/Specifications.w"
parse_node * Specifications__from_kind(kind *K) ;
#line 19 "inform7/Chapter 20/Specifications.w"
kind * Specifications__to_kind(parse_node *spec) ;
#line 28 "inform7/Chapter 20/Specifications.w"
kind * Specifications__to_true_kind(parse_node *spec) ;
#line 34 "inform7/Chapter 20/Specifications.w"
kind * Specifications__to_true_kind_disambiguated(parse_node *spec) ;
#line 47 "inform7/Chapter 20/Specifications.w"
int Specifications__is_kind_like(parse_node *spec) ;
#line 57 "inform7/Chapter 20/Specifications.w"
int Specifications__is_description_like(parse_node *p) ;
#line 65 "inform7/Chapter 20/Specifications.w"
int Specifications__is_description(parse_node *p) ;
#line 71 "inform7/Chapter 20/Specifications.w"
pcalc_prop * Specifications__to_proposition(parse_node *p) ;
#line 83 "inform7/Chapter 20/Specifications.w"
instance * Specifications__object_exactly_described_if_any(parse_node *spec) ;
#line 100 "inform7/Chapter 20/Specifications.w"
parse_node * Specifications__new_new_variable_like(kind *K) ;
#line 106 "inform7/Chapter 20/Specifications.w"
kind * Specifications__kind_of_new_variable_like(parse_node *S) ;
#line 111 "inform7/Chapter 20/Specifications.w"
int Specifications__is_new_variable_like(parse_node *spec) ;
#line 124 "inform7/Chapter 20/Specifications.w"
void Specifications__write_out_in_English(OUTPUT_STREAM, parse_node *spec) ;
#line 150 "inform7/Chapter 20/Specifications.w"
int Specifications__compare_specificity(parse_node *spec1, parse_node *spec2, int *wont_mix) ;
#line 277 "inform7/Chapter 20/Specifications.w"
parse_node * Specifications__new_UNKNOWN(wording W) ;
#line 23 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_action_name(action_name *val) ;
#line 24 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_action_pattern(action_pattern *val) ;
#line 33 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_activity(activity *val) ;
#line 34 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_binary_predicate(binary_predicate *val) ;
#line 35 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_constant_phrase(constant_phrase *val) ;
#line 36 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_equation(equation *val) ;
#line 37 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_grammar_verb(grammar_verb *val) ;
#line 38 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_named_rulebook_outcome(named_rulebook_outcome *val) ;
#line 39 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_property(property *val) ;
#line 40 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_rule(rule *val) ;
#line 41 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_rulebook(rulebook *val) ;
#line 42 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_scene(scene *val) ;
#line 43 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_table(table *val) ;
#line 44 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_table_column(table_column *val) ;
#line 45 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_use_option(use_option *val) ;
#line 46 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_verb_conjugation(verb_conjugation *val) ;
#line 56 "inform7/Chapter 20/Rvalues.w"
action_name * Rvalues__to_action_name(parse_node *spec) ;
#line 57 "inform7/Chapter 20/Rvalues.w"
action_pattern * Rvalues__to_action_pattern(parse_node *spec) ;
#line 58 "inform7/Chapter 20/Rvalues.w"
activity * Rvalues__to_activity(parse_node *spec) ;
#line 59 "inform7/Chapter 20/Rvalues.w"
binary_predicate * Rvalues__to_binary_predicate(parse_node *spec) ;
#line 60 "inform7/Chapter 20/Rvalues.w"
constant_phrase * Rvalues__to_constant_phrase(parse_node *spec) ;
#line 61 "inform7/Chapter 20/Rvalues.w"
equation * Rvalues__to_equation(parse_node *spec) ;
#line 62 "inform7/Chapter 20/Rvalues.w"
grammar_verb * Rvalues__to_grammar_verb(parse_node *spec) ;
#line 63 "inform7/Chapter 20/Rvalues.w"
named_rulebook_outcome * Rvalues__to_named_rulebook_outcome(parse_node *spec) ;
#line 64 "inform7/Chapter 20/Rvalues.w"
property * Rvalues__to_property(parse_node *spec) ;
#line 65 "inform7/Chapter 20/Rvalues.w"
rule * Rvalues__to_rule(parse_node *spec) ;
#line 66 "inform7/Chapter 20/Rvalues.w"
rulebook * Rvalues__to_rulebook(parse_node *spec) ;
#line 67 "inform7/Chapter 20/Rvalues.w"
scene * Rvalues__to_scene(parse_node *spec) ;
#line 68 "inform7/Chapter 20/Rvalues.w"
table * Rvalues__to_table(parse_node *spec) ;
#line 69 "inform7/Chapter 20/Rvalues.w"
table_column * Rvalues__to_table_column(parse_node *spec) ;
#line 70 "inform7/Chapter 20/Rvalues.w"
use_option * Rvalues__to_use_option(parse_node *spec) ;
#line 71 "inform7/Chapter 20/Rvalues.w"
verb_conjugation * Rvalues__to_verb_conjugation(parse_node *spec) ;
#line 77 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_instance(instance *I) ;
#line 86 "inform7/Chapter 20/Rvalues.w"
instance * Rvalues__to_instance(parse_node *spec) ;
#line 91 "inform7/Chapter 20/Rvalues.w"
int Rvalues__is_object(parse_node *spec) ;
#line 98 "inform7/Chapter 20/Rvalues.w"
instance * Rvalues__to_object_instance(parse_node *spec) ;
#line 108 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__new_self_object_constant(void) ;
#line 115 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__new_nothing_object_constant(void) ;
#line 126 "inform7/Chapter 20/Rvalues.w"
int Rvalues__is_nothing_object_constant(parse_node *spec) ;
#line 131 "inform7/Chapter 20/Rvalues.w"
int Rvalues__is_self_object_constant(parse_node *spec) ;
#line 141 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_encoded_notation(kind *K, int encoded_value, wording W) ;
#line 149 "inform7/Chapter 20/Rvalues.w"
int Rvalues__to_encoded_notation(parse_node *spec) ;
#line 159 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_int(int n, wording W) ;
#line 167 "inform7/Chapter 20/Rvalues.w"
int Rvalues__to_int(parse_node *spec) ;
#line 179 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_IEEE_754(unsigned int n, wording W) ;
#line 187 "inform7/Chapter 20/Rvalues.w"
unsigned int Rvalues__to_IEEE_754(parse_node *spec) ;
#line 196 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_boolean(int flag, wording W) ;
#line 204 "inform7/Chapter 20/Rvalues.w"
int Rvalues__to_boolean(parse_node *spec) ;
#line 213 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_Unicode_point(int code_point, wording W) ;
#line 221 "inform7/Chapter 20/Rvalues.w"
int Rvalues__to_Unicode_point(parse_node *spec) ;
#line 231 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_time(int minutes_since_midnight, wording W) ;
#line 239 "inform7/Chapter 20/Rvalues.w"
int Rvalues__to_time(parse_node *spec) ;
#line 249 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_wording_of_list(kind *K, wording W) ;
#line 258 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_wording(wording W) ;
#line 268 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_unescaped_wording(wording W) ;
#line 278 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_permanent_STREAM(text_stream *S) ;
#line 292 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__from_pair(parse_node *X, parse_node *Y) ;
#line 304 "inform7/Chapter 20/Rvalues.w"
void Rvalues__to_pair(parse_node *pair, parse_node **X, parse_node **Y) ;
#line 315 "inform7/Chapter 20/Rvalues.w"
parse_node * Rvalues__constant_description(pcalc_prop *prop, wording W) ;
#line 323 "inform7/Chapter 20/Rvalues.w"
void Rvalues__set_constant_description_proposition(parse_node *spec, pcalc_prop *prop) ;
#line 335 "inform7/Chapter 20/Rvalues.w"
int Rvalues__is_CONSTANT_construction(parse_node *spec, kind_constructor *con) ;
#line 342 "inform7/Chapter 20/Rvalues.w"
int Rvalues__is_CONSTANT_of_kind(parse_node *spec, kind *K) ;
#line 387 "inform7/Chapter 20/Rvalues.w"
int Rvalues__compare_CONSTANT(parse_node *spec1, parse_node *spec2) ;
#line 433 "inform7/Chapter 20/Rvalues.w"
void Rvalues__write_out_in_English(OUTPUT_STREAM, parse_node *spec) ;
#line 465 "inform7/Chapter 20/Rvalues.w"
void Rvalues__log(parse_node *spec) ;
#line 486 "inform7/Chapter 20/Rvalues.w"
kind * Rvalues__to_kind(parse_node *spec) ;
#line 597 "inform7/Chapter 20/Rvalues.w"
void Rvalues__compile(OUTPUT_STREAM, parse_node *spec_found) ;
#line 66 "inform7/Chapter 20/Lvalues.w"
parse_node * Lvalues__new_LOCAL_VARIABLE(wording W, local_variable *lvar) ;
#line 74 "inform7/Chapter 20/Lvalues.w"
parse_node * Lvalues__new_actual_NONLOCAL_VARIABLE(nonlocal_variable *nlv) ;
#line 85 "inform7/Chapter 20/Lvalues.w"
parse_node * Lvalues__new_TABLE_ENTRY(wording W) ;
#line 93 "inform7/Chapter 20/Lvalues.w"
parse_node * Lvalues__new_LIST_ENTRY(parse_node *owner, parse_node *index) ;
#line 109 "inform7/Chapter 20/Lvalues.w"
parse_node * Lvalues__new_PROPERTY_VALUE(parse_node *prop, parse_node *owner) ;
#line 121 "inform7/Chapter 20/Lvalues.w"
parse_node * Lvalues__underlying_property(parse_node *spec) ;
#line 133 "inform7/Chapter 20/Lvalues.w"
node_type_t Lvalues__get_storage_form(parse_node *spec) ;
#line 141 "inform7/Chapter 20/Lvalues.w"
int Lvalues__is_actual_NONLOCAL_VARIABLE(parse_node *spec) ;
#line 146 "inform7/Chapter 20/Lvalues.w"
nonlocal_variable * Lvalues__get_nonlocal_variable_if_any(parse_node *spec) ;
#line 152 "inform7/Chapter 20/Lvalues.w"
int Lvalues__is_constant_NONLOCAL_VARIABLE(parse_node *spec) ;
#line 162 "inform7/Chapter 20/Lvalues.w"
int Lvalues__is_global_variable(parse_node *spec) ;
#line 170 "inform7/Chapter 20/Lvalues.w"
void Lvalues__write_out_in_English(OUTPUT_STREAM, parse_node *spec) ;
#line 197 "inform7/Chapter 20/Lvalues.w"
void Lvalues__log(parse_node *spec) ;
#line 217 "inform7/Chapter 20/Lvalues.w"
kind * Lvalues__to_kind(parse_node *spec) ;
#line 276 "inform7/Chapter 20/Lvalues.w"
local_variable * Lvalues__get_local_variable_if_any(parse_node *spec) ;
#line 287 "inform7/Chapter 20/Lvalues.w"
void Lvalues__compile(OUTPUT_STREAM, parse_node *spec_found) ;
#line 459 "inform7/Chapter 20/Lvalues.w"
char * Lvalues__storage_class_schema(node_type_t storage_class, int kind_of_store, int reducing_modulo_1440) ;
#line 59 "inform7/Chapter 20/Conditions.w"
parse_node * Conditions__new(time_period *tp) ;
#line 69 "inform7/Chapter 20/Conditions.w"
parse_node * Conditions__new_LOGICAL_AND(parse_node *spec1, parse_node *spec2) ;
#line 76 "inform7/Chapter 20/Conditions.w"
parse_node * Conditions__new_LOGICAL_OR(parse_node *spec1, parse_node *spec2) ;
#line 86 "inform7/Chapter 20/Conditions.w"
parse_node * Conditions__negate(parse_node *cond) ;
#line 97 "inform7/Chapter 20/Conditions.w"
parse_node * Conditions__new_TEST_PROPOSITION(pcalc_prop *prop) ;
#line 107 "inform7/Chapter 20/Conditions.w"
parse_node * Conditions__new_TEST_PHRASE_OPTION(int opt_num) ;
#line 116 "inform7/Chapter 20/Conditions.w"
parse_node * Conditions__new_TEST_ACTION(action_pattern *ap, wording W) ;
#line 124 "inform7/Chapter 20/Conditions.w"
int Conditions__is_TEST_ACTION(parse_node *spec) ;
#line 130 "inform7/Chapter 20/Conditions.w"
parse_node * Conditions__action_tested(parse_node *spec) ;
#line 141 "inform7/Chapter 20/Conditions.w"
parse_node * Conditions__attach_tense(parse_node *cond, int t) ;
#line 154 "inform7/Chapter 20/Conditions.w"
parse_node * Conditions__attach_historic_requirement(parse_node *cond, time_period *tp) ;
#line 184 "inform7/Chapter 20/Conditions.w"
void Conditions__write_out_in_English(OUTPUT_STREAM, parse_node *spec) ;
#line 201 "inform7/Chapter 20/Conditions.w"
void Conditions__log(parse_node *spec) ;
#line 220 "inform7/Chapter 20/Conditions.w"
int Conditions__compare_specificity_of_CONDITIONs(parse_node *spec1, parse_node *spec2) ;
#line 235 "inform7/Chapter 20/Conditions.w"
int Conditions__count(parse_node *spec) ;
#line 264 "inform7/Chapter 20/Conditions.w"
void Conditions__compile(OUTPUT_STREAM, parse_node *spec_found) ;
#line 13 "inform7/Chapter 20/Descriptions.w"
parse_node * Descriptions__from_proposition(pcalc_prop *prop, wording W) ;
#line 19 "inform7/Chapter 20/Descriptions.w"
pcalc_prop * Descriptions__to_proposition(parse_node *spec) ;
#line 30 "inform7/Chapter 20/Descriptions.w"
void Descriptions__set_proposition(parse_node *spec, pcalc_prop *prop) ;
#line 43 "inform7/Chapter 20/Descriptions.w"
parse_node * Descriptions__from_kind(kind *K, int composited) ;
#line 58 "inform7/Chapter 20/Descriptions.w"
kind * Descriptions__to_kind(parse_node *spec) ;
#line 67 "inform7/Chapter 20/Descriptions.w"
int Descriptions__makes_kind_explicit(parse_node *spec) ;
#line 73 "inform7/Chapter 20/Descriptions.w"
kind * Descriptions__explicit_kind(parse_node *spec) ;
#line 83 "inform7/Chapter 20/Descriptions.w"
parse_node * Descriptions__from_instance(instance *I, wording W) ;
#line 92 "inform7/Chapter 20/Descriptions.w"
instance * Descriptions__to_instance(parse_node *spec) ;
#line 110 "inform7/Chapter 20/Descriptions.w"
parse_node * Descriptions__to_rvalue(parse_node *spec) ;
#line 138 "inform7/Chapter 20/Descriptions.w"
int Descriptions__is_qualified(parse_node *spec) ;
#line 146 "inform7/Chapter 20/Descriptions.w"
int Descriptions__is_kind_like(parse_node *spec) ;
#line 154 "inform7/Chapter 20/Descriptions.w"
int Descriptions__is_complex(parse_node *spec) ;
#line 161 "inform7/Chapter 20/Descriptions.w"
int Descriptions__is_adjectives_plus_kind(parse_node *spec) ;
#line 182 "inform7/Chapter 20/Descriptions.w"
int Descriptions__number_of_adjectives_applied_to(parse_node *spec) ;
#line 187 "inform7/Chapter 20/Descriptions.w"
adjective_usage * Descriptions__first_adjective_usage(parse_node *spec) ;
#line 192 "inform7/Chapter 20/Descriptions.w"
void Descriptions__add_to_adjective_list(adjective_usage *au, parse_node *spec) ;
#line 204 "inform7/Chapter 20/Descriptions.w"
void Descriptions__add_to_adjective_list_w(adjective_usage *au, parse_node *spec) ;
#line 223 "inform7/Chapter 20/Descriptions.w"
void Descriptions__quantify(parse_node *spec, quantifier *q, int par) ;
#line 234 "inform7/Chapter 20/Descriptions.w"
pcalc_prop * Descriptions__get_inner_prop(parse_node *spec) ;
#line 244 "inform7/Chapter 20/Descriptions.w"
pcalc_prop * Descriptions__get_quantified_prop(parse_node *spec) ;
#line 255 "inform7/Chapter 20/Descriptions.w"
quantifier * Descriptions__get_quantifier(parse_node *spec) ;
#line 261 "inform7/Chapter 20/Descriptions.w"
int Descriptions__get_quantification_parameter(parse_node *spec) ;
#line 272 "inform7/Chapter 20/Descriptions.w"
void Descriptions__attach_calling(parse_node *spec, wording C) ;
#line 282 "inform7/Chapter 20/Descriptions.w"
wording Descriptions__get_calling(parse_node *spec) ;
#line 290 "inform7/Chapter 20/Descriptions.w"
void Descriptions__clear_calling(parse_node *spec) ;
#line 302 "inform7/Chapter 20/Descriptions.w"
int Descriptions__makes_callings(parse_node *spec) ;
#line 316 "inform7/Chapter 20/Descriptions.w"
void Descriptions__write_out_in_English(OUTPUT_STREAM, parse_node *spec) ;
#line 334 "inform7/Chapter 20/Descriptions.w"
int Descriptions__compare_specificity(parse_node *spec1, parse_node *spec2) ;
#line 84 "inform7/Chapter 20/Compiling from Specifications.w"
void Specifications__Compiler__compile(OUTPUT_STREAM, parse_node *spec) ;
#line 100 "inform7/Chapter 20/Compiling from Specifications.w"
void Specifications__Compiler__spec_compile_primitive(OUTPUT_STREAM, parse_node *spec) ;
#line 124 "inform7/Chapter 20/Compiling from Specifications.w"
void Specifications__Compiler__compile_to_kind(OUTPUT_STREAM, parse_node *value, kind *K_wanted) ;
#line 145 "inform7/Chapter 20/Compiling from Specifications.w"
void Specifications__Compiler__compile_constant_to_kind(OUTPUT_STREAM, parse_node *value, kind *K_wanted) ;
#line 114 "inform7/Chapter 20/Dash.w"
int Dash__problems_have_been_issued(void) ;
#line 158 "inform7/Chapter 20/Dash.w"
int Dash__worst_case(int rv1, int rv2) ;
#line 178 "inform7/Chapter 20/Dash.w"
int Dash__check_condition(parse_node *p) ;
#line 185 "inform7/Chapter 20/Dash.w"
int Dash__check_value(parse_node *p, kind *K) ;
#line 194 "inform7/Chapter 20/Dash.w"
int Dash__check_value_silently(parse_node *p, kind *K) ;
#line 203 "inform7/Chapter 20/Dash.w"
int Dash__check_invl(parse_node *p) ;
#line 208 "inform7/Chapter 20/Dash.w"
int Dash__funnel_to_level_2(parse_node *p, int silently) ;
#line 242 "inform7/Chapter 20/Dash.w"
int Dash__typecheck_recursive(parse_node *p, parse_node *context, int consider_alternatives) ;
#line 521 "inform7/Chapter 20/Dash.w"
int Dash__typecheck_recursive_inner(parse_node *p, parse_node *context, int consider_alternatives) ;
#line 2096 "inform7/Chapter 20/Dash.w"
kind * Dash__fix_arithmetic_operand(parse_node *operand) ;
#line 2138 "inform7/Chapter 20/Dash.w"
int Dash__set_up_any_local_required(parse_node *inv) ;
#line 2279 "inform7/Chapter 20/Dash.w"
int Dash__failed_one(parse_node *inv, parse_node *context, kind *kind_needed) ;
#line 2287 "inform7/Chapter 20/Dash.w"
int Dash__failed(parse_node **list_of_possible_readings, int no_of_possible_readings, parse_node *context, kind *kind_needed) ;
#line 2455 "inform7/Chapter 20/Dash.w"
void Dash__note_inv_token_text(parse_node *p, int new_name) ;
#line 2532 "inform7/Chapter 20/Dash.w"
int Dash__typecheck_single_node(parse_node *p, kind *kind_expected, int condition_context) ;
#line 3392 "inform7/Chapter 20/Dash.w"
int Dash__reading_passed(parse_node *p) ;
#line 3398 "inform7/Chapter 20/Dash.w"
char * Dash__verdict_to_text(parse_node *p) ;
#line 3409 "inform7/Chapter 20/Dash.w"
char * Dash__quick_verdict_to_text(parse_node *p) ;
#line 3423 "inform7/Chapter 20/Dash.w"
void Dash__set_flag(parse_node *p, int flag) ;
#line 3429 "inform7/Chapter 20/Dash.w"
void Dash__clear_flags(parse_node *p) ;
#line 3434 "inform7/Chapter 20/Dash.w"
void Dash__clear_flag(parse_node *p, int flag) ;
#line 3440 "inform7/Chapter 20/Dash.w"
int Dash__test_flag(parse_node *p, int flag) ;
#line 3449 "inform7/Chapter 20/Dash.w"
void Dash__experiment(wording W, int full) ;
#line 93 "inform7/Chapter 21/Properties.w"
property * Properties__obtain(wording W, int valued) ;
#line 117 "inform7/Chapter 21/Properties.w"
property * Properties__create(wording W) ;
#line 287 "inform7/Chapter 21/Properties.w"
kind * Properties__to_kind(property *prn) ;
#line 381 "inform7/Chapter 21/Properties.w"
int Properties__match_longest(wording W) ;
#line 396 "inform7/Chapter 21/Properties.w"
property_permission * Properties__permission_list(property *prn) ;
#line 399 "inform7/Chapter 21/Properties.w"
void Properties__set_permission_list(property *prn, property_permission *pp) ;
#line 406 "inform7/Chapter 21/Properties.w"
void Properties__log(property *prn) ;
#line 417 "inform7/Chapter 21/Properties.w"
void Properties__log_basic_pname(property *prn) ;
#line 429 "inform7/Chapter 21/Properties.w"
int Properties__is_either_or(property *prn) ;
#line 432 "inform7/Chapter 21/Properties.w"
int Properties__is_value_property(property *prn) ;
#line 443 "inform7/Chapter 21/Properties.w"
int Properties__can_be_compiled(property *prn) ;
#line 452 "inform7/Chapter 21/Properties.w"
int Properties__is_shown_in_index(property *prn) ;
#line 455 "inform7/Chapter 21/Properties.w"
void Properties__exclude_from_index(property *prn) ;
#line 462 "inform7/Chapter 21/Properties.w"
void Properties__set_indexed_already_flag(property *prn, int state) ;
#line 465 "inform7/Chapter 21/Properties.w"
int Properties__get_indexed_already_flag(property *prn) ;
#line 472 "inform7/Chapter 21/Properties.w"
void Properties__offset_in_runtime_metadata_table_is(property *prn, int pos) ;
#line 475 "inform7/Chapter 21/Properties.w"
int Properties__get_offset_in_runtime_metadata_table(property *prn) ;
#line 489 "inform7/Chapter 21/Properties.w"
void Properties__set_translation(property *prn, char *t) ;
#line 500 "inform7/Chapter 21/Properties.w"
char * Properties__get_translation(property *prn) ;
#line 505 "inform7/Chapter 21/Properties.w"
int Properties__has_been_translated(property *prn) ;
#line 515 "inform7/Chapter 21/Properties.w"
void Properties__translates(wording W, parse_node *p2) ;
#line 572 "inform7/Chapter 21/Properties.w"
void Properties__alias_translations(OUTPUT_STREAM) ;
#line 587 "inform7/Chapter 21/Properties.w"
void Properties__begin_traverse(void) ;
#line 591 "inform7/Chapter 21/Properties.w"
int Properties__visited_in_traverse(property *prn) ;
#line 606 "inform7/Chapter 21/Properties.w"
possession_marker * Properties__get_possession_marker(property *prn) ;
#line 617 "inform7/Chapter 21/Properties.w"
void Properties__compile_inferred_value(OUTPUT_STREAM, inference_subject *infs, property *prn) ;
#line 634 "inform7/Chapter 21/Properties.w"
int Properties__compile_property_value_inner(OUTPUT_STREAM, inference_subject *infs, property *prn) ;
#line 57 "inform7/Chapter 21/Either-Or Properties.w"
property * Properties__EitherOr__obtain(wording W, inference_subject *infs) ;
#line 89 "inform7/Chapter 21/Either-Or Properties.w"
property * Properties__EitherOr__new_nameless(char *I6_form) ;
#line 101 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__initialise(property *prn) ;
#line 115 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__make_negations(property *prn, property *neg) ;
#line 145 "inform7/Chapter 21/Either-Or Properties.w"
property * Properties__EitherOr__get_negation(property *prn) ;
#line 153 "inform7/Chapter 21/Either-Or Properties.w"
int Properties__EitherOr__stored_in_negation(property *prn) ;
#line 158 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__make_stored_in_negation(property *prn) ;
#line 169 "inform7/Chapter 21/Either-Or Properties.w"
grammar_verb * Properties__EitherOr__get_parsing_grammar(property *prn) ;
#line 174 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__set_parsing_grammar(property *prn, grammar_verb *gv) ;
#line 179 "inform7/Chapter 21/Either-Or Properties.w"
adjectival_phrase * Properties__EitherOr__get_aph(property *prn) ;
#line 187 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__assert(property *prn, inference_subject *owner, int parity, int certainty) ;
#line 203 "inform7/Chapter 21/Either-Or Properties.w"
int Properties__EitherOr__implemented_as_attribute(property *prn) ;
#line 209 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__implement_as_attribute(property *prn, int state) ;
#line 225 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__compile_value(OUTPUT_STREAM, property *prn, int val) ;
#line 230 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__compile_default_value(OUTPUT_STREAM, property *prn) ;
#line 242 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__create_adjective_from_property(property *prn, wording W, kind *K) ;
#line 251 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__make_new_adjective_sense_from_property(property *prn, wording W, kind *K) ;
#line 264 "inform7/Chapter 21/Either-Or Properties.w"
adjective_meaning * Properties__EitherOr__ADJ_parse(parse_node *q, int sense, wording AW, wording DNW, wording CONW, wording CALLW) ;
#line 273 "inform7/Chapter 21/Either-Or Properties.w"
int Properties__EitherOr__ADJ_compile(property *prn, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 282 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__ADJ_compiling_soon(adjective_meaning *am, property *prn, int T) ;
#line 362 "inform7/Chapter 21/Either-Or Properties.w"
int Properties__EitherOr__ADJ_assert(property *prn, inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) ;
#line 372 "inform7/Chapter 21/Either-Or Properties.w"
int Properties__EitherOr__ADJ_index(property *prn) ;
#line 13 "inform7/Chapter 21/Valued Properties.w"
property * Properties__Valued__obtain(wording W) ;
#line 22 "inform7/Chapter 21/Valued Properties.w"
property * Properties__Valued__obtain_within_kind(wording W, kind *K) ;
#line 65 "inform7/Chapter 21/Valued Properties.w"
property * Properties__Valued__new_nameless(char *I6_form, kind *K) ;
#line 80 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__initialise(property *prn) ;
#line 88 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__make_setting_relation(property *prn, wording W) ;
#line 100 "inform7/Chapter 21/Valued Properties.w"
kind * Properties__Valued__kind(property *prn) ;
#line 105 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__set_kind(property *prn, kind *K) ;
#line 140 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__make_coincide_with_kind(property *prn, kind *K) ;
#line 148 "inform7/Chapter 21/Valued Properties.w"
int Properties__Valued__coincides_with_kind(property *prn) ;
#line 156 "inform7/Chapter 21/Valued Properties.w"
binary_predicate * Properties__Valued__get_setting_bp(property *prn) ;
#line 164 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__set_stored_relation(property *prn, binary_predicate *bp) ;
#line 169 "inform7/Chapter 21/Valued Properties.w"
binary_predicate * Properties__Valued__get_stored_relation(property *prn) ;
#line 182 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__now_used_for_non_typesafe_relation(property *prn) ;
#line 187 "inform7/Chapter 21/Valued Properties.w"
int Properties__Valued__is_used_for_non_typesafe_relation(property *prn) ;
#line 195 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__assert(property *prn, inference_subject *owner, parse_node *val, int certainty) ;
#line 208 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__compile_value(OUTPUT_STREAM, property *prn, parse_node *val) ;
#line 217 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__compile_default_value(OUTPUT_STREAM, property *prn) ;
#line 20 "inform7/Chapter 21/Condition Properties.w"
void Properties__Conditions__initialise(property *prn) ;
#line 28 "inform7/Chapter 21/Condition Properties.w"
property * Properties__Conditions__new(inference_subject *infs, wording NW, parse_node *set, int *already) ;
#line 139 "inform7/Chapter 21/Condition Properties.w"
inference_subject * Properties__Conditions__of_what(property *prn) ;
#line 23 "inform7/Chapter 21/Indefinite Appearance.w"
void Properties__Appearance__infer(inference_subject *infs, parse_node *spec) ;
#line 63 "inform7/Chapter 21/Indefinite Appearance.w"
void Properties__Appearance__reallocate(inference_subject *infs) ;
#line 25 "inform7/Chapter 21/The Provision Relation.w"
void Properties__ProvisionRelation__REL_create_initial_stock(void) ;
#line 38 "inform7/Chapter 21/The Provision Relation.w"
void Properties__ProvisionRelation__REL_create_second_stock(void) ;
#line 47 "inform7/Chapter 21/The Provision Relation.w"
int Properties__ProvisionRelation__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 65 "inform7/Chapter 21/The Provision Relation.w"
int Properties__ProvisionRelation__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 82 "inform7/Chapter 21/The Provision Relation.w"
int Properties__ProvisionRelation__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 131 "inform7/Chapter 21/The Provision Relation.w"
int Properties__ProvisionRelation__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 87 "inform7/Chapter 21/Measurement Adjectives.w"
binary_predicate * Properties__Measurement__weak_comparison_bp(int shape) ;
#line 98 "inform7/Chapter 21/Measurement Adjectives.w"
char * Properties__Measurement__strict_comparison(int shape) ;
#line 111 "inform7/Chapter 21/Measurement Adjectives.w"
measurement_definition * Properties__Measurement__retrieve(property *prn, int shape) ;
#line 121 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__read_property_details(measurement_definition *mdef, property **prn, int *shape) ;
#line 134 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__validate_definitions(void) ;
#line 142 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__validate(measurement_definition *mdef) ;
#line 208 "inform7/Chapter 21/Measurement Adjectives.w"
int Properties__Measurement__is_valid(measurement_definition *mdef) ;
#line 252 "inform7/Chapter 21/Measurement Adjectives.w"
adjective_meaning * Properties__Measurement__ADJ_parse(parse_node *q, int sense, wording AW, wording DNW, wording CONW, wording CALLW) ;
#line 393 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__ADJ_compiling_soon(adjective_meaning *am, measurement_definition *mdef, int T) ;
#line 404 "inform7/Chapter 21/Measurement Adjectives.w"
int Properties__Measurement__ADJ_compile(measurement_definition *mdef, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 409 "inform7/Chapter 21/Measurement Adjectives.w"
int Properties__Measurement__ADJ_assert(measurement_definition *mdef, inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) ;
#line 422 "inform7/Chapter 21/Measurement Adjectives.w"
int Properties__Measurement__ADJ_index(measurement_definition *mdef) ;
#line 429 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__compile_MADJ_routines(OUTPUT_STREAM) ;
#line 466 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__create_comparatives(void) ;
#line 21 "inform7/Chapter 21/Comparative Relations.w"
void Properties__ComparativeRelations__REL_create_initial_stock(void) ;
#line 35 "inform7/Chapter 21/Comparative Relations.w"
void Properties__ComparativeRelations__REL_create_second_stock(void) ;
#line 45 "inform7/Chapter 21/Comparative Relations.w"
int Properties__ComparativeRelations__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 72 "inform7/Chapter 21/Comparative Relations.w"
int Properties__ComparativeRelations__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 82 "inform7/Chapter 21/Comparative Relations.w"
int Properties__ComparativeRelations__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 115 "inform7/Chapter 21/Comparative Relations.w"
int Properties__ComparativeRelations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 13 "inform7/Chapter 21/Same Property Relation.w"
void Properties__SameRelations__REL_create_initial_stock(void) ;
#line 33 "inform7/Chapter 21/Same Property Relation.w"
void Properties__SameRelations__REL_create_second_stock(void) ;
#line 84 "inform7/Chapter 21/Same Property Relation.w"
int Properties__SameRelations__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 92 "inform7/Chapter 21/Same Property Relation.w"
int Properties__SameRelations__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 102 "inform7/Chapter 21/Same Property Relation.w"
int Properties__SameRelations__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 110 "inform7/Chapter 21/Same Property Relation.w"
property * Properties__SameRelations__bp_get_same_as_property(binary_predicate *bp) ;
#line 117 "inform7/Chapter 21/Same Property Relation.w"
int Properties__SameRelations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 12 "inform7/Chapter 21/Setting Property Relation.w"
void Properties__SettingRelations__REL_create_initial_stock(void) ;
#line 23 "inform7/Chapter 21/Setting Property Relation.w"
binary_predicate * Properties__SettingRelations__make_set_property_BP(wording W) ;
#line 38 "inform7/Chapter 21/Setting Property Relation.w"
binary_predicate * Properties__SettingRelations__find_set_property_BP(wording W) ;
#line 51 "inform7/Chapter 21/Setting Property Relation.w"
void Properties__SettingRelations__fix_property_bp(binary_predicate *bp) ;
#line 99 "inform7/Chapter 21/Setting Property Relation.w"
binary_predicate * Properties__SettingRelations__make_set_nameless_property_BP(property *prn) ;
#line 112 "inform7/Chapter 21/Setting Property Relation.w"
void Properties__SettingRelations__REL_create_second_stock(void) ;
#line 126 "inform7/Chapter 21/Setting Property Relation.w"
void Properties__SettingRelations__set_property_BP_schemas(binary_predicate *bp, property *prn) ;
#line 148 "inform7/Chapter 21/Setting Property Relation.w"
int Properties__SettingRelations__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 219 "inform7/Chapter 21/Setting Property Relation.w"
int Properties__SettingRelations__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 230 "inform7/Chapter 21/Setting Property Relation.w"
int Properties__SettingRelations__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 255 "inform7/Chapter 21/Setting Property Relation.w"
int Properties__SettingRelations__bp_sets_a_property(binary_predicate *bp) ;
#line 263 "inform7/Chapter 21/Setting Property Relation.w"
int Properties__SettingRelations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 102 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__allocate_attributes(void) ;
#line 166 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_attributes(OUTPUT_STREAM) ;
#line 250 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__begin_sequencing_objects(void) ;
#line 261 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__place_this_object_next(instance *I) ;
#line 273 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__place_objects_in_definition_sequence(void) ;
#line 300 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_all(OUTPUT_STREAM) ;
#line 311 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_class_definitions(OUTPUT_STREAM, inference_subject *within) ;
#line 324 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_subject(OUTPUT_STREAM, inference_subject *subj) ;
#line 439 "inform7/Chapter 21/Properties of Objects.w"
int Properties__ObjectImplementation__compile_property_within_object_body(OUTPUT_STREAM, inference_subject *know, property *prn) ;
#line 494 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_has_property(OUTPUT_STREAM, property *prn) ;
#line 527 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__property_metadata_array(OUTPUT_STREAM) ;
#line 614 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__CreatePropertyOffsets_routine(OUTPUT_STREAM) ;
#line 659 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_stub_properties(OUTPUT_STREAM) ;
#line 37 "inform7/Chapter 21/Properties of Values.w"
property_of_value_storage * Properties__ValueImplementation__get_storage(void) ;
#line 45 "inform7/Chapter 21/Properties of Values.w"
void Properties__ValueImplementation__pp_set_table_storage(int t, int i) ;
#line 69 "inform7/Chapter 21/Properties of Values.w"
void Properties__ValueImplementation__compile_properties(OUTPUT_STREAM, kind *K) ;
#line 156 "inform7/Chapter 21/Properties of Values.w"
int Properties__ValueImplementation__kind_has_a_vph(kind *K) ;
#line 182 "inform7/Chapter 21/Properties of Values.w"
int Properties__ValueImplementation__kind_no_permitted_properties(OUTPUT_STREAM, int count_only, kind *K) ;
#line 137 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__begin(void) ;
#line 144 "inform7/Chapter 22/Inference Subjects.w"
inference_subject * InferenceSubjects__new_fundamental(inference_subject *from, char *lname) ;
#line 154 "inform7/Chapter 22/Inference Subjects.w"
inference_subject * InferenceSubjects__new(inference_subject *from, int KOI, general_pointer gp, int cert) ;
#line 165 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__infs_initialise(inference_subject *infs, general_pointer gp, int KOI, int cert, inference_subject *from, char *lname) ;
#line 194 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__renew(inference_subject *infs, inference_subject *from, int KOI, general_pointer gp, int cert) ;
#line 204 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__alias_to_nonlocal_variable(inference_subject *infs, nonlocal_variable *q) ;
#line 208 "inform7/Chapter 22/Inference Subjects.w"
int InferenceSubjects__aliased_but_diverted(inference_subject *infs) ;
#line 228 "inform7/Chapter 22/Inference Subjects.w"
int InferenceSubjects__is_within(inference_subject *smaller, inference_subject *larger) ;
#line 236 "inform7/Chapter 22/Inference Subjects.w"
int InferenceSubjects__is_strictly_within(inference_subject *subj, inference_subject *larger) ;
#line 245 "inform7/Chapter 22/Inference Subjects.w"
inference_subject * InferenceSubjects__narrowest_broader_subject(inference_subject *narrow) ;
#line 256 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__falls_within(inference_subject *narrow, inference_subject *broad) ;
#line 266 "inform7/Chapter 22/Inference Subjects.w"
parse_node * InferenceSubjects__where_created(inference_subject *infs) ;
#line 271 "inform7/Chapter 22/Inference Subjects.w"
int InferenceSubjects__get_default_certainty(inference_subject *infs) ;
#line 275 "inform7/Chapter 22/Inference Subjects.w"
assemblies_data * InferenceSubjects__get_assemblies_data(inference_subject *infs) ;
#line 280 "inform7/Chapter 22/Inference Subjects.w"
inference * InferenceSubjects__get_inferences(inference_subject *infs) ;
#line 284 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__set_inferences(inference_subject *infs, inference *inf) ;
#line 289 "inform7/Chapter 22/Inference Subjects.w"
implication * InferenceSubjects__get_implications(inference_subject *infs) ;
#line 293 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__set_implications(inference_subject *infs, implication *imp) ;
#line 297 "inform7/Chapter 22/Inference Subjects.w"
property_permission ** InferenceSubjects__get_permissions(inference_subject *infs) ;
#line 306 "inform7/Chapter 22/Inference Subjects.w"
inference_subject * InferenceSubjects__from_specification(parse_node *spec) ;
#line 332 "inform7/Chapter 22/Inference Subjects.w"
parse_node * InferenceSubjects__as_constant(inference_subject *infs) ;
#line 348 "inform7/Chapter 22/Inference Subjects.w"
instance * InferenceSubjects__as_instance(inference_subject *infs) ;
#line 356 "inform7/Chapter 22/Inference Subjects.w"
instance * InferenceSubjects__as_object_instance(inference_subject *infs) ;
#line 365 "inform7/Chapter 22/Inference Subjects.w"
kind * InferenceSubjects__as_nonobject_kind(inference_subject *infs) ;
#line 375 "inform7/Chapter 22/Inference Subjects.w"
kind * InferenceSubjects__as_kind(inference_subject *infs) ;
#line 384 "inform7/Chapter 22/Inference Subjects.w"
nonlocal_variable * InferenceSubjects__as_nlv(inference_subject *infs) ;
#line 390 "inform7/Chapter 22/Inference Subjects.w"
binary_predicate * InferenceSubjects__as_bp(inference_subject *infs) ;
#line 396 "inform7/Chapter 22/Inference Subjects.w"
instance * InferenceSubjects__as_nc(inference_subject *infs) ;
#line 405 "inform7/Chapter 22/Inference Subjects.w"
int InferenceSubjects__is_an_object(inference_subject *infs) ;
#line 409 "inform7/Chapter 22/Inference Subjects.w"
int InferenceSubjects__is_a_kind_of_object(inference_subject *infs) ;
#line 423 "inform7/Chapter 22/Inference Subjects.w"
kind * InferenceSubjects__domain(inference_subject *infs) ;
#line 430 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__log(inference_subject *infs) ;
#line 446 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__log_knowledge_about(inference_subject *infs) ;
#line 459 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__log_infs_hierarchy(void) ;
#line 464 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__log_subjects_hierarchically(inference_subject *infs, int count) ;
#line 481 "inform7/Chapter 22/Inference Subjects.w"
wording InferenceSubjects__get_name_text(inference_subject *infs) ;
#line 505 "inform7/Chapter 22/Inference Subjects.w"
general_pointer InferenceSubjects__new_permission_granted(inference_subject *infs) ;
#line 523 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__make_adj_const_domain(inference_subject *infs, instance *nc, property *prn) ;
#line 540 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__complete_model(inference_subject *infs) ;
#line 555 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__check_model(inference_subject *infs) ;
#line 575 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__write_element_of_condition(inference_subject *infs, char *cond) ;
#line 597 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__compile_all(OUTPUT_STREAM) ;
#line 114 "inform7/Chapter 22/Property Permissions.w"
property_permission * World__Permissions__find(inference_subject *infs, property *prn, int allow_inheritance) ;
#line 141 "inform7/Chapter 22/Property Permissions.w"
property_permission * World__Permissions__grant(inference_subject *infs, property *prn, int allow_inheritance) ;
#line 199 "inform7/Chapter 22/Property Permissions.w"
property * World__Permissions__get_property(property_permission *pp) ;
#line 203 "inform7/Chapter 22/Property Permissions.w"
inference_subject * World__Permissions__get_subject(property_permission *pp) ;
#line 207 "inform7/Chapter 22/Property Permissions.w"
general_pointer World__Permissions__get_storage_data(property_permission *pp) ;
#line 211 "inform7/Chapter 22/Property Permissions.w"
parse_node * World__Permissions__where_granted(property_permission *pp) ;
#line 219 "inform7/Chapter 22/Property Permissions.w"
void World__Permissions__index(property *prn) ;
#line 99 "inform7/Chapter 22/Inferences.w"
inference * World__Inferences__create_inference(int type, int certitude) ;
#line 120 "inform7/Chapter 22/Inferences.w"
inference * World__Inferences__create_property_inference(inference_subject *infs, property *prn, parse_node *val) ;
#line 132 "inform7/Chapter 22/Inferences.w"
inference * World__Inferences__create_relation_inference(inference_subject *infs0, inference_subject *infs1) ;
#line 140 "inform7/Chapter 22/Inferences.w"
inference * World__Inferences__create_relation_inference_spec(parse_node *spec0, parse_node *spec1) ;
#line 158 "inform7/Chapter 22/Inferences.w"
void World__Inferences__draw_property(inference_subject *infs, property *prn, parse_node *val) ;
#line 164 "inform7/Chapter 22/Inferences.w"
void World__Inferences__draw_negated_property(inference_subject *infs, property *prn, parse_node *val) ;
#line 171 "inform7/Chapter 22/Inferences.w"
void World__Inferences__draw_relation(binary_predicate *bp, inference_subject *infs0, inference_subject *infs1) ;
#line 177 "inform7/Chapter 22/Inferences.w"
void World__Inferences__draw_relation_spec(binary_predicate *bp, parse_node *spec0, parse_node *spec1) ;
#line 187 "inform7/Chapter 22/Inferences.w"
void World__Inferences__draw(int type, inference_subject *about, int certitude, inference_subject *infs0, inference_subject *infs1) ;
#line 199 "inform7/Chapter 22/Inferences.w"
int World__Inferences__get_timestamp(inference *i) ;
#line 203 "inform7/Chapter 22/Inferences.w"
int World__Inferences__get_inference_type(inference *i) ;
#line 207 "inform7/Chapter 22/Inferences.w"
parse_node * World__Inferences__where_inferred(inference *i) ;
#line 211 "inform7/Chapter 22/Inferences.w"
int World__Inferences__get_certainty(inference *i) ;
#line 215 "inform7/Chapter 22/Inferences.w"
void World__Inferences__set_certainty(inference *i, int ce) ;
#line 219 "inform7/Chapter 22/Inferences.w"
int World__Inferences__added_in_construction(inference *i) ;
#line 223 "inform7/Chapter 22/Inferences.w"
property * World__Inferences__get_property(inference *i) ;
#line 227 "inform7/Chapter 22/Inferences.w"
parse_node * World__Inferences__get_property_value(inference *i) ;
#line 231 "inform7/Chapter 22/Inferences.w"
parse_node * World__Inferences__set_property_value_kind(inference *i, kind *K) ;
#line 241 "inform7/Chapter 22/Inferences.w"
void World__Inferences__get_references(inference *i, inference_subject **infs1, inference_subject **infs2) ;
#line 246 "inform7/Chapter 22/Inferences.w"
void World__Inferences__get_references_spec(inference *i, parse_node **spec1, parse_node **spec2) ;
#line 251 "inform7/Chapter 22/Inferences.w"
instance * World__Inferences__get_reference_as_object(inference *i) ;
#line 271 "inform7/Chapter 22/Inferences.w"
int World__Inferences__get_EO_state(inference_subject *infs, property *prn) ;
#line 290 "inform7/Chapter 22/Inferences.w"
int World__Inferences__get_EO_state_without_inheritance(inference_subject *infs, property *prn, parse_node **where) ;
#line 312 "inform7/Chapter 22/Inferences.w"
void World__Inferences__verify_prop_states(inference_subject *infs) ;
#line 336 "inform7/Chapter 22/Inferences.w"
parse_node * World__Inferences__get_prop_state(inference_subject *infs, property *prn) ;
#line 349 "inform7/Chapter 22/Inferences.w"
parse_node * World__Inferences__get_prop_state_at(inference_subject *infs, property *prn, parse_node **where) ;
#line 366 "inform7/Chapter 22/Inferences.w"
parse_node * World__Inferences__get_prop_state_without_inheritance(inference_subject *infs, property *prn, parse_node **where) ;
#line 385 "inform7/Chapter 22/Inferences.w"
void World__Inferences__index(inference_subject *infs, int brief) ;
#line 417 "inform7/Chapter 22/Inferences.w"
int World__Inferences__has_or_can_have(inference_subject *infs, property *prn) ;
#line 432 "inform7/Chapter 22/Inferences.w"
void World__Inferences__index_provided(inference_subject *infs, int bool, int c, char *cert, int brief) ;
#line 472 "inform7/Chapter 22/Inferences.w"
void World__Inferences__index_specific(inference_subject *infs) ;
#line 547 "inform7/Chapter 22/Inferences.w"
int World__Inferences__compare_inferences(inference *i1, inference *i2) ;
#line 583 "inform7/Chapter 22/Inferences.w"
void World__Inferences__diversion_on(void) ;
#line 586 "inform7/Chapter 22/Inferences.w"
void World__Inferences__diversion_off(void) ;
#line 590 "inform7/Chapter 22/Inferences.w"
inference_subject * World__Inferences__divert_infs(inference_subject *infs) ;
#line 612 "inform7/Chapter 22/Inferences.w"
void World__Inferences__join_inference(inference *i, inference_subject *infs) ;
#line 824 "inform7/Chapter 22/Inferences.w"
void World__Inferences__report_inference(inference *i, inference_subject *infs, char *what_happened) ;
#line 831 "inform7/Chapter 22/Inferences.w"
void World__Inferences__log_kind(int it) ;
#line 839 "inform7/Chapter 22/Inferences.w"
void World__Inferences__log(inference *in) ;
#line 54 "inform7/Chapter 22/Complete Model World.w"
void World__complete(void) ;
#line 210 "inform7/Chapter 22/Complete Model World.w"
void World__complete_additions(void) ;
#line 18 "inform7/Chapter 22/Compile Model World.w"
void World__Compile__set_rough_memory_usage(kind *K, int words_used) ;
#line 25 "inform7/Chapter 22/Compile Model World.w"
int World__Compile__get_rough_memory_usage(kind *K) ;
#line 36 "inform7/Chapter 22/Compile Model World.w"
void World__Compile__compile(OUTPUT_STREAM) ;
#line 94 "inform7/Chapter 23/Text Literals.w"
void Strings__TextLiterals__suppress_quote_expansion(wording W) ;
#line 102 "inform7/Chapter 23/Text Literals.w"
literal_text * Strings__TextLiterals__lt_new(int w1, int colour) ;
#line 121 "inform7/Chapter 23/Text Literals.w"
int Strings__TextLiterals__lt_cmp(int w1, literal_text *lt) ;
#line 130 "inform7/Chapter 23/Text Literals.w"
void Strings__TextLiterals__mark_as_unescaped(literal_text *lt) ;
#line 137 "inform7/Chapter 23/Text Literals.w"
literal_text * Strings__TextLiterals__compile_literal(OUTPUT_STREAM, wording W) ;
#line 223 "inform7/Chapter 23/Text Literals.w"
literal_text * Strings__TextLiterals__rotate(int w1, literal_text *y) ;
#line 247 "inform7/Chapter 23/Text Literals.w"
void Strings__TextLiterals__compile_quotation(OUTPUT_STREAM, wording W) ;
#line 261 "inform7/Chapter 23/Text Literals.w"
literal_text * Strings__TextLiterals__compile_literal_from_text(OUTPUT_STREAM, char *p) ;
#line 273 "inform7/Chapter 23/Text Literals.w"
void Strings__TextLiterals__compile(OUTPUT_STREAM) ;
#line 277 "inform7/Chapter 23/Text Literals.w"
void Strings__TextLiterals__traverse_lts(OUTPUT_STREAM, literal_text *lt) ;
#line 323 "inform7/Chapter 23/Text Literals.w"
void Strings__TextLiterals__compile_small_block(OUTPUT_STREAM, literal_text *lt) ;
#line 329 "inform7/Chapter 23/Text Literals.w"
literal_text * Strings__TextLiterals__compile_literal_sb(OUTPUT_STREAM, wording W) ;
#line 66 "inform7/Chapter 23/Text Substitutions.w"
text_substitution * Strings__TextSubstitutions__new_text_substitution(wording W, ph_stack_frame *phsf, rule *R, int marker) ;
#line 110 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__allow_no_further_text_subs(void) ;
#line 118 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__text_substitution_name(OUTPUT_STREAM, text_substitution *ts) ;
#line 132 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__text_substitution_cue(OUTPUT_STREAM, wording W) ;
#line 174 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__append_text_substitution_proviso(void) ;
#line 207 "inform7/Chapter 23/Text Substitutions.w"
int Strings__TextSubstitutions__compilation_coroutine(OUTPUT_STREAM, int in_response_mode) ;
#line 236 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__compile_single_substitution(OUTPUT_STREAM, text_substitution *ts) ;
#line 297 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__compile_text_routines_in_response_mode(OUTPUT_STREAM) ;
#line 34 "inform7/Chapter 23/Responses.w"
void Strings__response_launcher_name(OUTPUT_STREAM, response_message *resp) ;
#line 42 "inform7/Chapter 23/Responses.w"
void Strings__compile_response_constant(OUTPUT_STREAM, rule *R, int marker) ;
#line 65 "inform7/Chapter 23/Responses.w"
response_message * Strings__response_cue(OUTPUT_STREAM, rule *owner, int marker, wording W, ph_stack_frame *phsf, int via_I6) ;
#line 85 "inform7/Chapter 23/Responses.w"
void Strings__compile_response_launchers(OUTPUT_STREAM) ;
#line 165 "inform7/Chapter 23/Responses.w"
void Strings__compile_responses(OUTPUT_STREAM) ;
#line 304 "inform7/Chapter 23/Responses.w"
ph_stack_frame * Strings__frame_for_response(response_message *resp) ;
#line 313 "inform7/Chapter 23/Responses.w"
void Strings__assert_response_value(rule *R, int marker, wording W) ;
#line 321 "inform7/Chapter 23/Responses.w"
void Strings__index_response(rule *R, int marker, response_message *resp) ;
#line 345 "inform7/Chapter 23/Responses.w"
int Strings__get_marker_from_response_spec(parse_node *rs) ;
#line 368 "inform7/Chapter 23/Responses.w"
void Strings__compile_general(OUTPUT_STREAM, parse_node *str) ;
#line 76 "inform7/Chapter 24/List Constants.w"
literal_list * Lists__empty_literal_list(wording W) ;
#line 99 "inform7/Chapter 24/List Constants.w"
literal_list * Lists__find_list_at(int incipit) ;
#line 112 "inform7/Chapter 24/List Constants.w"
literal_list * Lists__add_to_ll(parse_node *spec, literal_list *ll, wording W, int bad) ;
#line 131 "inform7/Chapter 24/List Constants.w"
kind * Lists__kind_of_ll(literal_list *ll, int issue_problems) ;
#line 240 "inform7/Chapter 24/List Constants.w"
kind * Lists__kind_of_list_at(wording W) ;
#line 247 "inform7/Chapter 24/List Constants.w"
void Lists__check_one(wording W) ;
#line 256 "inform7/Chapter 24/List Constants.w"
void Lists__check(OUTPUT_STREAM) ;
#line 269 "inform7/Chapter 24/List Constants.w"
void Lists__compile_literal_list(OUTPUT_STREAM, wording W) ;
#line 283 "inform7/Chapter 24/List Constants.w"
void Lists__compile(OUTPUT_STREAM) ;
#line 329 "inform7/Chapter 24/List Constants.w"
void Lists__compile_default_list(OUTPUT_STREAM, char *identifier, kind *K) ;
#line 64 "inform7/Chapter 25/Table Columns.w"
table_column * Tables__Columns__new_table_column(wording W) ;
#line 84 "inform7/Chapter 25/Table Columns.w"
void Tables__Columns__log(table_column *tc) ;
#line 102 "inform7/Chapter 25/Table Columns.w"
kind * Tables__Columns__get_kind(table_column *tc) ;
#line 106 "inform7/Chapter 25/Table Columns.w"
kind * Tables__Columns__to_kind(table_column *tc) ;
#line 110 "inform7/Chapter 25/Table Columns.w"
void Tables__Columns__set_kind(table_column *tc, table *t, kind *K) ;
#line 137 "inform7/Chapter 25/Table Columns.w"
binary_predicate * Tables__Columns__get_listed_in_predicate(table_column *tc) ;
#line 149 "inform7/Chapter 25/Table Columns.w"
int Tables__Columns__get_id(table_column *tc) ;
#line 153 "inform7/Chapter 25/Table Columns.w"
void Tables__Columns__compile_run_time_support(OUTPUT_STREAM) ;
#line 178 "inform7/Chapter 25/Table Columns.w"
table_column_usage Tables__Columns__add_to_table(wording W, table *t) ;
#line 276 "inform7/Chapter 25/Table Columns.w"
table_column * Tables__Columns__find_table_column(wording W, table *t, wording *EXPW) ;
#line 323 "inform7/Chapter 25/Table Columns.w"
void Tables__Columns__check_explicit_headings(table *t, int i, table_column_usage *tcu) ;
#line 368 "inform7/Chapter 25/Table Columns.w"
void Tables__Columns__note_kind(table *t, int i, table_column_usage *tcu, parse_node *cell, kind *K, int generic) ;
#line 517 "inform7/Chapter 25/Table Columns.w"
void Tables__Columns__approve_kind(table *t, int i, table_column_usage *tcu) ;
#line 85 "inform7/Chapter 25/Tables.w"
void Tables__traverse_to_create(void) ;
#line 88 "inform7/Chapter 25/Tables.w"
void Tables__visit_to_create(parse_node *p) ;
#line 100 "inform7/Chapter 25/Tables.w"
void Tables__traverse_to_stock(void) ;
#line 116 "inform7/Chapter 25/Tables.w"
void Tables__check_tables_for_kind_clashes(void) ;
#line 138 "inform7/Chapter 25/Tables.w"
table * Tables__new_table_structure(void) ;
#line 166 "inform7/Chapter 25/Tables.w"
void Tables__add_table_contribution(table *t, parse_node *src) ;
#line 178 "inform7/Chapter 25/Tables.w"
void Tables__log(table *t) ;
#line 185 "inform7/Chapter 25/Tables.w"
int Tables__get_no_columns(table *t) ;
#line 189 "inform7/Chapter 25/Tables.w"
int Tables__get_no_rows(table *t) ;
#line 199 "inform7/Chapter 25/Tables.w"
int Tables__expand_block_constants(table *t) ;
#line 205 "inform7/Chapter 25/Tables.w"
kind * Tables__kind_of_ith_column(table *t, int i) ;
#line 214 "inform7/Chapter 25/Tables.w"
char * Tables__identifier(table *t) ;
#line 218 "inform7/Chapter 25/Tables.w"
parse_node * Tables__get_headline(table *t) ;
#line 306 "inform7/Chapter 25/Tables.w"
void Tables__create_table(parse_node *PN) ;
#line 804 "inform7/Chapter 25/Tables.w"
void Tables__stock_table(table *t, int phase) ;
#line 982 "inform7/Chapter 25/Tables.w"
void Tables__stock_table_cell(table *t, parse_node *cell, int row_count, int col_count) ;
#line 1060 "inform7/Chapter 25/Tables.w"
void Tables__complete(void) ;
#line 1137 "inform7/Chapter 25/Tables.w"
void Tables__amend_table(table *main_table, table *amendments) ;
#line 1313 "inform7/Chapter 25/Tables.w"
void Tables__splice_table_row(table *table_to, table *table_from, int row_to, int row_from) ;
#line 1337 "inform7/Chapter 25/Tables.w"
void Tables__index(void) ;
#line 1354 "inform7/Chapter 25/Tables.w"
int Tables__index_tables_in(extension_file *ef, int efc) ;
#line 1453 "inform7/Chapter 25/Tables.w"
int Tables__table_within(table *t, extension_file *ef) ;
#line 16 "inform7/Chapter 25/Runtime Support for Tables.w"
void Tables__Support__compile(OUTPUT_STREAM) ;
#line 293 "inform7/Chapter 25/Runtime Support for Tables.w"
void Tables__Support__compile_print_table_names(OUTPUT_STREAM) ;
#line 323 "inform7/Chapter 25/Runtime Support for Tables.w"
void Tables__Support__compile_max_score(OUTPUT_STREAM) ;
#line 102 "inform7/Chapter 25/Tables of Definitions.w"
void Tables__Defining__kind_defined_by_table(parse_node *pn) ;
#line 12 "inform7/Chapter 25/Listed-In Relations.w"
void Tables__Relations__REL_create_initial_stock(void) ;
#line 28 "inform7/Chapter 25/Listed-In Relations.w"
binary_predicate * Tables__Relations__make_listed_in_predicate(table_column *tc) ;
#line 48 "inform7/Chapter 25/Listed-In Relations.w"
void Tables__Relations__supply_kind_for_listed_in_tc(binary_predicate *bp, kind *K) ;
#line 57 "inform7/Chapter 25/Listed-In Relations.w"
void Tables__Relations__REL_create_second_stock(void) ;
#line 63 "inform7/Chapter 25/Listed-In Relations.w"
int Tables__Relations__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 72 "inform7/Chapter 25/Listed-In Relations.w"
int Tables__Relations__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 84 "inform7/Chapter 25/Listed-In Relations.w"
int Tables__Relations__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 92 "inform7/Chapter 25/Listed-In Relations.w"
int Tables__Relations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 134 "inform7/Chapter 26/Equations.w"
void Equations__traverse_to_create(void) ;
#line 137 "inform7/Chapter 26/Equations.w"
void Equations__visit_to_create(parse_node *p) ;
#line 161 "inform7/Chapter 26/Equations.w"
equation * Equations__new(wording W, int anonymous) ;
#line 281 "inform7/Chapter 26/Equations.w"
void Equations__set_wherewithal(equation *eqn, wording W) ;
#line 290 "inform7/Chapter 26/Equations.w"
void Equations__traverse_to_stock(void) ;
#line 305 "inform7/Chapter 26/Equations.w"
void Equations__examine(equation *eqn) ;
#line 332 "inform7/Chapter 26/Equations.w"
int Equations__eqn_declare_symbols(equation *eqn) ;
#line 463 "inform7/Chapter 26/Equations.w"
int Equations__eqn_declare_variables_inner(equation *eqn, wording W, int temp) ;
#line 472 "inform7/Chapter 26/Equations.w"
int Equations__eqn_dec_var(equation *eqn, wording W, int X, void *XP) ;
#line 550 "inform7/Chapter 26/Equations.w"
void Equations__eqn_remove_temp_variables(equation *eqn) ;
#line 571 "inform7/Chapter 26/Equations.w"
void Equations__declare_local_variables(equation *eqn) ;
#line 576 "inform7/Chapter 26/Equations.w"
void Equations__declare_local(equation *eqn, wording W, kind *K) ;
#line 585 "inform7/Chapter 26/Equations.w"
void Equations__eqn_declare_standard_symbols(void) ;
#line 610 "inform7/Chapter 26/Equations.w"
equation_symbol * Equations__eqn_add_symbol(equation *eqn, wording W, kind *K, parse_node *spec) ;
#line 647 "inform7/Chapter 26/Equations.w"
int Equations__equation_symbol_legal(wording W) ;
#line 669 "inform7/Chapter 26/Equations.w"
equation_node * Equations__enode_new(int t) ;
#line 689 "inform7/Chapter 26/Equations.w"
equation_node * Equations__enode_new_op(int op) ;
#line 695 "inform7/Chapter 26/Equations.w"
equation_node * Equations__enode_new_symbol(equation_symbol *ev) ;
#line 701 "inform7/Chapter 26/Equations.w"
equation_node * Equations__enode_new_constant(parse_node *spec) ;
#line 711 "inform7/Chapter 26/Equations.w"
void Equations__log_equation_node(equation_node *tok) ;
#line 715 "inform7/Chapter 26/Equations.w"
void Equations__log_equation_node_inner(equation_node *tok, int d) ;
#line 763 "inform7/Chapter 26/Equations.w"
equation_node * Equations__eqn_parse(equation *eqn) ;
#line 959 "inform7/Chapter 26/Equations.w"
int Equations__multiplication_is_implied(equation_node *previous_token, equation_node *token) ;
#line 972 "inform7/Chapter 26/Equations.w"
int Equations__application_is_implied(equation_node *previous_token, equation_node *token) ;
#line 1005 "inform7/Chapter 26/Equations.w"
void Equations__log_sr_stacks(void) ;
#line 1020 "inform7/Chapter 26/Equations.w"
void Equations__enode_sr_start(void) ;
#line 1030 "inform7/Chapter 26/Equations.w"
equation_node * Equations__enode_sr_result(void) ;
#line 1054 "inform7/Chapter 26/Equations.w"
int Equations__enode_sr_token(equation *eqn, equation_node *tok) ;
#line 1106 "inform7/Chapter 26/Equations.w"
int Equations__enode_emit(equation_node *tok) ;
#line 1146 "inform7/Chapter 26/Equations.w"
int Equations__enode_lt(equation_node *tok1, equation_node *tok2) ;
#line 1151 "inform7/Chapter 26/Equations.w"
int Equations__enode_eq(equation_node *tok1, equation_node *tok2) ;
#line 1156 "inform7/Chapter 26/Equations.w"
int Equations__enode_gt(equation_node *tok1, equation_node *tok2) ;
#line 1173 "inform7/Chapter 26/Equations.w"
int Equations__f_function(equation_node *tok) ;
#line 1197 "inform7/Chapter 26/Equations.w"
int Equations__g_function(equation_node *tok) ;
#line 1224 "inform7/Chapter 26/Equations.w"
int Equations__eqn_typecheck(equation *eqn) ;
#line 1254 "inform7/Chapter 26/Equations.w"
int Equations__enode_count_equals(equation_node *tok) ;
#line 1264 "inform7/Chapter 26/Equations.w"
int Equations__enode_is_equals(equation_node *tok) ;
#line 1279 "inform7/Chapter 26/Equations.w"
int Equations__enode_typecheck(equation *eqn, equation_node *tok) ;
#line 1550 "inform7/Chapter 26/Equations.w"
void Equations__promote_subequation(equation *eqn, equation_node *tok, int deeply) ;
#line 1560 "inform7/Chapter 26/Equations.w"
void Equations__demote_subequation(equation *eqn, equation_node *tok) ;
#line 1571 "inform7/Chapter 26/Equations.w"
void Equations__compile(OUTPUT_STREAM) ;
#line 1583 "inform7/Chapter 26/Equations.w"
char * Equations__identifier(equation *eqn) ;
#line 1594 "inform7/Chapter 26/Equations.w"
void Equations__set_usage_notes(equation *eqn, wording W) ;
#line 1603 "inform7/Chapter 26/Equations.w"
void Equations__compile_solution(OUTPUT_STREAM, wording W, equation *eqn) ;
#line 1616 "inform7/Chapter 26/Equations.w"
void Equations__compile_solution_inner(OUTPUT_STREAM, wording W, equation *eqn) ;
#line 1769 "inform7/Chapter 26/Equations.w"
void Equations__enode_compile(OUTPUT_STREAM, equation *eqn, equation_node *tok) ;
#line 1824 "inform7/Chapter 26/Equations.w"
void Equations__enode_compilation_error(equation *eqn, equation_node *tok) ;
#line 1852 "inform7/Chapter 26/Equations.w"
int Equations__eqn_rearrange(equation *eqn, equation_symbol *to_solve) ;
#line 2121 "inform7/Chapter 26/Equations.w"
int Equations__enode_count_var(equation_node *tok, equation_symbol *to_solve) ;
#line 2136 "inform7/Chapter 26/Equations.w"
void Equations__internal_test(wording E) ;
#line 2163 "inform7/Chapter 26/Equations.w"
void Equations__log(equation *eqn) ;
#line 2167 "inform7/Chapter 26/Equations.w"
void Equations__log_equation_parsed(equation *eqn) ;
#line 2172 "inform7/Chapter 26/Equations.w"
void Equations__index(void) ;
#line 110 "inform7/Chapter 27/Rules.w"
rule * Rules__new(wording W, int named) ;
#line 148 "inform7/Chapter 27/Rules.w"
rule * Rules__by_name(wording W) ;
#line 167 "inform7/Chapter 27/Rules.w"
int Rules__vet_name(wording W) ;
#line 187 "inform7/Chapter 27/Rules.w"
kind * Rules__to_kind(rule *R) ;
#line 198 "inform7/Chapter 27/Rules.w"
void Rules__set_I7_definition(rule *R, phrase *ph) ;
#line 202 "inform7/Chapter 27/Rules.w"
void Rules__set_I6_definition(rule *R, char *identifier) ;
#line 206 "inform7/Chapter 27/Rules.w"
char * Rules__get_I6_definition(rule *R) ;
#line 210 "inform7/Chapter 27/Rules.w"
phrase * Rules__get_I7_definition(rule *R) ;
#line 218 "inform7/Chapter 27/Rules.w"
void Rules__impose_constraint(rule *S, rule *R, wording W, int sense) ;
#line 248 "inform7/Chapter 27/Rules.w"
void Rules__compile_constraint(OUTPUT_STREAM, applicability_condition *acl) ;
#line 294 "inform7/Chapter 27/Rules.w"
void Rules__log(rule *R) ;
#line 309 "inform7/Chapter 27/Rules.w"
int Rules__compare_specificity(rule *R1, rule *R2, int dflag) ;
#line 333 "inform7/Chapter 27/Rules.w"
int Rules__eq(rule *R1, rule *R2) ;
#line 353 "inform7/Chapter 27/Rules.w"
void Rules__set_kind_from(rule *R, rulebook *RB) ;
#line 385 "inform7/Chapter 27/Rules.w"
void Rules__acquire_stvol(rule *R, stacked_variable_owner_list *stvol) ;
#line 390 "inform7/Chapter 27/Rules.w"
void Rules__acquire_action_variables(rule *R) ;
#line 414 "inform7/Chapter 27/Rules.w"
void Rules__request_automatic_placement(rule *R) ;
#line 426 "inform7/Chapter 27/Rules.w"
void Rules__check_placement_safety(void) ;
#line 469 "inform7/Chapter 27/Rules.w"
void Rules__compile(OUTPUT_STREAM, rule *R) ;
#line 483 "inform7/Chapter 27/Rules.w"
void Rules__compile_rule_printing_switch(OUTPUT_STREAM) ;
#line 513 "inform7/Chapter 27/Rules.w"
void Rules__compile_comment(OUTPUT_STREAM, rule *R, int index, int from) ;
#line 527 "inform7/Chapter 27/Rules.w"
void Rules__compile_definition(OUTPUT_STREAM, rule *R, int *i, int max_i) ;
#line 564 "inform7/Chapter 27/Rules.w"
void Rules__set_italicised_index_text(rule *R, wording W) ;
#line 574 "inform7/Chapter 27/Rules.w"
void Rules__set_numbered_rules(void) ;
#line 581 "inform7/Chapter 27/Rules.w"
int Rules__index(rule *R, rulebook *owner, scene *during_scene) ;
#line 705 "inform7/Chapter 27/Rules.w"
void Rules__set_always_test_actor(rule *R) ;
#line 712 "inform7/Chapter 27/Rules.w"
void Rules__set_never_test_actor(rule *R) ;
#line 719 "inform7/Chapter 27/Rules.w"
void Rules__set_marked_for_anyone(rule *R, int to) ;
#line 726 "inform7/Chapter 27/Rules.w"
void Rules__suppress_action_testing(rule *R) ;
#line 733 "inform7/Chapter 27/Rules.w"
void Rules__copy_actor_test_flags(rule *R_to, rule *R_from) ;
#line 751 "inform7/Chapter 27/Rules.w"
int Rules__rule_is_named(rule *R) ;
#line 756 "inform7/Chapter 27/Rules.w"
response_message * Rules__rule_defines_response(rule *R, int code) ;
#line 762 "inform7/Chapter 27/Rules.w"
void Rules__check_response_usages(void) ;
#line 793 "inform7/Chapter 27/Rules.w"
void Rules__now_rule_defines_response(rule *R, int code, response_message *resp) ;
#line 798 "inform7/Chapter 27/Rules.w"
void Rules__now_rule_needs_response(rule *R, int code, wording W) ;
#line 804 "inform7/Chapter 27/Rules.w"
wording Rules__get_response_value(rule *R, int code) ;
#line 809 "inform7/Chapter 27/Rules.w"
parse_node * Rules__get_response_sentence(rule *R, int code) ;
#line 814 "inform7/Chapter 27/Rules.w"
ph_stack_frame * Rules__stack_frame(rule *R) ;
#line 51 "inform7/Chapter 27/Rule Bookings.w"
booking * Rules__Bookings__new(rule *R) ;
#line 68 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__log(booking *br) ;
#line 83 "inform7/Chapter 27/Rule Bookings.w"
rule * Rules__Bookings__get_rule(booking *br) ;
#line 103 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__request_automatic_placement(booking *br) ;
#line 113 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__make_automatic_placements(void) ;
#line 133 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__place(ph_usage_data *phud, booking *br) ;
#line 211 "inform7/Chapter 27/Rule Bookings.w"
int Rules__Bookings__compare_specificity_of_br(booking *br1, booking *br2, int log) ;
#line 246 "inform7/Chapter 27/Rule Bookings.w"
booking * Rules__Bookings__list_new(void) ;
#line 304 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_add(booking *list_head, booking *new_rule, int placing, int side, rule *ref_rule) ;
#line 471 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_remove(booking *list_head, rule *ref_rule) ;
#line 484 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_log(booking *list_head) ;
#line 498 "inform7/Chapter 27/Rule Bookings.w"
int Rules__Bookings__no_rules_in_list(booking *list_head) ;
#line 507 "inform7/Chapter 27/Rule Bookings.w"
int Rules__Bookings__list_is_empty(booking *list_head, scene *S) ;
#line 520 "inform7/Chapter 27/Rule Bookings.w"
int Rules__Bookings__list_is_empty_of_i7_rules(booking *list_head) ;
#line 529 "inform7/Chapter 27/Rule Bookings.w"
int Rules__Bookings__list_contains(booking *list_head, rule *to_find) ;
#line 538 "inform7/Chapter 27/Rule Bookings.w"
int Rules__Bookings__list_contains_ph(booking *list_head, phrase *ph_to_find) ;
#line 553 "inform7/Chapter 27/Rule Bookings.w"
int Rules__Bookings__list_index(booking *list_head, scene *context, action_name *action_context, char *billing, rulebook *owner, int *resp_count) ;
#line 582 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_suppress_indexed_links(void) ;
#line 586 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_resume_indexed_links(void) ;
#line 590 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__br_start_index_line(booking *prev, char *billing) ;
#line 601 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__br_show_linkage_icon(booking *prev) ;
#line 623 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_judge_ordering(booking *list_head) ;
#line 719 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_compile_rule_phrases(booking *list_head, OUTPUT_STREAM, int *i, int max_i) ;
#line 756 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__start_list_compilation(OUTPUT_STREAM) ;
#line 776 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_compile(booking *list_head, OUTPUT_STREAM, char *identifier, int action_based, int parameter_based) ;
#line 930 "inform7/Chapter 27/Rule Bookings.w"
action_name * Rules__Bookings__br_required_action(booking *br) ;
#line 222 "inform7/Chapter 27/Rulebooks.w"
rulebook * Rulebooks__new(kind *create_as, wording W) ;
#line 276 "inform7/Chapter 27/Rulebooks.w"
outcomes * Rulebooks__get_outcomes(rulebook *rb) ;
#line 280 "inform7/Chapter 27/Rulebooks.w"
kind * Rulebooks__contains_kind(rulebook *rb) ;
#line 286 "inform7/Chapter 27/Rulebooks.w"
kind * Rulebooks__to_kind(rulebook *rb) ;
#line 292 "inform7/Chapter 27/Rulebooks.w"
rulebook * Rulebooks__new_automatic(wording W, kind *basis, int oc, int ata, int ubfaa, int rda) ;
#line 305 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__set_alt_name(rulebook *rb, wording AW) ;
#line 311 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__fragment_by_actions(rulebook *rb, int wn) ;
#line 315 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__requires_specific_action(rulebook *rb) ;
#line 327 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__affected_by_placement(rulebook *rb, parse_node *where) ;
#line 334 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__rb_no_placements(rulebook *rb) ;
#line 341 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__rb_index_placements(rulebook *rb) ;
#line 356 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__focus(rulebook *rb) ;
#line 360 "inform7/Chapter 27/Rulebooks.w"
kind * Rulebooks__get_parameter_kind(rulebook *rb) ;
#line 364 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__used_by_future_actions(rulebook *rb) ;
#line 368 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__is_empty(rulebook *rb, scene *context) ;
#line 373 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__no_rules(rulebook *rb) ;
#line 378 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__rule_in_rulebook(rule *R, rulebook *rb) ;
#line 383 "inform7/Chapter 27/Rulebooks.w"
booking * Rulebooks__first_booking(rulebook *rb) ;
#line 388 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__runs_during_activities(rulebook *rb) ;
#line 418 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__add_variable(rulebook *rb, parse_node *cnode) ;
#line 498 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__make_stvs_accessible(rulebook *rb, stacked_variable_owner *stvo) ;
#line 502 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__rulebook_var_creators_array(OUTPUT_STREAM) ;
#line 519 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__rulebook_var_creators_lookup(OUTPUT_STREAM) ;
#line 535 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__log_name_only(rulebook *rb) ;
#line 539 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__log(rulebook *rb) ;
#line 545 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__index(rulebook *rb, char *billing, scene *context, action_name *action_context, int *resp_count) ;
#line 561 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__index_action_rules(action_name *an, rulebook *rb, int code, char *desc, int *resp_count) ;
#line 633 "inform7/Chapter 27/Rulebooks.w"
rulebook_match Rulebooks__rb_match_from_description(wording W) ;
#line 715 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__attach_rule(rulebook *rb, booking *the_new_rule, int placing, int side, rule *ref_rule) ;
#line 775 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__detach_rule(rulebook *rb, rule *the_new_rule) ;
#line 785 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__compile_rule_phrases(rulebook *rb, OUTPUT_STREAM, int *i, int max_i) ;
#line 798 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__rulebooks_array_array(OUTPUT_STREAM) ;
#line 806 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__procedurals_exist(void) ;
#line 810 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__compile_rulebooks(OUTPUT_STREAM) ;
#line 826 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__RulebookNames_array(OUTPUT_STREAM) ;
#line 866 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__parse_properties(rulebook *rb, wording W) ;
#line 871 "inform7/Chapter 27/Rulebooks.w"
kind * Rulebooks__kind_from_context(void) ;
#line 886 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__index_page(int n) ;
#line 1096 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__noteworthy_rulebooks(extension_file *ef) ;
#line 1114 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__index_scene(void) ;
#line 1120 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__index_rules_box(char *name, wording W, char *doc_link, rulebook *rb, activity *av, char *text, int indent, int hide_behind_plus) ;
#line 90 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__initialise_outcomes(outcomes *outs, kind *K, int def) ;
#line 97 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__set_default_outcome(outcomes *outs, int def) ;
#line 101 "inform7/Chapter 27/Focus and Outcome.w"
kind * Rulebooks__Outcomes__get_outcome_kind(outcomes *outs) ;
#line 242 "inform7/Chapter 27/Focus and Outcome.w"
named_rulebook_outcome * Rulebooks__Outcomes__rbno_by_name(wording W) ;
#line 255 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__compile_default_outcome(outcomes *outs, OUTPUT_STREAM) ;
#line 280 "inform7/Chapter 27/Focus and Outcome.w"
rulebook_outcome * Rulebooks__Outcomes__rbo_from_context(named_rulebook_outcome *rbno) ;
#line 297 "inform7/Chapter 27/Focus and Outcome.w"
rulebook * Rulebooks__Outcomes__allow_outcome(named_rulebook_outcome *rbno) ;
#line 316 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__compile_outcome(OUTPUT_STREAM, named_rulebook_outcome *rbno) ;
#line 351 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__index_outcomes(outcomes *outs, int suppress_outcome) ;
#line 384 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__RulebookOutcomePrintingRule_routine(OUTPUT_STREAM) ;
#line 401 "inform7/Chapter 27/Focus and Outcome.w"
char * Rulebooks__Outcomes__get_default_value(void) ;
#line 413 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__initialise_focus(focus *foc, kind *parameter_kind) ;
#line 435 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__modify_rule_to_suit_focus(focus *foc, rule *R) ;
#line 449 "inform7/Chapter 27/Focus and Outcome.w"
int Rulebooks__Outcomes__get_focus(focus *foc) ;
#line 453 "inform7/Chapter 27/Focus and Outcome.w"
kind * Rulebooks__Outcomes__get_focus_parameter_kind(focus *foc) ;
#line 457 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__set_focus_ata(focus *foc, int ata) ;
#line 17 "inform7/Chapter 27/Rule Placement Sentences.w"
void Rules__Placement__declare_I6_written_rule(wording W, parse_node *p2) ;
#line 83 "inform7/Chapter 27/Rule Placement Sentences.w"
void Rules__Placement__request_substitute(parse_node *p1, parse_node *p2, parse_node *p3, int sense) ;
#line 113 "inform7/Chapter 27/Rule Placement Sentences.w"
void Rules__Placement__constrain_effect(parse_node *p1, parse_node *p2, int sense) ;
#line 217 "inform7/Chapter 27/Rule Placement Sentences.w"
void Rules__Placement__manual_placement(int verb, parse_node *subj) ;
#line 249 "inform7/Chapter 27/Rule Placement Sentences.w"
void Rules__Placement__place_in_rulebook(parse_node *p1, parse_node *p2, int sense) ;
#line 55 "inform7/Chapter 27/Stacked Variables.w"
void StackedVariables__compile_lvalue_to_text(stacked_variable *stv, char *to) ;
#line 62 "inform7/Chapter 27/Stacked Variables.w"
void StackedVariables__compile_rvalue_to_text(stacked_variable *stv, char *to) ;
#line 69 "inform7/Chapter 27/Stacked Variables.w"
int StackedVariables__get_owner_id(stacked_variable *stv) ;
#line 73 "inform7/Chapter 27/Stacked Variables.w"
int StackedVariables__get_offset(stacked_variable *stv) ;
#line 77 "inform7/Chapter 27/Stacked Variables.w"
kind * StackedVariables__get_kind(stacked_variable *stv) ;
#line 82 "inform7/Chapter 27/Stacked Variables.w"
nonlocal_variable * StackedVariables__get_variable(stacked_variable *stv) ;
#line 87 "inform7/Chapter 27/Stacked Variables.w"
void StackedVariables__set_matching_text(stacked_variable *stv, wording W) ;
#line 91 "inform7/Chapter 27/Stacked Variables.w"
wording StackedVariables__get_matching_text(stacked_variable *stv) ;
#line 95 "inform7/Chapter 27/Stacked Variables.w"
stacked_variable * StackedVariables__parse_match_clause(stacked_variable_owner *stvo, wording W) ;
#line 103 "inform7/Chapter 27/Stacked Variables.w"
stacked_variable_owner * StackedVariables__new_owner(int id) ;
#line 111 "inform7/Chapter 27/Stacked Variables.w"
int StackedVariables__owner_empty(stacked_variable_owner *stvo) ;
#line 116 "inform7/Chapter 27/Stacked Variables.w"
stacked_variable * StackedVariables__add_empty(stacked_variable_owner *stvo, wording W, kind *K) ;
#line 139 "inform7/Chapter 27/Stacked Variables.w"
stacked_variable_owner_list * StackedVariables__add_owner_to_list(stacked_variable_owner_list *stvol, stacked_variable_owner *stvo) ;
#line 158 "inform7/Chapter 27/Stacked Variables.w"
stacked_variable_owner_list * StackedVariables__append_owner_list(stacked_variable_owner_list *stvol, stacked_variable_owner_list *extras) ;
#line 168 "inform7/Chapter 27/Stacked Variables.w"
int StackedVariables__list_length(stacked_variable_list *stvl) ;
#line 177 "inform7/Chapter 27/Stacked Variables.w"
void StackedVariables__index_owner(stacked_variable_owner *stvo) ;
#line 187 "inform7/Chapter 27/Stacked Variables.w"
stacked_variable * StackedVariables__parse_from_owner_list(stacked_variable_owner_list *stvol, wording W) ;
#line 199 "inform7/Chapter 27/Stacked Variables.w"
stacked_variable * StackedVariables__parse_from_list(stacked_variable_list *stvl, wording W) ;
#line 208 "inform7/Chapter 27/Stacked Variables.w"
stacked_variable_list * StackedVariables__add_to_list(stacked_variable_list *stvl, stacked_variable *stv) ;
#line 219 "inform7/Chapter 27/Stacked Variables.w"
int StackedVariables__compile_frame_creator(OUTPUT_STREAM, stacked_variable_owner *stvo, char *name_prototype, int name_id) ;
#line 101 "inform7/Chapter 27/Activities.w"
void Activities__create(parse_node *pn) ;
#line 149 "inform7/Chapter 27/Activities.w"
activity * Activities__new(kind *creation_kind, wording W) ;
#line 239 "inform7/Chapter 27/Activities.w"
kind * Activities__to_kind(activity *av) ;
#line 270 "inform7/Chapter 27/Activities.w"
void Activities__add_variable(activity *av, parse_node *cnode) ;
#line 348 "inform7/Chapter 27/Activities.w"
void Activities__activity_var_creators_array(OUTPUT_STREAM) ;
#line 366 "inform7/Chapter 27/Activities.w"
void Activities__index_by_number(int id, int indent) ;
#line 372 "inform7/Chapter 27/Activities.w"
void Activities__index(activity *av, int indent) ;
#line 388 "inform7/Chapter 27/Activities.w"
int Activities__no_rules(activity *av) ;
#line 396 "inform7/Chapter 27/Activities.w"
void Activities__index_details(activity *av) ;
#line 404 "inform7/Chapter 27/Activities.w"
char * Activities__identifier(activity *av) ;
#line 408 "inform7/Chapter 27/Activities.w"
int Activities__count_list(activity_list *avl) ;
#line 548 "inform7/Chapter 27/Activities.w"
activity_list * Activities__parse_list(wording W) ;
#line 563 "inform7/Chapter 27/Activities.w"
activity_list * Activities__parse_list_inner(wording W, int state) ;
#line 572 "inform7/Chapter 27/Activities.w"
void Activities__compile_activity_list(OUTPUT_STREAM, activity_list *al) ;
#line 600 "inform7/Chapter 27/Activities.w"
void Activities__compile_activity_constants(OUTPUT_STREAM) ;
#line 607 "inform7/Chapter 27/Activities.w"
void Activities__Activity_before_rulebooks_array(OUTPUT_STREAM) ;
#line 617 "inform7/Chapter 27/Activities.w"
void Activities__Activity_for_rulebooks_array(OUTPUT_STREAM) ;
#line 627 "inform7/Chapter 27/Activities.w"
void Activities__Activity_after_rulebooks_array(OUTPUT_STREAM) ;
#line 637 "inform7/Chapter 27/Activities.w"
void Activities__Activity_atb_rulebooks_array(OUTPUT_STREAM) ;
#line 648 "inform7/Chapter 27/Activities.w"
void Activities__annotate_list_for_cross_references(activity_list *avl, phrase *ph) ;
#line 659 "inform7/Chapter 27/Activities.w"
void Activities__index_cross_references(activity *av) ;
#line 51 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__advance_phrase_time_to(int advance_to) ;
#line 75 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__traverse_for_names(void) ;
#line 80 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__visit_for_names(parse_node *p) ;
#line 146 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__traverse(void) ;
#line 154 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__visit_to_count(parse_node *p, int *progress_target) ;
#line 158 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__visit_to_create(parse_node *p, int *progress_target, int *progress_made) ;
#line 180 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__register_meanings(void) ;
#line 213 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__parse_rule_parameters(void) ;
#line 231 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__add_rules_to_rulebooks(void) ;
#line 246 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__parse_rule_placements(void) ;
#line 251 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__visit_to_parse_placements(parse_node *p) ;
#line 284 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__compile_first_block(OUTPUT_STREAM) ;
#line 425 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__TimedEventsTable_array(OUTPUT_STREAM) ;
#line 430 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__TimedEventTimesTable_array(OUTPUT_STREAM) ;
#line 438 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__rulebooks_array_array(OUTPUT_STREAM) ;
#line 443 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__compile_rulebooks(OUTPUT_STREAM) ;
#line 448 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__RulebookNames_array(OUTPUT_STREAM) ;
#line 459 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__compile_rule_printing_switch(OUTPUT_STREAM) ;
#line 498 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__compile_as_needed(OUTPUT_STREAM) ;
#line 85 "inform7/Chapter 28/Phrases.w"
void Phrases__create_from_preamble(parse_node *p) ;
#line 304 "inform7/Chapter 28/Phrases.w"
void Phrases__parse_possible_inline_defn(wording W, int *wn, int *mor) ;
#line 314 "inform7/Chapter 28/Phrases.w"
void Phrases__log(phrase *ph) ;
#line 320 "inform7/Chapter 28/Phrases.w"
void Phrases__log_briefly(phrase *ph) ;
#line 327 "inform7/Chapter 28/Phrases.w"
void Phrases__write_HTML_representation(OUTPUT_STREAM, phrase *ph, int format) ;
#line 334 "inform7/Chapter 28/Phrases.w"
int Phrases__compiled_inline(phrase *ph) ;
#line 339 "inform7/Chapter 28/Phrases.w"
char * Phrases__get_inline_definition(phrase *ph) ;
#line 345 "inform7/Chapter 28/Phrases.w"
char * Phrases__identifier(phrase *ph) ;
#line 349 "inform7/Chapter 28/Phrases.w"
parse_node * Phrases__declaration_node(phrase *ph) ;
#line 360 "inform7/Chapter 28/Phrases.w"
void Phrases__compile(OUTPUT_STREAM, phrase *ph, int *i, int max_i, stacked_variable_owner_list *legible, to_phrase_request *req, applicability_condition *acl) ;
#line 53 "inform7/Chapter 28/Phrase Usage.w"
void Phrases__Usage__predeclare_name_in(parse_node *p) ;
#line 74 "inform7/Chapter 28/Phrase Usage.w"
rule * Phrases__Usage__to_rule(ph_usage_data *phud, phrase *ph) ;
#line 246 "inform7/Chapter 28/Phrase Usage.w"
ph_usage_data Phrases__Usage__new(wording W, int coarse_mode) ;
#line 513 "inform7/Chapter 28/Phrase Usage.w"
wording Phrases__Usage__get_preamble_text(ph_usage_data *phud) ;
#line 525 "inform7/Chapter 28/Phrase Usage.w"
wording Phrases__Usage__get_prewhile_text(ph_usage_data *phud) ;
#line 544 "inform7/Chapter 28/Phrase Usage.w"
int Phrases__Usage__get_effect(ph_usage_data *phud) ;
#line 548 "inform7/Chapter 28/Phrase Usage.w"
int Phrases__Usage__get_rulebook_placement(ph_usage_data *phud) ;
#line 552 "inform7/Chapter 28/Phrase Usage.w"
rulebook * Phrases__Usage__get_rulebook(ph_usage_data *phud) ;
#line 556 "inform7/Chapter 28/Phrase Usage.w"
void Phrases__Usage__set_rulebook(ph_usage_data *phud, rulebook *rb) ;
#line 561 "inform7/Chapter 28/Phrase Usage.w"
int Phrases__Usage__get_timing_of_event(ph_usage_data *phud) ;
#line 565 "inform7/Chapter 28/Phrase Usage.w"
int Phrases__Usage__has_name_as_constant(ph_usage_data *phud) ;
#line 572 "inform7/Chapter 28/Phrase Usage.w"
wording Phrases__Usage__get_equation_form(ph_usage_data *phud) ;
#line 578 "inform7/Chapter 28/Phrase Usage.w"
phrase * Phrases__Usage__get_equation_inverse(ph_usage_data *phud) ;
#line 596 "inform7/Chapter 28/Phrase Usage.w"
void Phrases__Usage__log(ph_usage_data *phud) ;
#line 637 "inform7/Chapter 28/Phrase Usage.w"
void Phrases__Usage__log_rule_name(ph_usage_data *phud) ;
#line 648 "inform7/Chapter 28/Phrase Usage.w"
void Phrases__Usage__write_I6_comment_describing(ph_usage_data *phud, OUTPUT_STREAM) ;
#line 657 "inform7/Chapter 28/Phrase Usage.w"
void Phrases__Usage__index_preamble(ph_usage_data *phud) ;
#line 677 "inform7/Chapter 28/Phrase Usage.w"
ph_runtime_context_data Phrases__Usage__to_runtime_context_data(ph_usage_data *phud) ;
#line 46 "inform7/Chapter 28/Phrase Runtime Context Data.w"
ph_runtime_context_data Phrases__Context__new(void) ;
#line 65 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__set_always_test_actor(ph_runtime_context_data *phrcd) ;
#line 69 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__clear_always_test_actor(ph_runtime_context_data *phrcd) ;
#line 73 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__set_never_test_actor(ph_runtime_context_data *phrcd) ;
#line 77 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__set_marked_for_anyone(ph_runtime_context_data *phrcd, int to) ;
#line 81 "inform7/Chapter 28/Phrase Runtime Context Data.w"
int Phrases__Context__get_marked_for_anyone(ph_runtime_context_data *phrcd) ;
#line 88 "inform7/Chapter 28/Phrase Runtime Context Data.w"
int Phrases__Context__within_action_context(ph_runtime_context_data *phrcd, action_name *an) ;
#line 94 "inform7/Chapter 28/Phrase Runtime Context Data.w"
action_name * Phrases__Context__required_action(ph_runtime_context_data *phrcd) ;
#line 100 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__suppress_action_testing(ph_runtime_context_data *phrcd) ;
#line 110 "inform7/Chapter 28/Phrase Runtime Context Data.w"
scene * Phrases__Context__get_scene(ph_runtime_context_data *phrcd) ;
#line 123 "inform7/Chapter 28/Phrase Runtime Context Data.w"
int Phrases__Context__outcome_restrictions_waived(void) ;
#line 141 "inform7/Chapter 28/Phrase Runtime Context Data.w"
int Phrases__Context__compare_specificity(ph_runtime_context_data *rcd1, ph_runtime_context_data *rcd2) ;
#line 232 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__ensure_avl(rule *R) ;
#line 271 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__compile_test_head(OUTPUT_STREAM, phrase *ph, applicability_condition *acl) ;
#line 294 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__compile_test_tail(OUTPUT_STREAM, phrase *ph, applicability_condition *acl) ;
#line 196 "inform7/Chapter 28/Phrase Type Data.w"
ph_type_data Phrases__TypeData__new(void) ;
#line 216 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__set_mor(ph_type_data *phtd, int mor, kind *K) ;
#line 221 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__get_mor(ph_type_data *phtd) ;
#line 225 "inform7/Chapter 28/Phrase Type Data.w"
kind * Phrases__TypeData__get_return_kind(ph_type_data *phtd) ;
#line 233 "inform7/Chapter 28/Phrase Type Data.w"
char * Phrases__TypeData__describe_manner_of_return(int mor, ph_type_data *phtd, kind **K) ;
#line 285 "inform7/Chapter 28/Phrase Type Data.w"
kind * Phrases__TypeData__kind(ph_type_data *phtd) ;
#line 297 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__contains_variables(ph_type_data *phtd) ;
#line 307 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__tokens_contain_variable(ph_type_data *phtd, int v) ;
#line 317 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__get_no_tokens(ph_type_data *phtd) ;
#line 324 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__index_of_token_creating_a_variable(ph_type_data *phtd) ;
#line 338 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__preamble_requires_property_value(ph_type_data *phtd) ;
#line 356 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__deprecated(ph_type_data *phtd) ;
#line 360 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__deprecate_phrase(ph_type_data *phtd) ;
#line 395 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__into_stack_frame(ph_stack_frame *phsf, ph_type_data *phtd, kind *kind_in_this_compilation, int first) ;
#line 425 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__comparison(ph_type_data *phtd1, ph_type_data *phtd2) ;
#line 555 "inform7/Chapter 28/Phrase Type Data.w"
say_details Phrases__TypeData__new_say_details(void) ;
#line 568 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__make_sd(say_details *sd, int ro, int cs, int pos, int at, int cat) ;
#line 581 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__log_say_details(say_details sd) ;
#line 600 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__is_a_say_phrase(phrase *ph) ;
#line 605 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__is_a_say_X_phrase(ph_type_data *phtd) ;
#line 612 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__is_a_spare_say_X_phrase(ph_type_data *phtd) ;
#line 622 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__is_the_primordial_say(ph_type_data *phtd) ;
#line 627 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__get_say_data(say_details *sd, int *say_cs, int *ssp_tok, int *ssp_ctok, int *ssp_pos) ;
#line 635 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__preface_for_say_HTML(OUTPUT_STREAM, say_details sd, int paste_format) ;
#line 653 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__epilogue_for_say_HTML(OUTPUT_STREAM, say_details sd, int paste_format) ;
#line 664 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__ssp_matches(ph_type_data *phtd, int ssp_tok, int list_pos, wording *W) ;
#line 686 "inform7/Chapter 28/Phrase Type Data.w"
inline_details Phrases__TypeData__new_inline_details(void) ;
#line 705 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__make_id(inline_details *id, int op, int assgn, int let, int blk, int only_in) ;
#line 718 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__log_inline_details(inline_details id) ;
#line 731 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__make_inline(ph_type_data *phtd) ;
#line 735 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__invoked_inline(phrase *ph) ;
#line 742 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__is_a_let_assignment(phrase *ph) ;
#line 747 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__is_a_let_equation(phrase *ph) ;
#line 752 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__arithmetic_operation(phrase *ph) ;
#line 756 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__is_arithmetic_phrase(phrase *ph) ;
#line 762 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__is_assignment_phrase(phrase *ph) ;
#line 766 "inform7/Chapter 28/Phrase Type Data.w"
char * Phrases__TypeData__only_in(phrase *ph) ;
#line 771 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__block_follows(phrase *ph) ;
#line 784 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__return_decided_dimensionally(ph_type_data *phtd) ;
#line 798 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__inline_type_data_comparison(ph_type_data *phtd1, ph_type_data *phtd2) ;
#line 12 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__log(ph_type_data *phtd) ;
#line 46 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__log_briefly(ph_type_data *phtd) ;
#line 69 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__write_HTML_representation(OUTPUT_STREAM, ph_type_data *phtd, int paste_format, parse_node *inv) ;
#line 209 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__inv_write_HTML_representation(OUTPUT_STREAM, parse_node *inv) ;
#line 233 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__write_index_representation(ph_type_data *phtd, phrase *ph) ;
#line 258 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__write_reveal_box(ph_type_data *phtd, phrase *ph) ;
#line 342 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__phtd_write_I6_comment_describing(ph_type_data *phtd, OUTPUT_STREAM) ;
#line 369 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__parse(ph_type_data *phtd, wording XW, wording *OW) ;
#line 564 "inform7/Chapter 28/Describing Phrase Type Data.w"
wording Phrases__TypeData__Textual__phtd_parse_return_data(ph_type_data *phtd, wording XW) ;
#line 593 "inform7/Chapter 28/Describing Phrase Type Data.w"
wording Phrases__TypeData__Textual__phtd_parse_doodads(ph_type_data *phtd, wording W, int *say_flag) ;
#line 773 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__phtd_parse_word_sequence(ph_type_data *phtd, wording W) ;
#line 950 "inform7/Chapter 28/Describing Phrase Type Data.w"
int Phrases__TypeData__Textual__find_kind_variable_domains(kind *K, int *usages, kind **declarations) ;
#line 998 "inform7/Chapter 28/Describing Phrase Type Data.w"
char * Phrases__TypeData__Textual__incipit(phrase *ph) ;
#line 47 "inform7/Chapter 28/Phrase Options.w"
ph_options_data Phrases__Options__new(wording W) ;
#line 55 "inform7/Chapter 28/Phrase Options.w"
int Phrases__Options__allows_options(ph_options_data *phod) ;
#line 66 "inform7/Chapter 28/Phrase Options.w"
int Phrases__Options__parse(ph_options_data *phod, wording W) ;
#line 76 "inform7/Chapter 28/Phrase Options.w"
void Phrases__Options__index(ph_options_data *phod) ;
#line 100 "inform7/Chapter 28/Phrase Options.w"
ph_options_data Phrases__Options__parse_declared_options(wording W) ;
#line 152 "inform7/Chapter 28/Phrase Options.w"
void Phrases__Options__phod_add_phrase_option(ph_options_data *phod, wording W) ;
#line 192 "inform7/Chapter 28/Phrase Options.w"
int Phrases__Options__parse_invoked_options(parse_node *inv, int silently) ;
#line 33 "inform7/Chapter 28/Phrases as Values.w"
constant_phrase * Phrases__Constants__create(wording NW, wording RW) ;
#line 47 "inform7/Chapter 28/Phrases as Values.w"
constant_phrase * Phrases__Constants__parse(wording NW) ;
#line 65 "inform7/Chapter 28/Phrases as Values.w"
kind * Phrases__Constants__kind(constant_phrase *cphr) ;
#line 81 "inform7/Chapter 28/Phrases as Values.w"
phrase * Phrases__Constants__as_phrase(constant_phrase *cphr) ;
#line 100 "inform7/Chapter 28/Phrases as Values.w"
void Phrases__Constants__compile(OUTPUT_STREAM, constant_phrase *cphr) ;
#line 112 "inform7/Chapter 28/Phrases as Values.w"
void Phrases__Constants__compile_closures(OUTPUT_STREAM) ;
#line 161 "inform7/Chapter 28/Phrases as Values.w"
void Phrases__Constants__compile_default_closure(OUTPUT_STREAM, char *closure_identifier, kind *K) ;
#line 54 "inform7/Chapter 28/To Phrases.w"
int Routines__ToPhrases__compare(phrase *ph1, phrase *ph2) ;
#line 93 "inform7/Chapter 28/To Phrases.w"
void Routines__ToPhrases__new(phrase *ph) ;
#line 123 "inform7/Chapter 28/To Phrases.w"
void Routines__ToPhrases__register_all(void) ;
#line 133 "inform7/Chapter 28/To Phrases.w"
int Routines__ToPhrases__sequence_count(phrase *ph) ;
#line 160 "inform7/Chapter 28/To Phrases.w"
to_phrase_request * Routines__ToPhrases__make_request(phrase *ph, kind *K, kind_variable_declaration *kvd, wording W) ;
#line 211 "inform7/Chapter 28/To Phrases.w"
void Routines__ToPhrases__make_identifier(char *identifier, phrase *ph, kind *req_kind) ;
#line 252 "inform7/Chapter 28/To Phrases.w"
int Routines__ToPhrases__compilation_coroutine(OUTPUT_STREAM, int *i, int max_i) ;
#line 272 "inform7/Chapter 28/To Phrases.w"
void Routines__ToPhrases__comment_on_request( to_phrase_request *req, OUTPUT_STREAM) ;
#line 286 "inform7/Chapter 28/To Phrases.w"
kind * Routines__ToPhrases__kind_of_request(to_phrase_request *req) ;
#line 291 "inform7/Chapter 28/To Phrases.w"
kind ** Routines__ToPhrases__kind_variables_for_request(to_phrase_request *req) ;
#line 301 "inform7/Chapter 28/To Phrases.w"
int Routines__ToPhrases__allows_options(phrase *ph) ;
#line 305 "inform7/Chapter 28/To Phrases.w"
int Routines__ToPhrases__parse_phrase_option_used(phrase *ph, wording W) ;
#line 37 "inform7/Chapter 28/Timed Phrases.w"
void Phrases__Timed__TimedEventsTable_array(OUTPUT_STREAM) ;
#line 51 "inform7/Chapter 28/Timed Phrases.w"
void Phrases__Timed__TimedEventTimesTable_array(OUTPUT_STREAM) ;
#line 68 "inform7/Chapter 28/Timed Phrases.w"
void Phrases__Timed__note_usage(phrase *ph, parse_node *at) ;
#line 87 "inform7/Chapter 28/Timed Phrases.w"
void Phrases__Timed__check_for_unused(void) ;
#line 105 "inform7/Chapter 28/Timed Phrases.w"
void Phrases__Timed__index(void) ;
#line 27 "inform7/Chapter 28/Phrasebook Index.w"
void Phrases__Index__index_page_Phrasebook(void) ;
#line 191 "inform7/Chapter 28/Phrasebook Index.w"
int Phrases__Index__ph_same_doc(phrase *p1, phrase *p2) ;
#line 205 "inform7/Chapter 28/Phrasebook Index.w"
void Phrases__Index__index_definition_area(wording W, int show_if_unhyphenated) ;
#line 107 "inform7/Chapter 29/Adjectival Definitions.w"
void Phrases__Adjectives__traverse(void) ;
#line 111 "inform7/Chapter 29/Adjectival Definitions.w"
void Phrases__Adjectives__look_for_headers(parse_node *p) ;
#line 195 "inform7/Chapter 29/Adjectival Definitions.w"
definition * Phrases__Adjectives__def_new(parse_node *q) ;
#line 18 "inform7/Chapter 29/Adjectives by Raw Phrase.w"
adjective_meaning * Phrases__RawPhrasal__ADJ_parse(parse_node *q, int sense, wording AW, wording DNW, wording CONW, wording CALLW) ;
#line 55 "inform7/Chapter 29/Adjectives by Raw Phrase.w"
void Phrases__RawPhrasal__ADJ_compiling_soon(adjective_meaning *am, definition *def, int T) ;
#line 58 "inform7/Chapter 29/Adjectives by Raw Phrase.w"
int Phrases__RawPhrasal__ADJ_compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 62 "inform7/Chapter 29/Adjectives by Raw Phrase.w"
int Phrases__RawPhrasal__ADJ_assert(definition *def, inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) ;
#line 67 "inform7/Chapter 29/Adjectives by Raw Phrase.w"
int Phrases__RawPhrasal__ADJ_index(definition *def) ;
#line 16 "inform7/Chapter 29/Adjectives by Raw Condition.w"
adjective_meaning * Phrases__RawCondition__ADJ_parse(parse_node *q, int sense, wording AW, wording DNW, wording CONW, wording CALLW) ;
#line 38 "inform7/Chapter 29/Adjectives by Raw Condition.w"
void Phrases__RawCondition__ADJ_compiling_soon(adjective_meaning *am, definition *def, int T) ;
#line 41 "inform7/Chapter 29/Adjectives by Raw Condition.w"
int Phrases__RawCondition__ADJ_compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 45 "inform7/Chapter 29/Adjectives by Raw Condition.w"
int Phrases__RawCondition__ADJ_assert(definition *def, inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) ;
#line 50 "inform7/Chapter 29/Adjectives by Raw Condition.w"
int Phrases__RawCondition__ADJ_index(definition *def) ;
#line 11 "inform7/Chapter 29/Adjectives by Phrase.w"
void Phrases__Phrasal__define_adjective_by_phrase(parse_node *p, phrase *ph, wording *CW, kind **K) ;
#line 29 "inform7/Chapter 29/Adjectives by Phrase.w"
adjective_meaning * Phrases__Phrasal__ADJ_parse(parse_node *q, int sense, wording AW, wording DNW, wording CONW, wording CALLW) ;
#line 43 "inform7/Chapter 29/Adjectives by Phrase.w"
void Phrases__Phrasal__ADJ_compiling_soon(adjective_meaning *am, definition *def, int T) ;
#line 46 "inform7/Chapter 29/Adjectives by Phrase.w"
int Phrases__Phrasal__ADJ_compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 50 "inform7/Chapter 29/Adjectives by Phrase.w"
int Phrases__Phrasal__ADJ_assert(definition *def, inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) ;
#line 55 "inform7/Chapter 29/Adjectives by Phrase.w"
int Phrases__Phrasal__ADJ_index(definition *def) ;
#line 10 "inform7/Chapter 29/Adjectives by Condition.w"
adjective_meaning * Phrases__Condition__ADJ_parse(parse_node *q, int sense, wording AW, wording DNW, wording CONW, wording CALLW) ;
#line 27 "inform7/Chapter 29/Adjectives by Condition.w"
void Phrases__Condition__ADJ_compiling_soon(adjective_meaning *am, definition *def, int T) ;
#line 31 "inform7/Chapter 29/Adjectives by Condition.w"
int Phrases__Condition__ADJ_compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 71 "inform7/Chapter 29/Adjectives by Condition.w"
int Phrases__Condition__ADJ_assert(definition *def, inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) ;
#line 76 "inform7/Chapter 29/Adjectives by Condition.w"
int Phrases__Condition__ADJ_index(definition *def) ;
#line 104 "inform7/Chapter 30/Local Variables.w"
locals_slate LocalVariables__blank_slate(void) ;
#line 117 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__deep_copy_locals_slate(locals_slate *slate_to, locals_slate *slate_from) ;
#line 132 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__add_to_locals_slate(locals_slate *slate, int purpose, wording W, kind *K, char *override_lvalue, int override_index) ;
#line 223 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__add_call_parameter(ph_stack_frame *phsf, wording W, kind *K) ;
#line 234 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__get_parameter_number(local_variable *lvar) ;
#line 244 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__new(wording W, kind *K) ;
#line 258 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__add_internal(locals_slate *slate, char *name, int purpose) ;
#line 265 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__add_internal_local(char *name) ;
#line 273 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__add_named_call(char *name) ;
#line 281 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__add_internal_local_c(char *name, char *comment) ;
#line 295 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__add_table_lookup(void) ;
#line 304 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__add_switch_value(kind *K) ;
#line 313 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__options_parameter_is_needed(ph_stack_frame *phsf) ;
#line 323 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__deallocate(local_variable *lvar) ;
#line 336 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__deallocate_all(ph_stack_frame *phsf) ;
#line 346 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__count(ph_stack_frame *phsf) ;
#line 366 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__copy(ph_stack_frame *phsf_to, ph_stack_frame *phsf_from) ;
#line 389 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__find_i6_var(locals_slate *slate, char *name, int purpose) ;
#line 401 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__by_name(char *name) ;
#line 410 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__are_we_using_table_lookup(void) ;
#line 422 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__get_ith_parameter(int i) ;
#line 446 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__parse(ph_stack_frame *phsf, wording W) ;
#line 453 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__parse_inner(ph_stack_frame *phsf, wording W) ;
#line 489 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__monitor_local_parsing(ph_stack_frame *phsf) ;
#line 498 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__used_stack_selection(void) ;
#line 502 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__local_parsed_recently(ph_stack_frame *phsf) ;
#line 520 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__it_variable(void) ;
#line 530 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__is_possessive_form_of_it_enabled(void) ;
#line 536 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__enable_possessive_form_of_it(void) ;
#line 542 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__add_pronoun(ph_stack_frame *phsf, wording W, kind *K) ;
#line 547 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__alias_pronoun(ph_stack_frame *phsf, wording W) ;
#line 558 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__compile_storage(OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 571 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__compile_retrieval(OUTPUT_STREAM, ph_stack_frame *phsf) ;
#line 584 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__make_available_to_equation(equation *eqn) ;
#line 599 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__ensure_called_local(wording W, kind *K) ;
#line 613 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__make_necessary_callings(wording W) ;
#line 723 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__permit_as_new_local(parse_node *found, int as_calling) ;
#line 742 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__log(local_variable *lvar) ;
#line 752 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__describe_repetition_local(OUTPUT_STREAM, local_variable *lvar) ;
#line 766 "inform7/Chapter 30/Local Variables.w"
kind * LocalVariables__kind(local_variable *lvar) ;
#line 771 "inform7/Chapter 30/Local Variables.w"
kind * LocalVariables__unproblematic_kind(local_variable *lvar) ;
#line 780 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__set_kind(local_variable *lvar, kind *K) ;
#line 794 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__unprotect(local_variable *lvar) ;
#line 799 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__protected(local_variable *lvar) ;
#line 823 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__set_scope_to(local_variable *lvar, int s) ;
#line 833 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__mark_to_free_at_end_of_scope(local_variable *lvar) ;
#line 837 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__end_scope(OUTPUT_STREAM, int s) ;
#line 860 "inform7/Chapter 30/Local Variables.w"
local_variable * LocalVariables__latest_repeat_variable(void) ;
#line 891 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__begin_condition(OUTPUT_STREAM) ;
#line 896 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__add_calling_to_condition(local_variable *lvar) ;
#line 908 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__end_condition(OUTPUT_STREAM) ;
#line 936 "inform7/Chapter 30/Local Variables.w"
char * LocalVariables__lvalue(local_variable *lvar) ;
#line 944 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__compile_parameter_list(OUTPUT_STREAM, ph_stack_frame *phsf, int no_vars) ;
#line 960 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__declare(OUTPUT_STREAM, ph_stack_frame *phsf, int call_pars_only) ;
#line 58 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__empty_stack(void) ;
#line 68 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__prepush_stack(void) ;
#line 75 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__push_stack(void) ;
#line 84 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__pop_stack(void) ;
#line 98 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__begin_code_blocks(void) ;
#line 112 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__end_code_blocks(void) ;
#line 133 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__beginning_block_phrase(OUTPUT_STREAM, control_structure_phrase *csp) ;
#line 158 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__supply_kind_and_stream(kind *K, text_stream *TAIL) ;
#line 167 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__open_code_block(OUTPUT_STREAM) ;
#line 177 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__make_indentation_follow_code(OUTPUT_STREAM) ;
#line 187 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__divide_code_block(OUTPUT_STREAM) ;
#line 196 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__close_code_block(OUTPUT_STREAM) ;
#line 214 "inform7/Chapter 30/Phrase Blocks.w"
int Frames__Blocks__inside_a_loop_body(void) ;
#line 230 "inform7/Chapter 30/Phrase Blocks.w"
int Frames__Blocks__current_block_level(void) ;
#line 234 "inform7/Chapter 30/Phrase Blocks.w"
char * Frames__Blocks__name_of_current_block(void) ;
#line 239 "inform7/Chapter 30/Phrase Blocks.w"
parse_node * Frames__Blocks__start_of_current_block(void) ;
#line 244 "inform7/Chapter 30/Phrase Blocks.w"
kind * Frames__Blocks__switch_value_kind(void) ;
#line 258 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__compile_break(OUTPUT_STREAM) ;
#line 276 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__set_variable_scope(local_variable *lvar) ;
#line 287 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__set_scope_to_block_about_to_open(local_variable *lvar) ;
#line 67 "inform7/Chapter 30/Stack Frames.w"
ph_stack_frame Frames__new(void) ;
#line 87 "inform7/Chapter 30/Stack Frames.w"
ph_stack_frame * Frames__new_nonphrasal(void) ;
#line 96 "inform7/Chapter 30/Stack Frames.w"
void Frames__remove_nonphrase_stack_frame(void) ;
#line 105 "inform7/Chapter 30/Stack Frames.w"
ph_stack_frame * Frames__boxed_frame(ph_stack_frame *phsf) ;
#line 123 "inform7/Chapter 30/Stack Frames.w"
ph_stack_frame * Frames__current_stack_frame(void) ;
#line 127 "inform7/Chapter 30/Stack Frames.w"
void Frames__make_current(ph_stack_frame *phsf) ;
#line 132 "inform7/Chapter 30/Stack Frames.w"
void Frames__remove_current(void) ;
#line 140 "inform7/Chapter 30/Stack Frames.w"
void Frames__set_kind_returned(ph_stack_frame *phsf, kind *K) ;
#line 144 "inform7/Chapter 30/Stack Frames.w"
kind * Frames__get_kind_returned(void) ;
#line 153 "inform7/Chapter 30/Stack Frames.w"
void Frames__set_kind_variables(ph_stack_frame *phsf, kind **vars) ;
#line 157 "inform7/Chapter 30/Stack Frames.w"
kind * Frames__get_kind_variable(int N) ;
#line 164 "inform7/Chapter 30/Stack Frames.w"
kind ** Frames__temporarily_set_kvs(kind **vars) ;
#line 175 "inform7/Chapter 30/Stack Frames.w"
void Frames__set_stvol(ph_stack_frame *phsf, stacked_variable_owner_list *stvol) ;
#line 179 "inform7/Chapter 30/Stack Frames.w"
stacked_variable_owner_list * Frames__get_stvol(void) ;
#line 190 "inform7/Chapter 30/Stack Frames.w"
void Frames__determines_the_past(void) ;
#line 198 "inform7/Chapter 30/Stack Frames.w"
int Frames__used_for_past_tense(void) ;
#line 208 "inform7/Chapter 30/Stack Frames.w"
void Frames__log(ph_stack_frame *phsf) ;
#line 232 "inform7/Chapter 30/Stack Frames.w"
void Frames__need_at_least_this_many_formals(int N) ;
#line 249 "inform7/Chapter 30/Stack Frames.w"
pointer_allocation * Frames__add_allocation(kind *K, char *proto) ;
#line 269 "inform7/Chapter 30/Stack Frames.w"
void Frames__compile_allocation(OUTPUT_STREAM, kind *K) ;
#line 323 "inform7/Chapter 30/Stack Frames.w"
char * Frames__pall_get_local_reference(pointer_allocation *pall) ;
#line 327 "inform7/Chapter 30/Stack Frames.w"
char * Frames__pall_get_expanded_schema(pointer_allocation *pall) ;
#line 44 "inform7/Chapter 30/Chronology.w"
void Chronology__ap_compile_forced_to_present(OUTPUT_STREAM, action_pattern ap) ;
#line 52 "inform7/Chapter 30/Chronology.w"
void Chronology__compile_past_action_pattern(OUTPUT_STREAM, time_period duration, action_pattern ap) ;
#line 98 "inform7/Chapter 30/Chronology.w"
void Chronology__compile_past_tense_condition(OUTPUT_STREAM, parse_node *spec) ;
#line 179 "inform7/Chapter 30/Chronology.w"
void Chronology__allow_no_further_past_tenses(void) ;
#line 209 "inform7/Chapter 30/Chronology.w"
void Chronology__past_actions_i6_routines(OUTPUT_STREAM) ;
#line 252 "inform7/Chapter 30/Chronology.w"
void Chronology__past_tenses_i6_escape(OUTPUT_STREAM) ;
#line 364 "inform7/Chapter 30/Chronology.w"
void Chronology__chronology_extents_i6_escape(OUTPUT_STREAM) ;
#line 145 "inform7/Chapter 31/Invocations.w"
parse_node * Invocations__new(void) ;
#line 161 "inform7/Chapter 31/Invocations.w"
void Invocations__log(parse_node *inv) ;
#line 195 "inform7/Chapter 31/Invocations.w"
void Invocations__mark_to_save_self(parse_node *inv) ;
#line 199 "inform7/Chapter 31/Invocations.w"
int Invocations__is_marked_to_save_self(parse_node *inv) ;
#line 203 "inform7/Chapter 31/Invocations.w"
void Invocations__mark_unproven(parse_node *inv) ;
#line 207 "inform7/Chapter 31/Invocations.w"
int Invocations__is_marked_unproven(parse_node *inv) ;
#line 214 "inform7/Chapter 31/Invocations.w"
void Invocations__set_word_range(parse_node *inv, wording W) ;
#line 222 "inform7/Chapter 31/Invocations.w"
void Invocations__set_verb_conjugation(parse_node *inv, verb_conjugation *vc, verb_conjugation *modal, int neg) ;
#line 233 "inform7/Chapter 31/Invocations.w"
void Invocations__set_adjectival_phrase(parse_node *inv, adjectival_phrase *aph) ;
#line 242 "inform7/Chapter 31/Invocations.w"
parse_node * Invocations__new_token(node_type_t t) ;
#line 254 "inform7/Chapter 31/Invocations.w"
void Invocations__make_token(parse_node *inv, int i, node_type_t t, wording W, kind *K) ;
#line 270 "inform7/Chapter 31/Invocations.w"
void Invocations__set_token_check_to_do(parse_node *inv, int i, parse_node *spec) ;
#line 281 "inform7/Chapter 31/Invocations.w"
void Invocations__set_token_as_parsed(parse_node *inv, int i, parse_node *spec) ;
#line 292 "inform7/Chapter 31/Invocations.w"
void Invocations__set_token_to_be_parsed_against(parse_node *inv, int i, parse_node *spec) ;
#line 303 "inform7/Chapter 31/Invocations.w"
void Invocations__set_token_variable_kind(parse_node *inv, int i, kind *K) ;
#line 317 "inform7/Chapter 31/Invocations.w"
parse_node * Invocations__get_token(parse_node *inv, int i) ;
#line 325 "inform7/Chapter 31/Invocations.w"
parse_node * Invocations__get_token_check_to_do(parse_node *inv, int i) ;
#line 333 "inform7/Chapter 31/Invocations.w"
parse_node * Invocations__get_token_as_parsed(parse_node *inv, int i) ;
#line 341 "inform7/Chapter 31/Invocations.w"
parse_node * Invocations__get_token_to_be_parsed_against(parse_node *inv, int i) ;
#line 349 "inform7/Chapter 31/Invocations.w"
kind * Invocations__get_token_variable_kind(parse_node *inv, int i) ;
#line 357 "inform7/Chapter 31/Invocations.w"
int Invocations__get_no_tokens(parse_node *inv) ;
#line 368 "inform7/Chapter 31/Invocations.w"
int Invocations__get_no_tokens_needed(parse_node *inv) ;
#line 379 "inform7/Chapter 31/Invocations.w"
void Invocations__set_phrase_options(parse_node *inv, wording W) ;
#line 392 "inform7/Chapter 31/Invocations.w"
wording Invocations__get_phrase_options(parse_node *inv) ;
#line 402 "inform7/Chapter 31/Invocations.w"
int Invocations__get_phrase_options_bitmap(parse_node *inv) ;
#line 408 "inform7/Chapter 31/Invocations.w"
void Invocations__set_phrase_options_bitmap(parse_node *inv, int further_bits) ;
#line 424 "inform7/Chapter 31/Invocations.w"
int Invocations__implies_newline(parse_node *inv) ;
#line 434 "inform7/Chapter 31/Invocations.w"
parse_node * Invocations__add_to_list(parse_node *invl, parse_node *inv) ;
#line 445 "inform7/Chapter 31/Invocations.w"
int Invocations__length_of_list(parse_node *invl) ;
#line 454 "inform7/Chapter 31/Invocations.w"
parse_node * Invocations__first_in_list(parse_node *invl) ;
#line 468 "inform7/Chapter 31/Invocations.w"
parse_node * Invocations__sort_list(parse_node *invl) ;
#line 525 "inform7/Chapter 31/Invocations.w"
int Invocations__comparison(const void *i1, const void *i2) ;
#line 542 "inform7/Chapter 31/Invocations.w"
int Invocations__eq(parse_node *inv1, parse_node *inv2) ;
#line 573 "inform7/Chapter 31/Invocations.w"
void Invocations__log_list(parse_node *invl) ;
#line 585 "inform7/Chapter 31/Invocations.w"
void Invocations__log_list_in_detail(parse_node *invl) ;
#line 33 "inform7/Chapter 31/Parse Invocations.w"
void Phrases__Parser__register_excerpt(phrase *ph) ;
#line 57 "inform7/Chapter 31/Parse Invocations.w"
void Phrases__Parser__register_phrasal(unsigned int phrase_mc, phrase *ph, wording W) ;
#line 246 "inform7/Chapter 31/Parse Invocations.w"
parse_node * Phrases__Parser__parse_against(phrase *ph, parse_node *p) ;
#line 326 "inform7/Chapter 31/Parse Invocations.w"
void Phrases__Parser__parse_within_inv(parse_node *inv) ;
#line 40 "inform7/Chapter 31/Compile Invocations.w"
void Invocations__Compiler__compile_invocation_list(OUTPUT_STREAM, parse_node *invl, wording W) ;
#line 509 "inform7/Chapter 31/Compile Invocations.w"
int Invocations__Compiler__compile_single_invocation(OUTPUT_STREAM, parse_node *inv, source_location *where_from, tokens_packet *tokens) ;
#line 11 "inform7/Chapter 31/Compile Invocations As Calls.w"
void Invocations__AsCalls__csi_by_call(OUTPUT_STREAM, parse_node *inv, source_location *where_from, tokens_packet *tokens) ;
#line 35 "inform7/Chapter 31/Compile Invocations As Calls.w"
void Invocations__AsCalls__compile_function_call(OUTPUT_STREAM, tokens_packet *tokens, char *identifier, int phrase_options) ;
#line 34 "inform7/Chapter 31/Compile Invocations Inline.w"
int Invocations__Inline__csi_inline(OUTPUT_STREAM, parse_node *inv, source_location *where_from, tokens_packet *tokens) ;
#line 200 "inform7/Chapter 31/Compile Invocations Inline.w"
void Invocations__Inline__copy_and_trim(char *to, char *from) ;
#line 206 "inform7/Chapter 31/Compile Invocations Inline.w"
void Invocations__Inline__trim_tail(char *to) ;
#line 218 "inform7/Chapter 31/Compile Invocations Inline.w"
void Invocations__Inline__csi_inline_inner(OUTPUT_STREAM, char *inline_definition, parse_node *inv, source_location *where_from, tokens_packet *tokens, local_variable **my_vars) ;
#line 1675 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node * Invocations__Inline__parse_bracing_operand_as_identifier(char *operand, phrase *ph, tokens_packet *tokens, local_variable **my_vars) ;
#line 1711 "inform7/Chapter 31/Compile Invocations Inline.w"
kind * Invocations__Inline__parse_bracing_operand_as_kind(char *operand, kind_variable_declaration *kvd) ;
#line 30 "inform7/Chapter 31/Compile Phrases.w"
void Routines__Compile__routine(OUTPUT_STREAM, phrase *ph, stacked_variable_owner_list *legible, to_phrase_request *req, applicability_condition *acl) ;
#line 130 "inform7/Chapter 31/Compile Phrases.w"
void Routines__Compile__identifier(char *identifier, phrase *ph, to_phrase_request *req) ;
#line 142 "inform7/Chapter 31/Compile Phrases.w"
int Routines__Compile__disallow_let(void) ;
#line 146 "inform7/Chapter 31/Compile Phrases.w"
int Routines__Compile__code_block(OUTPUT_STREAM, int statement_count, parse_node *pn, int top_level) ;
#line 161 "inform7/Chapter 31/Compile Phrases.w"
int Routines__Compile__code_line(OUTPUT_STREAM, int statement_count, parse_node *p) ;
#line 508 "inform7/Chapter 31/Compile Phrases.w"
void Routines__Compile__switch_head(OUTPUT_STREAM, parse_node *val) ;
#line 528 "inform7/Chapter 31/Compile Phrases.w"
void Routines__Compile__line(OUTPUT_STREAM, parse_node *p, int already_parsed) ;
#line 566 "inform7/Chapter 31/Compile Phrases.w"
parse_node * Routines__Compile__line_being_compiled(void) ;
#line 601 "inform7/Chapter 31/Compile Phrases.w"
int Routines__Compile__verify_say_node_list(parse_node *say_node_list) ;
#line 880 "inform7/Chapter 31/Compile Phrases.w"
void Routines__Compile__add_say_construction_to_error(int ssp_tok) ;
#line 890 "inform7/Chapter 31/Compile Phrases.w"
void Routines__Compile__add_scte_list(int ssp_tok, int list_pos) ;
#line 106 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__set_identifier(char *file_extension) ;
#line 123 "inform7/Chapter 32/Virtual Machines.w"
int VirtualMachines__is_16_bit(void) ;
#line 133 "inform7/Chapter 32/Virtual Machines.w"
int VirtualMachines__allow_this_many_locals(int N) ;
#line 139 "inform7/Chapter 32/Virtual Machines.w"
int VirtualMachines__allow_MAX_LOCAL_VARIABLES(void) ;
#line 148 "inform7/Chapter 32/Virtual Machines.w"
int VirtualMachines__supports(kind *K) ;
#line 161 "inform7/Chapter 32/Virtual Machines.w"
char * VirtualMachines__get_blorbed_extension(void) ;
#line 171 "inform7/Chapter 32/Virtual Machines.w"
char * VirtualMachines__get_default_interpreter(void) ;
#line 197 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__match_against(wording W) ;
#line 322 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__plot_icon(OUTPUT_STREAM, int minor) ;
#line 328 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__write_key(OUTPUT_STREAM) ;
#line 341 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__index_innards(void) ;
#line 354 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__write_current(void) ;
#line 375 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__write_icons(OUTPUT_STREAM, wording W) ;
#line 430 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__note_usage(char *cat, wording W, char *name, int words, int bytes, int each) ;
#line 448 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__index_memory_usage(void) ;
#line 497 "inform7/Chapter 32/Virtual Machines.w"
int VirtualMachines__compare_usage(const void *ent1, const void *ent2) ;
#line 519 "inform7/Chapter 32/Virtual Machines.w"
int VirtualMachines__get_next_free_blorb_resource_ID(void) ;
#line 102 "inform7/Chapter 32/Inform 6 Inclusions.w"
void Config__Inclusions__inform_6_inclusion(parse_node *PN) ;
#line 189 "inform7/Chapter 32/Inform 6 Inclusions.w"
void Config__Inclusions__compile_inclusions_for_subject(OUTPUT_STREAM, inference_subject *infs) ;
#line 75 "inform7/Chapter 32/Use Options.w"
void UseOptions__new_use_option(parse_node *p) ;
#line 112 "inform7/Chapter 32/Use Options.w"
use_option * UseOptions__parse_uo(wording OW) ;
#line 175 "inform7/Chapter 32/Use Options.w"
void UseOptions__handle_set_use_option(parse_node *p) ;
#line 179 "inform7/Chapter 32/Use Options.w"
void UseOptions__set_use_options(parse_node *p) ;
#line 254 "inform7/Chapter 32/Use Options.w"
void UseOptions__set_immediate_option_flags(wording W, use_option *uo) ;
#line 313 "inform7/Chapter 32/Use Options.w"
int UseOptions__get_dynamic_memory_allocation(void) ;
#line 320 "inform7/Chapter 32/Use Options.w"
int UseOptions__get_index_figure_thumbnails(void) ;
#line 328 "inform7/Chapter 32/Use Options.w"
int UseOptions__uo_set_from(use_option *uo, int category, extension_file *ef) ;
#line 347 "inform7/Chapter 32/Use Options.w"
void UseOptions__compile(OUTPUT_STREAM) ;
#line 366 "inform7/Chapter 32/Use Options.w"
void UseOptions__compile_icl_commands(OUTPUT_STREAM) ;
#line 384 "inform7/Chapter 32/Use Options.w"
void UseOptions__index(void) ;
#line 427 "inform7/Chapter 32/Use Options.w"
void UseOptions__index_options_in_force_from(int category, extension_file *ef) ;
#line 492 "inform7/Chapter 32/Use Options.w"
void UseOptions__TestUseOption_routine(OUTPUT_STREAM) ;
#line 35 "inform7/Chapter 32/List Together.w"
void ListTogether__new(OUTPUT_STREAM, int include_articles) ;
#line 51 "inform7/Chapter 32/List Together.w"
int ListTogether__compilation_coroutine(OUTPUT_STREAM) ;
#line 42 "inform7/Chapter 32/Jump Labels.w"
label_namespace * JumpLabels__new_namespace(char *name) ;
#line 64 "inform7/Chapter 32/Jump Labels.w"
label_namespace * JumpLabels__namespace_by_prefix(char *name) ;
#line 72 "inform7/Chapter 32/Jump Labels.w"
label_namespace * JumpLabels__read_or_create_namespace(char *name) ;
#line 83 "inform7/Chapter 32/Jump Labels.w"
int JumpLabels__read_counter(char *namespace, int advance_flag) ;
#line 94 "inform7/Chapter 32/Jump Labels.w"
void JumpLabels__write(OUTPUT_STREAM, char *namespace) ;
#line 108 "inform7/Chapter 32/Jump Labels.w"
void JumpLabels__allocate_counter(char *namespace, int multiplier) ;
#line 113 "inform7/Chapter 32/Jump Labels.w"
void JumpLabels__compile_necessary_storage(OUTPUT_STREAM) ;
#line 14 "inform7/Chapter 32/Identifiers.w"
int Identifiers__valid(char *p) ;
#line 40 "inform7/Chapter 32/Identifiers.w"
void Identifiers__compose(char *ledger, char nature_character, int id_number, wording W) ;
#line 60 "inform7/Chapter 32/Identifiers.w"
void Identifiers__purify(char *identifier) ;
#line 38 "inform7/Chapter 32/Dictionary Words.w"
void DictionaryWords__compile(OUTPUT_STREAM, char *p, int pluralise) ;
#line 35 "inform7/Chapter 32/Compiled Text.w"
void CompiledText__from_ISO_string(OUTPUT_STREAM, char *p, int options) ;
#line 121 "inform7/Chapter 32/Compiled Text.w"
int CompiledText__alphabetic(int letter) ;
#line 130 "inform7/Chapter 32/Compiled Text.w"
int CompiledText__expand_unisub(OUTPUT_STREAM, char *p, int i) ;
#line 151 "inform7/Chapter 32/Compiled Text.w"
void CompiledText__from_text_with_options(OUTPUT_STREAM, wording W, int opts, int raw) ;
#line 163 "inform7/Chapter 32/Compiled Text.w"
void CompiledText__comment(OUTPUT_STREAM, wording W) ;
#line 167 "inform7/Chapter 32/Compiled Text.w"
void CompiledText__from_text(OUTPUT_STREAM, wording W) ;
#line 174 "inform7/Chapter 32/Compiled Text.w"
void CompiledText__divider_comment(OUTPUT_STREAM) ;
#line 25 "inform7/Chapter 32/Routines.w"
text_stream * Routines__begin(OUTPUT_STREAM, char *name) ;
#line 29 "inform7/Chapter 32/Routines.w"
text_stream * Routines__begin_numbered(OUTPUT_STREAM, char *format, int id) ;
#line 61 "inform7/Chapter 32/Routines.w"
text_stream * Routines__begin_framed(OUTPUT_STREAM, char *name, ph_stack_frame *phsf) ;
#line 97 "inform7/Chapter 32/Routines.w"
text_stream * Routines__end(OUTPUT_STREAM) ;
#line 101 "inform7/Chapter 32/Routines.w"
text_stream * Routines__end_retrieving(OUTPUT_STREAM, ph_stack_frame *retrieve) ;
#line 29 "inform7/Chapter 33/Interactive Fiction ID.w"
char * PL__Bibliographic__IFID__read_uuid(void) ;
#line 55 "inform7/Chapter 33/Interactive Fiction ID.w"
void PL__Bibliographic__IFID__UUID_ARRAY_array(OUTPUT_STREAM) ;
#line 41 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__start(void) ;
#line 72 "inform7/Chapter 33/Bibliographic Data.w"
int PL__Bibliographic__bibliographic_new_variable_notify(nonlocal_variable *q) ;
#line 105 "inform7/Chapter 33/Bibliographic Data.w"
natural_language * PL__Bibliographic__scan_language(parse_node *PN) ;
#line 119 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__bibliographic_data(parse_node *PN) ;
#line 175 "inform7/Chapter 33/Bibliographic Data.w"
int PL__Bibliographic__story_author_is(char *p) ;
#line 231 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__set_episode_data(parse_node *pn) ;
#line 244 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__compile_constants(OUTPUT_STREAM) ;
#line 316 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__index_library_card(void) ;
#line 341 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__library_card_entry(char *field, nonlocal_variable *nlv, char *t) ;
#line 358 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__contents_heading(void) ;
#line 371 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__index_bibliographic_variable(nonlocal_variable *nlv, char *t) ;
#line 119 "inform7/Chapter 33/Release Instructions.w"
void PL__Bibliographic__Release__handle_release_declaration(parse_node *p) ;
#line 123 "inform7/Chapter 33/Release Instructions.w"
void PL__Bibliographic__Release__handle_release_declaration_inner(parse_node *p) ;
#line 273 "inform7/Chapter 33/Release Instructions.w"
auxiliary_file * PL__Bibliographic__Release__create_aux_file(filename *name, pathname *fold, char *desc, int payload) ;
#line 291 "inform7/Chapter 33/Release Instructions.w"
void PL__Bibliographic__Release__write_ifiction_and_blurb(void) ;
#line 530 "inform7/Chapter 33/Release Instructions.w"
void PL__Bibliographic__Release__write_ifiction_record(OUTPUT_STREAM, char *header, int cover_picture_number, char *cover_art_format, unsigned int height, unsigned int width) ;
#line 753 "inform7/Chapter 33/Release Instructions.w"
int PL__Bibliographic__Release__write_var_to_XML(OUTPUT_STREAM, nonlocal_variable *nlv, int desc_mode) ;
#line 790 "inform7/Chapter 33/Release Instructions.w"
void PL__Bibliographic__Release__write_release_blurb(OUTPUT_STREAM, int cover_picture_number, char *cover_art_format) ;
#line 1075 "inform7/Chapter 33/Release Instructions.w"
void PL__Bibliographic__Release__visit_to_quote(OUTPUT_STREAM, parse_node *p) ;
#line 38 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__start(void) ;
#line 64 "inform7/Chapter 34/The Naming Thicket.w"
int PL__Naming__naming_new_property_notify(property *prn) ;
#line 89 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__now_has_proper_name(inference_subject *infs) ;
#line 94 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__object_now_has_proper_name(instance *I) ;
#line 100 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__object_now_has_plural_name(instance *I) ;
#line 116 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__object_takes_definite_article(inference_subject *subj) ;
#line 127 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__transfer_details(inference_subject *from, inference_subject *to) ;
#line 137 "inform7/Chapter 34/The Naming Thicket.w"
instance * PL__Naming__object_this_is_named_after(instance *I) ;
#line 148 "inform7/Chapter 34/The Naming Thicket.w"
int PL__Naming__object_is_privately_named(instance *I) ;
#line 160 "inform7/Chapter 34/The Naming Thicket.w"
int PL__Naming__naming_complete_model(int stage) ;
#line 431 "inform7/Chapter 34/The Naming Thicket.w"
int PL__Naming__look_for_printed_name(inference_subject *subj) ;
#line 447 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__compose_words_to_I6_naming_text(OUTPUT_STREAM, wording W, int cap, int your_flag) ;
#line 479 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__compile_small_names(OUTPUT_STREAM) ;
#line 38 "inform7/Chapter 34/Instance Counting.w"
void PL__Counting__start(void) ;
#line 49 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__counting_new_subject_notify(inference_subject *subj) ;
#line 54 "inform7/Chapter 34/Instance Counting.w"
counting_data * PL__Counting__new_data(inference_subject *subj) ;
#line 79 "inform7/Chapter 34/Instance Counting.w"
void PL__Counting__make_instance_counts(void) ;
#line 113 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__instance_count(instance *I, kind *K) ;
#line 132 "inform7/Chapter 34/Instance Counting.w"
instance * PL__Counting__next_instance_of(instance *I, kind *k) ;
#line 150 "inform7/Chapter 34/Instance Counting.w"
parse_node * PL__Counting__next_instance_of_as_value(instance *I, kind *k) ;
#line 166 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__counting_compile_model_tables(OUTPUT_STREAM) ;
#line 207 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__kind_of_object_count(kind *K) ;
#line 235 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__counting_complete_model(int stage) ;
#line 337 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__counting_estimate_property_usage(kind *k, int *words_used) ;
#line 354 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__optimise_loop(i6_schema *sch, kind *K) ;
#line 100 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__start(void) ;
#line 154 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_name_to_early_infs(wording W, inference_subject **infs) ;
#line 170 "inform7/Chapter 34/Spatial Model.w"
spatial_data * PL__Spatial__new_data(inference_subject *subj) ;
#line 186 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_log_inference_type(int it) ;
#line 198 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_inferences_contradict(inference *A, inference *B, int similarity) ;
#line 206 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_explain_contradiction(inference *A, inference *B, int similarity, inference_subject *subj) ;
#line 247 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_new_base_kind_notify(kind *new_base, char *name, wording W) ;
#line 260 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_new_subject_notify(inference_subject *subj) ;
#line 270 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_set_kind_notify(instance *I, kind *k) ;
#line 283 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_set_subkind_notify(kind *sub, kind *super) ;
#line 319 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__object_is_a_room(instance *I) ;
#line 330 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__get_world_size(int *rooms, int *things) ;
#line 357 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_new_property_notify(property *prn) ;
#line 378 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_default_appearance(inference_subject *infs, parse_node *txt) ;
#line 448 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_parse_composite_NQs(wording *W, wording *DW, quantifier **quant, kind **some_kind) ;
#line 472 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_act_on_special_NPs(parse_node *p) ;
#line 486 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_intervene_in_assertion(parse_node *px, parse_node *py) ;
#line 523 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__infer_presence_here(instance *I) ;
#line 544 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__infer_presence_nowhere(instance *I) ;
#line 556 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__IF_complete_model(int stage) ;
#line 575 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_stage_I(void) ;
#line 750 "inform7/Chapter 34/Spatial Model.w"
instance * PL__Spatial__progenitor(instance *I) ;
#line 756 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__set_progenitor(instance *of, instance *to, inference *reason) ;
#line 768 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__void_progenitor(instance *of) ;
#line 781 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_stage_II(void) ;
#line 920 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__seek_room(parse_node *sent, instance **I) ;
#line 945 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__log_object_tree(void) ;
#line 952 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__log_object_tree_recursively(instance *I, int depth) ;
#line 970 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__adopt_object(instance *orphan, instance *foster) ;
#line 984 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__part_object(instance *orphan) ;
#line 1043 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__encloses(instance *I1, instance *I2) ;
#line 1056 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_stage_III(void) ;
#line 1257 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__add_to_object_sequence(instance *I, int depth) ;
#line 1271 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__get_definition_depth(instance *I) ;
#line 1283 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_stage_IV(void) ;
#line 1304 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__index_spatial_relationship(instance *I) ;
#line 1324 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__no_detail_index(instance *I) ;
#line 1332 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__index_object_further(instance *I, int depth, int details) ;
#line 1365 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_add_to_World_index(instance *O) ;
#line 33 "inform7/Chapter 34/Spatial Relations.w"
void PL__SpatialRelations__REL_create_initial_stock(void) ;
#line 154 "inform7/Chapter 34/Spatial Relations.w"
void PL__SpatialRelations__REL_create_second_stock(void) ;
#line 161 "inform7/Chapter 34/Spatial Relations.w"
int PL__SpatialRelations__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 173 "inform7/Chapter 34/Spatial Relations.w"
int PL__SpatialRelations__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 258 "inform7/Chapter 34/Spatial Relations.w"
int PL__SpatialRelations__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 265 "inform7/Chapter 34/Spatial Relations.w"
int PL__SpatialRelations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 35 "inform7/Chapter 34/The Player.w"
void PL__Player__start(void) ;
#line 58 "inform7/Chapter 34/The Player.w"
int PL__Player__player_new_instance_notify(instance *inst) ;
#line 67 "inform7/Chapter 34/The Player.w"
instance * PL__Player__get_start_room(void) ;
#line 100 "inform7/Chapter 34/The Player.w"
int PL__Player__player_new_quantity_notify(nonlocal_variable *nlv) ;
#line 159 "inform7/Chapter 34/The Player.w"
int PL__Player__player_variable_set_warning(nonlocal_variable *nlv, parse_node *val) ;
#line 193 "inform7/Chapter 34/The Player.w"
int PL__Player__player_detect_bodysnatching(inference_subject *body, int *snatcher, inference_subject **counterpart) ;
#line 221 "inform7/Chapter 34/The Player.w"
int PL__Player__player_irregular_genitive(inference_subject *owner, char *genitive, int *propriety) ;
#line 253 "inform7/Chapter 34/The Player.w"
int PL__Player__player_refine_implicit_noun(parse_node *p) ;
#line 271 "inform7/Chapter 34/The Player.w"
int PL__Player__player_complete_model(int stage) ;
#line 345 "inform7/Chapter 34/The Player.w"
void PL__Player__InitialSituation_array(OUTPUT_STREAM) ;
#line 361 "inform7/Chapter 34/The Player.w"
void PL__Player__index_object_further(instance *I, int depth, int details) ;
#line 367 "inform7/Chapter 34/The Player.w"
int PL__Player__player_annotate_in_World_index(instance *I) ;
#line 27 "inform7/Chapter 34/Backdrops.w"
void PL__Backdrops__start(void) ;
#line 48 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_new_base_kind_notify(kind *new_base, char *name, wording W) ;
#line 58 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__object_is_a_backdrop(instance *I) ;
#line 76 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_new_property_notify(property *prn) ;
#line 82 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__object_is_scenery(instance *I) ;
#line 91 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_estimate_property_usage(kind *k, int *words_used) ;
#line 99 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_log_inference_type(int it) ;
#line 117 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__assert_relations(binary_predicate *relation, instance *I0, instance *I1) ;
#line 154 "inform7/Chapter 34/Backdrops.w"
void PL__Backdrops__index_object_further(instance *loc, int depth, int details, char *bef, char *aft) ;
#line 184 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_intervene_in_assertion(parse_node *px, parse_node *py) ;
#line 211 "inform7/Chapter 34/Backdrops.w"
void PL__Backdrops__infer_presence_everywhere(instance *I) ;
#line 228 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_complete_model(int stage) ;
#line 43 "inform7/Chapter 34/Regions.w"
void PL__Regions__start(void) ;
#line 58 "inform7/Chapter 34/Regions.w"
regions_data * PL__Regions__new_data(inference_subject *subj) ;
#line 77 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_new_base_kind_notify(kind *new_base, char *name, wording W) ;
#line 84 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_new_subject_notify(inference_subject *subj) ;
#line 92 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_set_subkind_notify(kind *sub, kind *super) ;
#line 108 "inform7/Chapter 34/Regions.w"
int PL__Regions__object_is_a_region(instance *I) ;
#line 120 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_more_specific(instance *I1, instance *I2) ;
#line 146 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_new_property_notify(property *prn) ;
#line 155 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_estimate_property_usage(kind *k, int *words_used) ;
#line 165 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_intervene_in_assertion(parse_node *px, parse_node *py) ;
#line 206 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_name_to_early_infs(wording W, inference_subject **infs) ;
#line 214 "inform7/Chapter 34/Regions.w"
void PL__Regions__create_relations(void) ;
#line 232 "inform7/Chapter 34/Regions.w"
int PL__Regions__assert_relations(binary_predicate *relation, instance *I0, instance *I1) ;
#line 301 "inform7/Chapter 34/Regions.w"
instance * PL__Regions__enclosing(instance *reg) ;
#line 312 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_complete_model(int stage) ;
#line 362 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_add_to_World_index(instance *O) ;
#line 96 "inform7/Chapter 34/The Map.w"
void PL__Map__start(void) ;
#line 119 "inform7/Chapter 34/The Map.w"
map_data * PL__Map__new_data(inference_subject *subj) ;
#line 139 "inform7/Chapter 34/The Map.w"
int PL__Map__map_log_inference_type(int it) ;
#line 152 "inform7/Chapter 34/The Map.w"
int PL__Map__map_inferences_contradict(inference *A, inference *B, int similarity) ;
#line 174 "inform7/Chapter 34/The Map.w"
int PL__Map__map_new_base_kind_notify(kind *new_base, char *name, wording W) ;
#line 187 "inform7/Chapter 34/The Map.w"
int PL__Map__map_set_subkind_notify(kind *sub, kind *super) ;
#line 225 "inform7/Chapter 34/The Map.w"
int PL__Map__map_new_subject_notify(inference_subject *subj) ;
#line 233 "inform7/Chapter 34/The Map.w"
int PL__Map__object_is_a_direction(instance *I) ;
#line 243 "inform7/Chapter 34/The Map.w"
int PL__Map__object_is_a_door(instance *I) ;
#line 250 "inform7/Chapter 34/The Map.w"
int PL__Map__subject_is_a_door(inference_subject *infs) ;
#line 263 "inform7/Chapter 34/The Map.w"
int PL__Map__is_a_direction(inference_subject *infs) ;
#line 287 "inform7/Chapter 34/The Map.w"
int PL__Map__map_set_kind_notify(instance *I, kind *k) ;
#line 335 "inform7/Chapter 34/The Map.w"
int PL__Map__map_compile_object_header(OUTPUT_STREAM, instance *I) ;
#line 357 "inform7/Chapter 34/The Map.w"
void PL__Map__build_exits_array(void) ;
#line 388 "inform7/Chapter 34/The Map.w"
int PL__Map__map_compile_model_tables(OUTPUT_STREAM) ;
#line 444 "inform7/Chapter 34/The Map.w"
void PL__Map__get_door_data(instance *door, instance **c1, instance **c2) ;
#line 462 "inform7/Chapter 34/The Map.w"
int PL__Map__map_new_property_notify(property *prn) ;
#line 481 "inform7/Chapter 34/The Map.w"
int PL__Map__map_property_value_notify(property *prn, parse_node *val) ;
#line 499 "inform7/Chapter 34/The Map.w"
void PL__Map__set_found_in(instance *I, text_stream *S) ;
#line 516 "inform7/Chapter 34/The Map.w"
instance * PL__Map__get_value_of_opposite_property(instance *I) ;
#line 526 "inform7/Chapter 34/The Map.w"
int PL__Map__map_estimate_property_usage(kind *k, int *words_used) ;
#line 543 "inform7/Chapter 34/The Map.w"
int PL__Map__map_act_on_special_NPs(parse_node *p) ;
#line 566 "inform7/Chapter 34/The Map.w"
int PL__Map__map_check_going(parse_node *from, parse_node *to, parse_node *by, parse_node *through, parse_node *pushing) ;
#line 599 "inform7/Chapter 34/The Map.w"
int PL__Map__map_intervene_in_assertion(parse_node *px, parse_node *py) ;
#line 630 "inform7/Chapter 34/The Map.w"
void PL__Map__enter_one_way_mode(void) ;
#line 631 "inform7/Chapter 34/The Map.w"
void PL__Map__exit_one_way_mode(void) ;
#line 640 "inform7/Chapter 34/The Map.w"
void PL__Map__connect(inference_subject *i_from, inference_subject *i_to, inference_subject *i_dir) ;
#line 677 "inform7/Chapter 34/The Map.w"
void PL__Map__oneway_map_connection(instance *go_from, instance *go_to, instance *forwards_dir, int certainty_level) ;
#line 694 "inform7/Chapter 34/The Map.w"
int PL__Map__map_complete_model(int stage) ;
#line 1036 "inform7/Chapter 34/The Map.w"
int PL__Map__map_add_to_World_index(instance *O) ;
#line 1043 "inform7/Chapter 34/The Map.w"
int PL__Map__map_annotate_in_World_index(instance *O) ;
#line 25 "inform7/Chapter 34/Map Connection Relations.w"
void PL__MapDirections__create_relations(void) ;
#line 38 "inform7/Chapter 34/Map Connection Relations.w"
int PL__MapDirections__assert_relations(binary_predicate *relation, instance *I0, instance *I1) ;
#line 47 "inform7/Chapter 34/Map Connection Relations.w"
void PL__MapDirections__REL_create_initial_stock(void) ;
#line 58 "inform7/Chapter 34/Map Connection Relations.w"
binary_predicate * PL__MapDirections__create_sketchy_mapping_direction(wording W) ;
#line 143 "inform7/Chapter 34/Map Connection Relations.w"
void PL__MapDirections__make_mapped_predicate(instance *I, char *ident) ;
#line 172 "inform7/Chapter 34/Map Connection Relations.w"
void PL__MapDirections__REL_create_second_stock(void) ;
#line 180 "inform7/Chapter 34/Map Connection Relations.w"
int PL__MapDirections__REL_typecheck(binary_predicate *bp, kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) ;
#line 201 "inform7/Chapter 34/Map Connection Relations.w"
int PL__MapDirections__REL_assert(binary_predicate *bp, inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) ;
#line 221 "inform7/Chapter 34/Map Connection Relations.w"
int PL__MapDirections__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) ;
#line 228 "inform7/Chapter 34/Map Connection Relations.w"
int PL__MapDirections__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) ;
#line 236 "inform7/Chapter 34/Map Connection Relations.w"
binary_predicate * PL__MapDirections__get_mapping_relation(instance *dir) ;
#line 241 "inform7/Chapter 34/Map Connection Relations.w"
instance * PL__MapDirections__get_mapping_direction(binary_predicate *bp) ;
#line 55 "inform7/Chapter 34/Spatial Geometry.w"
vector Geometry__vec(int x, int y, int z) ;
#line 64 "inform7/Chapter 34/Spatial Geometry.w"
int Geometry__vec_eq(vector U, vector V) ;
#line 69 "inform7/Chapter 34/Spatial Geometry.w"
int Geometry__vec_lateral(vector V) ;
#line 77 "inform7/Chapter 34/Spatial Geometry.w"
vector Geometry__vec_plus(vector U, vector V) ;
#line 83 "inform7/Chapter 34/Spatial Geometry.w"
vector Geometry__vec_minus(vector U, vector V) ;
#line 89 "inform7/Chapter 34/Spatial Geometry.w"
vector Geometry__vec_negate(vector V) ;
#line 95 "inform7/Chapter 34/Spatial Geometry.w"
vector Geometry__vec_scale(int lambda, vector V) ;
#line 104 "inform7/Chapter 34/Spatial Geometry.w"
int Geometry__vec_length_squared(vector V) ;
#line 108 "inform7/Chapter 34/Spatial Geometry.w"
float Geometry__vec_length(vector V) ;
#line 121 "inform7/Chapter 34/Spatial Geometry.w"
float Geometry__vec_angular_separation(vector E, vector D) ;
#line 134 "inform7/Chapter 34/Spatial Geometry.w"
cuboid Geometry__empty_cuboid(void) ;
#line 141 "inform7/Chapter 34/Spatial Geometry.w"
void Geometry__adjust_cuboid(cuboid *C, vector V) ;
#line 157 "inform7/Chapter 34/Spatial Geometry.w"
void Geometry__merge_cuboid(cuboid *C, cuboid X) ;
#line 173 "inform7/Chapter 34/Spatial Geometry.w"
void Geometry__cuboid_translate(cuboid *C, vector D) ;
#line 183 "inform7/Chapter 34/Spatial Geometry.w"
int Geometry__within_cuboid(vector P, cuboid C) ;
#line 200 "inform7/Chapter 34/Spatial Geometry.w"
int Geometry__cuboid_index(vector P, cuboid C) ;
#line 208 "inform7/Chapter 34/Spatial Geometry.w"
int Geometry__cuboid_volume(cuboid C) ;
#line 221 "inform7/Chapter 34/Spatial Geometry.w"
void Geometry__thicken_cuboid(cuboid *C, vector V, vector S) ;
#line 144 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__establish_spatial_coordinates(void) ;
#line 169 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__initialise_mapping_data(map_data *md) ;
#line 187 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__set_room_position(instance *R, vector P) ;
#line 193 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__set_room_position_breaking_cache(instance *R, vector P) ;
#line 201 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__lock_exit_in_place(instance *I, int exit, instance *I2) ;
#line 206 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__lock_one_exit(instance *F, int exit, instance *T) ;
#line 230 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__initialise_page_directions(void) ;
#line 244 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__map_direction_as_if(instance *I, instance *I2) ;
#line 248 "inform7/Chapter 34/Spatial Map.w"
instance * PL__SpatialMap__mapped_as_if(instance *I) ;
#line 262 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__direction_is_mappable(int story_direction) ;
#line 275 "inform7/Chapter 34/Spatial Map.w"
vector PL__SpatialMap__direction_as_vector(int story_direction) ;
#line 297 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__opposite(int story_direction) ;
#line 321 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__rotate_direction(int story_direction, int way) ;
#line 345 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__direction_is_lateral(int story_direction) ;
#line 355 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__direction_is_along_lattice(int story_direction) ;
#line 383 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__cell_position_for_direction(int story_direction, int *mx, int *my) ;
#line 406 "inform7/Chapter 34/Spatial Map.w"
char * PL__SpatialMap__find_icon_label(int story_direction) ;
#line 426 "inform7/Chapter 34/Spatial Map.w"
char * PL__SpatialMap__usual_Inform_direction_name(int story_direction) ;
#line 449 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__establish_benchmark_room(void) ;
#line 466 "inform7/Chapter 34/Spatial Map.w"
instance * PL__SpatialMap__room_exit(instance *origin, int dir_num, instance **via) ;
#line 486 "inform7/Chapter 34/Spatial Map.w"
instance * PL__SpatialMap__room_exit_as_indexed(instance *origin, int dir_num, instance **via) ;
#line 626 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__form_spatial_relationship(instance *R, int dir, instance *T) ;
#line 642 "inform7/Chapter 34/Spatial Map.w"
instance * PL__SpatialMap__read_smap(instance *from, int dir) ;
#line 652 "inform7/Chapter 34/Spatial Map.w"
instance * PL__SpatialMap__read_smap_cross(instance *from, int dir) ;
#line 662 "inform7/Chapter 34/Spatial Map.w"
instance * PL__SpatialMap__read_slock(instance *from, int dir) ;
#line 672 "inform7/Chapter 34/Spatial Map.w"
connected_submap * PL__SpatialMap__new_submap(void) ;
#line 695 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__add_room_to_submap(instance *R, connected_submap *sub) ;
#line 721 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__occupied_in_submap(connected_submap *sub, vector P) ;
#line 731 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__move_room_within_submap(connected_submap *sub, vector O, vector P) ;
#line 740 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__add_room_to_cache(connected_submap *sub, vector P, int m) ;
#line 799 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__free_incidence_cache(connected_submap *sub) ;
#line 809 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__empty_submap(connected_submap *sub) ;
#line 819 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__destroy_submap(connected_submap *sub) ;
#line 829 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__move_component(connected_submap *sub, vector D) ;
#line 848 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__create_submaps_from_zones(connected_submap *sub, int Z1_number, connected_submap *Zone1, int Z2_number, connected_submap *Zone2) ;
#line 865 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__create_zones_from_submaps(connected_submap *sub, int Z1_number, connected_submap *Zone1, int Z2_number, connected_submap *Zone2) ;
#line 905 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__create_map_component_around(instance *at) ;
#line 927 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__translate_room(instance *R, vector D) ;
#line 931 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__move_room_to(instance *R, vector P) ;
#line 947 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__move_anything_locked_to(instance *R) ;
#line 955 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__move_anything_locked_to_r(instance *R) ;
#line 974 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__lock_positions_in_submap(connected_submap *sub) ;
#line 1022 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__establish_natural_lengths(connected_submap *sub) ;
#line 1060 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__heat_sum(int h1, int h2) ;
#line 1072 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_submap_heat(connected_submap *sub) ;
#line 1096 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_room_heat(instance *R) ;
#line 1123 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_exit_heat(instance *from, int exit) ;
#line 1160 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__exit_aligned(instance *from, int exit) ;
#line 1191 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__position_submap(connected_submap *sub) ;
#line 1428 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__work_out_optimal_cutpoint(connected_submap *sub, instance **from, instance **to, int *way, instance **from2, instance **to2, int *way2) ;
#line 1524 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__assign_generation_count(instance *at, instance *from, int size, int *best_spread, instance **best_from1, instance **best_to1, int *best_dir1, instance **best_from2, instance **best_to2, int *best_dir2, int *contact_generation, instance **contact_from, instance **contact_to, int *contact_dir) ;
#line 1739 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__divide_into_zones_onecut(connected_submap *sub, instance *R1, instance *R2, int *Z1_count, int *Z2_count, int Z1, int Z2) ;
#line 1768 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__divide_into_zones_onecut_r(instance *at, instance *from, instance *our_capital, instance *foreign_capital, int *borders) ;
#line 1800 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__divide_into_zones_twocut(instance *div_F1, instance *div_T1, instance *other_F, instance *div_T2, int Z1, int Z2) ;
#line 1813 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__divide_into_zones_twocut_r(instance *at, instance *not_X1, instance *not_Y1, instance *not_X2, instance *not_Y2) ;
#line 1853 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__save_component_positions(connected_submap *sub) ;
#line 1859 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__restore_component_positions(connected_submap *sub) ;
#line 1891 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__cool_submap(connected_submap *sub) ;
#line 1929 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__cool_component_from(connected_submap *sub, instance *R) ;
#line 2010 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__undo_cool_exit(void) ;
#line 2015 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__cool_exit(instance *R, int exit) ;
#line 2045 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__quench_submap(connected_submap *sub, instance *avoid1, instance *avoid2) ;
#line 2100 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__diffuse_submap(connected_submap *sub) ;
#line 2172 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__diffuse_across(instance *at, instance *avoiding) ;
#line 2203 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__radiate_submap(connected_submap *sub) ;
#line 2300 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__radiate_across(instance *at, instance *avoiding, int not_this_way) ;
#line 2327 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__explode_submap(connected_submap *sub) ;
#line 2519 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__compare_components(const void *ent1, const void *ent2) ;
#line 2548 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__component_is_adjoining(connected_submap *sub) ;
#line 2553 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__component_is_isolated(connected_submap *sub) ;
#line 2562 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_component_placement_heat(connected_submap *sub) ;
#line 2579 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_cross_component_heat(connected_submap *sub) ;
#line 2585 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__find_link_to_placed_components(connected_submap *sub, instance **outer, instance **inner) ;
#line 2590 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__no_links_to_placed_components(connected_submap *sub) ;
#line 2594 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__no_links_to_other_components(connected_submap *sub) ;
#line 2607 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__cross_component_links(connected_submap *sub, instance **outer, instance **inner, int *heat, int posnd) ;
#line 2682 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_cross_link_heat(instance *R, instance *S, int dir) ;
#line 2687 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__component_metric(vector P1, vector P2, int dir) ;
#line 2748 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__log_precis_of_map(void) ;
#line 2850 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__visit_to_transcribe(parse_node *p) ;
#line 2861 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__index_room_connections(instance *R) ;
#line 2951 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__log_spatial_layout(void) ;
#line 32 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__calculate_map_grid(void) ;
#line 197 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__correct_pair(vector P, vector D, int from_i1, int from_i2, int to_i1, int to_i2) ;
#line 274 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__correct_diagonal(vector BL, int SW_to_NE) ;
#line 347 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__begin_variable_width_table(void) ;
#line 353 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__begin_map_table(int width, int height) ;
#line 359 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__begin_variable_width_table_with_background(char *bg_image) ;
#line 368 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__end_map_table(void) ;
#line 388 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__plot_map_icon(char *icon_name) ;
#line 392 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__plot_map_icon_with_tip(char *icon_name, char *tool_tip) ;
#line 403 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__render_map_as_HTML(void) ;
#line 531 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__devise_level_rubric(int z, char **level_rubric, int *par) ;
#line 572 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__render_single_room_as_HTML(instance *R) ;
#line 597 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__plot_map_level(int x0, int x1, int y0, int y1, int z, int pass) ;
#line 869 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__plot_map_cell(int pass, vector P, int i1, int i2, int faux_exit) ;
#line 948 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__index_room_square(instance *I, int pass) ;
#line 1035 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__colour_chip(instance *I, instance *Reg, parse_node *at) ;
#line 1050 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__add_region_key(void) ;
#line 1058 "inform7/Chapter 34/HTML Map.w"
int PL__HTMLMap__add_key_for(instance *reg) ;
#line 158 "inform7/Chapter 34/EPS Map.w"
int PL__EPSMap__get_map_variable_index(char *name) ;
#line 168 "inform7/Chapter 34/EPS Map.w"
int PL__EPSMap__get_map_variable_index_forgivingly(char *name) ;
#line 181 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__prepare_map_parameter_scope(map_parameter_scope *scope) ;
#line 199 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__put_mp(char *name, map_parameter_scope *scope, instance *scope_I, kind *scope_k, char *put_string, int put_integer) ;
#line 229 "inform7/Chapter 34/EPS Map.w"
map_parameter_scope * PL__EPSMap__scope_for_single_room(instance *rm) ;
#line 233 "inform7/Chapter 34/EPS Map.w"
int PL__EPSMap__obj_in_region(instance *I, instance *reg) ;
#line 242 "inform7/Chapter 34/EPS Map.w"
char * PL__EPSMap__get_string_mp(char *name, map_parameter_scope *scope) ;
#line 255 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__put_string_mp(char *name, map_parameter_scope *scope, char *val) ;
#line 265 "inform7/Chapter 34/EPS Map.w"
int PL__EPSMap__get_int_mp(char *name, map_parameter_scope *scope) ;
#line 275 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__put_int_mp(char *name, map_parameter_scope *scope, int val) ;
#line 286 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__traverse_for_map_parameters(int pass) ;
#line 291 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__look_for_map_parameters(parse_node *p, int *pass) ;
#line 495 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__new_map_hint_sentence(int pass, parse_node *p) ;
#line 773 "inform7/Chapter 34/EPS Map.w"
int PL__EPSMap__parse_eps_map_offset(char *original) ;
#line 800 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__render_map_as_EPS(void) ;
#line 880 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_map(OUTPUT_STREAM) ;
#line 1150 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__plot_text_at(OUTPUT_STREAM, char *text_to_plot, instance *I, int abbrev_to, char *font, int x, int y, int pointsize, int centre_h, int centre_v) ;
#line 1218 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_header(OUTPUT_STREAM, int bounding_box_width, int bounding_box_height, char *default_font, int default_point_size) ;
#line 1232 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_circular_path(OUTPUT_STREAM, int x0, int y0, int radius) ;
#line 1239 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_rectangular_path(OUTPUT_STREAM, int x0, int y0, int x1, int y1) ;
#line 1250 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_room_boundary_path(OUTPUT_STREAM, int bx, int by, int boxsize, char *shape) ;
#line 1264 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_horizontal_line_path(OUTPUT_STREAM, int x0, int x1, int y) ;
#line 1273 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_dashed_arrow(OUTPUT_STREAM, int length, vector Dir, int x0, int y0) ;
#line 1287 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_Bezier_curve(OUTPUT_STREAM, int stiffness0, int stiffness1, int x0, int y0, int exit0, int x1, int y1, int exit1) ;
#line 1305 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_line_width_setting(OUTPUT_STREAM, int new) ;
#line 1310 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_line_width_unsetting(OUTPUT_STREAM) ;
#line 1318 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_text(OUTPUT_STREAM, char *text, int x, int y, char *font, int pointsize, int centre_h, int centre_v) ;
#line 1337 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_set_colour(OUTPUT_STREAM, char *htmlcolour) ;
#line 1345 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__choose_colour_beam(OUTPUT_STREAM, char hex1, char hex2) ;
#line 1350 "inform7/Chapter 34/EPS Map.w"
int PL__EPSMap__hex_to_int(char hex) ;
#line 1376 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_set_greyscale(OUTPUT_STREAM, int N) ;
#line 16 "inform7/Chapter 34/Showme Command.w"
void PL__Showme__start(void) ;
#line 31 "inform7/Chapter 34/Showme Command.w"
void PL__Showme__compile_SHOWME_details(OUTPUT_STREAM) ;
#line 37 "inform7/Chapter 34/Showme Command.w"
void PL__Showme__compile_SHOWME_type(OUTPUT_STREAM, int val) ;
#line 47 "inform7/Chapter 34/Showme Command.w"
void PL__Showme__compile_SHOWME_type_subj(OUTPUT_STREAM, int val, inference_subject *subj) ;
#line 98 "inform7/Chapter 34/Showme Command.w"
int PL__Showme__is_property_worth_SHOWME(OUTPUT_STREAM, inference_subject *subj, property *prn) ;
#line 102 "inform7/Chapter 34/Showme Command.w"
void PL__Showme__compile_property_SHOWME(OUTPUT_STREAM, inference_subject *subj, property *prn) ;
#line 109 "inform7/Chapter 34/Showme Command.w"
int PL__Showme__SHOWME_primitive(OUTPUT_STREAM, inference_subject *subj, property *prn, int comp) ;
#line 97 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__start(void) ;
#line 106 "inform7/Chapter 34/Scenes.w"
int PL__Scenes__scenes_new_base_kind_notify(kind *new_base, char *name, wording W) ;
#line 124 "inform7/Chapter 34/Scenes.w"
int PL__Scenes__scenes_new_property_notify(property *prn) ;
#line 137 "inform7/Chapter 34/Scenes.w"
int PL__Scenes__scenes_new_named_instance_notify(instance *I) ;
#line 150 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__new_scene(instance *I) ;
#line 190 "inform7/Chapter 34/Scenes.w"
scene * PL__Scenes__from_named_constant(instance *I) ;
#line 198 "inform7/Chapter 34/Scenes.w"
wording PL__Scenes__get_name(scene *sc) ;
#line 205 "inform7/Chapter 34/Scenes.w"
int PL__Scenes__parse_scene_end_name(scene *sc, wording EW, int create) ;
#line 238 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__new_scene_rulebook(scene *sc, int end) ;
#line 315 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__begins_or_ends_when(parse_node *p) ;
#line 443 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__new_scene_anchor(parse_node *p, int phase) ;
#line 558 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__DetectSceneChange_routine(OUTPUT_STREAM) ;
#line 596 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__test_scene_end(OUTPUT_STREAM, scene *sc, int end) ;
#line 653 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__compile_scene_end(OUTPUT_STREAM, scene *sc, int end) ;
#line 668 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__compile_scene_end_dash(OUTPUT_STREAM, scene *sc, int end) ;
#line 780 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__ShowSceneStatus_routine(OUTPUT_STREAM) ;
#line 824 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__PrintSceneName_routine(OUTPUT_STREAM) ;
#line 869 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__test_during_clause(OUTPUT_STREAM, parse_node *spec) ;
#line 20 "inform7/Chapter 34/Temporal Map.w"
void PL__Scenes__Index__index(void) ;
#line 32 "inform7/Chapter 34/Temporal Map.w"
void PL__Scenes__Index__index_rules(void) ;
#line 255 "inform7/Chapter 34/Temporal Map.w"
void PL__Scenes__Index__index_from_scene(scene *sc, int depth, int end, scene *sc_from, scene **sorted, int nr) ;
#line 340 "inform7/Chapter 34/Temporal Map.w"
void PL__Scenes__Index__scene_icon(char *si) ;
#line 344 "inform7/Chapter 34/Temporal Map.w"
void PL__Scenes__Index__scene_icon_append(char *si) ;
#line 348 "inform7/Chapter 34/Temporal Map.w"
void PL__Scenes__Index__scene_icon_legend(char *si, char *gloss) ;
#line 352 "inform7/Chapter 34/Temporal Map.w"
void PL__Scenes__Index__scene_icon_unspaced(char *si) ;
#line 361 "inform7/Chapter 34/Temporal Map.w"
int PL__Scenes__Index__compare_scenes(const void *ent1, const void *ent2) ;
#line 106 "inform7/Chapter 35/Actions.w"
void PL__Actions__start(void) ;
#line 121 "inform7/Chapter 35/Actions.w"
int PL__Actions__actions_new_base_kind_notify(kind *new_base, char *name, wording W) ;
#line 137 "inform7/Chapter 35/Actions.w"
int PL__Actions__actions_compile_constant(OUTPUT_STREAM, kind *K, parse_node *spec) ;
#line 161 "inform7/Chapter 35/Actions.w"
int PL__Actions__actions_offered_property(kind *K, parse_node *owner, parse_node *what) ;
#line 171 "inform7/Chapter 35/Actions.w"
int PL__Actions__actions_offered_specification(parse_node *owner, wording W) ;
#line 184 "inform7/Chapter 35/Actions.w"
int PL__Actions__actions_typecheck_equality(kind *K1, kind *K2) ;
#line 198 "inform7/Chapter 35/Actions.w"
int PL__Actions__actions_forbid_setting(kind *K) ;
#line 226 "inform7/Chapter 35/Actions.w"
action_name * PL__Actions__act_new(wording W, int implemented_by_I7) ;
#line 332 "inform7/Chapter 35/Actions.w"
int PL__Actions__action_names_overlap(action_name *an1, action_name *an2) ;
#line 345 "inform7/Chapter 35/Actions.w"
void PL__Actions__log(action_name *an) ;
#line 388 "inform7/Chapter 35/Actions.w"
action_name * PL__Actions__longest_null(wording W, int tense, int *excess) ;
#line 401 "inform7/Chapter 35/Actions.w"
int PL__Actions__it_optional(action_name *an) ;
#line 405 "inform7/Chapter 35/Actions.w"
int PL__Actions__abbreviable(action_name *an) ;
#line 409 "inform7/Chapter 35/Actions.w"
char * PL__Actions__identifier(action_name *an) ;
#line 413 "inform7/Chapter 35/Actions.w"
rulebook * PL__Actions__get_fragmented_rulebook(action_name *an, rulebook *rb) ;
#line 420 "inform7/Chapter 35/Actions.w"
rulebook * PL__Actions__switch_fragmented_rulebook(action_name *new_an, rulebook *orig) ;
#line 431 "inform7/Chapter 35/Actions.w"
void PL__Actions__actions_set_specification_text(action_name *an, int wn) ;
#line 434 "inform7/Chapter 35/Actions.w"
int PL__Actions__an_get_specification_text(action_name *an) ;
#line 443 "inform7/Chapter 35/Actions.w"
void PL__Actions__name_all(void) ;
#line 451 "inform7/Chapter 35/Actions.w"
void PL__Actions__translates(wording W, parse_node *p2) ;
#line 473 "inform7/Chapter 35/Actions.w"
int PL__Actions__get_stem_length(action_name *an) ;
#line 535 "inform7/Chapter 35/Actions.w"
void PL__Actions__an_add_variable(action_name *an, parse_node *cnode) ;
#line 656 "inform7/Chapter 35/Actions.w"
stacked_variable * PL__Actions__parse_match_clause(action_name *an, wording W) ;
#line 660 "inform7/Chapter 35/Actions.w"
void PL__Actions__compile_action_name_var_creators(OUTPUT_STREAM) ;
#line 840 "inform7/Chapter 35/Actions.w"
void PL__Actions__act_parse_definition(parse_node *p) ;
#line 872 "inform7/Chapter 35/Actions.w"
int PL__Actions__is_out_of_world(action_name *an) ;
#line 877 "inform7/Chapter 35/Actions.w"
kind * PL__Actions__get_data_type_of_noun(action_name *an) ;
#line 881 "inform7/Chapter 35/Actions.w"
kind * PL__Actions__get_data_type_of_second_noun(action_name *an) ;
#line 885 "inform7/Chapter 35/Actions.w"
wording PL__Actions__set_text_to_name_tensed(action_name *an, int tense) ;
#line 890 "inform7/Chapter 35/Actions.w"
int PL__Actions__can_have_parameters(action_name *an) ;
#line 895 "inform7/Chapter 35/Actions.w"
int PL__Actions__get_max_parameters(action_name *an) ;
#line 899 "inform7/Chapter 35/Actions.w"
int PL__Actions__get_min_parameters(action_name *an) ;
#line 911 "inform7/Chapter 35/Actions.w"
int PL__Actions__can_be_compiled_in_past_tense(action_name *an) ;
#line 920 "inform7/Chapter 35/Actions.w"
void PL__Actions__compile_action_bitmap_property(OUTPUT_STREAM) ;
#line 925 "inform7/Chapter 35/Actions.w"
void PL__Actions__ActionHappened_array(OUTPUT_STREAM) ;
#line 937 "inform7/Chapter 35/Actions.w"
void PL__Actions__add_gl(action_name *an, grammar_line *gl) ;
#line 942 "inform7/Chapter 35/Actions.w"
void PL__Actions__remove_gl(action_name *an) ;
#line 949 "inform7/Chapter 35/Actions.w"
void PL__Actions__check_types_for_grammar(action_name *an, int tok_values, kind **tok_value_kinds) ;
#line 1061 "inform7/Chapter 35/Actions.w"
void PL__Actions__compile_action_routines(OUTPUT_STREAM) ;
#line 1080 "inform7/Chapter 35/Actions.w"
void PL__Actions__ActionData_array(OUTPUT_STREAM) ;
#line 1121 "inform7/Chapter 35/Actions.w"
void PL__Actions__DB_Action_Details(OUTPUT_STREAM) ;
#line 1170 "inform7/Chapter 35/Actions.w"
void PL__Actions__cat_something2(OUTPUT_STREAM, action_name *an, int n) ;
#line 1181 "inform7/Chapter 35/Actions.w"
void PL__Actions__print_action_text_to(wording W, int start, OUTPUT_STREAM) ;
#line 1191 "inform7/Chapter 35/Actions.w"
void PL__Actions__ActionCoding_array(OUTPUT_STREAM) ;
#line 1207 "inform7/Chapter 35/Actions.w"
int PL__Actions__index(action_name *an, int pass, extension_file **ext, heading **current_area, int f, int *new_par, int bold, int on_details_page) ;
#line 1327 "inform7/Chapter 35/Actions.w"
void PL__Actions__act_index_something(action_name *an, int argc) ;
#line 38 "inform7/Chapter 35/Action Name Lists.w"
action_name_list * PL__Actions__Lists__anl_new(void) ;
#line 53 "inform7/Chapter 35/Action Name Lists.w"
void PL__Actions__Lists__log(action_name_list *anl) ;
#line 71 "inform7/Chapter 35/Action Name Lists.w"
void PL__Actions__Lists__log_briefly(action_name_list *anl) ;
#line 91 "inform7/Chapter 35/Action Name Lists.w"
action_name * PL__Actions__Lists__get_singleton_action(action_name_list *anl) ;
#line 271 "inform7/Chapter 35/Action Name Lists.w"
action_name_list * PL__Actions__Lists__flip_anl_parity(action_name_list *anl, int flip_all) ;
#line 287 "inform7/Chapter 35/Action Name Lists.w"
action_name_list * PL__Actions__Lists__parse(wording W, int tense) ;
#line 300 "inform7/Chapter 35/Action Name Lists.w"
action_name_list * PL__Actions__Lists__anl_parse_internal(wording W) ;
#line 382 "inform7/Chapter 35/Action Name Lists.w"
action_name_list * PL__Actions__Lists__extract_actions_only(wording W) ;
#line 400 "inform7/Chapter 35/Action Name Lists.w"
action_name * PL__Actions__Lists__get_single_action(action_name_list *anl) ;
#line 427 "inform7/Chapter 35/Action Name Lists.w"
int PL__Actions__Lists__get_explicit_anyone_flag(action_name_list *anl) ;
#line 432 "inform7/Chapter 35/Action Name Lists.w"
int PL__Actions__Lists__negated(action_name_list *anl) ;
#line 437 "inform7/Chapter 35/Action Name Lists.w"
void PL__Actions__Lists__compile(OUTPUT_STREAM, action_name_list *anl) ;
#line 477 "inform7/Chapter 35/Action Name Lists.w"
int PL__Actions__Lists__compare_specificity(action_name_list *anl1, action_name_list *anl2) ;
#line 489 "inform7/Chapter 35/Action Name Lists.w"
int PL__Actions__Lists__count_actions_covered(action_name_list *anl) ;
#line 126 "inform7/Chapter 35/Action Patterns.w"
action_pattern PL__Actions__Patterns__new(void) ;
#line 155 "inform7/Chapter 35/Action Patterns.w"
ap_optional_clause * PL__Actions__Patterns__apoc_new(stacked_variable *stv, parse_node *spec) ;
#line 164 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__ap_add_optional_clause(action_pattern *ap, ap_optional_clause *apoc) ;
#line 207 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__ap_count_optional_clauses(action_pattern *ap) ;
#line 218 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__compare_specificity_of_apoc_list(action_pattern *ap1, action_pattern *ap2) ;
#line 243 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__log(action_pattern *ap) ;
#line 270 "inform7/Chapter 35/Action Patterns.w"
action_pattern * PL__Actions__Patterns__ap_store(action_pattern ap) ;
#line 276 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__is_named(action_pattern *ap) ;
#line 283 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__is_valid(action_pattern *ap) ;
#line 288 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__is_request(action_pattern *ap) ;
#line 293 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__within_action_context(action_pattern *ap, action_name *an) ;
#line 306 "inform7/Chapter 35/Action Patterns.w"
action_name_list * PL__Actions__Patterns__list(action_pattern *ap) ;
#line 311 "inform7/Chapter 35/Action Patterns.w"
action_name * PL__Actions__Patterns__required_action(action_pattern *ap) ;
#line 317 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__object_based(action_pattern *ap) ;
#line 322 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__is_unspecific(action_pattern *ap) ;
#line 335 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__ap_clause_is_unspecific(parse_node *spec) ;
#line 341 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__is_overspecific(action_pattern *ap) ;
#line 352 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__suppress_action_testing(action_pattern *ap) ;
#line 360 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__categorise_as(action_pattern *ap, wording W) ;
#line 395 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__clear_validation_case(void) ;
#line 401 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__get_validation_case(parse_node **spec, kind **set_K, kind **set_K2) ;
#line 412 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__suspend_validation(int state) ;
#line 416 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__validate_parameter(parse_node *spec, kind *K) ;
#line 461 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__validate_when(parse_node *spec) ;
#line 469 "inform7/Chapter 35/Action Patterns.w"
parse_node * PL__Actions__Patterns__nullify_nonspecific_references(parse_node *spec) ;
#line 475 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__check_going(parse_node *spec, char *keyword, kind *ka, kind *kb) ;
#line 516 "inform7/Chapter 35/Action Patterns.w"
action_pattern PL__Actions__Patterns__parse_parametric(wording W, kind *K) ;
#line 527 "inform7/Chapter 35/Action Patterns.w"
parse_node * PL__Actions__Patterns__parse_action_parameter(wording W) ;
#line 532 "inform7/Chapter 35/Action Patterns.w"
parse_node * PL__Actions__Patterns__parse_verified_action_parameter(wording W) ;
#line 715 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__suppress(void) ;
#line 721 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__resume(int old_state) ;
#line 775 "inform7/Chapter 35/Action Patterns.w"
action_pattern * PL__Actions__Patterns__ap_parse_inner(wording W, int tense) ;
#line 952 "inform7/Chapter 35/Action Patterns.w"
action_pattern PL__Actions__Patterns__parse_action_pattern_dash(wording W) ;
#line 1320 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__ap_count_rooms(action_pattern *ap) ;
#line 1328 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__ap_count_going(action_pattern *ap) ;
#line 1336 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__count_aspects(action_pattern *ap) ;
#line 1359 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__compare_specificity(action_pattern *ap1, action_pattern *ap2) ;
#line 1481 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__put_action_object_into_ap(action_pattern *ap, int pos, wording W) ;
#line 1503 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__compile_try(OUTPUT_STREAM, action_pattern *ap, int store_instead) ;
#line 1549 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__compile_try_action_parameter(OUTPUT_STREAM, parse_node *spec, kind *required_kind) ;
#line 1575 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__CAP_insert_clause(int f, OUTPUT_STREAM, char *i6_condition) ;
#line 1601 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__compile_pattern_match_clause(int f, OUTPUT_STREAM, nonlocal_variable *I6_global_variable, parse_node *spec, kind *verify_as_kind, int adapt_region) ;
#line 1737 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__as_stored_action(OUTPUT_STREAM, action_pattern *ap) ;
#line 1771 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__compile_pattern_match(OUTPUT_STREAM, action_pattern ap, int naming_mode) ;
#line 1956 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__refers_to_past(action_pattern *ap) ;
#line 1961 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__convert_to_present_tense(action_pattern *ap) ;
#line 1965 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__pta_acceptable(parse_node *spec) ;
#line 1974 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__makes_callings(action_pattern *ap) ;
#line 1984 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__compile_present_tense(OUTPUT_STREAM, action_pattern *ap) ;
#line 1988 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__compile_past_tense(OUTPUT_STREAM, action_pattern *ap) ;
#line 2031 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__is_an_action_variable(parse_node *spec) ;
#line 24 "inform7/Chapter 35/Looping Over Scope.w"
loop_over_scope * PL__Actions__ScopeLoops__new(parse_node *what) ;
#line 35 "inform7/Chapter 35/Looping Over Scope.w"
int PL__Actions__ScopeLoops__compilation_coroutine(OUTPUT_STREAM) ;
#line 27 "inform7/Chapter 35/Named Action Patterns.w"
named_action_pattern * PL__Actions__Patterns__Named__nap_new(wording W) ;
#line 37 "inform7/Chapter 35/Named Action Patterns.w"
named_action_pattern * PL__Actions__Patterns__Named__by_name(wording W) ;
#line 44 "inform7/Chapter 35/Named Action Patterns.w"
char * PL__Actions__Patterns__Named__identifier(named_action_pattern *nap) ;
#line 48 "inform7/Chapter 35/Named Action Patterns.w"
void PL__Actions__Patterns__Named__add(action_pattern *app, wording W) ;
#line 64 "inform7/Chapter 35/Named Action Patterns.w"
int PL__Actions__Patterns__Named__within_action_context(named_action_pattern *nap, action_name *an) ;
#line 71 "inform7/Chapter 35/Named Action Patterns.w"
void PL__Actions__Patterns__Named__index(void) ;
#line 98 "inform7/Chapter 35/Named Action Patterns.w"
void PL__Actions__Patterns__Named__compile(OUTPUT_STREAM) ;
#line 39 "inform7/Chapter 35/Actions Index.w"
void PL__Actions__Index__index_meta_verb(char *t) ;
#line 48 "inform7/Chapter 35/Actions Index.w"
void PL__Actions__Index__test_verb(char *t) ;
#line 57 "inform7/Chapter 35/Actions Index.w"
void PL__Actions__Index__verb_definition(char *p, char *trueverb, wording W) ;
#line 81 "inform7/Chapter 35/Actions Index.w"
command_index_entry * PL__Actions__Index__vie_new_from(char *headword, grammar_verb *gv, int nature) ;
#line 91 "inform7/Chapter 35/Actions Index.w"
void PL__Actions__Index__commands(void) ;
#line 152 "inform7/Chapter 35/Actions Index.w"
void PL__Actions__Index__alphabetical(void) ;
#line 218 "inform7/Chapter 35/Actions Index.w"
int PL__Actions__Index__compare_action_names(const void *ent1, const void *ent2) ;
#line 227 "inform7/Chapter 35/Actions Index.w"
void PL__Actions__Index__page(void) ;
#line 240 "inform7/Chapter 35/Actions Index.w"
void PL__Actions__Index__detail_pages(void) ;
#line 262 "inform7/Chapter 35/Actions Index.w"
void PL__Actions__Index__tokens(void) ;
#line 64 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__traverse(void) ;
#line 67 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__visit(parse_node *p) ;
#line 90 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__compile_understanding(OUTPUT_STREAM, wording W, int table_entry) ;
#line 447 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__understand_sentence(wording W, wording ASW) ;
#line 523 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__understand_the_command(wording W, wording ASW) ;
#line 583 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__understand_property_block(property *pr, int level, inference_subject *subj, wording WHENW) ;
#line 610 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__understand_nothing(understanding_reference *ur, wording WHENW) ;
#line 631 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__understand_block(wording W, understanding_reference *ur, wording WHENW, int table_entry) ;
#line 908 "inform7/Chapter 36/Traverse for Grammar.w"
int PL__Parsing__valid_new_token_name(wording W) ;
#line 52 "inform7/Chapter 36/Grammar Properties.w"
parsing_data * PL__Parsing__Visibility__new_data(inference_subject *subj) ;
#line 58 "inform7/Chapter 36/Grammar Properties.w"
parsing_pp_data * PL__Parsing__Visibility__new_pp_data(property_permission *pp) ;
#line 69 "inform7/Chapter 36/Grammar Properties.w"
void PL__Parsing__Visibility__start(void) ;
#line 77 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__parsing_new_subject_notify(inference_subject *subj) ;
#line 82 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__parsing_new_permission_notify(property_permission *new_pp) ;
#line 107 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__parsing_new_variable_notify(nonlocal_variable *var) ;
#line 131 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__parsing_estimate_property_usage(kind *k, int *words_used) ;
#line 143 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__parsing_complete_model(int stage) ;
#line 276 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__seek(property *pr, inference_subject *subj, int level, wording WHENW) ;
#line 293 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__any_property_visible_to_subject(inference_subject *subj, int allow_inheritance) ;
#line 304 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__get_level(property_permission *pp) ;
#line 308 "inform7/Chapter 36/Grammar Properties.w"
parse_node * PL__Parsing__Visibility__get_condition(property_permission *pp) ;
#line 327 "inform7/Chapter 36/Grammar Properties.w"
void PL__Parsing__Visibility__log_parsing_visibility(inference_subject *infs) ;
#line 89 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb * PL__Parsing__Verbs__gv_new(int gv_is) ;
#line 109 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__log(grammar_verb *gv) ;
#line 150 "inform7/Chapter 36/Grammar Verbs.w"
wording PL__Parsing__Verbs__get_verb_text(grammar_verb *gv) ;
#line 154 "inform7/Chapter 36/Grammar Verbs.w"
int PL__Parsing__Verbs__gv_is_genuinely_verbal(grammar_verb *gv) ;
#line 166 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb * PL__Parsing__Verbs__find_or_create_command(wording W) ;
#line 184 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb * PL__Parsing__Verbs__find_command(wording W) ;
#line 211 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__add_command(grammar_verb *gv, wording W) ;
#line 227 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__remove_command(grammar_verb *gv, wording W) ;
#line 257 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__index_command_aliases(grammar_verb *gv) ;
#line 264 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__remove_action(grammar_verb *gv, action_name *an) ;
#line 272 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__gv_compile_Verb_directive_header(OUTPUT_STREAM, grammar_verb *gv) ;
#line 306 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__reserve(char *verb_name) ;
#line 312 "inform7/Chapter 36/Grammar Verbs.w"
int PL__Parsing__Verbs__command_verb_reserved(char *verb_tried) ;
#line 322 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__normalise_cv_to(char *from, char *to) ;
#line 339 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__make_command_index_entries(grammar_verb *gv) ;
#line 350 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__index_normal(grammar_verb *gv, char *headword) ;
#line 354 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__index_alias(grammar_verb *gv, char *headword) ;
#line 367 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb * PL__Parsing__Verbs__named_token_new(wording W) ;
#line 376 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb * PL__Parsing__Verbs__named_token_by_name(wording W) ;
#line 387 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__index_tokens(void) ;
#line 407 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__index_tokens_for(wording W, char *special, parse_node *where, grammar_line *defns, char *help, char *explanation) ;
#line 424 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__translates(wording W, parse_node *p2) ;
#line 437 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__compile_i6_token(OUTPUT_STREAM, grammar_verb *gv) ;
#line 450 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb * PL__Parsing__Verbs__consultation_new(void) ;
#line 463 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb * PL__Parsing__Verbs__for_subject(inference_subject *subj) ;
#line 473 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__take_out_one_word_grammar(OUTPUT_STREAM, grammar_verb *gv) ;
#line 479 "inform7/Chapter 36/Grammar Verbs.w"
int PL__Parsing__Verbs__allow_mixed_lines(grammar_verb *gv) ;
#line 490 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb * PL__Parsing__Verbs__for_kind(kind *K) ;
#line 506 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb * PL__Parsing__Verbs__for_prn(property *prn) ;
#line 522 "inform7/Chapter 36/Grammar Verbs.w"
int PL__Parsing__Verbs__is_empty(grammar_verb *gv) ;
#line 527 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__add_line(grammar_verb *gv, grammar_line *gl) ;
#line 549 "inform7/Chapter 36/Grammar Verbs.w"
kind * PL__Parsing__Verbs__get_data_type_as_token(grammar_verb *gv) ;
#line 558 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__compile_conditions(OUTPUT_STREAM) ;
#line 571 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__prepare(void) ;
#line 581 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__gv_slash_all(void) ;
#line 597 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__gv_determine_all(void) ;
#line 608 "inform7/Chapter 36/Grammar Verbs.w"
parse_node * PL__Parsing__Verbs__determine(grammar_verb *gv, int depth) ;
#line 655 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__compile_all(OUTPUT_STREAM) ;
#line 701 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__compile(OUTPUT_STREAM, grammar_verb *gv) ;
#line 761 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__gv_compile_parse_name_lines(OUTPUT_STREAM, grammar_verb *gv) ;
#line 784 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__gv_compile_lines(OUTPUT_STREAM, grammar_verb *gv) ;
#line 799 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__sort_grammar_verb(grammar_verb *gv) ;
#line 81 "inform7/Chapter 36/Grammar Lines.w"
grammar_line * PL__Parsing__Lines__new(int wn, action_name *ac, parse_node *token_list, int reversed, int pluralised) ;
#line 110 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__log(grammar_line *gl) ;
#line 114 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__set_single_type(grammar_line *gl, parse_node *gl_value) ;
#line 123 "inform7/Chapter 36/Grammar Lines.w"
int PL__Parsing__Lines__list_length(grammar_line *list_head) ;
#line 130 "inform7/Chapter 36/Grammar Lines.w"
grammar_line * PL__Parsing__Lines__list_add(grammar_line *list_head, grammar_line *new_gl) ;
#line 141 "inform7/Chapter 36/Grammar Lines.w"
grammar_line * PL__Parsing__Lines__list_remove(grammar_line *list_head, action_name *find) ;
#line 167 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__line_list_compile_condition_tokens(OUTPUT_STREAM, grammar_line *list_head) ;
#line 216 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__set_understand_when(grammar_line *gl, wording W) ;
#line 219 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__set_understand_prop(grammar_line *gl, pcalc_prop *prop) ;
#line 222 "inform7/Chapter 36/Grammar Lines.w"
int PL__Parsing__Lines__conditional(grammar_line *gl) ;
#line 228 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__gl_compile_condition_token_as_needed(OUTPUT_STREAM, grammar_line *gl) ;
#line 268 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__gl_compile_extra_token_for_condition(OUTPUT_STREAM, grammar_line *gl, int gv_is, int current_label) ;
#line 301 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__set_mistake(grammar_line *gl, int wn) ;
#line 306 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__gl_compile_mistake_token_as_needed(OUTPUT_STREAM, grammar_line *gl) ;
#line 317 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__gl_compile_extra_token_for_mistake(OUTPUT_STREAM, grammar_line *gl, int gv_is, int current_label) ;
#line 327 "inform7/Chapter 36/Grammar Lines.w"
int PL__Parsing__Lines__gl_compile_result_of_mistake(OUTPUT_STREAM, grammar_line *gl) ;
#line 332 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__MistakeActionSub_routine(OUTPUT_STREAM) ;
#line 364 "inform7/Chapter 36/Grammar Lines.w"
int PL__Parsing__Lines__gl_contains_single_unconditional_word(grammar_line *gl) ;
#line 386 "inform7/Chapter 36/Grammar Lines.w"
grammar_line * PL__Parsing__Lines__list_take_out_one_word_grammar(OUTPUT_STREAM, grammar_line *list_head) ;
#line 407 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__line_list_slash(grammar_line *gl_head) ;
#line 427 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__slash_grammar_line(grammar_line *gl) ;
#line 504 "inform7/Chapter 36/Grammar Lines.w"
parse_node * PL__Parsing__Lines__line_list_determine(grammar_line *list_head, int depth, int gv_is, grammar_verb *gv, int genuinely_verbal) ;
#line 557 "inform7/Chapter 36/Grammar Lines.w"
parse_node * PL__Parsing__Lines__gl_determine(grammar_line *gl, int depth, int gv_is, grammar_verb *gv, int genuinely_verbal) ;
#line 633 "inform7/Chapter 36/Grammar Lines.w"
grammar_line * PL__Parsing__Lines__list_sort(grammar_line *list_head) ;
#line 826 "inform7/Chapter 36/Grammar Lines.w"
int PL__Parsing__Lines__grammar_line_must_precede(grammar_line *L1, grammar_line *L2) ;
#line 886 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__sorted_line_list_compile(OUTPUT_STREAM, grammar_line *list_head, int gv_is, grammar_verb *gv, int genuinely_verbal) ;
#line 906 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__reset_labels(void) ;
#line 918 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__compile_grammar_line(OUTPUT_STREAM, grammar_line *gl, int gv_is, grammar_verb *gv, int genuinely_verbal) ;
#line 1025 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__compile_token_line(OUTPUT_STREAM, int code_mode, parse_node *pn, parse_node *pn_to, int gv_is, int consult_mode, int *token_values, kind **token_value_kinds) ;
#line 1139 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__compile_slash_gprs(OUTPUT_STREAM) ;
#line 1160 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__sorted_list_index_normal(grammar_line *list_head, char *headword) ;
#line 1166 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__gl_index_normal(grammar_line *gl, char *headword) ;
#line 1201 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__list_assert_ownership(grammar_line *list_head, grammar_verb *gv) ;
#line 1210 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__list_with_action_add(grammar_line *list_head, grammar_line *gl) ;
#line 1221 "inform7/Chapter 36/Grammar Lines.w"
int PL__Parsing__Lines__index_list_with_action(grammar_line *gl) ;
#line 1246 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__index_list_for_token(grammar_line *gl) ;
#line 27 "inform7/Chapter 36/Grammar Types.w"
grammar_type PL__Parsing__Tokens__Types__new(int supports_return_type) ;
#line 45 "inform7/Chapter 36/Grammar Types.w"
int PL__Parsing__Tokens__Types__add_type(grammar_type *gty, parse_node *spec, int multiple_flag, int score) ;
#line 65 "inform7/Chapter 36/Grammar Types.w"
int PL__Parsing__Tokens__Types__has_return_type(grammar_type *gty) ;
#line 70 "inform7/Chapter 36/Grammar Types.w"
int PL__Parsing__Tokens__Types__get_no_resulting_values(grammar_type *gty) ;
#line 74 "inform7/Chapter 36/Grammar Types.w"
parse_node * PL__Parsing__Tokens__Types__get_single_type(grammar_type *gty) ;
#line 83 "inform7/Chapter 36/Grammar Types.w"
void PL__Parsing__Tokens__Types__set_single_type(grammar_type *gty, parse_node *spec) ;
#line 91 "inform7/Chapter 36/Grammar Types.w"
void PL__Parsing__Tokens__Types__compile_to_string(OUTPUT_STREAM, grammar_type *gty) ;
#line 95 "inform7/Chapter 36/Grammar Types.w"
kind * PL__Parsing__Tokens__Types__get_data_type_as_token(grammar_type *gty) ;
#line 109 "inform7/Chapter 36/Grammar Types.w"
int PL__Parsing__Tokens__Types__must_precede(grammar_type *gty1, grammar_type *gty2) ;
#line 81 "inform7/Chapter 36/Grammar Tokens.w"
void PL__Parsing__Tokens__break_into_tokens(parse_node *pn, wording W) ;
#line 112 "inform7/Chapter 36/Grammar Tokens.w"
int PL__Parsing__Tokens__is_literal(parse_node *pn) ;
#line 121 "inform7/Chapter 36/Grammar Tokens.w"
int PL__Parsing__Tokens__is_multiple(parse_node *pn) ;
#line 135 "inform7/Chapter 36/Grammar Tokens.w"
int PL__Parsing__Tokens__is_text(parse_node *pn) ;
#line 148 "inform7/Chapter 36/Grammar Tokens.w"
int PL__Parsing__Tokens__gsb_for_special_token(int gtc) ;
#line 166 "inform7/Chapter 36/Grammar Tokens.w"
char * PL__Parsing__Tokens__i6_token_for_special_token(int gtc) ;
#line 181 "inform7/Chapter 36/Grammar Tokens.w"
char * PL__Parsing__Tokens__i6_constant_for_special_token(int gtc) ;
#line 200 "inform7/Chapter 36/Grammar Tokens.w"
kind * PL__Parsing__Tokens__kind_for_special_token(int gtc) ;
#line 312 "inform7/Chapter 36/Grammar Tokens.w"
void PL__Parsing__Tokens__incompatible_change_problem(char *token_tried, char *token_instead, char *token_better) ;
#line 371 "inform7/Chapter 36/Grammar Tokens.w"
parse_node * PL__Parsing__Tokens__determine(parse_node *pn, int depth, int *score) ;
#line 472 "inform7/Chapter 36/Grammar Tokens.w"
kind * PL__Parsing__Tokens__compile(OUTPUT_STREAM, parse_node *pn, int code_mode, char *failure_label, int consult_mode) ;
#line 33 "inform7/Chapter 36/Noun Filter Tokens.w"
noun_filter_token * PL__Parsing__Tokens__Filters__nft_new(parse_node *spec, int global_scope, int any_things) ;
#line 57 "inform7/Chapter 36/Noun Filter Tokens.w"
void PL__Parsing__Tokens__Filters__nft_compile_routine_name(OUTPUT_STREAM, noun_filter_token *nft) ;
#line 61 "inform7/Chapter 36/Noun Filter Tokens.w"
void PL__Parsing__Tokens__Filters__nft_compile_routine(OUTPUT_STREAM, noun_filter_token *nft) ;
#line 128 "inform7/Chapter 36/Noun Filter Tokens.w"
int PL__Parsing__Tokens__Filters__new_id(parse_node *spec, int global_scope, int any_things) ;
#line 144 "inform7/Chapter 36/Noun Filter Tokens.w"
void PL__Parsing__Tokens__Filters__compile_id(OUTPUT_STREAM, int id, int code_mode) ;
#line 166 "inform7/Chapter 36/Noun Filter Tokens.w"
void PL__Parsing__Tokens__Filters__compile(OUTPUT_STREAM) ;
#line 19 "inform7/Chapter 36/Tokens Parsing Values.w"
void PL__Parsing__Tokens__Values__number(OUTPUT_STREAM) ;
#line 24 "inform7/Chapter 36/Tokens Parsing Values.w"
void PL__Parsing__Tokens__Values__time(OUTPUT_STREAM) ;
#line 32 "inform7/Chapter 36/Tokens Parsing Values.w"
void PL__Parsing__Tokens__Values__truth_state(OUTPUT_STREAM) ;
#line 37 "inform7/Chapter 36/Tokens Parsing Values.w"
void PL__Parsing__Tokens__Values__compile_type_gprs(OUTPUT_STREAM) ;
#line 122 "inform7/Chapter 36/Tokens Parsing Values.w"
void PL__Parsing__Tokens__Values__gprv_compile(OUTPUT_STREAM, kind *K) ;
#line 125 "inform7/Chapter 36/Tokens Parsing Values.w"
void PL__Parsing__Tokens__Values__igprv_compile(OUTPUT_STREAM, kind *K) ;
#line 27 "inform7/Chapter 36/General Parsing Routines.w"
text_stream * PL__Parsing__Tokens__General__compile_gpr_head(OUTPUT_STREAM, int id) ;
#line 38 "inform7/Chapter 36/General Parsing Routines.w"
text_stream * PL__Parsing__Tokens__General__compile_gpr_tail(OUTPUT_STREAM) ;
#line 44 "inform7/Chapter 36/General Parsing Routines.w"
text_stream * PL__Parsing__Tokens__General__compile_prn_pr_head(OUTPUT_STREAM, property *prn) ;
#line 55 "inform7/Chapter 36/General Parsing Routines.w"
text_stream * PL__Parsing__Tokens__General__compile_prn_pr_tail(OUTPUT_STREAM, property *prn) ;
#line 73 "inform7/Chapter 36/General Parsing Routines.w"
grammar_verb * PL__Parsing__Tokens__General__get_consultation_gv(void) ;
#line 78 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__prepare_consultation_gv(void) ;
#line 82 "inform7/Chapter 36/General Parsing Routines.w"
int PL__Parsing__Tokens__General__print_consultation_gv_name(OUTPUT_STREAM) ;
#line 96 "inform7/Chapter 36/General Parsing Routines.w"
text_stream * PL__Parsing__Tokens__General__compile_consult_head(OUTPUT_STREAM, int id) ;
#line 110 "inform7/Chapter 36/General Parsing Routines.w"
text_stream * PL__Parsing__Tokens__General__compile_consult_tail(OUTPUT_STREAM) ;
#line 132 "inform7/Chapter 36/General Parsing Routines.w"
text_stream * PL__Parsing__Tokens__General__compile_parse_name_property(inference_subject *subj) ;
#line 198 "inform7/Chapter 36/General Parsing Routines.w"
text_stream * PL__Parsing__Tokens__General__compile_parse_name_head(OUTPUT_STREAM, inference_subject *subj, grammar_verb *gv) ;
#line 240 "inform7/Chapter 36/General Parsing Routines.w"
text_stream * PL__Parsing__Tokens__General__top_of_head(OUTPUT_STREAM, int id, inference_subject *subj, int test_distinguishability, int sometimes_has_visible_properties) ;
#line 291 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__after_gl_failed(OUTPUT_STREAM, int label, int pluralised) ;
#line 304 "inform7/Chapter 36/General Parsing Routines.w"
text_stream * PL__Parsing__Tokens__General__compile_parse_name_tail(OUTPUT_STREAM) ;
#line 335 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__consider_visible_properties(OUTPUT_STREAM, inference_subject *subj, int test_distinguishability) ;
#line 363 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__start_considering_visible_properties(OUTPUT_STREAM, int phase) ;
#line 367 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__consider_visible_property(OUTPUT_STREAM, inference_subject *subj, property *pr, property_permission *pp, int phase) ;
#line 401 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__finish_considering_visible_properties(OUTPUT_STREAM, int phase) ;
#line 420 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__begin_distinguishing_visible_properties(OUTPUT_STREAM) ;
#line 428 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__test_distinguish_visible_property(OUTPUT_STREAM, text_stream *COND) ;
#line 439 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__distinguish_visible_property(OUTPUT_STREAM, property *prn) ;
#line 462 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__finish_distinguishing_visible_properties(OUTPUT_STREAM) ;
#line 473 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__begin_parsing_visible_properties(OUTPUT_STREAM) ;
#line 479 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__test_parse_visible_property(OUTPUT_STREAM, text_stream *COND) ;
#line 486 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__parse_visible_property(OUTPUT_STREAM, inference_subject *subj, property *prn, int visibility_level) ;
#line 527 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__parse_visible_either_or(OUTPUT_STREAM, property *prn, int visibility_level, int pass_l) ;
#line 545 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__pvp_test_begins(OUTPUT_STREAM) ;
#line 549 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__pvp_test_words(OUTPUT_STREAM, wording W) ;
#line 559 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__pvp_test_passes(OUTPUT_STREAM, int visibility_level, int pass_l) ;
#line 568 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__finish_parsing_visible_properties(OUTPUT_STREAM) ;
#line 238 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__new_test_text(parse_node *PN) ;
#line 279 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__check_test_command(char *p) ;
#line 299 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__write_text(OUTPUT_STREAM) ;
#line 322 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__compile_switch(OUTPUT_STREAM) ;
#line 336 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__compile_printout(OUTPUT_STREAM) ;
#line 346 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__new_internal(int code, wording W) ;
#line 355 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__InternalTestCases_routine(OUTPUT_STREAM) ;
#line 458 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__begin_internal_reporting(void) ;
#line 462 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__end_internal_reporting(void) ;
#line 466 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__showme(OUTPUT_STREAM, parse_node *spec) ;
#line 45 "inform7/Chapter 37/Figures.w"
void PL__Figures__start(void) ;
#line 53 "inform7/Chapter 37/Figures.w"
int PL__Figures__figures_new_base_kind_notify(kind *new_base, char *name, wording W) ;
#line 62 "inform7/Chapter 37/Figures.w"
int PL__Figures__figures_new_named_instance_notify(instance *nc) ;
#line 78 "inform7/Chapter 37/Figures.w"
blorb_figure * PL__Figures__new_blorb_figure(instance *nc) ;
#line 93 "inform7/Chapter 37/Figures.w"
void PL__Figures__handle_figure_definition(parse_node *p) ;
#line 133 "inform7/Chapter 37/Figures.w"
void PL__Figures__register_figure(wording F, wording FN) ;
#line 173 "inform7/Chapter 37/Figures.w"
char * PL__Figures__description_of_cover_art(void) ;
#line 184 "inform7/Chapter 37/Figures.w"
void PL__Figures__write_picture_manifest(OUTPUT_STREAM, int include_cover, char *cover_art_format) ;
#line 223 "inform7/Chapter 37/Figures.w"
void PL__Figures__write_blurb_commands(OUTPUT_STREAM) ;
#line 241 "inform7/Chapter 37/Figures.w"
void PL__Figures__write_copy_commands(void) ;
#line 253 "inform7/Chapter 37/Figures.w"
void PL__Figures__tableoffigures_array(OUTPUT_STREAM) ;
#line 269 "inform7/Chapter 37/Figures.w"
void PL__Figures__index_all(void) ;
#line 41 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__start(void) ;
#line 49 "inform7/Chapter 37/Sound Effects.w"
int PL__Sounds__sounds_new_base_kind_notify(kind *new_base, char *name, wording W) ;
#line 58 "inform7/Chapter 37/Sound Effects.w"
int PL__Sounds__sounds_new_named_instance_notify(instance *nc) ;
#line 74 "inform7/Chapter 37/Sound Effects.w"
blorb_sound * PL__Sounds__new_blorb_sound(instance *nc) ;
#line 85 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__handle_sound_definition(parse_node *p) ;
#line 116 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__register_sound(wording F, wording FN) ;
#line 160 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__write_sounds_manifest(OUTPUT_STREAM) ;
#line 178 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__write_blurb_commands(OUTPUT_STREAM) ;
#line 195 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__write_copy_commands(void) ;
#line 209 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__tableofsounds_array(OUTPUT_STREAM) ;
#line 221 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__index_all(void) ;
#line 43 "inform7/Chapter 37/External Files.w"
void PL__Files__start(void) ;
#line 52 "inform7/Chapter 37/External Files.w"
int PL__Files__files_new_base_kind_notify(kind *new_base, char *name, wording W) ;
#line 60 "inform7/Chapter 37/External Files.w"
int PL__Files__files_new_named_instance_notify(instance *nc) ;
#line 79 "inform7/Chapter 37/External Files.w"
external_file * PL__Files__new_external_file(instance *nc) ;
#line 145 "inform7/Chapter 37/External Files.w"
void PL__Files__handle_file_definition(parse_node *p) ;
#line 151 "inform7/Chapter 37/External Files.w"
void PL__Files__register_file(wording F, wording FN) ;
#line 246 "inform7/Chapter 37/External Files.w"
int PL__Files__files_compile_constant(OUTPUT_STREAM, kind *K, parse_node *spec) ;
#line 266 "inform7/Chapter 37/External Files.w"
void PL__Files__arrays(OUTPUT_STREAM) ;
#line 300 "inform7/Chapter 37/External Files.w"
void PL__Files__index_all(void) ;
#line 13 "inform7/Chapter 38/Main Routine.w"
int main(int argc, char *argv[]) ;
#line 29 "inform7/Chapter 38/Main Routine.w"
int Main__core_inform_main(int argc, char *argv[]) ;
#line 136 "inform7/Chapter 38/Main Routine.w"
char * Main__cli_pair(char *wanted, char *got) ;
#line 68 "inform7/Chapter 38/Translate to Identifiers.w"
void IdentifierTranslations__as(parse_node *pn) ;
#line 142 "inform7/Chapter 38/Translate to Identifiers.w"
void IdentifierTranslations__plus_responses(parse_node *p, rule *R) ;
#line 162 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__interpret(OUTPUT_STREAM, unsigned char *sf, char *segment_name, int N_escape) ;
#line 927 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__error(char *message) ;
#line 948 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__compile_I7_from_I6(OUTPUT_STREAM, char *p) ;
#line 997 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__new_intervention(int stage, char *segment, char *part, unsigned char *i6, char *seg) ;
#line 1025 "inform7/Chapter 38/I6 Template Interpreter.w"
int TemplateFiles__I6T_file_intervene(OUTPUT_STREAM, int stage, char *segment, char *part) ;
#line 1052 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__report_unacted_upon_interventions(void) ;
#line 1084 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__compile_build_number(OUTPUT_STREAM) ;
#line 1094 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__register_sentence_handlers(void) ;
#line 93 "inform7/Chapter 38/Plugins.w"
word_assemblage Plugins__Manage__wording(int N) ;
#line 136 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__start(void) ;
#line 189 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__start_core(void) ;
#line 234 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__plug_in(wording W) ;
#line 272 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__show_configuration(OUTPUT_STREAM) ;
#line 281 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__show(OUTPUT_STREAM, char *label, int state) ;
#line 296 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__define_IFDEF_symbols(OUTPUT_STREAM) ;
#line 306 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__command(char *command) ;
#line 324 "inform7/Chapter 38/Plugins.w"
int Plugins__Manage__plugged_in(plugin *P) ;
#line 88 "inform7/Chapter 38/Plugin Calls.w"
void Plugins__Call__initialise_calls(void) ;
#line 96 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__name_to_early_infs(wording W, inference_subject **infs) ;
#line 100 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__new_variable_notify(nonlocal_variable *q) ;
#line 104 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__new_base_kind_notify(kind *K, char *d, wording W) ;
#line 108 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__compile_constant(OUTPUT_STREAM, kind *K, parse_node *spec) ;
#line 112 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__new_subject_notify(inference_subject *subj) ;
#line 116 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__new_named_instance_notify(instance *nc) ;
#line 120 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__new_permission_notify(property_permission *pp) ;
#line 124 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__irregular_genitive(inference_subject *owner, char *genitive, int *propriety) ;
#line 128 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__set_kind_notify(instance *I, kind *k) ;
#line 132 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__set_subkind_notify(kind *sub, kind *super) ;
#line 136 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__complete_model(int stage) ;
#line 141 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__parse_composite_NQs(wording *W, wording *DW, quantifier **quantifier_used, kind **some_kind) ;
#line 146 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__refine_implicit_noun(parse_node *p) ;
#line 151 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__act_on_special_NPs(parse_node *p) ;
#line 155 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__new_property_notify(property *prn) ;
#line 159 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__property_value_notify(property *prn, parse_node *val) ;
#line 163 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__more_specific(instance *I1, instance *I2) ;
#line 167 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__inferences_contradict(inference *A, inference *B, int similarity) ;
#line 171 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__explain_contradiction(inference *A, inference *B, int similarity, inference_subject *subj) ;
#line 176 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__intervene_in_assertion(parse_node *px, parse_node *py) ;
#line 180 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__log_inference_type(int it) ;
#line 184 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__compile_object_header(OUTPUT_STREAM, instance *I) ;
#line 188 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__estimate_property_usage(kind *k, int *words_used) ;
#line 192 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__check_going(parse_node *from, parse_node *to, parse_node *by, parse_node *through, parse_node *pushing) ;
#line 197 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__compile_model_tables(OUTPUT_STREAM) ;
#line 201 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__default_appearance(inference_subject *infs, parse_node *txt) ;
#line 205 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__offered_property(kind *K, parse_node *owner, parse_node *what) ;
#line 209 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__offered_specification(parse_node *owner, wording W) ;
#line 213 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__typecheck_equality(kind *K1, kind *K2) ;
#line 217 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__forbid_setting(kind *K) ;
#line 221 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__variable_set_warning(nonlocal_variable *q, parse_node *val) ;
#line 225 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__detect_bodysnatching(inference_subject *body, int *snatcher, inference_subject **counterpart) ;
#line 230 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__add_to_World_index(instance *O) ;
#line 234 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__annotate_in_World_index(instance *O) ;
#line 413 "inform7/Chapter 2/Debugging Log.w"
nonterminal *include_in_debugging_sentence_subject_NTM = NULL;
#line 417 "inform7/Chapter 2/Debugging Log.w"
nonterminal *debugging_log_request_NTM = NULL;
#line 69 "inform7/Chapter 4/HTML Documentation.w"
nonterminal *extension_documentation_heading_NTM = NULL;
#line 99 "inform7/Chapter 4/HTML Documentation.w"
nonterminal *extension_example_header_NTM = NULL;
#line 103 "inform7/Chapter 4/HTML Documentation.w"
nonterminal *row_of_asterisks_NTM = NULL;
#line 307 "inform7/Chapter 4/HTML Documentation.w"
nonterminal *extension_documentation_paste_marker_NTM = NULL;
#line 130 "inform7/Chapter 5/Documentation References.w"
nonterminal *documentation_symbol_tail_NTM = NULL;
#line 134 "inform7/Chapter 5/Documentation References.w"
nonterminal *documentation_symbol_NTM = NULL;
#line 618 "inform7/Chapter 7/Tries and Inflections.w"
nonterminal *small_trie_test_NTM = NULL;
#line 266 "inform7/Chapter 7/Natural Languages.w"
nonterminal *natural_language_NTM = NULL;
#line 460 "inform7/Chapter 7/Preform.w"
nonterminal *preform_nonterminal_NTM = NULL;
#line 74 "inform7/Chapter 7/English Inflections.w"
nonterminal *singular_noun_to_its_indefinite_article_NTM = NULL;
#line 82 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_indef_a_NTM = NULL;
#line 93 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_indef_b_NTM = NULL;
#line 161 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_indef_c_NTM = NULL;
#line 248 "inform7/Chapter 7/English Inflections.w"
nonterminal *singular_noun_to_its_plural_NTM = NULL;
#line 262 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_plural_uninflected_NTM = NULL;
#line 317 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_plural_pronouns_NTM = NULL;
#line 345 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_plural_irregular_NTM = NULL;
#line 365 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_plural_irregular_inflections_NTM = NULL;
#line 382 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_plural_assimilated_classical_inflections_NTM = NULL;
#line 413 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_plural_irregular_o_suffixes_NTM = NULL;
#line 451 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_plural_regular_inflections_NTM = NULL;
#line 535 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_plural_append_s_NTM = NULL;
#line 655 "inform7/Chapter 7/English Inflections.w"
nonterminal *verb_conjugation_instructions_NTM = NULL;
#line 724 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_have_conjugation_NTM = NULL;
#line 814 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_have_tabulation_NTM = NULL;
#line 825 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_have_present_NTM = NULL;
#line 862 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_do_conjugation_NTM = NULL;
#line 867 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_do_tabulation_NTM = NULL;
#line 878 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_do_present_NTM = NULL;
#line 901 "inform7/Chapter 7/English Inflections.w"
nonterminal *regular_verb_conjugation_NTM = NULL;
#line 919 "inform7/Chapter 7/English Inflections.w"
nonterminal *regular_verb_tabulation_NTM = NULL;
#line 937 "inform7/Chapter 7/English Inflections.w"
nonterminal *regular_verb_present_NTM = NULL;
#line 943 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_be_conjugation_NTM = NULL;
#line 948 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_be_tabulation_NTM = NULL;
#line 958 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_be_present_NTM = NULL;
#line 961 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_be_past_NTM = NULL;
#line 983 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_be_able_to_conjugation_NTM = NULL;
#line 988 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_be_able_to_tabulation_NTM = NULL;
#line 1024 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_be_able_to_auxiliary_NTM = NULL;
#line 1029 "inform7/Chapter 7/English Inflections.w"
nonterminal *to_be_able_to_auxiliary_tabulation_NTM = NULL;
#line 1039 "inform7/Chapter 7/English Inflections.w"
nonterminal *modal_conjugation_NTM = NULL;
#line 1044 "inform7/Chapter 7/English Inflections.w"
nonterminal *modal_tabulation_NTM = NULL;
#line 1083 "inform7/Chapter 7/English Inflections.w"
nonterminal *contracted_to_be_conjugation_NTM = NULL;
#line 1089 "inform7/Chapter 7/English Inflections.w"
nonterminal *contracted_to_be_tabulation_NTM = NULL;
#line 1101 "inform7/Chapter 7/English Inflections.w"
nonterminal *contracted_to_be_present_NTM = NULL;
#line 1104 "inform7/Chapter 7/English Inflections.w"
nonterminal *contracted_to_be_past_NTM = NULL;
#line 1107 "inform7/Chapter 7/English Inflections.w"
nonterminal *contracted_to_be_past_negated_NTM = NULL;
#line 1123 "inform7/Chapter 7/English Inflections.w"
nonterminal *contracted_to_have_conjugation_NTM = NULL;
#line 1129 "inform7/Chapter 7/English Inflections.w"
nonterminal *contracted_to_have_tabulation_NTM = NULL;
#line 1141 "inform7/Chapter 7/English Inflections.w"
nonterminal *contracted_to_have_present_NTM = NULL;
#line 1157 "inform7/Chapter 7/English Inflections.w"
nonterminal *arent_conjugation_NTM = NULL;
#line 1163 "inform7/Chapter 7/English Inflections.w"
nonterminal *arent_tabulation_NTM = NULL;
#line 1170 "inform7/Chapter 7/English Inflections.w"
nonterminal *arent_present_NTM = NULL;
#line 1173 "inform7/Chapter 7/English Inflections.w"
nonterminal *arent_past_NTM = NULL;
#line 1176 "inform7/Chapter 7/English Inflections.w"
nonterminal *arent_perfect_NTM = NULL;
#line 1188 "inform7/Chapter 7/English Inflections.w"
nonterminal *informal_negated_modal_conjugation_NTM = NULL;
#line 1197 "inform7/Chapter 7/English Inflections.w"
nonterminal *informal_negated_modal_tabulation_NTM = NULL;
#line 1204 "inform7/Chapter 7/English Inflections.w"
nonterminal *informal_negated_modal_present_NTM = NULL;
#line 1210 "inform7/Chapter 7/English Inflections.w"
nonterminal *cant_modal_conjugation_NTM = NULL;
#line 1216 "inform7/Chapter 7/English Inflections.w"
nonterminal *cant_modal_tabulation_NTM = NULL;
#line 1232 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_modal_contracted_present_NTM = NULL;
#line 1244 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_modal_contracted_past_NTM = NULL;
#line 1256 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_modal_contracted_future_NTM = NULL;
#line 1316 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_present_participle_NTM = NULL;
#line 1330 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_irregular_present_participle_NTM = NULL;
#line 1520 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_irregular_compound_present_participle_NTM = NULL;
#line 1539 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_regular_a_present_participle_NTM = NULL;
#line 1589 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_regular_b_present_participle_NTM = NULL;
#line 1594 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_regular_c_present_participle_NTM = NULL;
#line 1606 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_past_participle_NTM = NULL;
#line 1610 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_irregular_past_participle_NTM = NULL;
#line 1770 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_present_verb_form_NTM = NULL;
#line 1774 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_irregular_third_person_present_NTM = NULL;
#line 1786 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_past_NTM = NULL;
#line 1793 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_irregular_past_NTM = NULL;
#line 2337 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_irregular_compound_past_NTM = NULL;
#line 2353 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_regular_a_past_NTM = NULL;
#line 2400 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_regular_b_past_NTM = NULL;
#line 2405 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_regular_c_past_NTM = NULL;
#line 2432 "inform7/Chapter 7/English Inflections.w"
nonterminal *pasturise_participle_NTM = NULL;
#line 2437 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_pasturise_exceptions_NTM = NULL;
#line 2902 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_pasturise_regular_y_NTM = NULL;
#line 2908 "inform7/Chapter 7/English Inflections.w"
nonterminal *en_trie_pasturise_regular_NTM = NULL;
#line 2916 "inform7/Chapter 7/English Inflections.w"
nonterminal *adjective_to_plural_NTM = NULL;
#line 2919 "inform7/Chapter 7/English Inflections.w"
nonterminal *adjective_to_masculine_singular_NTM = NULL;
#line 2922 "inform7/Chapter 7/English Inflections.w"
nonterminal *adjective_to_feminine_singular_NTM = NULL;
#line 2925 "inform7/Chapter 7/English Inflections.w"
nonterminal *adjective_to_masculine_plural_NTM = NULL;
#line 2928 "inform7/Chapter 7/English Inflections.w"
nonterminal *adjective_to_feminine_plural_NTM = NULL;
#line 13 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *pronoun_NTM = NULL;
#line 17 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *nominative_pronoun_NTM = NULL;
#line 21 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *accusative_pronoun_NTM = NULL;
#line 33 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *possessive_first_person_NTM = NULL;
#line 37 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *possessive_second_person_NTM = NULL;
#line 41 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *possessive_third_person_NTM = NULL;
#line 52 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *relative_clause_marker_NTM = NULL;
#line 58 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *article_NTM = NULL;
#line 73 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *definite_article_NTM = NULL;
#line 76 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *indefinite_article_NTM = NULL;
#line 83 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *optional_definite_article_NTM = NULL;
#line 87 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *optional_article_NTM = NULL;
#line 91 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *compulsory_article_NTM = NULL;
#line 118 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *non_participles_NTM = NULL;
#line 121 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *probable_participle_NTM = NULL;
#line 132 "inform7/Chapter 8/Articles and Pronouns.w"
nonterminal *negated_clause_NTM = NULL;
#line 305 "inform7/Chapter 8/Determiners and Quantifiers.w"
nonterminal *determiner_names_NTM = NULL;
#line 373 "inform7/Chapter 8/Determiners and Quantifiers.w"
nonterminal *determination_of_NTM = NULL;
#line 391 "inform7/Chapter 8/Determiners and Quantifiers.w"
nonterminal *excluded_from_determiners_NTM = NULL;
#line 162 "inform7/Chapter 8/Time Periods.w"
nonterminal *historical_reference_possible_NTM = NULL;
#line 168 "inform7/Chapter 8/Time Periods.w"
nonterminal *historical_reference_NTM = NULL;
#line 172 "inform7/Chapter 8/Time Periods.w"
nonterminal *repetition_specification_NTM = NULL;
#line 182 "inform7/Chapter 8/Time Periods.w"
nonterminal *repetitions_NTM = NULL;
#line 186 "inform7/Chapter 8/Time Periods.w"
nonterminal *iteration_repetitions_NTM = NULL;
#line 193 "inform7/Chapter 8/Time Periods.w"
nonterminal *turn_repetitions_NTM = NULL;
#line 197 "inform7/Chapter 8/Time Periods.w"
nonterminal *rep_number_NTM = NULL;
#line 63 "inform7/Chapter 9/Adjectives.w"
nonterminal *adjective_name_NTM = NULL;
#line 1032 "inform7/Chapter 9/Adjective Meanings.w"
nonterminal *adaptive_adjective_NTM = NULL;
#line 1494 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *specifies_sentence_subject_NTM = NULL;
#line 1500 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_group_list_NTM = NULL;
#line 1504 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_group_tail_NTM = NULL;
#line 1508 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_group_NTM = NULL;
#line 1564 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *specifies_sentence_object_NTM = NULL;
#line 1568 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *kind_specified_NTM = NULL;
#line 1572 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_specification_tail_NTM = NULL;
#line 1579 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *scaling_instruction_NTM = NULL;
#line 1605 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_list_NTM = NULL;
#line 1611 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_NTM = NULL;
#line 1615 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_option_list_NTM = NULL;
#line 1619 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_option_tail_NTM = NULL;
#line 1623 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_part_option_NTM = NULL;
#line 1949 "inform7/Chapter 10/Literal Patterns.w"
nonterminal *literal_pattern_group_name_NTM = NULL;
#line 71 "inform7/Chapter 10/Times of Day.w"
nonterminal *s_literal_time_NTM = NULL;
#line 76 "inform7/Chapter 10/Times of Day.w"
nonterminal *elapsed_time_NTM = NULL;
#line 81 "inform7/Chapter 10/Times of Day.w"
nonterminal *clock_time_NTM = NULL;
#line 85 "inform7/Chapter 10/Times of Day.w"
nonterminal *am_pm_NTM = NULL;
#line 111 "inform7/Chapter 10/Times of Day.w"
nonterminal *digital_clock_time_NTM = NULL;
#line 139 "inform7/Chapter 10/Times of Day.w"
nonterminal *continental_clock_time_NTM = NULL;
#line 167 "inform7/Chapter 10/Times of Day.w"
nonterminal *event_rule_preamble_NTM = NULL;
#line 44 "inform7/Chapter 10/Unicode Translations.w"
nonterminal *translates_into_unicode_sentence_subject_NTM = NULL;
#line 54 "inform7/Chapter 10/Unicode Translations.w"
nonterminal *translates_into_unicode_sentence_object_NTM = NULL;
#line 77 "inform7/Chapter 10/Unicode Translations.w"
nonterminal *s_unicode_character_NTM = NULL;
#line 81 "inform7/Chapter 10/Unicode Translations.w"
nonterminal *unicode_character_name_NTM = NULL;
#line 335 "inform7/Chapter 10/Nametags.w"
nonterminal *translates_into_nl_sentence_subject_NTM = NULL;
#line 343 "inform7/Chapter 10/Instances.w"
nonterminal *instance_of_object_NTM = NULL;
#line 349 "inform7/Chapter 10/Instances.w"
nonterminal *instance_of_non_object_NTM = NULL;
#line 356 "inform7/Chapter 10/Instances.w"
nonterminal *instance_NTM = NULL;
#line 64 "inform7/Chapter 10/Nonlocal Variables.w"
nonterminal *notable_variables_NTM = NULL;
#line 658 "inform7/Chapter 10/Nonlocal Variables.w"
nonterminal *value_understood_variable_name_NTM = NULL;
#line 697 "inform7/Chapter 11/Binary Predicates.w"
nonterminal *relation_name_NTM = NULL;
#line 66 "inform7/Chapter 11/Relations.w"
nonterminal *relation_names_NTM = NULL;
#line 109 "inform7/Chapter 11/Relations.w"
nonterminal *relates_sentence_subject_NTM = NULL;
#line 259 "inform7/Chapter 11/Relations.w"
nonterminal *relates_sentence_left_object_NTM = NULL;
#line 263 "inform7/Chapter 11/Relations.w"
nonterminal *relates_sentence_right_object_NTM = NULL;
#line 268 "inform7/Chapter 11/Relations.w"
nonterminal *relation_term_right_named_NTM = NULL;
#line 272 "inform7/Chapter 11/Relations.w"
nonterminal *relation_term_right_NTM = NULL;
#line 278 "inform7/Chapter 11/Relations.w"
nonterminal *relation_term_basic_NTM = NULL;
#line 742 "inform7/Chapter 11/Relations.w"
nonterminal *relation_storage_construction_NTM = NULL;
#line 170 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *general_verb_NTM = NULL;
#line 187 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *general_verb_present_positive_NTM = NULL;
#line 208 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *foreign_verb_present_positive_NTM = NULL;
#line 231 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *copular_verb_NTM = NULL;
#line 251 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *copular_verb_present_positive_NTM = NULL;
#line 275 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *negated_noncopular_verb_present_NTM = NULL;
#line 297 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *universal_verb_NTM = NULL;
#line 316 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *possession_verb_present_positive_NTM = NULL;
#line 338 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *negated_verb_NTM = NULL;
#line 357 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *past_tense_verb_NTM = NULL;
#line 458 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *inequality_conjugations_NTM = NULL;
#line 588 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *verb_implies_sentence_subject_NTM = NULL;
#line 592 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *infinitive_usage_NTM = NULL;
#line 596 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *infinitive_usage_exceptional_NTM = NULL;
#line 605 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *conjugation_NTM = NULL;
#line 618 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *participle_like_NTM = NULL;
#line 634 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *verb_implies_sentence_object_NTM = NULL;
#line 772 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *list_comma_division_NTM = NULL;
#line 1201 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *adaptive_verb_NTM = NULL;
#line 1218 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *adaptive_verb_infinitive_NTM = NULL;
#line 1230 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *auxiliary_verb_only_NTM = NULL;
#line 1234 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *instance_of_verb_NTM = NULL;
#line 1251 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *not_instance_of_verb_at_run_time_NTM = NULL;
#line 1255 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *modal_verb_NTM = NULL;
#line 1274 "inform7/Chapter 11/Conjugation of Verbs.w"
nonterminal *verb_infinitive_NTM = NULL;
#line 125 "inform7/Chapter 11/Prepositions.w"
nonterminal *preposition_NTM = NULL;
#line 146 "inform7/Chapter 11/Prepositions.w"
nonterminal *preposition_implying_player_NTM = NULL;
#line 202 "inform7/Chapter 11/Prepositions.w"
nonterminal *comparative_property_construction_NTM = NULL;
#line 208 "inform7/Chapter 11/Prepositions.w"
nonterminal *same_property_as_construction_NTM = NULL;
#line 216 "inform7/Chapter 11/Prepositions.w"
nonterminal *same_property_as_in_lexicon_NTM = NULL;
#line 90 "inform7/Chapter 12/Lexical Services.w"
nonterminal *if_start_of_paragraph_NTM = NULL;
#line 107 "inform7/Chapter 12/Lexical Services.w"
nonterminal *if_start_of_source_text_NTM = NULL;
#line 117 "inform7/Chapter 12/Lexical Services.w"
nonterminal *if_not_deliberately_capitalised_NTM = NULL;
#line 342 "inform7/Chapter 12/Wordings.w"
nonterminal *balanced_text_NTM = NULL;
#line 429 "inform7/Chapter 13/Sentences.w"
nonterminal *dividing_sentence_NTM = NULL;
#line 433 "inform7/Chapter 13/Sentences.w"
nonterminal *heading_NTM = NULL;
#line 440 "inform7/Chapter 13/Sentences.w"
nonterminal *extension_end_marker_sentence_NTM = NULL;
#line 589 "inform7/Chapter 13/Sentences.w"
nonterminal *structural_sentence_NTM = NULL;
#line 606 "inform7/Chapter 13/Sentences.w"
nonterminal *language_modifying_sentence_NTM = NULL;
#line 617 "inform7/Chapter 13/Sentences.w"
nonterminal *use_option_sentence_shape_NTM = NULL;
#line 677 "inform7/Chapter 13/Sentences.w"
nonterminal *comma_divisible_sentence_NTM = NULL;
#line 695 "inform7/Chapter 13/Sentences.w"
nonterminal *list_or_division_NTM = NULL;
#line 294 "inform7/Chapter 13/Headings.w"
nonterminal *heading_qualifier_NTM = NULL;
#line 300 "inform7/Chapter 13/Headings.w"
nonterminal *bracketed_heading_qualifier_NTM = NULL;
#line 307 "inform7/Chapter 13/Headings.w"
nonterminal *platform_qualifier_NTM = NULL;
#line 311 "inform7/Chapter 13/Headings.w"
nonterminal *platform_identifier_NTM = NULL;
#line 317 "inform7/Chapter 13/Headings.w"
nonterminal *extension_qualifier_NTM = NULL;
#line 324 "inform7/Chapter 13/Headings.w"
nonterminal *extension_identifier_NTM = NULL;
#line 294 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *nonstructural_sentence_NTM = NULL;
#line 492 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *nounphrase_NTM = NULL;
#line 495 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *nounphrase_definite_NTM = NULL;
#line 499 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *nounphrase_figure_NTM = NULL;
#line 502 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *nounphrase_sound_NTM = NULL;
#line 505 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *nounphrase_external_file_NTM = NULL;
#line 508 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *nounphrase_actionable_NTM = NULL;
#line 511 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *variable_creation_tail_NTM = NULL;
#line 518 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *translation_target_NTM = NULL;
#line 545 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *existential_sentence_NTM = NULL;
#line 569 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *existential_sentence_inner_NTM = NULL;
#line 577 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *existential_sentence_inner_tail1_NTM = NULL;
#line 581 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *existential_sentence_inner_tail2_NTM = NULL;
#line 585 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *existential_sentence_inner_tail3_NTM = NULL;
#line 639 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *certainty_NTM = NULL;
#line 697 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_NTM = NULL;
#line 707 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail1_without_rc_NTM = NULL;
#line 713 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail2_without_rc_NTM = NULL;
#line 719 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail3_without_rc_NTM = NULL;
#line 725 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail4_without_rc_NTM = NULL;
#line 731 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail1_NTM = NULL;
#line 735 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail2_NTM = NULL;
#line 739 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail3_NTM = NULL;
#line 743 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail4_NTM = NULL;
#line 777 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail1_inner_NTM = NULL;
#line 783 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail2_inner_NTM = NULL;
#line 789 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail3_inner_NTM = NULL;
#line 795 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *regular_sentence_tail4_inner_NTM = NULL;
#line 842 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *bad_nonstructural_sentence_diagnosis_NTM = NULL;
#line 845 "inform7/Chapter 13/Verb Phrases.w"
nonterminal *bad_nonstructural_sentence_diagnosis_tail_NTM = NULL;
#line 74 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *nounphrase_articled_NTM = NULL;
#line 98 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_balanced_NTM = NULL;
#line 102 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_articled_balanced_NTM = NULL;
#line 135 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *nounphrase_articled_list_NTM = NULL;
#line 140 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_articled_tail_NTM = NULL;
#line 164 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *nounphrase_rule_list_NTM = NULL;
#line 169 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_rule_tail_NTM = NULL;
#line 173 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *nounphrase_rule_NTM = NULL;
#line 183 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *nounphrase_alternative_list_NTM = NULL;
#line 188 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_alternative_tail_NTM = NULL;
#line 207 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *nounphrase_as_object_NTM = NULL;
#line 211 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *nounphrase_as_subject_NTM = NULL;
#line 216 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_inner_NTM = NULL;
#line 224 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *if_copular_NTM = NULL;
#line 263 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_relative_phrase_limited_NTM = NULL;
#line 269 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_relative_phrase_unlimited_NTM = NULL;
#line 283 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_relative_phrase_exception_NTM = NULL;
#line 302 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_relative_phrase_implicit_NTM = NULL;
#line 308 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_relative_phrase_explicit_NTM = NULL;
#line 387 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_inner_without_rp_NTM = NULL;
#line 413 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_with_or_having_tail_NTM = NULL;
#line 419 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_new_property_list_NTM = NULL;
#line 424 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_new_property_NTM = NULL;
#line 427 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_new_property_tail_NTM = NULL;
#line 431 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_tail_NTM = NULL;
#line 443 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_kind_phrase_NTM = NULL;
#line 447 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_kind_phrase_unarticled_NTM = NULL;
#line 460 "inform7/Chapter 13/Noun Phrases.w"
nonterminal *np_from_or_of_tail_NTM = NULL;
#line 225 "inform7/Chapter 13/Of and From.w"
nonterminal *prohibited_property_owners_NTM = NULL;
#line 235 "inform7/Chapter 13/Of and From.w"
nonterminal *action_name_formal_NTM = NULL;
#line 238 "inform7/Chapter 13/Of and From.w"
nonterminal *activity_name_formal_NTM = NULL;
#line 241 "inform7/Chapter 13/Of and From.w"
nonterminal *relation_name_formal_NTM = NULL;
#line 244 "inform7/Chapter 13/Of and From.w"
nonterminal *rule_name_formal_NTM = NULL;
#line 247 "inform7/Chapter 13/Of and From.w"
nonterminal *rulebook_name_formal_NTM = NULL;
#line 260 "inform7/Chapter 13/Of and From.w"
nonterminal *has_properties_called_sentence_object_NTM = NULL;
#line 264 "inform7/Chapter 13/Of and From.w"
nonterminal *has_property_name_tail_NTM = NULL;
#line 268 "inform7/Chapter 13/Of and From.w"
nonterminal *has_property_name_NTM = NULL;
#line 272 "inform7/Chapter 13/Of and From.w"
nonterminal *bad_property_name_diagnosis_NTM = NULL;
#line 328 "inform7/Chapter 13/Of and From.w"
nonterminal *sentence_needing_second_look_NTM = NULL;
#line 1291 "inform7/Chapter 13/Rule Subtrees.w"
nonterminal *verify_expanded_text_substitution_NTM = NULL;
#line 1474 "inform7/Chapter 13/Rule Subtrees.w"
nonterminal *control_structure_phrase_NTM = NULL;
#line 1486 "inform7/Chapter 13/Rule Subtrees.w"
nonterminal *end_control_structure_phrase_NTM = NULL;
#line 1491 "inform7/Chapter 13/Rule Subtrees.w"
nonterminal *other_significant_phrase_NTM = NULL;
#line 1498 "inform7/Chapter 13/Rule Subtrees.w"
nonterminal *phrase_with_comma_notation_NTM = NULL;
#line 1504 "inform7/Chapter 13/Rule Subtrees.w"
nonterminal *instead_keyword_NTM = NULL;
#line 1511 "inform7/Chapter 13/Rule Subtrees.w"
nonterminal *phrase_beginning_block_NTM = NULL;
#line 72 "inform7/Chapter 14/Including Extensions.w"
nonterminal *extension_title_and_version_NTM = NULL;
#line 78 "inform7/Chapter 14/Including Extensions.w"
nonterminal *extension_unversioned_NTM = NULL;
#line 82 "inform7/Chapter 14/Including Extensions.w"
nonterminal *extension_unversioned_inner_NTM = NULL;
#line 99 "inform7/Chapter 14/Including Extensions.w"
nonterminal *extension_version_NTM = NULL;
#line 230 "inform7/Chapter 14/Including Extensions.w"
nonterminal *extension_body_NTM = NULL;
#line 346 "inform7/Chapter 14/Including Extensions.w"
nonterminal *begins_here_sentence_subject_NTM = NULL;
#line 306 "inform7/Chapter 15/Traverse for Assertions.w"
nonterminal *no_verb_diagnosis_NTM = NULL;
#line 373 "inform7/Chapter 15/Refine Parse Tree.w"
nonterminal *newfound_property_of_NTM = NULL;
#line 481 "inform7/Chapter 15/Refine Parse Tree.w"
nonterminal *assertion_np_as_value_NTM = NULL;
#line 400 "inform7/Chapter 15/The Creator.w"
nonterminal *grammatical_gender_marker_NTM = NULL;
#line 403 "inform7/Chapter 15/The Creator.w"
nonterminal *grammatical_gender_abbreviation_NTM = NULL;
#line 444 "inform7/Chapter 15/The Creator.w"
nonterminal *creation_problem_diagnosis_NTM = NULL;
#line 1060 "inform7/Chapter 15/The Creator.w"
nonterminal *text_ending_with_a_calling_NTM = NULL;
#line 1064 "inform7/Chapter 15/The Creator.w"
nonterminal *text_including_a_calling_NTM = NULL;
#line 1077 "inform7/Chapter 15/The Creator.w"
nonterminal *unsuitable_name_NTM = NULL;
#line 1082 "inform7/Chapter 15/The Creator.w"
nonterminal *unsuitable_name_for_locals_NTM = NULL;
#line 1087 "inform7/Chapter 15/The Creator.w"
nonterminal *unfortunate_name_NTM = NULL;
#line 1719 "inform7/Chapter 15/Make Assertions.w"
nonterminal *something_loose_diagnosis_NTM = NULL;
#line 31 "inform7/Chapter 15/Property Declarations.w"
nonterminal *forbidden_property_owners_NTM = NULL;
#line 126 "inform7/Chapter 15/Property Declarations.w"
nonterminal *can_be_sentence_object_NTM = NULL;
#line 132 "inform7/Chapter 15/Property Declarations.w"
nonterminal *condition_name_NTM = NULL;
#line 136 "inform7/Chapter 15/Property Declarations.w"
nonterminal *condition_name_inner_NTM = NULL;
#line 141 "inform7/Chapter 15/Property Declarations.w"
nonterminal *condition_name_innermost_NTM = NULL;
#line 24 "inform7/Chapter 16/Architecture of the S-Parser.w"
nonterminal *s_plain_text_NTM = NULL;
#line 40 "inform7/Chapter 16/Architecture of the S-Parser.w"
nonterminal *s_plain_text_with_equals_NTM = NULL;
#line 64 "inform7/Chapter 16/Architecture of the S-Parser.w"
nonterminal *s_value_NTM = NULL;
#line 76 "inform7/Chapter 16/Architecture of the S-Parser.w"
nonterminal *s_condition_NTM = NULL;
#line 88 "inform7/Chapter 16/Architecture of the S-Parser.w"
nonterminal *s_non_action_condition_NTM = NULL;
#line 103 "inform7/Chapter 16/Architecture of the S-Parser.w"
nonterminal *s_type_expression_NTM = NULL;
#line 119 "inform7/Chapter 16/Architecture of the S-Parser.w"
nonterminal *s_descriptive_type_expression_NTM = NULL;
#line 132 "inform7/Chapter 16/Architecture of the S-Parser.w"
nonterminal *s_type_expression_or_value_NTM = NULL;
#line 140 "inform7/Chapter 16/Architecture of the S-Parser.w"
nonterminal *s_explicit_action_NTM = NULL;
#line 157 "inform7/Chapter 16/Architecture of the S-Parser.w"
nonterminal *s_constant_action_NTM = NULL;
#line 20 "inform7/Chapter 16/Parse Literals.w"
nonterminal *s_literal_NTM = NULL;
#line 32 "inform7/Chapter 16/Parse Literals.w"
nonterminal *s_literal_unit_notation_NTM = NULL;
#line 49 "inform7/Chapter 16/Parse Literals.w"
nonterminal *cardinal_number_in_words_NTM = NULL;
#line 67 "inform7/Chapter 16/Parse Literals.w"
nonterminal *ordinal_number_in_words_NTM = NULL;
#line 94 "inform7/Chapter 16/Parse Literals.w"
nonterminal *cardinal_number_NTM = NULL;
#line 103 "inform7/Chapter 16/Parse Literals.w"
nonterminal *ordinal_number_NTM = NULL;
#line 115 "inform7/Chapter 16/Parse Literals.w"
nonterminal *cardinal_number_unlimited_NTM = NULL;
#line 148 "inform7/Chapter 16/Parse Literals.w"
nonterminal *quoted_text_NTM = NULL;
#line 155 "inform7/Chapter 16/Parse Literals.w"
nonterminal *quoted_text_with_subs_NTM = NULL;
#line 162 "inform7/Chapter 16/Parse Literals.w"
nonterminal *quoted_text_without_subs_NTM = NULL;
#line 173 "inform7/Chapter 16/Parse Literals.w"
nonterminal *empty_text_NTM = NULL;
#line 184 "inform7/Chapter 16/Parse Literals.w"
nonterminal *response_letter_NTM = NULL;
#line 200 "inform7/Chapter 16/Parse Literals.w"
nonterminal *s_literal_truth_state_NTM = NULL;
#line 214 "inform7/Chapter 16/Parse Literals.w"
nonterminal *s_literal_real_number_NTM = NULL;
#line 221 "inform7/Chapter 16/Parse Literals.w"
nonterminal *literal_real_in_digits_NTM = NULL;
#line 18 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_constant_value_NTM = NULL;
#line 54 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_miscellaneous_proper_noun_NTM = NULL;
#line 81 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_named_constant_NTM = NULL;
#line 97 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_rulebook_outcome_name_NTM = NULL;
#line 106 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_use_option_name_NTM = NULL;
#line 114 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_rule_name_NTM = NULL;
#line 129 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_table_column_name_NTM = NULL;
#line 142 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *property_name_as_noun_phrase_NTM = NULL;
#line 146 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_property_name_NTM = NULL;
#line 180 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_adjective_list_as_desc_NTM = NULL;
#line 240 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_adjective_list_NTM = NULL;
#line 245 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_adjective_list_unarticled_NTM = NULL;
#line 255 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_adjective_NTM = NULL;
#line 378 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_qualifiable_noun_NTM = NULL;
#line 382 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_qualifiable_common_noun_NTM = NULL;
#line 385 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_qualifiable_proper_noun_NTM = NULL;
#line 392 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_instance_name_NTM = NULL;
#line 413 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_applicable_adjective_list_NTM = NULL;
#line 469 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_description_NTM = NULL;
#line 473 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_description_uncomposite_NTM = NULL;
#line 476 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_description_uncomposite_inner_NTM = NULL;
#line 480 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_description_uncalled_NTM = NULL;
#line 490 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_description_unspecified_NTM = NULL;
#line 494 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_common_description_unspecified_NTM = NULL;
#line 498 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_proper_description_unspecified_NTM = NULL;
#line 502 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *if_trying_omission_permitted_NTM = NULL;
#line 507 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *if_multiplicitous_NTM = NULL;
#line 516 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_description_nounless_NTM = NULL;
#line 520 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_description_nounless_uncomposite_NTM = NULL;
#line 524 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_description_nounless_uncalled_NTM = NULL;
#line 534 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_description_nounless_unspecified_NTM = NULL;
#line 617 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_calling_name_NTM = NULL;
#line 634 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_specifier_NTM = NULL;
#line 654 "inform7/Chapter 16/Constants and Descriptions.w"
nonterminal *s_specifying_noun_NTM = NULL;
#line 58 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_type_expression_uncached_NTM = NULL;
#line 62 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_type_expression_unarticled_NTM = NULL;
#line 85 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_descriptive_type_expression_uncached_NTM = NULL;
#line 89 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_descriptive_type_expression_unarticled_NTM = NULL;
#line 106 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_variable_scope_NTM = NULL;
#line 111 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_variable_contents_NTM = NULL;
#line 162 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *if_let_equation_mode_NTM = NULL;
#line 172 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *if_pronoun_present_NTM = NULL;
#line 182 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *if_table_column_expected_NTM = NULL;
#line 188 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *if_property_name_expected_NTM = NULL;
#line 245 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_value_uncached_NTM = NULL;
#line 278 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_equation_usage_NTM = NULL;
#line 367 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_variable_NTM = NULL;
#line 373 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_nonglobal_variable_NTM = NULL;
#line 378 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_variable_as_value_NTM = NULL;
#line 384 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_local_variable_NTM = NULL;
#line 396 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_stacked_variable_NTM = NULL;
#line 412 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_global_variable_NTM = NULL;
#line 423 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *property_of_shape_NTM = NULL;
#line 435 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_value_phrase_non_of_NTM = NULL;
#line 453 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_value_phrase_NTM = NULL;
#line 480 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_table_reference_NTM = NULL;
#line 559 "inform7/Chapter 16/Type Expressions and Values.w"
nonterminal *s_action_pattern_as_value_NTM = NULL;
#line 37 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_sentence_NTM = NULL;
#line 52 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_existential_np_NTM = NULL;
#line 55 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_existential_verb_tail_NTM = NULL;
#line 105 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_general_verb_tail_NTM = NULL;
#line 136 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_universal_relation_term_NTM = NULL;
#line 158 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_np_with_relative_clause_NTM = NULL;
#line 162 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_implied_relative_verb_tail_NTM = NULL;
#line 166 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_relative_verb_tail_NTM = NULL;
#line 233 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_purely_physical_description_NTM = NULL;
#line 243 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *if_forced_physical_NTM = NULL;
#line 254 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_noun_phrase_NTM = NULL;
#line 259 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_noun_phrase_nounless_NTM = NULL;
#line 268 "inform7/Chapter 16/Verbal and Relative Clauses.w"
nonterminal *s_descriptive_np_NTM = NULL;
#line 23 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_condition_uncached_NTM = NULL;
#line 32 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_condition_pure_NTM = NULL;
#line 54 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_condition_with_chronology_NTM = NULL;
#line 104 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_condition_atomic_NTM = NULL;
#line 124 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_nonexistential_phrase_to_decide_NTM = NULL;
#line 129 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_existential_phrase_to_decide_NTM = NULL;
#line 134 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *existential_verb_phrase_NTM = NULL;
#line 137 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_phrase_to_decide_NTM = NULL;
#line 153 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_phrase_option_in_use_NTM = NULL;
#line 172 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_action_pattern_as_condition_NTM = NULL;
#line 175 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_action_pattern_as_negated_condition_NTM = NULL;
#line 181 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_past_action_pattern_as_condition_NTM = NULL;
#line 184 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_past_action_pattern_as_negated_condition_NTM = NULL;
#line 215 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_command_NTM = NULL;
#line 219 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_say_command_NTM = NULL;
#line 226 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_to_phrase_NTM = NULL;
#line 239 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_say_phrase_NTM = NULL;
#line 248 "inform7/Chapter 16/Conditions and Phrases.w"
nonterminal *s_text_substitution_NTM = NULL;
#line 631 "inform7/Chapter 19/Kinds.w"
nonterminal *notable_linguistic_kinds_NTM = NULL;
#line 41 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *if_parsing_phrase_tokens_NTM = NULL;
#line 51 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *s_phrase_token_type_NTM = NULL;
#line 65 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_kind_for_template_NTM = NULL;
#line 78 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *s_kind_as_name_token_NTM = NULL;
#line 97 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_kind_as_name_token_NTM = NULL;
#line 104 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_kind_abbreviating_NTM = NULL;
#line 112 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_kind_NTM = NULL;
#line 123 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_kind_articled_NTM = NULL;
#line 131 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_variable_definition_NTM = NULL;
#line 142 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_base_kind_NTM = NULL;
#line 176 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_irregular_kind_construction_NTM = NULL;
#line 195 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_kind_construction_NTM = NULL;
#line 260 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_single_material_NTM = NULL;
#line 265 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_optional_material_NTM = NULL;
#line 272 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_tupled_material_NTM = NULL;
#line 277 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_tuple_list_NTM = NULL;
#line 361 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_kind_of_kind_NTM = NULL;
#line 407 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_kind_variable_NTM = NULL;
#line 421 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_formal_kind_variable_NTM = NULL;
#line 432 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_formal_kind_variable_singular_NTM = NULL;
#line 444 "inform7/Chapter 19/Describing Kinds.w"
nonterminal *k_kind_variable_texts_NTM = NULL;
#line 2078 "inform7/Chapter 20/Dash.w"
nonterminal *structural_phrase_problem_diagnosis_NTM = NULL;
#line 2426 "inform7/Chapter 20/Dash.w"
nonterminal *failed_text_substitution_diagnosis_NTM = NULL;
#line 2476 "inform7/Chapter 20/Dash.w"
nonterminal *condition_problem_diagnosis_NTM = NULL;
#line 2480 "inform7/Chapter 20/Dash.w"
nonterminal *condition_problem_part_tail_NTM = NULL;
#line 2484 "inform7/Chapter 20/Dash.w"
nonterminal *condition_problem_part_NTM = NULL;
#line 2647 "inform7/Chapter 20/Dash.w"
nonterminal *unknown_text_shape_NTM = NULL;
#line 2652 "inform7/Chapter 20/Dash.w"
nonterminal *unknown_text_substitution_problem_diagnosis_NTM = NULL;
#line 2787 "inform7/Chapter 20/Dash.w"
nonterminal *unknown_value_problem_diagnosis_NTM = NULL;
#line 2794 "inform7/Chapter 20/Dash.w"
nonterminal *unknown_use_option_diagnosis_NTM = NULL;
#line 2798 "inform7/Chapter 20/Dash.w"
nonterminal *unknown_activity_diagnosis_NTM = NULL;
#line 228 "inform7/Chapter 21/Properties.w"
nonterminal *notable_properties_NTM = NULL;
#line 269 "inform7/Chapter 21/Properties.w"
nonterminal *property_name_construction_NTM = NULL;
#line 299 "inform7/Chapter 21/Properties.w"
nonterminal *property_name_NTM = NULL;
#line 313 "inform7/Chapter 21/Properties.w"
nonterminal *either_or_property_name_NTM = NULL;
#line 325 "inform7/Chapter 21/Properties.w"
nonterminal *value_property_name_NTM = NULL;
#line 341 "inform7/Chapter 21/Properties.w"
nonterminal *property_name_v_NTM = NULL;
#line 357 "inform7/Chapter 21/Properties.w"
nonterminal *name_looking_like_property_test_NTM = NULL;
#line 364 "inform7/Chapter 21/Properties.w"
nonterminal *ambiguous_property_name_NTM = NULL;
#line 229 "inform7/Chapter 21/Measurement Adjectives.w"
nonterminal *measurement_adjective_definition_NTM = NULL;
#line 234 "inform7/Chapter 21/Measurement Adjectives.w"
nonterminal *measurement_range_NTM = NULL;
#line 74 "inform7/Chapter 21/Setting Property Relation.w"
nonterminal *relation_property_name_NTM = NULL;
#line 60 "inform7/Chapter 24/List Constants.w"
nonterminal *s_literal_list_NTM = NULL;
#line 64 "inform7/Chapter 24/List Constants.w"
nonterminal *literal_list_contents_NTM = NULL;
#line 68 "inform7/Chapter 24/List Constants.w"
nonterminal *literal_list_entry_NTM = NULL;
#line 219 "inform7/Chapter 25/Table Columns.w"
nonterminal *table_column_heading_NTM = NULL;
#line 226 "inform7/Chapter 25/Table Columns.w"
nonterminal *table_column_heading_unbracketed_NTM = NULL;
#line 268 "inform7/Chapter 25/Table Columns.w"
nonterminal *table_column_name_construction_NTM = NULL;
#line 253 "inform7/Chapter 25/Tables.w"
nonterminal *table_header_NTM = NULL;
#line 259 "inform7/Chapter 25/Tables.w"
nonterminal *table_new_name_NTM = NULL;
#line 281 "inform7/Chapter 25/Tables.w"
nonterminal *table_names_construction_NTM = NULL;
#line 291 "inform7/Chapter 25/Tables.w"
nonterminal *table_footer_NTM = NULL;
#line 858 "inform7/Chapter 25/Tables.w"
nonterminal *table_cell_NTM = NULL;
#line 867 "inform7/Chapter 25/Tables.w"
nonterminal *table_cell_blank_NTM = NULL;
#line 870 "inform7/Chapter 25/Tables.w"
nonterminal *table_cell_value_NTM = NULL;
#line 878 "inform7/Chapter 25/Tables.w"
nonterminal *list_of_double_quotes_NTM = NULL;
#line 312 "inform7/Chapter 25/Runtime Support for Tables.w"
nonterminal *rankings_table_name_NTM = NULL;
#line 30 "inform7/Chapter 25/Tables of Definitions.w"
nonterminal *defined_by_sentence_subject_NTM = NULL;
#line 52 "inform7/Chapter 25/Tables of Definitions.w"
nonterminal *defined_by_sentence_object_NTM = NULL;
#line 387 "inform7/Chapter 25/Tables of Definitions.w"
nonterminal *unfortunate_table_column_property_NTM = NULL;
#line 145 "inform7/Chapter 26/Equations.w"
nonterminal *equation_name_NTM = NULL;
#line 198 "inform7/Chapter 26/Equations.w"
nonterminal *text_ending_in_comma_NTM = NULL;
#line 242 "inform7/Chapter 26/Equations.w"
nonterminal *equation_names_construction_NTM = NULL;
#line 325 "inform7/Chapter 26/Equations.w"
nonterminal *equation_where_NTM = NULL;
#line 388 "inform7/Chapter 26/Equations.w"
nonterminal *equation_where_list_NTM = NULL;
#line 393 "inform7/Chapter 26/Equations.w"
nonterminal *equation_where_tail_NTM = NULL;
#line 397 "inform7/Chapter 26/Equations.w"
nonterminal *equation_where_setting_entry_NTM = NULL;
#line 400 "inform7/Chapter 26/Equations.w"
nonterminal *equation_where_setting_NTM = NULL;
#line 409 "inform7/Chapter 26/Equations.w"
nonterminal *equation_symbol_NTM = NULL;
#line 639 "inform7/Chapter 26/Equations.w"
nonterminal *valid_equation_symbol_NTM = NULL;
#line 160 "inform7/Chapter 27/Rulebooks.w"
nonterminal *new_rulebook_name_NTM = NULL;
#line 209 "inform7/Chapter 27/Rulebooks.w"
nonterminal *rulebook_name_construction_NTM = NULL;
#line 396 "inform7/Chapter 27/Rulebooks.w"
nonterminal *rulebook_variable_name_NTM = NULL;
#line 583 "inform7/Chapter 27/Rulebooks.w"
nonterminal *rulebook_stem_NTM = NULL;
#line 611 "inform7/Chapter 27/Rulebooks.w"
nonterminal *rulebook_stem_inner_NTM = NULL;
#line 616 "inform7/Chapter 27/Rulebooks.w"
nonterminal *rulebook_stem_inner_unarticled_NTM = NULL;
#line 625 "inform7/Chapter 27/Rulebooks.w"
nonterminal *rulebook_stem_name_NTM = NULL;
#line 848 "inform7/Chapter 27/Rulebooks.w"
nonterminal *rulebook_property_NTM = NULL;
#line 110 "inform7/Chapter 27/Focus and Outcome.w"
nonterminal *rulebook_default_outcome_NTM = NULL;
#line 114 "inform7/Chapter 27/Focus and Outcome.w"
nonterminal *rule_outcome_NTM = NULL;
#line 153 "inform7/Chapter 27/Focus and Outcome.w"
nonterminal *rulebook_outcome_list_NTM = NULL;
#line 158 "inform7/Chapter 27/Focus and Outcome.w"
nonterminal *rulebook_outcome_tail_NTM = NULL;
#line 162 "inform7/Chapter 27/Focus and Outcome.w"
nonterminal *rulebook_outcome_setting_entry_NTM = NULL;
#line 165 "inform7/Chapter 27/Focus and Outcome.w"
nonterminal *form_of_named_rule_outcome_NTM = NULL;
#line 230 "inform7/Chapter 27/Focus and Outcome.w"
nonterminal *named_rulebook_outcome_NTM = NULL;
#line 28 "inform7/Chapter 27/Rule Placement Sentences.w"
nonterminal *rulebook_name_NTM = NULL;
#line 38 "inform7/Chapter 27/Rule Placement Sentences.w"
nonterminal *rule_name_NTM = NULL;
#line 61 "inform7/Chapter 27/Rule Placement Sentences.w"
nonterminal *substitutes_for_sentence_subject_NTM = NULL;
#line 65 "inform7/Chapter 27/Rule Placement Sentences.w"
nonterminal *substitutes_for_sentence_object_NTM = NULL;
#line 106 "inform7/Chapter 27/Rule Placement Sentences.w"
nonterminal *does_nothing_sentence_subject_NTM = NULL;
#line 141 "inform7/Chapter 27/Rule Placement Sentences.w"
nonterminal *listed_in_sentence_subject_NTM = NULL;
#line 148 "inform7/Chapter 27/Rule Placement Sentences.w"
nonterminal *listed_in_sentence_object_NTM = NULL;
#line 167 "inform7/Chapter 27/Rule Placement Sentences.w"
nonterminal *destination_rulebook_NTM = NULL;
#line 116 "inform7/Chapter 27/Activities.w"
nonterminal *activity_sentence_subject_NTM = NULL;
#line 121 "inform7/Chapter 27/Activities.w"
nonterminal *activity_noted_NTM = NULL;
#line 126 "inform7/Chapter 27/Activities.w"
nonterminal *activity_new_name_NTM = NULL;
#line 135 "inform7/Chapter 27/Activities.w"
nonterminal *activity_name_construction_NTM = NULL;
#line 248 "inform7/Chapter 27/Activities.w"
nonterminal *activity_variable_name_NTM = NULL;
#line 434 "inform7/Chapter 27/Activities.w"
nonterminal *run_time_context_NTM = NULL;
#line 438 "inform7/Chapter 27/Activities.w"
nonterminal *activity_list_unnegated_NTM = NULL;
#line 443 "inform7/Chapter 27/Activities.w"
nonterminal *activity_tail_NTM = NULL;
#line 447 "inform7/Chapter 27/Activities.w"
nonterminal *activity_list_entry_NTM = NULL;
#line 463 "inform7/Chapter 27/Activities.w"
nonterminal *activity_operand_NTM = NULL;
#line 534 "inform7/Chapter 27/Activities.w"
nonterminal *activity_name_NTM = NULL;
#line 555 "inform7/Chapter 27/Activities.w"
nonterminal *if_parsing_al_conditions_NTM = NULL;
#line 285 "inform7/Chapter 28/Phrases.w"
nonterminal *inline_phrase_definition_NTM = NULL;
#line 136 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *rule_preamble_NTM = NULL;
#line 200 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *now_phrase_preamble_NTM = NULL;
#line 210 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *rule_preamble_fine_NTM = NULL;
#line 214 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *rule_preamble_finer_NTM = NULL;
#line 219 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *rulebook_stem_embellished_NTM = NULL;
#line 226 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *rulebook_bud_NTM = NULL;
#line 457 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *unrecognised_rule_stem_diagnosis_NTM = NULL;
#line 537 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *when_while_clause_NTM = NULL;
#line 934 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *parametric_problem_diagnosis_NTM = NULL;
#line 961 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *action_problem_diagnosis_NTM = NULL;
#line 1000 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *action_when_diagnosis_NTM = NULL;
#line 1010 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *anl_diagnosis_NTM = NULL;
#line 1014 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *anl_inner_diagnosis_NTM = NULL;
#line 1018 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *anl_tail_diagnosis_NTM = NULL;
#line 1022 "inform7/Chapter 28/Phrase Usage.w"
nonterminal *anl_entry_diagnosis_NTM = NULL;
#line 457 "inform7/Chapter 28/Describing Phrase Type Data.w"
nonterminal *phrase_preamble_NTM = NULL;
#line 462 "inform7/Chapter 28/Describing Phrase Type Data.w"
nonterminal *to_preamble_NTM = NULL;
#line 481 "inform7/Chapter 28/Describing Phrase Type Data.w"
nonterminal *phrase_vetting_NTM = NULL;
#line 509 "inform7/Chapter 28/Describing Phrase Type Data.w"
nonterminal *say_preamble_NTM = NULL;
#line 534 "inform7/Chapter 28/Describing Phrase Type Data.w"
nonterminal *to_return_data_NTM = NULL;
#line 543 "inform7/Chapter 28/Describing Phrase Type Data.w"
nonterminal *return_kind_NTM = NULL;
#line 660 "inform7/Chapter 28/Describing Phrase Type Data.w"
nonterminal *phrase_definition_word_or_token_NTM = NULL;
#line 673 "inform7/Chapter 28/Describing Phrase Type Data.w"
nonterminal *phrase_token_declaration_NTM = NULL;
#line 134 "inform7/Chapter 28/Phrase Options.w"
nonterminal *phrase_option_declaration_list_NTM = NULL;
#line 139 "inform7/Chapter 28/Phrase Options.w"
nonterminal *phrase_option_declaration_tail_NTM = NULL;
#line 145 "inform7/Chapter 28/Phrase Options.w"
nonterminal *phrase_option_declaration_setting_entry_NTM = NULL;
#line 249 "inform7/Chapter 28/Phrase Options.w"
nonterminal *phrase_option_list_NTM = NULL;
#line 254 "inform7/Chapter 28/Phrase Options.w"
nonterminal *phrase_option_tail_NTM = NULL;
#line 258 "inform7/Chapter 28/Phrase Options.w"
nonterminal *phrase_option_setting_entry_NTM = NULL;
#line 289 "inform7/Chapter 28/Phrase Options.w"
nonterminal *phrase_option_NTM = NULL;
#line 130 "inform7/Chapter 28/Phrasebook Index.w"
nonterminal *heading_with_parenthesis_NTM = NULL;
#line 135 "inform7/Chapter 28/Phrasebook Index.w"
nonterminal *heading_name_hyphenated_NTM = NULL;
#line 52 "inform7/Chapter 29/Adjectival Definitions.w"
nonterminal *definition_header_NTM = NULL;
#line 85 "inform7/Chapter 29/Adjectival Definitions.w"
nonterminal *adjective_definition_NTM = NULL;
#line 90 "inform7/Chapter 29/Adjectival Definitions.w"
nonterminal *adjective_domain_NTM = NULL;
#line 95 "inform7/Chapter 29/Adjectival Definitions.w"
nonterminal *adjective_wording_NTM = NULL;
#line 11 "inform7/Chapter 29/Adjectives by Raw Phrase.w"
nonterminal *inform6_routine_adjective_definition_NTM = NULL;
#line 10 "inform7/Chapter 29/Adjectives by Raw Condition.w"
nonterminal *inform6_condition_adjective_definition_NTM = NULL;
#line 638 "inform7/Chapter 30/Local Variables.w"
nonterminal *new_called_name_NTM = NULL;
#line 642 "inform7/Chapter 30/Local Variables.w"
nonterminal *new_called_name_unarticled_NTM = NULL;
#line 648 "inform7/Chapter 30/Local Variables.w"
nonterminal *existing_local_name_NTM = NULL;
#line 16 "inform7/Chapter 31/Parse Invocations.w"
nonterminal *end_phrase_construction_NTM = NULL;
#line 366 "inform7/Chapter 31/Compile Invocations Inline.w"
nonterminal *inline_substitution_NTM = NULL;
#line 375 "inform7/Chapter 31/Compile Invocations Inline.w"
nonterminal *name_local_to_inline_stack_frame_NTM = NULL;
#line 222 "inform7/Chapter 32/Virtual Machines.w"
nonterminal *vm_description_list_NTM = NULL;
#line 227 "inform7/Chapter 32/Virtual Machines.w"
nonterminal *vm_description_tail_NTM = NULL;
#line 231 "inform7/Chapter 32/Virtual Machines.w"
nonterminal *vm_description_entry_NTM = NULL;
#line 238 "inform7/Chapter 32/Virtual Machines.w"
nonterminal *version_identification_NTM = NULL;
#line 307 "inform7/Chapter 32/Virtual Machines.w"
nonterminal *virtual_machine_NTM = NULL;
#line 53 "inform7/Chapter 32/Inform 6 Inclusions.w"
nonterminal *inform6_inclusion_location_NTM = NULL;
#line 61 "inform7/Chapter 32/Inform 6 Inclusions.w"
nonterminal *inclusion_side_NTM = NULL;
#line 96 "inform7/Chapter 32/Use Options.w"
nonterminal *use_translates_as_sentence_object_NTM = NULL;
#line 129 "inform7/Chapter 32/Use Options.w"
nonterminal *use_sentence_object_NTM = NULL;
#line 140 "inform7/Chapter 32/Use Options.w"
nonterminal *notable_use_option_name_NTM = NULL;
#line 265 "inform7/Chapter 32/Use Options.w"
nonterminal *immediate_use_NTM = NULL;
#line 270 "inform7/Chapter 32/Use Options.w"
nonterminal *immediate_use_tail_NTM = NULL;
#line 274 "inform7/Chapter 32/Use Options.w"
nonterminal *immediate_use_entry_NTM = NULL;
#line 52 "inform7/Chapter 33/Bibliographic Data.w"
nonterminal *notable_bibliographic_variables_NTM = NULL;
#line 92 "inform7/Chapter 33/Bibliographic Data.w"
nonterminal *titling_line_NTM = NULL;
#line 96 "inform7/Chapter 33/Bibliographic Data.w"
nonterminal *plain_titling_line_NTM = NULL;
#line 212 "inform7/Chapter 33/Bibliographic Data.w"
nonterminal *episode_sentence_object_NTM = NULL;
#line 65 "inform7/Chapter 33/Release Instructions.w"
nonterminal *release_sentence_object_NTM = NULL;
#line 104 "inform7/Chapter 33/Release Instructions.w"
nonterminal *privacy_indicator_NTM = NULL;
#line 108 "inform7/Chapter 33/Release Instructions.w"
nonterminal *exposed_innards_NTM = NULL;
#line 49 "inform7/Chapter 34/The Naming Thicket.w"
nonterminal *notable_naming_properties_NTM = NULL;
#line 237 "inform7/Chapter 34/Spatial Model.w"
nonterminal *notable_spatial_kinds_NTM = NULL;
#line 348 "inform7/Chapter 34/Spatial Model.w"
nonterminal *notable_spatial_properties_NTM = NULL;
#line 422 "inform7/Chapter 34/Spatial Model.w"
nonterminal *spatial_specifying_nouns_NTM = NULL;
#line 466 "inform7/Chapter 34/Spatial Model.w"
nonterminal *notable_spatial_noun_phrases_NTM = NULL;
#line 52 "inform7/Chapter 34/The Player.w"
nonterminal *notable_player_instances_NTM = NULL;
#line 92 "inform7/Chapter 34/The Player.w"
nonterminal *notable_player_variables_NTM = NULL;
#line 245 "inform7/Chapter 34/The Player.w"
nonterminal *implicit_player_relationship_NTM = NULL;
#line 42 "inform7/Chapter 34/Backdrops.w"
nonterminal *notable_backdrops_kinds_NTM = NULL;
#line 70 "inform7/Chapter 34/Backdrops.w"
nonterminal *notable_backdrops_properties_NTM = NULL;
#line 178 "inform7/Chapter 34/Backdrops.w"
nonterminal *notable_backdrops_noun_phrases_NTM = NULL;
#line 71 "inform7/Chapter 34/Regions.w"
nonterminal *notable_regions_kinds_NTM = NULL;
#line 140 "inform7/Chapter 34/Regions.w"
nonterminal *notable_regions_properties_NTM = NULL;
#line 167 "inform7/Chapter 34/The Map.w"
nonterminal *notable_map_kinds_NTM = NULL;
#line 280 "inform7/Chapter 34/The Map.w"
nonterminal *notable_map_directions_NTM = NULL;
#line 455 "inform7/Chapter 34/The Map.w"
nonterminal *notable_map_properties_NTM = NULL;
#line 536 "inform7/Chapter 34/The Map.w"
nonterminal *notable_map_noun_phrases_NTM = NULL;
#line 91 "inform7/Chapter 34/Map Connection Relations.w"
nonterminal *mapping_relation_construction_NTM = NULL;
#line 94 "inform7/Chapter 34/Map Connection Relations.w"
nonterminal *mapping_preposition_construction_NTM = NULL;
#line 103 "inform7/Chapter 34/Map Connection Relations.w"
nonterminal *notable_directions_NTM = NULL;
#line 997 "inform7/Chapter 34/HTML Map.w"
nonterminal *map_name_abbreviation_omission_words_NTM = NULL;
#line 304 "inform7/Chapter 34/EPS Map.w"
nonterminal *direction_name_NTM = NULL;
#line 316 "inform7/Chapter 34/EPS Map.w"
nonterminal *index_map_sentence_subject_NTM = NULL;
#line 328 "inform7/Chapter 34/EPS Map.w"
nonterminal *map_positioning_NTM = NULL;
#line 388 "inform7/Chapter 34/EPS Map.w"
nonterminal *map_setting_NTM = NULL;
#line 393 "inform7/Chapter 34/EPS Map.w"
nonterminal *map_setting_scope_NTM = NULL;
#line 397 "inform7/Chapter 34/EPS Map.w"
nonterminal *map_setting_scope_unarticled_NTM = NULL;
#line 411 "inform7/Chapter 34/EPS Map.w"
nonterminal *map_parameter_NTM = NULL;
#line 440 "inform7/Chapter 34/EPS Map.w"
nonterminal *map_setting_value_NTM = NULL;
#line 447 "inform7/Chapter 34/EPS Map.w"
nonterminal *map_setting_boolean_NTM = NULL;
#line 457 "inform7/Chapter 34/EPS Map.w"
nonterminal *map_offset_NTM = NULL;
#line 467 "inform7/Chapter 34/EPS Map.w"
nonterminal *map_rubric_NTM = NULL;
#line 118 "inform7/Chapter 34/Scenes.w"
nonterminal *notable_scene_properties_NTM = NULL;
#line 176 "inform7/Chapter 34/Scenes.w"
nonterminal *notable_scenes_NTM = NULL;
#line 335 "inform7/Chapter 34/Scenes.w"
nonterminal *scene_ends_sentence_subject_NTM = NULL;
#line 352 "inform7/Chapter 34/Scenes.w"
nonterminal *scene_ends_sentence_adverb_NTM = NULL;
#line 360 "inform7/Chapter 34/Scenes.w"
nonterminal *scene_ends_sentence_object_NTM = NULL;
#line 404 "inform7/Chapter 34/Scenes.w"
nonterminal *scene_name_NTM = NULL;
#line 408 "inform7/Chapter 34/Scenes.w"
nonterminal *scene_name_unarticled_NTM = NULL;
#line 424 "inform7/Chapter 34/Scenes.w"
nonterminal *scene_end_name_NTM = NULL;
#line 430 "inform7/Chapter 34/Scenes.w"
nonterminal *scene_end_name_creating_NTM = NULL;
#line 850 "inform7/Chapter 34/Scenes.w"
nonterminal *s_scene_description_NTM = NULL;
#line 213 "inform7/Chapter 35/Actions.w"
nonterminal *notable_actions_NTM = NULL;
#line 220 "inform7/Chapter 35/Actions.w"
nonterminal *action_name_construction_NTM = NULL;
#line 326 "inform7/Chapter 35/Actions.w"
nonterminal *action_pronoun_NTM = NULL;
#line 355 "inform7/Chapter 35/Actions.w"
nonterminal *action_name_NTM = NULL;
#line 382 "inform7/Chapter 35/Actions.w"
nonterminal *action_optional_trailing_prepositions_NTM = NULL;
#line 491 "inform7/Chapter 35/Actions.w"
nonterminal *action_variable_NTM = NULL;
#line 499 "inform7/Chapter 35/Actions.w"
nonterminal *action_variable_name_NTM = NULL;
#line 697 "inform7/Chapter 35/Actions.w"
nonterminal *action_sentence_subject_NTM = NULL;
#line 725 "inform7/Chapter 35/Actions.w"
nonterminal *action_clause_NTM = NULL;
#line 732 "inform7/Chapter 35/Actions.w"
nonterminal *action_applications_NTM = NULL;
#line 744 "inform7/Chapter 35/Actions.w"
nonterminal *act_req_NTM = NULL;
#line 748 "inform7/Chapter 35/Actions.w"
nonterminal *action_access_NTM = NULL;
#line 756 "inform7/Chapter 35/Actions.w"
nonterminal *action_sentence_object_NTM = NULL;
#line 760 "inform7/Chapter 35/Actions.w"
nonterminal *action_clauses_NTM = NULL;
#line 765 "inform7/Chapter 35/Actions.w"
nonterminal *action_clause_terminated_NTM = NULL;
#line 111 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *action_list_NTM = NULL;
#line 119 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *anl_excluded_NTM = NULL;
#line 123 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *anl_minimal_common_operand_NTM = NULL;
#line 148 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *anl_to_tail_NTM = NULL;
#line 152 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *anl_operand_NTM = NULL;
#line 155 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *anl_in_tail_NTM = NULL;
#line 183 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *anl_NTM = NULL;
#line 187 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *anl_tail_NTM = NULL;
#line 202 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *anl_entry_NTM = NULL;
#line 207 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *named_action_pattern_NTM = NULL;
#line 215 "inform7/Chapter 35/Action Name Lists.w"
nonterminal *anl_entry_with_action_NTM = NULL;
#line 595 "inform7/Chapter 35/Action Patterns.w"
nonterminal *action_pattern_NTM = NULL;
#line 609 "inform7/Chapter 35/Action Patterns.w"
nonterminal *we_are_action_pattern_NTM = NULL;
#line 620 "inform7/Chapter 35/Action Patterns.w"
nonterminal *action_pattern_negated_NTM = NULL;
#line 631 "inform7/Chapter 35/Action Patterns.w"
nonterminal *action_pattern_past_NTM = NULL;
#line 639 "inform7/Chapter 35/Action Patterns.w"
nonterminal *action_pattern_past_negated_NTM = NULL;
#line 660 "inform7/Chapter 35/Action Patterns.w"
nonterminal *action_pattern_core_actor_NTM = NULL;
#line 679 "inform7/Chapter 35/Action Patterns.w"
nonterminal *actor_description_NTM = NULL;
#line 746 "inform7/Chapter 35/Action Patterns.w"
nonterminal *action_pattern_core_NTM = NULL;
#line 753 "inform7/Chapter 35/Action Patterns.w"
nonterminal *action_pattern_past_core_NTM = NULL;
#line 769 "inform7/Chapter 35/Action Patterns.w"
nonterminal *action_pronominal_NTM = NULL;
#line 820 "inform7/Chapter 35/Action Patterns.w"
nonterminal *ap_common_core_NTM = NULL;
#line 831 "inform7/Chapter 35/Action Patterns.w"
nonterminal *condition_in_ap_NTM = NULL;
#line 857 "inform7/Chapter 35/Action Patterns.w"
nonterminal *ap_common_core_inner_NTM = NULL;
#line 868 "inform7/Chapter 35/Action Patterns.w"
nonterminal *ap_common_core_inner_inner_NTM = NULL;
#line 892 "inform7/Chapter 35/Action Patterns.w"
nonterminal *ap_common_core_inner_inner_inner_NTM = NULL;
#line 921 "inform7/Chapter 35/Action Patterns.w"
nonterminal *action_operand_NTM = NULL;
#line 926 "inform7/Chapter 35/Action Patterns.w"
nonterminal *going_action_irregular_operand_NTM = NULL;
#line 930 "inform7/Chapter 35/Action Patterns.w"
nonterminal *understanding_action_irregular_operand_NTM = NULL;
#line 938 "inform7/Chapter 35/Action Patterns.w"
nonterminal *action_parameter_NTM = NULL;
#line 945 "inform7/Chapter 35/Action Patterns.w"
nonterminal *if_nonconstant_action_context_NTM = NULL;
#line 137 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_sentence_subject_NTM = NULL;
#line 159 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_regular_list_NTM = NULL;
#line 164 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_regular_tail_NTM = NULL;
#line 168 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_regular_entry_NTM = NULL;
#line 175 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_property_list_NTM = NULL;
#line 180 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_property_tail_NTM = NULL;
#line 184 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_property_entry_NTM = NULL;
#line 248 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_sentence_object_NTM = NULL;
#line 252 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_sentence_object_uncond_NTM = NULL;
#line 257 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_sentence_object_tail_NTM = NULL;
#line 261 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_sentence_entry_NTM = NULL;
#line 290 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_as_this_NTM = NULL;
#line 301 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_ref_NTM = NULL;
#line 373 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_command_sentence_object_NTM = NULL;
#line 402 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_property_sentence_object_NTM = NULL;
#line 406 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_property_sentence_object_unconditional_NTM = NULL;
#line 411 "inform7/Chapter 36/Traverse for Grammar.w"
nonterminal *understand_property_reference_NTM = NULL;
#line 94 "inform7/Chapter 36/Grammar Properties.w"
nonterminal *notable_parsing_variables_NTM = NULL;
#line 187 "inform7/Chapter 36/Grammar Lines.w"
nonterminal *understand_condition_NTM = NULL;
#line 63 "inform7/Chapter 36/Grammar Tokens.w"
nonterminal *grammar_token_breaking_NTM = NULL;
#line 208 "inform7/Chapter 36/Grammar Tokens.w"
nonterminal *grammar_token_NTM = NULL;
#line 225 "inform7/Chapter 36/Grammar Tokens.w"
nonterminal *standard_grammar_token_NTM = NULL;
#line 242 "inform7/Chapter 36/Grammar Tokens.w"
nonterminal *named_grammar_token_NTM = NULL;
#line 79 "inform7/Chapter 36/Test Scripts.w"
nonterminal *test_sentence_subject_NTM = NULL;
#line 90 "inform7/Chapter 36/Test Scripts.w"
nonterminal *internal_test_case_name_NTM = NULL;
#line 116 "inform7/Chapter 36/Test Scripts.w"
nonterminal *test_sentence_object_NTM = NULL;
#line 121 "inform7/Chapter 36/Test Scripts.w"
nonterminal *test_case_circumstance_list_NTM = NULL;
#line 126 "inform7/Chapter 36/Test Scripts.w"
nonterminal *test_case_circumstance_NTM = NULL;
#line 103 "inform7/Chapter 37/Figures.w"
nonterminal *figure_sentence_object_NTM = NULL;
#line 107 "inform7/Chapter 37/Figures.w"
nonterminal *figure_source_NTM = NULL;
#line 127 "inform7/Chapter 37/Figures.w"
nonterminal *notable_figures_NTM = NULL;
#line 95 "inform7/Chapter 37/Sound Effects.w"
nonterminal *sound_sentence_object_NTM = NULL;
#line 99 "inform7/Chapter 37/Sound Effects.w"
nonterminal *sound_source_NTM = NULL;
#line 91 "inform7/Chapter 37/External Files.w"
nonterminal *external_file_sentence_subject_NTM = NULL;
#line 97 "inform7/Chapter 37/External Files.w"
nonterminal *external_file_name_NTM = NULL;
#line 101 "inform7/Chapter 37/External Files.w"
nonterminal *external_file_owner_NTM = NULL;
#line 127 "inform7/Chapter 37/External Files.w"
nonterminal *external_file_sentence_object_NTM = NULL;
#line 36 "inform7/Chapter 38/Translate to Identifiers.w"
nonterminal *translates_into_i6_sentence_subject_NTM = NULL;
#line 61 "inform7/Chapter 38/Translate to Identifiers.w"
nonterminal *translates_into_i6_sentence_object_NTM = NULL;
#line 136 "inform7/Chapter 38/Translate to Identifiers.w"
nonterminal *extra_response_NTM = NULL;
#line 62 "inform7/Chapter 38/Plugins.w"
nonterminal *plugin_name_NTM = NULL;
#line 87 "inform7/Chapter 38/Plugins.w"
nonterminal *language_element_NTM = NULL;
#line 213 "inform7/Chapter 38/Plugins.w"
nonterminal *use_language_element_sentence_subject_NTM = NULL;
int from_NTMV = 0;
int unit_NTMV = 0;
int to_NTMV = 0;
int giving_parts_NTMV = 0;
int is_participle_NTMV = 0;
int rest1_NTMV = 0;
int rest2_NTMV = 0;
int t1_NTMV = 0;
int t2_NTMV = 0;
int auth1_NTMV = 0;
int auth2_NTMV = 0;
int k1_NTMV = 0;
int k2_NTMV = 0;
int nameforms_NTMV = 0;
int each_NTMV = 0;
int place_NTMV = 0;
int len_NTMV = 0;
rulebook * rulebook_m_NTMV = NULL;
int ds_NTMV = 0;
int future_NTMV = 0;
int any_NTMV = 0;
int inlinecode_NTMV = 0;
int event_time_NTMV = 0;
int written_NTMV = 0;
int named_NTMV = 0;
int inverted_NTMV = 0;
parse_node * parse_node_scenes_NTMV = NULL;
int bud1_NTMV = 0;
int bud2_NTMV = 0;
int cw1_NTMV = 0;
int cw2_NTMV = 0;
int deprecated_NTMV = 0;
int say_ann_NTMV = 0;
int operation_NTMV = 0;
int assignment_NTMV = 0;
int eqn_NTMV = 0;
int rel1_NTMV = 0;
int rel2_NTMV = 0;
preposition_usage * preposition_usage_pu_NTMV = NULL;
int run_on_NTMV = 0;
int control_NTMV = 0;
int token_form_NTMV = 0;
int token_construct_NTMV = 0;
int calling_NTMV = 0;
int antonym_NTMV = 0;
int opt_NTMV = 0;
local_variable * local_variable_var_NTMV = NULL;
parse_node * parse_node_s_NTMV = NULL;
int series_NTMV = 0;
int privacy_NTMV = 0;
int alttext_NTMV = 0;
kind * kind_k_NTMV = NULL;
quantifier * quantifier_q_NTMV = NULL;
instance * instance_x_NTMV = NULL;
instance * instance_y_NTMV = NULL;
int scoping_NTMV = 0;
int msvtype_NTMV = 0;
instance * instance_dir_NTMV = NULL;
char * char_partext_NTMV = NULL;
int parindex_NTMV = 0;
int level_NTMV = 0;
kind * kind_kscope_NTMV = NULL;
instance * instance_iscope_NTMV = NULL;
int msvalue_NTMV = 0;
int msword_NTMV = 0;
int rsize_NTMV = 0;
int edge_NTMV = 0;
int rfont_NTMV = 0;
int rcol_NTMV = 0;
int roff_NTMV = 0;
scene * scene_named_NTMV = NULL;
parse_node * parse_node_cond_NTMV = NULL;
int num_NTMV = 0;
kind * kind_op1_NTMV = NULL;
int ac1_NTMV = 0;
kind * kind_op2_NTMV = NULL;
int ac2_NTMV = 0;
kind * kind_understood_NTMV = NULL;
grammar_verb * grammar_verb_named_NTMV = NULL;
int ownership_NTMV = 0;
void register_tangled_nonterminals(void);
#line 18 "inform7/Chapter 1/Basic Definitions.w"
#line 45 "inform7/Chapter 1/Basic Definitions.w"
int this_is_a_release_compile = FALSE; /* Omit sections of source text marked not for release */
int existing_story_file = FALSE; /* Ignore source text to blorb existing story file? */
int rng_seed_at_start_of_play = 0; /* The seed value, or 0 if not seeded */
int census_mode = FALSE; /* NI running only to update extension documentation */
char *story_filename_extension = "ulx"; /* What story file we will eventually have */
int show_progress_indicator = TRUE; /* Produce percentage of progress messages */
int default_scoring_setting = FALSE; /* By default, whether a score is kept at run time */
int scoring_option_set = NOT_APPLICABLE; /* Whether in this case a score is kept at run time */
#line 59 "inform7/Chapter 1/Basic Definitions.w"
struct tm *the_present = NULL;
#line 65 "inform7/Chapter 1/Basic Definitions.w"
int no_deprecated_features = FALSE; /* forbid syntaxes marked as deprecated? */
#line 79 "inform7/Chapter 1/Basic Definitions.w"
int text_loaded_from_source = FALSE; /* Lexical scanning is done */
int model_world_under_construction = FALSE; /* World model is being constructed */
int model_world_constructed = FALSE; /* World model is now constructed */
int indexing_stage = FALSE; /* Everything is done except indexing */
#line 202 "inform7/Chapter 1/Basic Definitions.w"
text_stream debug_log_file_struct; /* The actual debugging log file */
text_stream inform6_file_struct; /* The actual I6 code file */
text_stream problems_file_struct; /* The actual report of Problems file */
text_stream index_file_struct; /* The current index file being written */
text_stream telemetry_file_struct; /* The actual telemetry file (if created) */
text_stream *debug_log_file = &debug_log_file_struct; /* The actual debugging log file */
text_stream *inform6_file = &inform6_file_struct; /* The actual I6 code file */
text_stream *problems_file = &problems_file_struct; /* The actual report of Problems file */
text_stream *telemetry_file = &telemetry_file_struct; /* The actual debugging log file */
text_stream *dl = NULL; /* Current destination of debugging text */
text_stream *ifl = NULL; /* Current destination of index text */
text_stream *probl = NULL; /* Current destination of problem message text */
text_stream *telmy = NULL; /* Current destination of telemetry text */
int problem_count = 0; /* The number of Problem messages so far produced */
int internal_error_thrown = FALSE;
int it_is_not_worth_adding = FALSE; /* To suppress the "It may be worth adding..." */
int trace_sentences = FALSE; /* Currently debugging text to trace rather than log */
int logging_to_I6_text = FALSE; /* Used for internal test cases */
#line 230 "inform7/Chapter 1/Basic Definitions.w"
int abort_I6T_interpreter = FALSE;
#line 21 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifndef PLATFORM_MACOSX
#ifndef PLATFORM_WINDOWS
#ifndef PLATFORM_UNIX
#ifndef PLATFORM_ANDROID
#define PLATFORM_MACOSX /* the original home for NI, and still the default */
#endif
#endif
#endif
#endif
#ifndef CPU_WORDSIZE_MULTIPLIER
#define CPU_WORDSIZE_MULTIPLIER 1 /* the CPU word size is by default 32 bits */
#endif
#line 77 "inform7/Chapter 2/Memory.w"
#line 61 "inform7/Chapter 2/Streams.w"
#define WRITE(args...) Streams__printf(OUT, args)
#define INDEX(args...) Streams__printf(ifl, args)
#define WRITE_TO(stream, args...) Streams__printf(stream, args)
#line 241 "inform7/Chapter 2/Streams.w"
#line 253 "inform7/Chapter 2/Streams.w"
int total_file_writes = 0; /* number of text files opened for writing during the run */
#line 28 "inform7/Chapter 2/Debugging Log.w"
#define LOG(args...) Log__dlprintf(args)
#define LOGIF(aspect, args...) { \
if (Log__aspect_switched_on(aspect##_DA)) Log__dlprintf(args); \
}
#define LOG_INDENT STREAM_INDENT(dl)
#define LOG_OUTDENT STREAM_OUTDENT(dl)
#line 117 "inform7/Chapter 2/Debugging Log.w"
#line 185 "inform7/Chapter 2/Debugging Log.w"
debugging_aspect the_debugging_aspects[] = {
{ "action", "creations", "", FALSE, FALSE },
{ "action", "pattern", "compilation", FALSE, FALSE },
{ "action", "pattern", "parsing", FALSE, FALSE },
{ "assemblies", "", "", FALSE, FALSE },
{ "assertions", "", "", FALSE, TRUE },
{ "case", "insensitive", "filehandling", FALSE, FALSE },
{ "conditions", "", "", FALSE, FALSE },
{ "constructed", "past", "participles", FALSE, FALSE },
{ "constructed", "plurals", "", FALSE, FALSE },
{ "debugging", "log", "contents", TRUE, FALSE },
{ "debugging", "log", "inclusions", TRUE, FALSE },
{ "description", "compilation", "", FALSE, FALSE },
{ "excerpt", "meanings", "", FALSE, FALSE },
{ "excerpt", "parsing", "", FALSE, FALSE },
{ "expressions", "", "", FALSE, FALSE },
{ "extensions", "census", "", FALSE, FALSE },
{ "figure", "creations", "", FALSE, FALSE },
{ "grammar", "", "", FALSE, FALSE },
{ "grammar", "construction", "", FALSE, FALSE },
{ "headings", "", "", FALSE, FALSE },
{ "implications", "", "", FALSE, TRUE },
{ "inferences", "", "", FALSE, TRUE },
{ "kind", "changes", "", FALSE, TRUE },
{ "kind", "checking", "", FALSE, FALSE },
{ "kind", "creations", "", FALSE, FALSE },
{ "lexical", "output", "", FALSE, FALSE },
{ "local", "variables", "", FALSE, FALSE },
{ "matching", "", "", FALSE, FALSE },
{ "meaning", "list", "allocation", FALSE, FALSE },
{ "memory", "allocation", "", FALSE, FALSE },
{ "noun", "resolution", "", FALSE, FALSE },
{ "object", "compilation", "", FALSE, FALSE },
{ "object", "creations", "", FALSE, FALSE },
{ "object", "tree", "", FALSE, FALSE },
{ "phrase", "comparisons", "", FALSE, FALSE },
{ "phrase", "compilation", "", FALSE, FALSE },
{ "phrase", "creations", "", FALSE, FALSE },
{ "phrase", "registration", "", FALSE, FALSE },
{ "phrase", "usage", "", FALSE, FALSE },
{ "predicate", "calculus", "", FALSE, FALSE },
{ "predicate", "calculus", "workings", FALSE, FALSE },
{ "pronouns", "", "", FALSE, FALSE },
{ "property", "creations", "", FALSE, FALSE },
{ "property", "provision", "", FALSE, FALSE },
{ "property", "translations", "", FALSE, FALSE },
{ "relation", "definitions", "", FALSE, FALSE },
{ "rule", "attachments", "", FALSE, FALSE },
{ "rulebook", "compilation", "", FALSE, FALSE },
{ "spatial", "map", "", FALSE, FALSE },
{ "spatial", "map", "workings", FALSE, FALSE },
{ "specification", "permissions", "", FALSE, FALSE },
{ "specification", "usage", "", FALSE, FALSE },
{ "specificities", "", "", FALSE, FALSE },
{ "table", "construction", "", FALSE, FALSE },
{ "template", "reading", "", FALSE, FALSE },
{ "text", "substitutions", "", FALSE, FALSE },
{ "time", "periods", "", FALSE, FALSE },
{ "variable", "creations", "", FALSE, FALSE },
{ "verifications", "", "", FALSE, FALSE },
{ "vocabulary", "", "", FALSE, FALSE },
{ "", "", "", FALSE, FALSE }
};
#line 50 "inform7/Chapter 3/Pathnames.w"
#line 55 "inform7/Chapter 3/Pathnames.w"
pathname *home_path = NULL;
#line 23 "inform7/Chapter 3/Filenames.w"
#line 19 "inform7/Chapter 3/Where Everything Lives.w"
char *AREA_NAME[3] = { "from .materials", "installed", "built in" };
#line 24 "inform7/Chapter 3/Where Everything Lives.w"
pathname *pathname_of_area[NO_FS_AREAS] = { NULL, NULL, NULL };
pathname *pathname_of_extensions[NO_FS_AREAS] = { NULL, NULL, NULL };
pathname *pathname_of_i6t_files[NO_FS_AREAS] = { NULL, NULL, NULL };
pathname *pathname_of_languages[NO_FS_AREAS] = { NULL, NULL, NULL };
pathname *pathname_of_website_templates[NO_FS_AREAS] = { NULL, NULL, NULL };
pathname *pathname_of_extension_docs = NULL;
pathname *pathname_of_extension_docs_inner = NULL;
pathname *pathname_of_materials_figures = NULL;
pathname *pathname_of_materials_release = NULL;
pathname *pathname_of_materials_sounds = NULL;
pathname *pathname_of_project = NULL;
pathname *pathname_of_project_index_details_folder = NULL;
pathname *pathname_of_project_index_folder = NULL;
pathname *pathname_of_released_figures = NULL;
pathname *pathname_of_released_interpreter = NULL;
pathname *pathname_of_released_sounds = NULL;
pathname *pathname_of_transient_census_data = NULL;
pathname *pathname_of_transient_external_resources = NULL;
#line 47 "inform7/Chapter 3/Where Everything Lives.w"
filename *filename_of_blurb = NULL;
filename *filename_of_cblorb_report = NULL;
filename *filename_of_cblorb_report_model = NULL;
filename *filename_of_compiled_i6_code = NULL;
filename *filename_of_debugging_log = NULL;
filename *filename_of_documentation_snippets = NULL;
filename *filename_of_epsfile = NULL;
filename *filename_of_existing_story_file = NULL;
filename *filename_of_extension_file_documentation_model = NULL;
filename *filename_of_extensions_census_errors = NULL;
filename *filename_of_extensions_dictionary = NULL;
filename *filename_of_extensions_documentation_model = NULL;
filename *filename_of_headings = NULL;
filename *filename_of_i7_source = NULL;
filename *filename_of_ifiction_record = NULL;
filename *filename_of_intro_booklet = NULL;
filename *filename_of_intro_postcard = NULL;
filename *filename_of_large_cover_art_jpeg = NULL;
filename *filename_of_large_cover_art_png = NULL;
filename *filename_of_large_default_cover_art = NULL;
filename *filename_of_manifest = NULL;
filename *filename_of_options = NULL;
filename *filename_of_parse_tree = NULL;
filename *filename_of_report = NULL;
filename *filename_of_small_cover_art_jpeg = NULL;
filename *filename_of_small_cover_art_png = NULL;
filename *filename_of_small_default_cover_art = NULL;
filename *filename_of_story_file = NULL;
filename *filename_of_telemetry = NULL;
filename *filename_of_uuid = NULL;
#line 32 "inform7/Chapter 5/Index File Services.w"
#line 44 "inform7/Chapter 5/Index File Services.w"
#line 45 "inform7/Chapter 5/Documentation References.w"
#line 49 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry *sorted_lexicon = NULL; /* head of list in lexicographic order */
lexicon_entry *current_main_verb = NULL; /* when parsing verb declarations */
#line 52 "inform7/Chapter 7/Vocabulary.w"
#line 32 "inform7/Chapter 7/Tries and Inflections.w"
#line 45 "inform7/Chapter 7/Tries and Inflections.w"
#line 22 "inform7/Chapter 7/Word Assemblages.w"
#line 27 "inform7/Chapter 7/Clusters.w"
#line 37 "inform7/Chapter 7/Clusters.w"
#line 26 "inform7/Chapter 7/Plurals Dictionary.w"
#line 47 "inform7/Chapter 7/Natural Languages.w"
#line 52 "inform7/Chapter 7/Natural Languages.w"
natural_language *English_language = NULL; /* until created, early in run */
#line 57 "inform7/Chapter 7/Natural Languages.w"
natural_language *language_of_play = NULL; /* the language read and typed by the player */
natural_language *language_of_source_text = NULL; /* the language written by the author */
#line 84 "inform7/Chapter 7/Preform.w"
int language_definition_top = -1;
#line 90 "inform7/Chapter 7/Preform.w"
natural_language *language_being_read_by_Preform = NULL;
#line 175 "inform7/Chapter 7/Preform.w"
#line 188 "inform7/Chapter 7/Preform.w"
#line 250 "inform7/Chapter 7/Preform.w"
#line 310 "inform7/Chapter 7/Preform.w"
#line 315 "inform7/Chapter 7/Preform.w"
int most_recent_result = 0; /* this is the variable which |inweb| writes |most_recent_result| */
void *most_recent_result_p = NULL; /* this is the variable which |inweb| writes |most_recent_result_p| */
#line 324 "inform7/Chapter 7/Preform.w"
vocabulary_entry *CAPITAL_K_V;
vocabulary_entry *CAPITAL_L_V;
vocabulary_entry *CLOSEBRACE_V;
vocabulary_entry *CLOSEBRACKET_V;
vocabulary_entry *COLON_V;
vocabulary_entry *COMMA_V;
vocabulary_entry *DOUBLEDASH_V;
vocabulary_entry *FORWARDSLASH_V;
vocabulary_entry *FULLSTOP_V;
vocabulary_entry *OPENBRACE_V;
vocabulary_entry *OPENBRACKET_V;
vocabulary_entry *OPENI6_V;
vocabulary_entry *PARBREAK_V;
vocabulary_entry *SEMICOLON_V;
vocabulary_entry *STROKE_V;
#line 358 "inform7/Chapter 7/Preform.w"
int no_req_bits = 0;
#line 59 "inform7/Chapter 7/Non-Parsing Preform.w"
#line 65 "inform7/Chapter 7/Non-Parsing Preform.w"
#line 69 "inform7/Chapter 7/Non-Parsing Preform.w"
verb_conjugation *to_be_conjugation = NULL;
#line 62 "inform7/Chapter 8/Determiners and Quantifiers.w"
#line 66 "inform7/Chapter 8/Determiners and Quantifiers.w"
quantifier
*for_all_quantifier = NULL, *not_for_all_quantifier = NULL,
*exists_quantifier = NULL, *not_exists_quantifier = NULL,
*all_but_quantifier = NULL, *not_all_but_quantifier = NULL,
*almost_all_quantifier = NULL, *almost_no_quantifier = NULL,
*most_quantifier = NULL, *under_half_quantifier = NULL,
*at_least_quantifier = NULL, *more_than_quantifier = NULL,
*at_most_quantifier = NULL, *less_than_quantifier = NULL,
*exactly_quantifier = NULL, *other_than_quantifier = NULL;
#line 102 "inform7/Chapter 8/Determiners and Quantifiers.w"
#line 36 "inform7/Chapter 8/Time Periods.w"
#line 55 "inform7/Chapter 9/Adjectives.w"
#line 66 "inform7/Chapter 9/Adjective Meanings.w"
#line 19 "inform7/Chapter 9/Adjective Usages.w"
#line 90 "inform7/Chapter 10/Literal Patterns.w"
#line 113 "inform7/Chapter 10/Literal Patterns.w"
#line 147 "inform7/Chapter 10/Literal Patterns.w"
#line 171 "inform7/Chapter 10/Literal Patterns.w"
#line 37 "inform7/Chapter 10/Times of Day.w"
kind *K_time = NULL;
#line 71 "inform7/Chapter 10/Excerpt Meanings.w"
#line 76 "inform7/Chapter 10/Excerpt Meanings.w"
parse_node *meaning_of_player = NULL;
#line 53 "inform7/Chapter 10/Nametags.w"
#line 48 "inform7/Chapter 10/Instances.w"
#line 56 "inform7/Chapter 10/Instances.w"
#line 60 "inform7/Chapter 10/Instances.w"
instance *latest_instance = NULL;
#line 67 "inform7/Chapter 10/Instances.w"
int no_ggs_recorded = 0;
instance *grammatical_genders[NO_GRAMMATICAL_GENDERS];
#line 43 "inform7/Chapter 10/Nonlocal Variables.w"
#line 48 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable *i6_glob_VAR = NULL;
nonlocal_variable *i6_nothing_VAR = NULL; /* the I6 |nothing| constant */
#line 54 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable *latest_nonlocal_variable = NULL;
#line 139 "inform7/Chapter 11/Binary Predicates.w"
#line 243 "inform7/Chapter 11/Binary Predicates.w"
#line 30 "inform7/Chapter 11/Relations.w"
#line 11 "inform7/Chapter 11/The Universal Relation.w"
binary_predicate *R_universal = NULL;
binary_predicate *R_meaning = NULL;
#line 37 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *regular_to_be = NULL; /* "is" */
verb_usage *negated_to_be = NULL; /* "is not" */
verb_usage *negated_plural_to_be = NULL; /* "are not" */
verb_usage *vu_search_list = NULL;
#line 36 "inform7/Chapter 11/Prepositions.w"
#line 45 "inform7/Chapter 12/Lexer.w"
source_location lexer_position;
#line 71 "inform7/Chapter 12/Lexer.w"
int lexer_wordcount; /* Number of words read in to arrays */
#line 206 "inform7/Chapter 12/Lexer.w"
lexer_details *lw_array = NULL; /* a dynamically allocated (and mobile) array */
int lexer_details_memory_allocated = 0; /* bytes allocated to this array */
int lexer_workspace_allocated = 0; /* bytes allocated to text storage */
#line 48 "inform7/Chapter 12/Read Source Text.w"
source_file *primary_source_file = NULL; /* first to be opened */
#line 26 "inform7/Chapter 12/Wordings.w"
#line 210 "inform7/Chapter 13/Parse Tree.w"
#line 222 "inform7/Chapter 13/Parse Tree.w"
parse_node *tree_root = NULL;
parse_node *current_sentence = NULL;
#line 236 "inform7/Chapter 13/Parse Tree.w"
#line 362 "inform7/Chapter 13/Parse Tree.w"
DECLARE_ANNOTATION_FUNCTIONS(action_meaning, action_pattern)
DECLARE_ANNOTATION_FUNCTIONS(aph, adjectival_phrase)
DECLARE_ANNOTATION_FUNCTIONS(condition_tense, time_period)
DECLARE_ANNOTATION_FUNCTIONS(constant_action_name, action_name)
DECLARE_ANNOTATION_FUNCTIONS(constant_action_pattern, action_pattern)
DECLARE_ANNOTATION_FUNCTIONS(constant_activity, activity)
DECLARE_ANNOTATION_FUNCTIONS(constant_binary_predicate, binary_predicate)
DECLARE_ANNOTATION_FUNCTIONS(constant_constant_phrase, constant_phrase)
DECLARE_ANNOTATION_FUNCTIONS(constant_equation, equation)
DECLARE_ANNOTATION_FUNCTIONS(constant_grammar_verb, grammar_verb)
DECLARE_ANNOTATION_FUNCTIONS(constant_instance, instance)
DECLARE_ANNOTATION_FUNCTIONS(constant_local_variable, local_variable)
DECLARE_ANNOTATION_FUNCTIONS(constant_named_rulebook_outcome, named_rulebook_outcome)
DECLARE_ANNOTATION_FUNCTIONS(constant_nonlocal_variable, nonlocal_variable)
DECLARE_ANNOTATION_FUNCTIONS(constant_property, property)
DECLARE_ANNOTATION_FUNCTIONS(constant_rule, rule)
DECLARE_ANNOTATION_FUNCTIONS(constant_rulebook, rulebook)
DECLARE_ANNOTATION_FUNCTIONS(constant_scene, scene)
DECLARE_ANNOTATION_FUNCTIONS(constant_table_column, table_column)
DECLARE_ANNOTATION_FUNCTIONS(constant_table, table)
DECLARE_ANNOTATION_FUNCTIONS(constant_text, text_stream)
DECLARE_ANNOTATION_FUNCTIONS(constant_use_option, use_option)
DECLARE_ANNOTATION_FUNCTIONS(constant_verb_conjugation, verb_conjugation)
DECLARE_ANNOTATION_FUNCTIONS(control_structure_used, control_structure_phrase)
DECLARE_ANNOTATION_FUNCTIONS(creation_proposition, pcalc_prop)
DECLARE_ANNOTATION_FUNCTIONS(defn_language, natural_language)
DECLARE_ANNOTATION_FUNCTIONS(embodying_heading, heading)
DECLARE_ANNOTATION_FUNCTIONS(end_control_structure_used, control_structure_phrase)
DECLARE_ANNOTATION_FUNCTIONS(evaluation, parse_node)
DECLARE_ANNOTATION_FUNCTIONS(grammar_token_relation, binary_predicate)
DECLARE_ANNOTATION_FUNCTIONS(grammar_value, parse_node)
DECLARE_ANNOTATION_FUNCTIONS(implicit_in_creation_of, inference_subject)
DECLARE_ANNOTATION_FUNCTIONS(interpretation_of_subject, inference_subject)
DECLARE_ANNOTATION_FUNCTIONS(kind_of_new_variable, kind)
DECLARE_ANNOTATION_FUNCTIONS(kind_of_value, kind)
DECLARE_ANNOTATION_FUNCTIONS(kind_required_by_context, kind)
DECLARE_ANNOTATION_FUNCTIONS(kind_resulting, kind)
DECLARE_ANNOTATION_FUNCTIONS(kind_variable_declarations, kind_variable_declaration)
DECLARE_ANNOTATION_FUNCTIONS(meaning, excerpt_meaning)
DECLARE_ANNOTATION_FUNCTIONS(modal_verb, verb_conjugation)
DECLARE_ANNOTATION_FUNCTIONS(new_relation_here, binary_predicate)
DECLARE_ANNOTATION_FUNCTIONS(phrase_invoked, phrase)
DECLARE_ANNOTATION_FUNCTIONS(phrase_options_invoked, invocation_options)
DECLARE_ANNOTATION_FUNCTIONS(problem_falls_under, parse_node)
DECLARE_ANNOTATION_FUNCTIONS(proposition, pcalc_prop)
DECLARE_ANNOTATION_FUNCTIONS(pu, preposition_usage)
DECLARE_ANNOTATION_FUNCTIONS(quant, quantifier)
DECLARE_ANNOTATION_FUNCTIONS(relationship, binary_predicate)
DECLARE_ANNOTATION_FUNCTIONS(say_adjective, adjectival_phrase)
DECLARE_ANNOTATION_FUNCTIONS(say_verb, verb_conjugation)
DECLARE_ANNOTATION_FUNCTIONS(subject_term, pcalc_term)
DECLARE_ANNOTATION_FUNCTIONS(subject, inference_subject)
DECLARE_ANNOTATION_FUNCTIONS(token_as_parsed, parse_node)
DECLARE_ANNOTATION_FUNCTIONS(token_check_to_do, parse_node)
DECLARE_ANNOTATION_FUNCTIONS(token_to_be_parsed_against, parse_node)
DECLARE_ANNOTATION_FUNCTIONS(vu, verb_usage)
#line 445 "inform7/Chapter 13/Parse Tree.w"
#line 17 "inform7/Chapter 13/Sentences.w"
int no_sentences_read = 0;
int sfsm_extension_position = 0; /* 0: not an extension; 1: before "begins here"; 2: before "ends here"; 3: after */
node_type_t ssnt = 0;
parse_node *first_extension_inclusion = NULL; /* presumably always the Standard Rules */
#line 74 "inform7/Chapter 13/Headings.w"
#line 81 "inform7/Chapter 13/Headings.w"
heading pseudo_heading; /* The entire source falls under this top-level heading */
#line 176 "inform7/Chapter 13/Headings.w"
#line 185 "inform7/Chapter 13/Headings.w"
#line 41 "inform7/Chapter 13/Rule Subtrees.w"
control_structure_phrase
*switch_CSP = NULL,
*if_CSP = NULL,
*repeat_CSP = NULL,
*while_CSP = NULL,
*otherwise_CSP = NULL,
*abbreviated_otherwise_CSP = NULL,
*otherwise_if_CSP = NULL,
*default_case_CSP = NULL,
*case_CSP = NULL,
*say_CSP = NULL,
*now_CSP = NULL,
*instead_CSP = NULL;
#line 178 "inform7/Chapter 14/Extension Files.w"
extension_file *standard_rules_extension; /* the Standard Rules by Graham Nelson */
#line 30 "inform7/Chapter 14/Extension Identifiers.w"
#line 54 "inform7/Chapter 14/Extension Identifiers.w"
#line 34 "inform7/Chapter 14/Extension Census.w"
#line 38 "inform7/Chapter 14/Extension Dictionary.w"
extension_dictionary_entry *first_in_sorted_dictionary = NULL;
#line 60 "inform7/Chapter 14/Extension Dictionary.w"
#line 32 "inform7/Chapter 15/Traverse for Assertions.w"
int traverse; /* always 1 or 2 */
int near_start_of_extension = 0;
#line 59 "inform7/Chapter 15/Traverse for Assertions.w"
#line 65 "inform7/Chapter 15/Traverse for Assertions.w"
sentence_handler *how_to_handle_nodes[MAX_OF_NTS_AND_VBS]; /* for non-|SENTENCE_NT| nodes */
sentence_handler *how_to_handle_sentences[MAX_OF_NTS_AND_VBS]; /* for |SENTENCE_NT| nodes */
#line 46 "inform7/Chapter 15/Assemblies.w"
#line 58 "inform7/Chapter 15/Assemblies.w"
#line 69 "inform7/Chapter 15/Assemblies.w"
#line 29 "inform7/Chapter 15/Implications.w"
#line 37 "inform7/Chapter 15/Implications.w"
#line 58 "inform7/Chapter 16/Parse Excerpts.w"
int no_calls_to_parse_excerpt = 0,
no_meanings_tried = 0,
no_meanings_tried_in_detail = 0,
no_successful_calls_to_parse_excerpt = 0, no_matched_ems = 0;
#line 67 "inform7/Chapter 16/Parse Excerpts.w"
vocabulary_entry *word_to_suppress_in_phrases = NULL;
#line 12 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int force_all_SP_noun_phrases_to_be_physical = FALSE;
#line 45 "inform7/Chapter 17/Terms.w"
#line 67 "inform7/Chapter 17/Terms.w"
#line 37 "inform7/Chapter 17/Atomic Propositions.w"
#line 30 "inform7/Chapter 17/Type Check Propositions.w"
#line 41 "inform7/Chapter 17/Type Check Propositions.w"
#line 11 "inform7/Chapter 18/The Equality Relation.w"
binary_predicate *R_equality = NULL;
#line 21 "inform7/Chapter 18/Quasinumeric Relations.w"
binary_predicate *R_numerically_greater_than = NULL;
binary_predicate *R_numerically_less_than = NULL;
binary_predicate *R_numerically_greater_than_or_equal_to = NULL;
binary_predicate *R_numerically_less_than_or_equal_to = NULL;
#line 80 "inform7/Chapter 18/Assert Propositions.w"
int ptim_recursion_depth = 0; /* depth of recursion of |Calculus__Propositions__Assert__prop_true_in_model| */
#line 66 "inform7/Chapter 18/I6 Schemas.w"
#line 29 "inform7/Chapter 18/Compile Atoms.w"
#line 48 "inform7/Chapter 18/Compile Atoms.w"
int suppress_C14CantChangeKind = FALSE;
int suppress_C14ActionVarsPastTense = FALSE;
#line 42 "inform7/Chapter 18/Deciding to Defer.w"
#line 139 "inform7/Chapter 19/Kinds.w"
kind *K_value = NULL;
kind *K_word_value = NULL;
kind *K_pointer_value = NULL;
kind *K_sayable_value = NULL;
#line 152 "inform7/Chapter 19/Kinds.w"
kind *K_arithmetic_value = NULL;
kind *K_real_arithmetic_value = NULL; /* those using real, not integer, arithmetic */
kind *K_enumerated_value = NULL;
#line 178 "inform7/Chapter 19/Kinds.w"
kind *K_nil = NULL;
kind_constructor *CON_NIL = NULL;
kind_constructor *CON_TUPLE_ENTRY = NULL;
#line 190 "inform7/Chapter 19/Kinds.w"
kind_constructor *CON_INTERMEDIATE = NULL;
#line 201 "inform7/Chapter 19/Kinds.w"
kind_constructor *CON_KIND_VARIABLE = NULL;
#line 207 "inform7/Chapter 19/Kinds.w"
kind *K_equation = NULL;
kind *K_grammatical_gender = NULL;
kind *K_natural_language = NULL;
kind *K_number = NULL;
kind *K_object = NULL;
kind *K_real_number = NULL;
kind *K_response = NULL;
kind *K_snippet = NULL;
kind *K_table = NULL;
kind *K_text = NULL;
kind *K_truth_state = NULL;
kind *K_unicode_character = NULL;
kind *K_use_option = NULL;
kind *K_verb = NULL;
#line 238 "inform7/Chapter 19/Kinds.w"
kind *K_rulebook_outcome = NULL;
kind *K_understanding = NULL;
#line 244 "inform7/Chapter 19/Kinds.w"
kind_constructor *CON_list_of = NULL;
kind_constructor *CON_description = NULL;
kind_constructor *CON_relation = NULL;
kind_constructor *CON_rule = NULL;
kind_constructor *CON_rulebook = NULL;
kind_constructor *CON_activity = NULL;
kind_constructor *CON_phrase = NULL;
kind_constructor *CON_property = NULL;
kind_constructor *CON_table_column = NULL;
kind_constructor *CON_combination = NULL;
kind_constructor *CON_variable = NULL;
#line 265 "inform7/Chapter 19/Kinds.w"
#line 269 "inform7/Chapter 19/Kinds.w"
int no_base_kinds_created = 0;
int no_intermediate_kinds_created = 0;
int no_constructed_kinds_created = 0;
#line 68 "inform7/Chapter 19/Kind Checking.w"
kind *values_of_kind_variables[MAX_KIND_VARIABLES];
#line 90 "inform7/Chapter 19/Kind Checking.w"
int kind_checker_mode = MATCH_KIND_VARIABLES_AS_SYMBOLS;
#line 106 "inform7/Chapter 19/Kind Checking.w"
#line 111 "inform7/Chapter 19/Kind Constructors.w"
#line 124 "inform7/Chapter 19/Kind Constructors.w"
int next_free_data_type_ID = 2; /* i.e., leaving room for |UNKNOWN_TY| to be 1 at run-time */
kind *latest_base_kind_of_value = NULL;
#line 77 "inform7/Chapter 19/Kind Interpreter.w"
#line 94 "inform7/Chapter 19/Kind Interpreter.w"
#line 105 "inform7/Chapter 19/Kind Interpreter.w"
#line 115 "inform7/Chapter 19/Kind Interpreter.w"
#line 119 "inform7/Chapter 19/Kind Interpreter.w"
kind_command_definition table_of_kind_commands[] = {
{ "can-coincide-with-property", can_coincide_with_property_KCC, BOOLEAN_KCA },
{ "can-exchange", can_exchange_KCC, BOOLEAN_KCA },
{ "defined-in-source-text", defined_in_source_text_KCC, BOOLEAN_KCA },
{ "has-i6-GPR", has_i6_GPR_KCC, BOOLEAN_KCA },
{ "indexed-grey-if-empty", indexed_grey_if_empty_KCC, BOOLEAN_KCA },
{ "is-incompletely-defined", is_incompletely_defined_KCC, BOOLEAN_KCA },
{ "is-template-variable", is_template_variable_KCC, BOOLEAN_KCA },
{ "multiple-block", multiple_block_KCC, BOOLEAN_KCA },
{ "named-values-created-with-assertions",
named_values_created_with_assertions_KCC, BOOLEAN_KCA },
{ "constant-compilation-method", constant_compilation_method_KCC, CCM_KCA },
{ "comparison-routine", comparison_routine_KCC, TEXT_KCA },
{ "default-value", default_value_KCC, TEXT_KCA },
{ "description", description_KCC, TEXT_KCA },
{ "distinguisher", distinguisher_KCC, TEXT_KCA },
{ "documentation-reference", documentation_reference_KCC, TEXT_KCA },
{ "explicit-i6-GPR", explicit_i6_GPR_KCC, TEXT_KCA },
{ "i6-printing-routine", i6_printing_routine_KCC, TEXT_KCA },
{ "i6-printing-routine-actions", i6_printing_routine_actions_KCC, TEXT_KCA },
{ "index-default-value", index_default_value_KCC, TEXT_KCA },
{ "index-maximum-value", index_maximum_value_KCC, TEXT_KCA },
{ "index-minimum-value", index_minimum_value_KCC, TEXT_KCA },
{ "loop-domain-schema", loop_domain_schema_KCC, TEXT_KCA },
{ "recognition-only-GPR", recognition_only_GPR_KCC, TEXT_KCA },
{ "specification-text", specification_text_KCC, TEXT_KCA },
{ "cast", cast_KCC, CONSTRUCTOR_KCA },
{ "comparison-schema", comparison_schema_KCC, CONSTRUCTOR_KCA },
{ "instance-of", instance_of_KCC, CONSTRUCTOR_KCA },
{ "modifying-adjective", modifying_adjective_KCC, VOCABULARY_KCA },
{ "plural", plural_KCC, VOCABULARY_KCA },
{ "singular", singular_KCC, VOCABULARY_KCA },
{ "constructor-arity", constructor_arity_KCC, TEXT_KCA },
{ "group", group_KCC, NUMERIC_KCA },
{ "heap-size-estimate", heap_size_estimate_KCC, NUMERIC_KCA },
{ "index-priority", index_priority_KCC, NUMERIC_KCA },
{ "small-block-size", small_block_size_KCC, NUMERIC_KCA },
{ "template-variable-number", template_variable_number_KCC, NUMERIC_KCA },
{ "apply-template", apply_template_KCC, TEMPLATE_KCA },
{ "apply-macro", apply_macro_KCC, MACRO_KCA },
{ NULL, -1, NO_KCA }
};
#line 178 "inform7/Chapter 19/Kind Interpreter.w"
#line 187 "inform7/Chapter 19/Kind Interpreter.w"
#line 194 "inform7/Chapter 19/Kind Interpreter.w"
#line 205 "inform7/Chapter 19/Kind Interpreter.w"
#line 14 "inform7/Chapter 19/Describing Kinds.w"
int kind_parsing_mode = NORMAL_KIND_PARSING;
#line 68 "inform7/Chapter 19/Dimensions.w"
#line 75 "inform7/Chapter 19/Dimensions.w"
#line 180 "inform7/Chapter 19/Dimensions.w"
#line 196 "inform7/Chapter 19/Dimensions.w"
#line 21 "inform7/Chapter 19/Floating-Point Values.w"
#line 75 "inform7/Chapter 19/Scaled Arithmetic Values.w"
#line 29 "inform7/Chapter 19/Runtime Support for Kinds.w"
#line 55 "inform7/Chapter 20/Compiling from Specifications.w"
int compilation_mode = DEREFERENCE_POINTERS_CMODE + IMPLY_NEWLINES_IN_SAY_CMODE; /* default */
#line 60 "inform7/Chapter 20/Dash.w"
#line 73 "inform7/Chapter 21/Properties.w"
#line 78 "inform7/Chapter 21/Properties.w"
property *P_specification = NULL; /* a pseudo-property for indexing kinds */
property *P_variable_initial_value = NULL; /* a pseudo-property for initialising variables */
property *P_indefinite_appearance_text = NULL;
property *P_description = NULL; /* a text property for holding annotations */
property *P_grammatical_gender = NULL; /* a value property describing names */
#line 17 "inform7/Chapter 21/The Provision Relation.w"
binary_predicate *R_provision = NULL;
#line 78 "inform7/Chapter 21/Measurement Adjectives.w"
#line 91 "inform7/Chapter 21/Properties of Objects.w"
instance **objects_in_compilation_list = NULL;
instance *first_object_in_compilation_list = NULL;
instance *last_object_in_compilation_list = NULL;
#line 24 "inform7/Chapter 21/Properties of Values.w"
property_of_value_storage *latest_povs = NULL; /* see below */
#line 74 "inform7/Chapter 22/Inference Subjects.w"
#line 125 "inform7/Chapter 22/Inference Subjects.w"
inference_subject *model_world = NULL;
inference_subject *nonlocal_variables = NULL;
inference_subject *global_constants = NULL;
inference_subject *relations = NULL;
#line 84 "inform7/Chapter 22/Property Permissions.w"
#line 63 "inform7/Chapter 22/Inferences.w"
int prevailing_mood = UNKNOWN_CE;
#line 88 "inform7/Chapter 22/Inferences.w"
#line 64 "inform7/Chapter 23/Text Literals.w"
#line 70 "inform7/Chapter 23/Text Literals.w"
literal_text *root_of_literal_text = NULL;
literal_text *z_node = NULL;
#line 83 "inform7/Chapter 23/Text Literals.w"
int divert_constant_text_bibliographically = FALSE; /* Compile literal text more literally */
int encode_constant_text_bibliographically = FALSE; /* Compile literal text semi-literally */
#line 36 "inform7/Chapter 23/Text Substitutions.w"
#line 40 "inform7/Chapter 23/Text Substitutions.w"
int no_further_text_subs = FALSE;
#line 46 "inform7/Chapter 23/Text Substitutions.w"
int compiling_text_routines_mode = FALSE; /* used for better problem messages */
#line 27 "inform7/Chapter 23/Responses.w"
#line 38 "inform7/Chapter 24/List Constants.w"
#line 47 "inform7/Chapter 24/List Constants.w"
#line 35 "inform7/Chapter 25/Table Columns.w"
#line 56 "inform7/Chapter 25/Table Columns.w"
#line 49 "inform7/Chapter 25/Tables.w"
#line 57 "inform7/Chapter 25/Tables.w"
#line 61 "inform7/Chapter 25/Tables.w"
parse_node *table_cell_node = NULL;
int table_cell_row = -1;
int table_cell_col = -1;
table *table_being_examined = NULL;
#line 36 "inform7/Chapter 26/Equations.w"
#line 59 "inform7/Chapter 26/Equations.w"
#line 64 "inform7/Chapter 26/Equations.w"
equation_symbol *standard_equation_symbols = NULL;
#line 124 "inform7/Chapter 26/Equations.w"
#line 63 "inform7/Chapter 27/Rules.w"
#line 67 "inform7/Chapter 27/Rules.w"
rule *rule_being_compiled = NULL; /* rule whose phrase's definition is being compiled */
rule *adopted_rule_for_compilation = NULL; /* when a new response is being compiled */
int adopted_marker_for_compilation = -1; /* when a new response is being compiled */
#line 91 "inform7/Chapter 27/Rules.w"
#line 32 "inform7/Chapter 27/Rule Bookings.w"
#line 72 "inform7/Chapter 27/Rulebooks.w"
#line 86 "inform7/Chapter 27/Rulebooks.w"
#line 98 "inform7/Chapter 27/Rulebooks.w"
#line 106 "inform7/Chapter 27/Rulebooks.w"
rulebook *built_in_rulebooks[MAX_BUILT_IN_RULEBOOKS];
struct stacked_variable_owner_list *all_action_processing_vars = NULL;
#line 38 "inform7/Chapter 27/Focus and Outcome.w"
#line 68 "inform7/Chapter 27/Focus and Outcome.w"
#line 77 "inform7/Chapter 27/Focus and Outcome.w"
#line 84 "inform7/Chapter 27/Focus and Outcome.w"
#line 48 "inform7/Chapter 27/Stacked Variables.w"
int max_frame_size_needed = 0;
#line 70 "inform7/Chapter 28/Phrases.w"
#line 74 "inform7/Chapter 28/Phrases.w"
struct phrase *first_in_logical_order = NULL;
#line 38 "inform7/Chapter 28/Phrase Usage.w"
#line 42 "inform7/Chapter 28/Phrase Usage.w"
rulebook_match parsed_rm;
#line 39 "inform7/Chapter 28/Phrase Runtime Context Data.w"
#line 60 "inform7/Chapter 28/Phrase Type Data.w"
#line 79 "inform7/Chapter 28/Phrase Type Data.w"
#line 147 "inform7/Chapter 28/Phrase Type Data.w"
#line 184 "inform7/Chapter 28/Phrase Type Data.w"
#line 33 "inform7/Chapter 28/Phrase Options.w"
#line 40 "inform7/Chapter 28/Phrase Options.w"
#line 27 "inform7/Chapter 28/Phrases as Values.w"
#line 23 "inform7/Chapter 28/To Phrases.w"
#line 31 "inform7/Chapter 28/Timed Phrases.w"
#line 39 "inform7/Chapter 29/Adjectival Definitions.w"
#line 43 "inform7/Chapter 30/Local Variables.w"
#line 70 "inform7/Chapter 30/Local Variables.w"
#line 34 "inform7/Chapter 30/Phrase Blocks.w"
#line 42 "inform7/Chapter 30/Phrase Blocks.w"
#line 34 "inform7/Chapter 30/Stack Frames.w"
#line 45 "inform7/Chapter 30/Stack Frames.w"
#line 60 "inform7/Chapter 30/Stack Frames.w"
#line 28 "inform7/Chapter 30/Chronology.w"
#line 34 "inform7/Chapter 30/Chronology.w"
#line 70 "inform7/Chapter 31/Invocations.w"
#line 138 "inform7/Chapter 31/Invocations.w"
#line 21 "inform7/Chapter 31/Compile Invocations.w"
#line 15 "inform7/Chapter 31/Compile Phrases.w"
phrase *phrase_being_compiled = NULL; /* phrase whose definition is being compiled */
#line 51 "inform7/Chapter 32/Virtual Machines.w"
#line 67 "inform7/Chapter 32/Virtual Machines.w"
#line 26 "inform7/Chapter 32/Inform 6 Inclusions.w"
#line 44 "inform7/Chapter 32/Use Options.w"
#line 48 "inform7/Chapter 32/Use Options.w"
int memory_economy_in_force = FALSE;
int dynamic_memory_allocation = 0;
int allow_engineering_notation = FALSE;
int use_exact_parsing_option = FALSE;
int index_figure_thumbnails = 50;
#line 66 "inform7/Chapter 32/Use Options.w"
#line 27 "inform7/Chapter 32/List Together.w"
#line 35 "inform7/Chapter 32/Jump Labels.w"
#line 24 "inform7/Chapter 33/Bibliographic Data.w"
nonlocal_variable *story_title_VAR = NULL;
nonlocal_variable *story_author_VAR = NULL;
nonlocal_variable *story_headline_VAR = NULL;
nonlocal_variable *story_genre_VAR = NULL;
nonlocal_variable *story_description_VAR = NULL;
nonlocal_variable *story_release_number_VAR = NULL;
nonlocal_variable *story_creation_year_VAR = NULL;
int episode_number = -1; /* for a work which is part of a numbered series */
char *series_name = NULL;
#line 23 "inform7/Chapter 33/Release Instructions.w"
int release_website = FALSE; /* Release along with a website? */
char *website_template_leafname = "Standard"; /* If so, the template name for it */
int release_interpreter = FALSE; /* Release along with an interpreter? */
char *interpreter_template_leafname = NULL; /* If so, the template name for it */
int release_booklet = FALSE; /* Release along with introductory booklet? */
int release_postcard = FALSE; /* Release along with Zarf's IF card? */
int release_cover = FALSE; /* Release along with cover art? */
parse_node *cover_filename_sentence = NULL; /* Where this was requested */
int cover_alt_text = -1; /* ALT text in case cover is displayed in HTML */
int release_solution = FALSE; /* Release along with a solution? */
int release_source = FALSE; /* Release along with the source text? */
int release_card = FALSE; /* Release along with the iFiction card? */
int solution_public = FALSE; /* If released, will this be linked on a website? */
int source_public = TRUE; /* If released, will this be linked on a website? */
int card_public = FALSE; /* If released, will this be linked on a website? */
int create_Materials = FALSE; /* Create a Materials folder if one doesn't exist already */
#line 55 "inform7/Chapter 33/Release Instructions.w"
#line 14 "inform7/Chapter 34/The Naming Thicket.w"
property *P_proper_named = NULL; /* an either/or property for names */
property *P_plural_named = NULL; /* an either/or property for names */
property *P_neuter = NULL; /* an either/or property for names */
property *P_female = NULL; /* an either/or property for names */
property *P_article = NULL; /* a value property for names */
property *P_privately_named = NULL;
property *P_printed_name = NULL;
property *P_printed_plural_name = NULL;
property *P_cap_short_name = NULL;
property *P_adaptive_text_viewpoint = NULL;
#line 29 "inform7/Chapter 34/The Naming Thicket.w"
text_stream SNAMES_struct;
text_stream *SNAMES = NULL;
int sn_r_counter = 0;
#line 24 "inform7/Chapter 34/Instance Counting.w"
#line 30 "inform7/Chapter 34/Instance Counting.w"
property *P_vector = NULL;
property *P_KD_Count = NULL; /* see below */
#line 52 "inform7/Chapter 34/Spatial Model.w"
#line 67 "inform7/Chapter 34/Spatial Model.w"
kind *K_room = NULL;
kind *K_thing = NULL;
kind *K_container = NULL;
kind *K_supporter = NULL;
kind *K_person = NULL;
property *P_initial_appearance = NULL;
property *P_wearable = NULL;
property *P_fixed_in_place = NULL;
property *P_component_parent = NULL;
property *P_component_child = NULL;
property *P_component_sibling = NULL;
property *P_worn = NULL;
property *P_mark_as_room = NULL;
property *P_mark_as_thing = NULL;
property *P_matching_key = NULL;
#line 90 "inform7/Chapter 34/Spatial Model.w"
inference_subject *infs_room = NULL;
inference_subject *infs_thing = NULL;
inference_subject *infs_supporter = NULL;
inference_subject *infs_person = NULL;
#line 11 "inform7/Chapter 34/Spatial Relations.w"
/* fundamental spatial relationships */
binary_predicate *R_containment = NULL;
binary_predicate *R_support = NULL;
binary_predicate *R_incorporation = NULL;
binary_predicate *R_carrying = NULL;
binary_predicate *R_holding = NULL;
binary_predicate *R_wearing = NULL;
binary_predicate *a_has_b_predicate = NULL;
binary_predicate *room_containment_predicate = NULL;
/* indirect spatial relationships */
binary_predicate *R_visibility = NULL;
binary_predicate *R_touchability = NULL;
binary_predicate *R_concealment = NULL;
binary_predicate *R_enclosure = NULL;
#line 16 "inform7/Chapter 34/The Player.w"
instance *start_room = NULL; /* room in which play begins: e.g., Barber's Shop */
instance *start_object = NULL; /* object in which play begins: e.g., a barber's chair */
instance *player_character_object = NULL; /* the player character object used in this run */
instance *I_yourself = NULL; /* the default player character object, |selfobj| in I6 */
#line 26 "inform7/Chapter 34/The Player.w"
nonlocal_variable *player_VAR = NULL; /* initially |player_character_object| and often always |I_yourself| */
nonlocal_variable *time_of_day_VAR = NULL;
nonlocal_variable *score_VAR = NULL;
#line 18 "inform7/Chapter 34/Backdrops.w"
kind *K_backdrop = NULL;
property *P_scenery = NULL; /* an I7 either/or property marking something as scenery */
property *P_absent = NULL; /* an I6-only property for backdrops out of play */
#line 16 "inform7/Chapter 34/Regions.w"
binary_predicate *R_regional_containment = NULL;
#line 22 "inform7/Chapter 34/Regions.w"
kind *K_region = NULL;
inference_subject *infs_region = NULL;
property *P_map_region = NULL; /* a value property giving the region of a room */
property *P_regional_found_in = NULL; /* an I6-only property used for implementation */
#line 37 "inform7/Chapter 34/Regions.w"
#line 54 "inform7/Chapter 34/The Map.w"
#line 62 "inform7/Chapter 34/The Map.w"
kind *K_direction = NULL;
kind *K_door = NULL;
instance *I_up = NULL;
instance *I_down = NULL;
#line 74 "inform7/Chapter 34/The Map.w"
property *P_door_dir = NULL; /* I6 only */
property *P_door_to = NULL; /* I6 only */
property *P_other_side = NULL; /* a value property for the other side of a door */
property *P_opposite = NULL; /* a value property for the reverse of a direction */
property *P_room_index = NULL; /* I6 only: workspace for path-finding through the map */
property *P_found_in = NULL; /* I6 only: needed for multiply-present objects */
#line 17 "inform7/Chapter 34/Map Connection Relations.w"
binary_predicate *R_adjacency = NULL;
#line 19 "inform7/Chapter 34/Spatial Geometry.w"
#line 25 "inform7/Chapter 34/Spatial Geometry.w"
vector Zero_vector = {0, 0, 0};
vector N_vector = {0, 1, 0};
vector NE_vector = {1, 1, 0};
vector NW_vector = {-1, 1, 0};
vector S_vector = {0, -1, 0};
vector SE_vector = {1, -1, 0};
vector SW_vector = {-1, -1, 0};
vector E_vector = {1, 0, 0};
vector W_vector = {-1, 0, 0};
vector U_vector = {0, 0, 1};
vector D_vector = {0, 0, -1};
#line 49 "inform7/Chapter 34/Spatial Geometry.w"
#line 83 "inform7/Chapter 34/Spatial Map.w"
#line 87 "inform7/Chapter 34/Spatial Map.w"
cuboid Universe;
#line 93 "inform7/Chapter 34/Spatial Map.w"
instance *benchmark_room = NULL;
#line 113 "inform7/Chapter 34/Spatial Map.w"
int drognas_spent = 0; /* in order to measure roughly how much work we're doing */
int cutpoint_spending = 0;
int division_spending = 0;
int slide_spending = 0;
int cooling_spending = 0;
int quenching_spending = 0;
int diffusion_spending = 0;
int radiation_spending = 0;
int explosion_spending = 0;
#line 20 "inform7/Chapter 34/EPS Map.w"
int write_EPS_format_map = FALSE;
#line 47 "inform7/Chapter 34/EPS Map.w"
#line 59 "inform7/Chapter 34/EPS Map.w"
map_parameter_scope global_map_scope = {
NULL,
{
{ TRUE, "font", FONT_MDT, "Helvetica", 0 },
{ TRUE, "minimum-map-width", INT_MDT, NULL, 72*5 },
{ TRUE, "title", TEXT_MDT, "Map", 0 },
{ TRUE, "title-size", INT_MDT, NULL, 24 },
{ TRUE, "title-font", FONT_MDT, "<font>", 0 },
{ TRUE, "title-colour", COL_MDT, "000000", 0 },
{ TRUE, "map-outline", BOOL_MDT, NULL, 1 },
{ TRUE, "border-size", INT_MDT, NULL, 12 },
{ TRUE, "vertical-spacing", INT_MDT, NULL, 6 },
{ TRUE, "monochrome", BOOL_MDT, NULL, 0 },
{ TRUE, "annotation-size", INT_MDT, NULL, 8 },
{ TRUE, "annotation-length", INT_MDT, NULL, 8 },
{ TRUE, "annotation-font", FONT_MDT, "<font>", 0 },
{ TRUE, "subtitle", TEXT_MDT, "Map", 0 },
{ TRUE, "subtitle-size", INT_MDT, NULL, 16 },
{ TRUE, "subtitle-font", FONT_MDT, "<font>", 0 },
{ TRUE, "subtitle-colour", COL_MDT, "000000", 0 },
{ TRUE, "grid-size", INT_MDT, NULL, 72 },
{ TRUE, "route-stiffness", INT_MDT, NULL, 100 },
{ TRUE, "route-thickness", INT_MDT, NULL, 1 },
{ TRUE, "route-colour", COL_MDT, "000000", 0 },
{ TRUE, "room-offset", OFF_MDT, NULL, 0 },
{ TRUE, "room-size", INT_MDT, NULL, 36 },
{ TRUE, "room-colour", COL_MDT, "DDDDDD", 0 },
{ TRUE, "room-name", TEXT_MDT, "", 0 },
{ TRUE, "room-name-size", INT_MDT, NULL, 12 },
{ TRUE, "room-name-font", FONT_MDT, "<font>", 0 },
{ TRUE, "room-name-colour", COL_MDT, "000000", 0 },
{ TRUE, "room-name-length", INT_MDT, NULL, 5 },
{ TRUE, "room-name-offset", OFF_MDT, NULL, 0 },
{ TRUE, "room-outline", BOOL_MDT, NULL, 1 },
{ TRUE, "room-outline-colour", COL_MDT, "000000", 0 },
{ TRUE, "room-outline-thickness", INT_MDT, NULL, 1 },
{ TRUE, "room-shape", TEXT_MDT, "square", 0 }
}
};
int changed_global_room_colour = FALSE;
#line 115 "inform7/Chapter 34/EPS Map.w"
#line 135 "inform7/Chapter 34/EPS Map.w"
#line 140 "inform7/Chapter 34/EPS Map.w"
vector U_vector_EPS = {2, 3, 0};
vector D_vector_EPS = {-2, -3, 0};
vector IN_vector_EPS = {3, 2, 0};
vector OUT_vector_EPS = {-3, -2, 0};
#line 148 "inform7/Chapter 34/EPS Map.w"
int index_map_with_pass = 0;
parse_node *index_map_with_p = NULL;
#line 34 "inform7/Chapter 34/Scenes.w"
#line 50 "inform7/Chapter 34/Scenes.w"
#line 54 "inform7/Chapter 34/Scenes.w"
property *P_recurring = NULL;
#line 59 "inform7/Chapter 34/Scenes.w"
scene *SC_entire_game = NULL;
#line 65 "inform7/Chapter 34/Scenes.w"
kind *K_scene = NULL;
#line 69 "inform7/Chapter 35/Actions.w"
stacked_variable_owner_list *all_nonempty_stacked_action_vars = NULL;
#line 75 "inform7/Chapter 35/Actions.w"
action_name *going_action = NULL;
#line 97 "inform7/Chapter 35/Actions.w"
kind *K_action_name = NULL;
kind *K_description_of_action = NULL;
kind *K_stored_action = NULL;
#line 66 "inform7/Chapter 35/Action Patterns.w"
#line 74 "inform7/Chapter 35/Action Patterns.w"
#line 89 "inform7/Chapter 35/Action Patterns.w"
int pap_failure_reason; /* one of the above */
int permit_trying_omission = FALSE; /* allow the keyword 'trying' to be omitted */
int permit_nonconstant_action_parameters = TRUE;
#line 31 "inform7/Chapter 35/Actions Index.w"
command_index_entry *sorted_command_index = NULL; /* in alphabetical order of |text| */
#line 23 "inform7/Chapter 36/Traverse for Grammar.w"
#line 32 "inform7/Chapter 36/Traverse for Grammar.w"
#line 44 "inform7/Chapter 36/Traverse for Grammar.w"
#line 15 "inform7/Chapter 36/Grammar Properties.w"
property *P_name = NULL;
property *P_parse_name = NULL;
property *P_action_bitmap = NULL;
nonlocal_variable *max_score_VAR = NULL;
nonlocal_variable *real_location_VAR = NULL;
nonlocal_variable *actor_location_VAR = NULL;
nonlocal_variable *parameter_object_VAR = NULL;
nonlocal_variable *I6_noun_VAR = NULL;
nonlocal_variable *I6_second_VAR = NULL;
nonlocal_variable *I6_actor_VAR = NULL;
#line 36 "inform7/Chapter 36/Grammar Properties.w"
#line 46 "inform7/Chapter 36/Grammar Properties.w"
#line 72 "inform7/Chapter 36/Grammar Verbs.w"
int no_verb_verb_defined = FALSE;
#line 83 "inform7/Chapter 36/Grammar Verbs.w"
#line 65 "inform7/Chapter 36/Grammar Lines.w"
#line 75 "inform7/Chapter 36/Grammar Lines.w"
#line 37 "inform7/Chapter 36/Test Scripts.w"
#line 47 "inform7/Chapter 36/Test Scripts.w"
#line 26 "inform7/Chapter 37/Figures.w"
#line 30 "inform7/Chapter 37/Figures.w"
blorb_figure *F_cover_art = NULL;
#line 38 "inform7/Chapter 37/Figures.w"
kind *K_figure_name = NULL;
#line 27 "inform7/Chapter 37/Sound Effects.w"
#line 34 "inform7/Chapter 37/Sound Effects.w"
kind *K_sound_name = NULL;
#line 31 "inform7/Chapter 37/External Files.w"
#line 36 "inform7/Chapter 37/External Files.w"
kind *K_external_file = NULL;
#line 35 "inform7/Chapter 38/I6 Template Interpreter.w"
#line 39 "inform7/Chapter 38/I6 Template Interpreter.w"
int do_not_generate_index = FALSE;
#line 32 "inform7/Chapter 38/Plugins.w"
plugin *core_plugin, *counting_plugin,
*naming_plugin, *parsing_plugin, *actions_plugin,
*spatial_plugin, *map_plugin, *player_plugin, *regions_plugin, *backdrops_plugin,
*showme_plugin,
*times_plugin, *scenes_plugin,
*figures_plugin, *sounds_plugin, *files_plugin,
*bibliographic_plugin;
plugin *registered_plugins[MAX_PLUGINS];
#line 57 "inform7/Chapter 38/Plugin Calls.w"
plugin_call *plugins_stack[MAX_PLUGS];
#line 68 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef PLATFORM_MACOSX
#define FOLDER_SEPARATOR '/'
#define INFORM_FOLDER_RELATIVE_TO_HOME "Library"
#define ICON_EXT "tif"
#define DEFAULT_HTML_FONT \
"face=\"lucida grande,geneva,arial,tahoma,verdana,helvetica,helv\" size=2"
#define POSIX_DIRECTORY_HANDLING
#define EXTENSIONS_MODEL_HTML "ExtensionsModel.html"
#define EXTENSION_FILE_MODEL_HTML "ExtensionFileModel.html"
#define JAVASCRIPT_MODEL_1
typedef long int pointer_sized_int;
#endif
#line 90 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef PLATFORM_WINDOWS
#define LOCALE_IS_ISO
#define FOLDER_SEPARATOR '\\'
#define INFORM_FOLDER_RELATIVE_TO_HOME ""
#define DEFAULT_HTML_FONT "size=2"
#define HTML_MAP_FONT_SIZE 11
#define WINDOWS_DIRECTORY_HANDLING
#define EXTENSIONS_MODEL_HTML "WinExtensionsModel.html"
#define EXTENSION_FILE_MODEL_HTML "WinExtensionFileModel.html"
#define JAVASCRIPT_MODEL_2
typedef long int pointer_sized_int;
#endif
#line 118 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef PLATFORM_WINDOWS
#define isdigit(x) Platform__Windows_isdigit(x)
int Platform__Windows_isdigit(int c) {
return ((c >= '0') && (c <= '9')) ? 1 : 0;
}
#endif
#line 131 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef PLATFORM_UNIX
#include <strings.h>
#line 134 "inform7/Chapter 1/Platform-Specific Definitions.w"
#define FOLDER_SEPARATOR '/'
#define INFORM_FOLDER_RELATIVE_TO_HOME ""
#define DEFAULT_HTML_FONT "size=2"
#define POSIX_DIRECTORY_HANDLING
#define EXTENSIONS_MODEL_HTML "ExtensionsModel.html"
#define EXTENSION_FILE_MODEL_HTML "ExtensionFileModel.html"
#define JAVASCRIPT_MODEL_1
typedef long int pointer_sized_int;
#endif
#line 147 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef PLATFORM_ANDROID
#include <strings.h>
#line 150 "inform7/Chapter 1/Platform-Specific Definitions.w"
#define SUPPRESS_MAIN
#define FOLDER_SEPARATOR '/'
#define INFORM_FOLDER_RELATIVE_TO_HOME ""
#define DEFAULT_HTML_FONT "size=2"
#define POSIX_DIRECTORY_HANDLING
#define EXTENSIONS_MODEL_HTML "ExtensionsModel.html"
#define EXTENSION_FILE_MODEL_HTML "ExtensionFileModel.html"
#define JAVASCRIPT_MODEL_1
typedef long int pointer_sized_int;
#endif
#line 168 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifndef ICON_EXT
#define ICON_EXT "png" /* File extension of the icons in the HTML index */
#endif
#line 183 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef POSIX_DIRECTORY_HANDLING
#include <sys/stat.h>
#include <sys/types.h>
#line 187 "inform7/Chapter 1/Platform-Specific Definitions.w"
#include <dirent.h>
int Platform__mkdir(char *path_to_folder) {
char transcoded_pathname[2*MAX_FILENAME_LENGTH];
Platform__transcode_ISO_string_to_locale(path_to_folder, transcoded_pathname);
int rv;
errno = 0;
rv = mkdir(transcoded_pathname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (rv == 0) return TRUE;
if (errno == EEXIST) return TRUE;
WRITE_TO(STDERR, "Failed to create folder <%s>\n", transcoded_pathname);
return FALSE;
}
void *Platform__opendir(char *path_to_folder) {
DIR *dirp = opendir(path_to_folder);
return (void *) dirp;
}
int Platform__readdir(void *folder, char *path_to_folder,
char *leafname) {
char path_to[2*MAX_FILENAME_LENGTH+2];
struct stat file_status;
int rv;
DIR *dirp = (DIR *) folder;
struct dirent *dp;
if ((dp = readdir(dirp)) == NULL) return FALSE;
sprintf(path_to, "%s%c%s", path_to_folder, FOLDER_SEPARATOR, dp->d_name);
rv = stat(path_to, &file_status);
if (rv != 0) {
WRITE_TO(STDERR, "Stat failed on %s\n", path_to);
return FALSE;
}
if (S_ISDIR(file_status.st_mode)) sprintf(leafname, "%s/", dp->d_name);
else strcpy(leafname, dp->d_name);
return TRUE;
}
void Platform__closedir(void *folder) {
DIR *dirp = (DIR *) folder;
closedir(dirp);
}
#endif
#line 236 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef WINDOWS_DIRECTORY_HANDLING
#include <sys/stat.h>
#include <direct.h>
#include <dirent.h>
#line 241 "inform7/Chapter 1/Platform-Specific Definitions.w"
#include <io.h>
int Platform__mkdir(char *path_to_folder) {
char transcoded_pathname[2*MAX_FILENAME_LENGTH];
Platform__transcode_ISO_string_to_locale(path_to_folder, transcoded_pathname);
int rv;
errno = 0;
rv = _mkdir(transcoded_pathname);
if (rv == 0) return TRUE;
if (errno == EEXIST) return TRUE;
WRITE_TO(STDERR, "Failed to create folder <%s>\n", transcoded_pathname);
return FALSE;
}
void *Platform__opendir(char *path_to_folder) {
DIR *dirp = opendir(path_to_folder);
return (void *) dirp;
}
int Platform__readdir(void *folder, char *path_to_folder,
char *leafname) {
char path_to[2*MAX_FILENAME_LENGTH+2];
struct _stat file_status;
int rv;
DIR *dirp = (DIR *) folder;
struct dirent *dp;
if ((dp = readdir(dirp)) == NULL) return FALSE;
sprintf(path_to, "%s%c%s", path_to_folder, FOLDER_SEPARATOR, dp->d_name);
rv = _stat(path_to, &file_status);
if (rv != 0) {
WRITE_TO(STDERR, "Stat failed on %s\n", path_to);
return FALSE;
}
if (S_ISDIR(file_status.st_mode))
sprintf(leafname, "%s%c", dp->d_name, FOLDER_SEPARATOR);
else strcpy(leafname, dp->d_name);
return TRUE;
}
void Platform__closedir(void *folder) {
DIR *dirp = (DIR *) folder;
closedir(dirp);
}
#endif
#line 294 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifndef LOCALE_IS_ISO
#ifndef LOCALE_IS_UTF8
#define LOCALE_IS_UTF8 1
#endif
#endif
#line 312 "inform7/Chapter 1/Platform-Specific Definitions.w"
FILE *Platform__iso_fopen(filename *F, char *usage) {
char pathname[MAX_FILENAME_LENGTH];
Filenames__to_string(pathname, F);
char transcoded_pathname[2*MAX_FILENAME_LENGTH];
Platform__transcode_ISO_string_to_locale(pathname, transcoded_pathname);
return fopen(transcoded_pathname, usage);
}
FILE *Platform__iso_fopen_caseless(filename *F, char *usage) {
char pathname[MAX_FILENAME_LENGTH];
Filenames__to_string(pathname, F);
char transcoded_pathname[2*MAX_FILENAME_LENGTH];
Platform__transcode_ISO_string_to_locale(pathname, transcoded_pathname);
return CIFilingSystem__fopen(transcoded_pathname, usage);
}
#line 331 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef LOCALE_IS_ISO
void Platform__transcode_ISO_string_to_locale(char *from, char *to) {
strcpy(to, from);
}
#endif
#ifdef LOCALE_IS_UTF8
void Platform__transcode_ISO_string_to_locale(char *from, char *to) {
Text__transcode_ISO_string_to_UTF8(from, to);
}
#endif
#line 358 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef LOCALE_IS_ISO
int Platform__truncated_locale_fgets(FILE *F, char *buffer, int limit) {
return Platform__truncated_iso_fgets(F, buffer, limit);
}
#endif
#ifdef LOCALE_IS_UTF8
int Platform__truncated_locale_fgets(FILE *F, char *buffer, int limit) {
int len=0, c;
if (buffer == NULL) return -1;
if (feof(F)) return -1;
while ((c = SourceFiles__utf8_fgetc(F, NULL, FALSE)) != EOF) {
if (len >= limit) break;
if ((c == '\x0a') || (c == '\x0d')) break;
if ((c >= 0x0300) && (c <= 0x036F) && (len > 0))
c = HTML__combining_accent(c, buffer[--len]);
buffer[len++] = (char) c;
}
buffer[len++] = 0;
return len;
}
#endif
#line 385 "inform7/Chapter 1/Platform-Specific Definitions.w"
#ifdef LOCALE_IS_ISO
void Platform__truncated_locale_arg(char *arg, char *buffer, int limit) {
Extensions__IDs__truncated_strcpy(buffer, arg, limit);
}
#endif
#ifdef LOCALE_IS_UTF8
void Platform__truncated_locale_arg(char *arg, char *buffer, int limit) {
int len=0, c;
while ((c = SourceFiles__utf8_fgetc(NULL, &arg, FALSE)) != 0) {
if (len >= limit) break;
if ((c == '\x0a') || (c == '\x0d')) break;
if ((c >= 0x0300) && (c <= 0x036F) && (len > 0))
c = HTML__combining_accent(c, buffer[--len]);
buffer[len++] = (char) c;
}
buffer[len++] = 0;
}
#endif
#line 409 "inform7/Chapter 1/Platform-Specific Definitions.w"
char Platform__tolower(char c) {
return (char) tolower((int) c);
}
char Platform__toupper(char c) {
return (char) toupper((int) c);
}
int Platform__isalpha(char c) {
return isalpha((int) c);
}
int Platform__isdigit(char c) {
return isdigit((int) c);
}
int Platform__strlen(const char *p) {
return (int) strlen(p);
}
#line 432 "inform7/Chapter 1/Platform-Specific Definitions.w"
int Platform__truncated_iso_fgets(FILE *F, char *buffer, int limit) {
int len=0, c;
if (buffer == NULL) return -1;
if (feof(F)) return -1;
while ((c = fgetc(F)) != EOF) {
if (len >= limit) break;
if (c == '\x0a') break;
if (c == '\x0d') break;
buffer[len++] = (char) c;
}
buffer[len++] = 0;
return len;
}
#line 271 "inform7/Chapter 2/Memory.w"
#line 277 "inform7/Chapter 2/Memory.w"
allocation_status_structure alloc_status[NO_MEMORY_TYPES];
void Memory__start(void) {
int i;
for (i=0; i<NO_MEMORY_TYPES; i++) {
alloc_status[i].first_in_memory = NULL;
alloc_status[i].last_in_memory = NULL;
alloc_status[i].objects_allocated = 0;
alloc_status[i].objects_count = 0;
alloc_status[i].bytes_allocated = 0;
alloc_status[i].no_allocated_together = 1;
alloc_status[i].name_of_type = "unused";
}
}
#line 340 "inform7/Chapter 2/Memory.w"
int no_blocks_allocated = 0;
int no_frames_allocated = 0; /* a much larger number, used only for the debugging log */
#line 354 "inform7/Chapter 2/Memory.w"
memblock_header *first_memblock_header = NULL; /* head of list of memory blocks */
memblock_header *current_memblock_header = NULL; /* tail of list of memory blocks */
int used_in_current_memblock = 0; /* number of bytes so far used in the tail memory block */
#line 364 "inform7/Chapter 2/Memory.w"
void Memory__allocate_another_block(void) {
unsigned char *cp;
memblock_header *mh;
{
#line 383 "inform7/Chapter 2/Memory.w"
int i;
if (no_blocks_allocated++ >= MAX_BLOCKS_ALLOWED)
internal_error(
"the memory manager has halted Inform, which seems to be generating "
"endless structures. Presumably it is trapped in a loop");
Memory__check_integrity();
LOGIF(MEMORY_ALLOCATION, "Allocating memory block %d (total objects now %d)\n",
no_blocks_allocated, no_frames_allocated);
cp = (unsigned char *) (malloc(MEMORY_GRANULARITY));
if (cp == NULL) Problems__Fatal__issue("Run out of memory: malloc failed");
LOGIF(MEMORY_ALLOCATION, "AOB: %08x to %08x\n",
(pointer_sized_int) cp, (pointer_sized_int) cp+MEMORY_GRANULARITY);
for (i=0; i<MEMORY_GRANULARITY; i++) cp[i] = 0;
}
#line 368 "inform7/Chapter 2/Memory.w"
;
mh = (memblock_header *) cp;
used_in_current_memblock = sizeof(memblock_header) + SAFETY_MARGIN;
mh->the_memory = (void *) (cp + used_in_current_memblock);
{
#line 401 "inform7/Chapter 2/Memory.w"
if (current_memblock_header == NULL) {
mh->block_number = 0;
first_memblock_header = mh;
} else {
mh->block_number = current_memblock_header->block_number + 1;
current_memblock_header->next = mh;
}
current_memblock_header = mh;
}
#line 374 "inform7/Chapter 2/Memory.w"
;
LOGIF(MEMORY_ALLOCATION, "AOB->the_memory: %08x\n", (pointer_sized_int) mh->the_memory);
}
#line 415 "inform7/Chapter 2/Memory.w"
void Memory__free_memory(void) {
Memory__I7_free_remaining();
memblock_header *mh = first_memblock_header;
while (mh != NULL) {
memblock_header *next_mh = mh->next;
void *p = (void *) mh;
free(p);
mh = next_mh;
}
}
#line 444 "inform7/Chapter 2/Memory.w"
#line 450 "inform7/Chapter 2/Memory.w"
memory_frame *first_memory_frame = NULL; /* earliest memory frame ever allocated */
memory_frame *last_memory_frame = NULL; /* most recent memory frame allocated */
#line 461 "inform7/Chapter 2/Memory.w"
int calls_to_cmi = 0;
void Memory__check_integrity(void) {
int c = calls_to_cmi++;
if (!((c<10) || (c == 100) || (c == 1000) || (c == 10000))) return;
LOGIF(MEMORY_ALLOCATION, "Beginning memory integrity check: ");
memory_frame *mf;
for (c = 0, mf = first_memory_frame; mf; c++, mf = mf->next_frame)
if (mf->integrity_check != INTEGRITY_NUMBER) {
LOG("*** Memory integrity check failed. Recent frames: ***\n");
Memory__debug_frames(c-20, c-1);
internal_error("Memory manager failed integrity check");
}
LOGIF(MEMORY_ALLOCATION, "*** Succeeded ***\n");
}
void Memory__debug_frames(int from, int to) {
int c;
memory_frame *mf;
for (c = 0, mf = first_memory_frame; (mf) && (c <= to); c++, mf = mf->next_frame)
if (c >= from) {
char *desc = "corrupt";
if (mf->integrity_check == INTEGRITY_NUMBER)
desc = alloc_status[mf->mem_type].name_of_type;
LOG("Frame at %08x: '%s'/%d\n",
(pointer_sized_int) mf, desc, mf->allocation_id);
}
}
#line 498 "inform7/Chapter 2/Memory.w"
void *Memory__allocate(int mem_type, int extent) {
unsigned char *cp;
memory_frame *mf;
int bytes_free_in_current_memblock, extent_without_overheads = extent;
extent += sizeof(memory_frame); /* each allocation is preceded by a memory frame */
extent += SAFETY_MARGIN; /* each allocation is followed by |SAFETY_MARGIN| null bytes */
{
#line 536 "inform7/Chapter 2/Memory.w"
if (current_memblock_header == NULL) Memory__allocate_another_block();
bytes_free_in_current_memblock = MEMORY_GRANULARITY - (used_in_current_memblock + extent);
if (bytes_free_in_current_memblock < BLANK_END_SIZE) {
Memory__allocate_another_block();
if (extent+BLANK_END_SIZE >= MEMORY_GRANULARITY)
Problems__Fatal__issue("Memory manager failed because granularity too low");
}
}
#line 506 "inform7/Chapter 2/Memory.w"
;
cp = ((unsigned char *) (current_memblock_header->the_memory)) + used_in_current_memblock;
used_in_current_memblock += extent;
mf = (memory_frame *) cp; /* the new memory frame, */
cp = cp + sizeof(memory_frame); /* following which is the actual allocated data */
mf->integrity_check = INTEGRITY_NUMBER;
mf->allocation_id = alloc_status[mem_type].objects_allocated;
mf->mem_type = mem_type;
{
#line 547 "inform7/Chapter 2/Memory.w"
mf->next_frame = NULL;
if (first_memory_frame == NULL) first_memory_frame = mf;
else last_memory_frame->next_frame = mf;
last_memory_frame = mf;
}
#line 518 "inform7/Chapter 2/Memory.w"
;
{
#line 555 "inform7/Chapter 2/Memory.w"
if (alloc_status[mem_type].first_in_memory == NULL)
alloc_status[mem_type].first_in_memory = (void *) cp;
alloc_status[mem_type].last_in_memory = (void *) cp;
alloc_status[mem_type].objects_allocated++;
alloc_status[mem_type].bytes_allocated += extent_without_overheads;
}
#line 519 "inform7/Chapter 2/Memory.w"
;
no_frames_allocated++;
return (void *) cp;
}
#line 697 "inform7/Chapter 2/Memory.w"
ALLOCATE_INDIVIDUALLY(action_name)
ALLOCATE_INDIVIDUALLY(activity)
ALLOCATE_INDIVIDUALLY(adjectival_phrase)
ALLOCATE_INDIVIDUALLY(adjective_meaning)
ALLOCATE_INDIVIDUALLY(applicability_condition)
ALLOCATE_INDIVIDUALLY(auxiliary_file)
ALLOCATE_INDIVIDUALLY(binary_predicate)
ALLOCATE_INDIVIDUALLY(blorb_figure)
ALLOCATE_INDIVIDUALLY(blorb_sound)
ALLOCATE_INDIVIDUALLY(booking)
ALLOCATE_INDIVIDUALLY(cached_understanding)
ALLOCATE_INDIVIDUALLY(cluster)
ALLOCATE_INDIVIDUALLY(command_index_entry)
ALLOCATE_INDIVIDUALLY(connected_submap)
ALLOCATE_INDIVIDUALLY(constant_phrase)
ALLOCATE_INDIVIDUALLY(contents_entry)
ALLOCATE_INDIVIDUALLY(control_structure_phrase)
ALLOCATE_INDIVIDUALLY(counting_data)
ALLOCATE_INDIVIDUALLY(definition)
ALLOCATE_INDIVIDUALLY(determiner)
ALLOCATE_INDIVIDUALLY(documentation_ref)
ALLOCATE_INDIVIDUALLY(EPS_map_level)
ALLOCATE_INDIVIDUALLY(equation_node)
ALLOCATE_INDIVIDUALLY(equation_symbol)
ALLOCATE_INDIVIDUALLY(equation)
ALLOCATE_INDIVIDUALLY(excerpt_meaning)
ALLOCATE_INDIVIDUALLY(extension_census_datum)
ALLOCATE_INDIVIDUALLY(extension_dictionary_entry)
ALLOCATE_INDIVIDUALLY(extension_file)
ALLOCATE_INDIVIDUALLY(external_file)
ALLOCATE_INDIVIDUALLY(filename)
ALLOCATE_INDIVIDUALLY(generalisation)
ALLOCATE_INDIVIDUALLY(grammar_line)
ALLOCATE_INDIVIDUALLY(grammar_verb)
ALLOCATE_INDIVIDUALLY(heading)
ALLOCATE_INDIVIDUALLY(i6_inclusion_matter)
ALLOCATE_INDIVIDUALLY(i6_memory_setting)
ALLOCATE_INDIVIDUALLY(I6T_intervention)
ALLOCATE_INDIVIDUALLY(implication)
ALLOCATE_INDIVIDUALLY(index_element)
ALLOCATE_INDIVIDUALLY(index_page)
ALLOCATE_INDIVIDUALLY(individual_name)
ALLOCATE_INDIVIDUALLY(inference_subject)
ALLOCATE_INDIVIDUALLY(instance)
ALLOCATE_INDIVIDUALLY(internal_test_case)
ALLOCATE_INDIVIDUALLY(inv_token_problem_token)
ALLOCATE_INDIVIDUALLY(kind_constructor)
ALLOCATE_INDIVIDUALLY(kind_macro_definition)
ALLOCATE_INDIVIDUALLY(kind_template_definition)
ALLOCATE_INDIVIDUALLY(kind_template_obligation)
ALLOCATE_INDIVIDUALLY(kind_variable_declaration)
ALLOCATE_INDIVIDUALLY(known_extension_clash)
ALLOCATE_INDIVIDUALLY(label_namespace)
ALLOCATE_INDIVIDUALLY(lexicon_entry)
ALLOCATE_INDIVIDUALLY(list_together_routine)
ALLOCATE_INDIVIDUALLY(literal_list)
ALLOCATE_INDIVIDUALLY(literal_pattern_name)
ALLOCATE_INDIVIDUALLY(literal_pattern)
ALLOCATE_INDIVIDUALLY(literal_text)
ALLOCATE_INDIVIDUALLY(llist_entry)
ALLOCATE_INDIVIDUALLY(loop_over_scope)
ALLOCATE_INDIVIDUALLY(map_data)
ALLOCATE_INDIVIDUALLY(measurement_definition)
ALLOCATE_INDIVIDUALLY(named_action_pattern)
ALLOCATE_INDIVIDUALLY(named_rulebook_outcome)
ALLOCATE_INDIVIDUALLY(nametag)
ALLOCATE_INDIVIDUALLY(natural_language)
ALLOCATE_INDIVIDUALLY(nonlocal_variable)
ALLOCATE_INDIVIDUALLY(nonterminal)
ALLOCATE_INDIVIDUALLY(noun_filter_token)
ALLOCATE_INDIVIDUALLY(parse_node)
ALLOCATE_INDIVIDUALLY(parsing_data)
ALLOCATE_INDIVIDUALLY(parsing_pp_data)
ALLOCATE_INDIVIDUALLY(past_tense_action_record)
ALLOCATE_INDIVIDUALLY(past_tense_condition_record)
ALLOCATE_INDIVIDUALLY(pathname)
ALLOCATE_INDIVIDUALLY(pcalc_prop_deferral)
ALLOCATE_INDIVIDUALLY(ph_stack_frame_box)
ALLOCATE_INDIVIDUALLY(phrase)
ALLOCATE_INDIVIDUALLY(plugin)
ALLOCATE_INDIVIDUALLY(plural_dictionary_entry)
ALLOCATE_INDIVIDUALLY(pointer_allocation)
ALLOCATE_INDIVIDUALLY(preposition_usage)
ALLOCATE_INDIVIDUALLY(production_list)
ALLOCATE_INDIVIDUALLY(production)
ALLOCATE_INDIVIDUALLY(property_of_value_storage)
ALLOCATE_INDIVIDUALLY(property_permission)
ALLOCATE_INDIVIDUALLY(property)
ALLOCATE_INDIVIDUALLY(ptoken)
ALLOCATE_INDIVIDUALLY(quantifier)
ALLOCATE_INDIVIDUALLY(regions_data)
ALLOCATE_INDIVIDUALLY(relation_guard)
ALLOCATE_INDIVIDUALLY(reserved_command_verb)
ALLOCATE_INDIVIDUALLY(response_message)
ALLOCATE_INDIVIDUALLY(rubric_holder)
ALLOCATE_INDIVIDUALLY(rule)
ALLOCATE_INDIVIDUALLY(rulebook_outcome)
ALLOCATE_INDIVIDUALLY(rulebook)
ALLOCATE_INDIVIDUALLY(runtime_kind_structure)
ALLOCATE_INDIVIDUALLY(scene)
ALLOCATE_INDIVIDUALLY(simple_memory_claim)
ALLOCATE_INDIVIDUALLY(slash_gpr)
ALLOCATE_INDIVIDUALLY(source_file)
ALLOCATE_INDIVIDUALLY(spatial_data)
ALLOCATE_INDIVIDUALLY(table_column)
ALLOCATE_INDIVIDUALLY(table)
ALLOCATE_INDIVIDUALLY(test_scenario)
ALLOCATE_INDIVIDUALLY(text_substitution)
ALLOCATE_INDIVIDUALLY(to_phrase_request)
ALLOCATE_INDIVIDUALLY(use_as_event)
ALLOCATE_INDIVIDUALLY(use_option)
ALLOCATE_INDIVIDUALLY(verb_conjugation)
ALLOCATE_INDIVIDUALLY(verb_usage)
ALLOCATE_INDIVIDUALLY(VM_usage_note)
ALLOCATE_INDIVIDUALLY(inference)
#line 815 "inform7/Chapter 2/Memory.w"
ALLOCATE_IN_ARRAYS(action_name_list, 1000)
ALLOCATE_IN_ARRAYS(action_pattern, 100)
ALLOCATE_IN_ARRAYS(activity_crossref, 100)
ALLOCATE_IN_ARRAYS(activity_list, 1000)
ALLOCATE_IN_ARRAYS(adjective_usage, 1000)
ALLOCATE_IN_ARRAYS(ap_optional_clause, 400)
ALLOCATE_IN_ARRAYS(application, 100)
ALLOCATE_IN_ARRAYS(dimensional_rule, 100)
ALLOCATE_IN_ARRAYS(extension_identifier_database_entry, 100)
ALLOCATE_IN_ARRAYS(i6_schema, 100)
ALLOCATE_IN_ARRAYS(instance_usage, 200)
ALLOCATE_IN_ARRAYS(invocation_options, 100)
ALLOCATE_IN_ARRAYS(kind_constructor_casting_rule, 100)
ALLOCATE_IN_ARRAYS(kind_constructor_comparison_schema, 100)
ALLOCATE_IN_ARRAYS(kind_constructor_instance, 100)
ALLOCATE_IN_ARRAYS(kind, 1000)
ALLOCATE_IN_ARRAYS(local_variable, 100)
ALLOCATE_IN_ARRAYS(match_avinue, 1000)
ALLOCATE_IN_ARRAYS(match_trie, 1000)
ALLOCATE_IN_ARRAYS(parse_node_annotation, 500)
ALLOCATE_IN_ARRAYS(pcalc_func, 1000)
ALLOCATE_IN_ARRAYS(pcalc_prop, 1000)
ALLOCATE_IN_ARRAYS(pcalc_term, 1000)
ALLOCATE_IN_ARRAYS(phrase_option, 100)
ALLOCATE_IN_ARRAYS(placement_affecting, 100)
ALLOCATE_IN_ARRAYS(plugin_call, 100)
ALLOCATE_IN_ARRAYS(scene_connector, 1000)
ALLOCATE_IN_ARRAYS(stacked_variable_list, 100)
ALLOCATE_IN_ARRAYS(stacked_variable_owner_list, 100)
ALLOCATE_IN_ARRAYS(stacked_variable_owner, 100)
ALLOCATE_IN_ARRAYS(stacked_variable, 100)
ALLOCATE_IN_ARRAYS(table_contribution, 100)
ALLOCATE_IN_ARRAYS(text_stream, 50)
ALLOCATE_IN_ARRAYS(time_period, 100)
ALLOCATE_IN_ARRAYS(understanding_item, 100)
ALLOCATE_IN_ARRAYS(understanding_reference, 100)
ALLOCATE_IN_ARRAYS(unit_sequence, 50)
ALLOCATE_IN_ARRAYS(vocabulary_entry, 100)
#line 878 "inform7/Chapter 2/Memory.w"
char *memory_needs[NUMBER_OF_MREASONS] = {
"extension dictionary",
"index sorting",
"instance-of-kind counting",
"source text",
"source text details",
"map in the World index",
"initial state for relations in groups",
"internal text-handling",
"tables of details of the kinds of values",
"lists for type-checking invocations",
"size estimates for compiled objects",
"compilation workspace for objects",
"documentation fragments",
"filename/pathname storage",
"relation bitmap storage"
};
#line 904 "inform7/Chapter 2/Memory.w"
int max_memory_at_once_for_each_need[NUMBER_OF_MREASONS],
memory_claimed_for_each_need[NUMBER_OF_MREASONS],
number_of_claims_for_each_need[NUMBER_OF_MREASONS];
int total_claimed_simply = 0;
#line 916 "inform7/Chapter 2/Memory.w"
void *Memory__I7_calloc(int how_many, int size_in_bytes, int reason) {
return Memory__I7_alloc(how_many, size_in_bytes, reason);
}
void *Memory__I7_malloc(int size_in_bytes, int reason) {
return Memory__I7_alloc(-1, size_in_bytes, reason);
}
#line 926 "inform7/Chapter 2/Memory.w"
void *Memory__I7_alloc(int N, int S, int R) {
void *pointer;
int bytes_needed;
if ((R < 0) || (R >= NUMBER_OF_MREASONS)) internal_error("no such memory reason");
if (total_claimed_simply == 0)
{
#line 960 "inform7/Chapter 2/Memory.w"
int i;
for (i=0; i<NUMBER_OF_MREASONS; i++) {
max_memory_at_once_for_each_need[i] = 0;
memory_claimed_for_each_need[i] = 0;
number_of_claims_for_each_need[i] = 0;
}
}
#line 930 "inform7/Chapter 2/Memory.w"
;
{
#line 944 "inform7/Chapter 2/Memory.w"
if (N > 0) {
pointer = calloc((size_t) N, (size_t) S);
bytes_needed = N*S;
} else {
pointer = malloc((size_t) S);
bytes_needed = S;
}
if (pointer == NULL)
Problems__Issue__memory_allocation_problem(_p_(BelievedImpossible), /* i.e., not reliably testable */
memory_needs[R]);
}
#line 931 "inform7/Chapter 2/Memory.w"
;
{
#line 970 "inform7/Chapter 2/Memory.w"
memory_claimed_for_each_need[R] += bytes_needed;
total_claimed_simply += bytes_needed;
number_of_claims_for_each_need[R]++;
if (memory_claimed_for_each_need[R] > max_memory_at_once_for_each_need[R])
max_memory_at_once_for_each_need[R] = memory_claimed_for_each_need[R];
}
#line 932 "inform7/Chapter 2/Memory.w"
;
simple_memory_claim *smc = CREATE(simple_memory_claim);
smc->memory_claimed = pointer;
smc->extent_of_claim = bytes_needed;
return pointer;
}
#line 983 "inform7/Chapter 2/Memory.w"
void Memory__I7_free(void *pointer, int R) {
if ((R < 0) || (R >= NUMBER_OF_MREASONS)) internal_error("no such memory reason");
if (pointer == NULL) internal_error("can't free NULL memory");
simple_memory_claim *smc;
LOOP_OVER(smc, simple_memory_claim)
if (smc->memory_claimed == pointer) {
free(pointer);
memory_claimed_for_each_need[R] -= smc->extent_of_claim;
total_claimed_simply -= smc->extent_of_claim;
DESTROY(smc, simple_memory_claim);
return;
}
internal_error("can't free this memory, which is not now allocated");
}
#line 1005 "inform7/Chapter 2/Memory.w"
void Memory__I7_free_remaining(void) {
simple_memory_claim *smc;
LOOP_OVER(smc, simple_memory_claim) {
free (smc->memory_claimed);
total_claimed_simply -= smc->extent_of_claim;
}
if (total_claimed_simply != 0)
internal_error("memory not freed exactly correctly");
}
#line 1019 "inform7/Chapter 2/Memory.w"
int Memory__log_usage(int total) {
if (total_claimed_simply == 0) return 0;
int i, t = 0;
for (i=0; i<NUMBER_OF_MREASONS; i++) {
t += max_memory_at_once_for_each_need[i];
if (total > 0)
LOG("0.%03d: %s - %d bytes in %d claim(s)\n",
Memory__proportion(max_memory_at_once_for_each_need[i], total),
memory_needs[i],
max_memory_at_once_for_each_need[i],
number_of_claims_for_each_need[i]);
}
return t;
}
#line 1038 "inform7/Chapter 2/Memory.w"
void Memory__log_statistics(void) {
int total_for_objects = MEMORY_GRANULARITY*no_blocks_allocated; /* usage in bytes */
int total_for_SMAs = Memory__log_usage(0); /* usage in bytes */
int sorted_usage[NO_MEMORY_TYPES]; /* memory type numbers, in usage order */
int total = (total_for_objects + total_for_SMAs)/1024; /* total memory usage in KB */
{
#line 1073 "inform7/Chapter 2/Memory.w"
int i;
for (i=0; i<NO_MEMORY_TYPES; i++) sorted_usage[i] = i;
qsort(sorted_usage, (size_t) NO_MEMORY_TYPES, sizeof(int), Memory__compare_usage);
}
#line 1044 "inform7/Chapter 2/Memory.w"
;
int total_for_objects_used = 0; /* out of the |total_for_objects|, the bytes used */
int total_objects = 0;
{
#line 1056 "inform7/Chapter 2/Memory.w"
int i, j;
for (j=0; j<NO_MEMORY_TYPES; j++) {
i = sorted_usage[j];
if (alloc_status[i].objects_allocated != 0) {
if (alloc_status[i].no_allocated_together == 1)
total_objects += alloc_status[i].objects_allocated;
else
total_objects += alloc_status[i].objects_allocated*
alloc_status[i].no_allocated_together;
total_for_objects_used += alloc_status[i].bytes_allocated;
}
}
}
#line 1048 "inform7/Chapter 2/Memory.w"
;
int overhead_for_objects = total_for_objects - total_for_objects_used; /* bytes wasted */
{
#line 1080 "inform7/Chapter 2/Memory.w"
LOG("\nReport by memory manager:\n\n");
LOG("Total consumption was %dK = %dMB, divided up in the following proportions:\n",
total, (total+512)/1024);
LOG("0.%03d: %d objects in %d frames in %d memory blocks (of %dK each):\n",
Memory__proportion(total_for_objects, total),
total_objects, no_frames_allocated, no_blocks_allocated, MEMORY_GRANULARITY/1024);
LOG(" 0.%03d: memory manager overhead - %d bytes\n",
Memory__proportion(overhead_for_objects, total), overhead_for_objects);
int i, j;
for (j=0; j<NO_MEMORY_TYPES; j++) {
i = sorted_usage[j];
if (alloc_status[i].objects_allocated != 0) {
LOG(" 0.%03d: %s - ",
Memory__proportion(alloc_status[i].bytes_allocated, total),
alloc_status[i].name_of_type);
if (alloc_status[i].no_allocated_together == 1) {
LOG("%d ", alloc_status[i].objects_count);
if (alloc_status[i].objects_count != alloc_status[i].objects_allocated)
LOG("(+%d deleted) ",
alloc_status[i].objects_allocated - alloc_status[i].objects_count);
} else LOG("%d blocks of %d = %d ",
alloc_status[i].objects_allocated, alloc_status[i].no_allocated_together,
alloc_status[i].objects_allocated*alloc_status[i].no_allocated_together);
LOG("objects, %d bytes\n", alloc_status[i].bytes_allocated);
}
}
Memory__log_usage(total);
LOG("\nCreated %d base kinds, %d intermediate kinds, %d constructed kinds\n",
no_base_kinds_created, no_intermediate_kinds_created, no_constructed_kinds_created);
}
#line 1050 "inform7/Chapter 2/Memory.w"
;
}
#line 1114 "inform7/Chapter 2/Memory.w"
int Memory__compare_usage(const void *ent1, const void *ent2) {
int ix1 = *((const int *) ent1);
int ix2 = *((const int *) ent2);
return alloc_status[ix2].bytes_allocated - alloc_status[ix1].bytes_allocated;
}
#line 1124 "inform7/Chapter 2/Memory.w"
int Memory__proportion(int bytes, int total) {
float B = (float) bytes, T = (float) total;
float P = (1000*B)/(1024*T);
return (int) P;
}
#line 1156 "inform7/Chapter 2/Memory.w"
general_pointer Memory__store_gp_null(void) {
general_pointer gp;
gp.pointer_to_data = NULL;
gp.run_time_type_code = -1; /* guaranteed to differ from all |_MT| values */
return gp;
}
int Memory__test_gp_null(general_pointer gp) {
if (gp.run_time_type_code == -1) return TRUE;
return FALSE;
}
#line 1215 "inform7/Chapter 2/Memory.w"
MAKE_REFERENCE_ROUTINES(char, 1000)
#line 268 "inform7/Chapter 2/Streams.w"
void Streams__initialise(text_stream *stream) {
if (stream == NULL) internal_error("tried to initialise NULL stream");
stream->write_to_file = NULL;
stream->write_to_memory = NULL;
stream->allocated_by_malloc = FALSE;
stream->chars_written = 0;
stream->chars_capacity = 2147483647;
stream->stream_continues = NULL;
stream->encoding_to_write_to_file = ISO_ENC;
stream->use_xml_escapes = FALSE;
stream->indentation_level = 0;
stream->indentation_pending = FALSE;
stream->unicode_buffer_pos = -1;
}
#line 288 "inform7/Chapter 2/Streams.w"
text_stream STDOUT_struct; int stdout_wrapper_initialised = FALSE;
text_stream *Streams__get_stdout(void) {
if (stdout_wrapper_initialised == FALSE) {
Streams__initialise(&STDOUT_struct); STDOUT_struct.write_to_file = stdout;
stdout_wrapper_initialised = TRUE;
}
return &STDOUT_struct;
}
#line 300 "inform7/Chapter 2/Streams.w"
text_stream STDERR_struct; int stderr_wrapper_initialised = FALSE;
text_stream *Streams__get_stderr(void) {
if (stderr_wrapper_initialised == FALSE) {
Streams__initialise(&STDERR_struct); STDERR_struct.write_to_file = stderr;
stderr_wrapper_initialised = TRUE;
}
return &STDERR_struct;
}
#line 314 "inform7/Chapter 2/Streams.w"
int Streams__open_to_file(text_stream *stream, filename *name, int encoding) {
if (stream == NULL) internal_error("tried to open NULL stream");
if (name == NULL) internal_error("stream_open_to_file on null filename");
Streams__initialise(stream);
stream->write_to_file = Platform__iso_fopen(name, "w");
if (stream->write_to_file == NULL) return FALSE;
stream->encoding_to_write_to_file = encoding;
total_file_writes++;
return TRUE;
}
#line 328 "inform7/Chapter 2/Streams.w"
int Streams__open_to_file_append(text_stream *stream, filename *name, int encoding) {
if (stream == NULL) internal_error("tried to open NULL stream");
if (name == NULL) internal_error("stream_open_to_file on null filename");
Streams__initialise(stream);
stream->write_to_file = Platform__iso_fopen(name, "a");
if (stream->write_to_file == NULL) return FALSE;
stream->encoding_to_write_to_file = encoding;
total_file_writes++;
return TRUE;
}
#line 345 "inform7/Chapter 2/Streams.w"
int Streams__open_to_memory(text_stream *stream, int capacity) {
if (stream == NULL) internal_error("tried to open NULL stream");
if (capacity < STREAM_MIN_ACCESSIBLE_LENGTH + SPACE_AT_END_OF_STREAM)
internal_error("memory stream too small");
Streams__initialise(stream);
stream->write_to_memory = Memory__I7_malloc(capacity, STREAM_MREASON);
if (stream->write_to_memory == NULL) return FALSE;
(stream->write_to_memory)[0] = 0;
stream->allocated_by_malloc = TRUE;
stream->chars_capacity = capacity;
return TRUE;
}
#line 363 "inform7/Chapter 2/Streams.w"
text_stream Streams__new_buffer(int capacity, char *at) {
if (at == NULL) internal_error("tried to make stream wrapper for NULL string");
if (capacity < STREAM_MIN_ACCESSIBLE_LENGTH + SPACE_AT_END_OF_STREAM)
internal_error("memory stream too small");
text_stream stream;
Streams__initialise(&stream);
stream.write_to_memory = at;
(stream.write_to_memory)[0] = 0;
stream.chars_capacity = capacity;
return stream;
}
#line 380 "inform7/Chapter 2/Streams.w"
void Streams__flush(text_stream *stream) {
if (stream == NULL) return;
if (stream->write_to_file) fflush(stream->write_to_file);
}
#line 388 "inform7/Chapter 2/Streams.w"
void Streams__close(text_stream *stream) {
if (stream == NULL) internal_error("tried to close NULL stream");
if (stream == &STDOUT_struct) internal_error("tried to close STDOUT stream");
if (stream == &STDERR_struct) internal_error("tried to close STDERR stream");
if (stream->chars_capacity == -1) internal_error("stream closed twice");
if (stream->stream_continues) {
Streams__close(stream->stream_continues);
stream->stream_continues = NULL;
}
stream->chars_capacity = -1; /* mark as closed */
stream->unicode_buffer_pos = -1;
if (stream->write_to_file)
{
#line 410 "inform7/Chapter 2/Streams.w"
if ((ferror(stream->write_to_file)) || (fclose(stream->write_to_file) == EOF))
Problems__Fatal__issue("The host computer reported an error trying to write a text file");
stream->write_to_file = NULL;
}
#line 399 "inform7/Chapter 2/Streams.w"
;
if (stream->write_to_memory)
{
#line 424 "inform7/Chapter 2/Streams.w"
if (stream->allocated_by_malloc) {
Memory__I7_free(stream->write_to_memory, STREAM_MREASON); stream = NULL;
}
}
#line 400 "inform7/Chapter 2/Streams.w"
;
}
#line 436 "inform7/Chapter 2/Streams.w"
void Streams__printf(text_stream *stream, char *fmt, ...) {
va_list ap; /* the variable argument list signified by the dots */
char *p;
if (stream == NULL) return;
STREAM_FLUSH(dl);
va_start(ap, fmt); /* macro to begin variable argument processing */
for (p = fmt; *p; p++) {
switch (*p) {
case '%':
{
#line 465 "inform7/Chapter 2/Streams.w"
int ival; double dval; char *sval;
char format_string[8], category = ' ';
int i = 1;
format_string[0] = '%';
p++;
while (*p) {
format_string[i++] = *p;
if ((islower(*p)) || (isupper(*p)) || (*p == '%')) category = *p;
p++;
if ((category != ' ') || (i==6)) break;
}
format_string[i] = 0; p--;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
switch (category) {
case 'c': case 'd': case 'i': case 'x': { /* |char| is promoted to |int| in variable arguments */
ival = va_arg(ap, int);
char temp[256];
if (snprintf(temp, 255, format_string, ival) >= 255) strcpy(temp, "?");
int j;
for (j = 0; temp[j]; j++) Streams__putc(temp[j], stream);
break;
}
case 'g': {
dval = va_arg(ap, double);
char temp[256];
if (snprintf(temp, 255, format_string, dval) >= 255) strcpy(temp, "?");
int j;
for (j = 0; temp[j]; j++) Streams__putc(temp[j], stream);
break;
}
case 's':
for (sval = va_arg(ap, char *); *sval; sval++) Streams__putc(*sval, stream);
break;
case 'f': {
filename *F = va_arg(ap, filename *);
char fn[MAX_FILENAME_LENGTH];
Filenames__to_string(fn, F);
int j;
for (j = 0; fn[j]; j++) Streams__putc(fn[j], stream);
break;
}
case 'p': {
pathname *P = va_arg(ap, pathname *);
char pn[MAX_FILENAME_LENGTH];
Pathnames__to_string(pn, P);
int j;
for (j = 0; pn[j]; j++) Streams__putc(pn[j], stream);
break;
}
case '%': Streams__putc('%', stream); break;
default:
fprintf(stderr, "*** Bad escape: <%s> ***\n", format_string);
internal_error("Unknown % string escape in stream_printf");
}
#pragma clang diagnostic pop
}
#line 444 "inform7/Chapter 2/Streams.w"
; break;
default: Streams__putc(*p, stream); break;
}
}
va_end(ap); /* macro to end variable argument processing */
}
#line 525 "inform7/Chapter 2/Streams.w"
void Streams__putc(int c_int, text_stream *stream) {
unsigned int c;
if (c_int >= 0) c = (unsigned int) c_int; else c = (unsigned int) (c_int + 256);
if (stream == NULL) return;
text_stream *first_stream = stream;
if (stream->write_to_file) {
switch (stream->unicode_buffer_pos) {
case -1:
if (c == UNICODE_CHAR_IN_STRING) { stream->unicode_buffer_pos = 0; return; }
break;
case 0:
stream->unicode_buffer[stream->unicode_buffer_pos++] = c; return;
case 1:
stream->unicode_buffer[stream->unicode_buffer_pos] = c;
stream->unicode_buffer_pos = -1;
c = stream->unicode_buffer[0] + 0x100*stream->unicode_buffer[1];
if ((stream->encoding_to_write_to_file == ISO_ENC) && (c >= 0x100)) c = '?';
break;
}
}
if (c != '\n')
{
#line 594 "inform7/Chapter 2/Streams.w"
if (first_stream->indentation_pending) {
first_stream->indentation_pending = FALSE;
int i;
for (i=0; i<first_stream->indentation_level; i++) {
Streams__putc(' ', first_stream); Streams__putc(' ', first_stream);
Streams__putc(' ', first_stream); Streams__putc(' ', first_stream);
}
}
}
#line 545 "inform7/Chapter 2/Streams.w"
;
if (stream->use_xml_escapes) {
switch(c) {
case NEWLINE_IN_STRING: Streams__literal(stream, "<br>"); return;
case '&': Streams__literal(stream, "&amp;"); return;
case '<': Streams__literal(stream, "&lt;"); return;
case '>': Streams__literal(stream, "&gt;"); return;
}
}
while (stream->stream_continues) stream = stream->stream_continues;
{
#line 621 "inform7/Chapter 2/Streams.w"
if (stream->chars_written + SPACE_AT_END_OF_STREAM >= stream->chars_capacity) {
if (stream->write_to_file) return; /* write nothing further */
if (stream->write_to_memory) {
int offset = 32 + 2*(stream->chars_capacity);
int needed = offset + ((int) sizeof(text_stream)) + 32;
void *further_allocation = Memory__I7_malloc(needed, STREAM_MREASON);
if (further_allocation == NULL) Problems__Fatal__issue("Out of memory");
text_stream *continuation = (text_stream *) (further_allocation + offset);
Streams__initialise(continuation);
continuation->write_to_memory = further_allocation;
continuation->chars_capacity = 2*stream->chars_capacity;
(continuation->write_to_memory)[0] = 0;
stream->stream_continues = continuation;
stream = continuation;
}
}
}
#line 555 "inform7/Chapter 2/Streams.w"
;
if (stream->write_to_file) {
switch(stream->encoding_to_write_to_file) {
case UTF8_ENC:
{
#line 582 "inform7/Chapter 2/Streams.w"
if (c >= 0x800) {
fputc(0xE0 + (c >> 12), stream->write_to_file);
fputc(0x80 + ((c >> 6) & 0x3f), stream->write_to_file);
fputc(0x80 + (c & 0x3f), stream->write_to_file);
} else if (c >= 0x80) {
fputc(0xC0 + (c >> 6), stream->write_to_file);
fputc(0x80 + (c & 0x3f), stream->write_to_file);
} else fputc((int) c, stream->write_to_file);
}
#line 558 "inform7/Chapter 2/Streams.w"
; break;
case ISO_ENC: fputc((int) c, stream->write_to_file); break;
default: internal_error("stream has unknown text encoding");
}
} else if (stream->write_to_memory) {
if (c >= 0x100) {
if (c >= 0x10000) c = '?';
(stream->write_to_memory)[stream->chars_written] = UNICODE_CHAR_IN_STRING;
(stream->write_to_memory)[stream->chars_written+1] = (char) ((c % 0x100));
(stream->write_to_memory)[stream->chars_written+2] = (char) ((c / 0x100)%0x100);
(stream->write_to_memory)[stream->chars_written+3] = 0;
stream->chars_written += 2;
} else {
(stream->write_to_memory)[stream->chars_written] = (char) c;
(stream->write_to_memory)[stream->chars_written+1] = 0;
}
}
if (c == '\n') first_stream->indentation_pending = TRUE;
stream->chars_written++;
}
#line 641 "inform7/Chapter 2/Streams.w"
void Streams__literal(text_stream *stream, char *p) {
if (stream == NULL) return;
int i, x = stream->use_xml_escapes;
stream->use_xml_escapes = FALSE;
for (i=0; p[i]; i++) Streams__putc((int) p[i], stream);
stream->use_xml_escapes = x;
}
#line 656 "inform7/Chapter 2/Streams.w"
void Streams__indent(text_stream *stream) {
if (stream == NULL) return;
stream->indentation_level++;
}
void Streams__outdent(text_stream *stream) {
if (stream == NULL) return;
stream->indentation_level--;
if ((stream->indentation_level < 0) && (problem_count == 0))
internal_error("stream indentation negative");
}
void Streams__set_indentation(text_stream *stream, int N) {
if (stream == NULL) return;
stream->indentation_level = N;
}
#line 680 "inform7/Chapter 2/Streams.w"
int Streams__get_position(text_stream *stream) {
int t = 0;
while (stream) {
t += stream->chars_written;
stream = stream->stream_continues;
}
return t;
}
#line 694 "inform7/Chapter 2/Streams.w"
int Streams__latest(text_stream *stream) {
if (stream == NULL) return 0;
if (stream->write_to_file) internal_error("stream_latest on file stream");
while ((stream->stream_continues) && (stream->stream_continues->chars_written > 0))
stream = stream->stream_continues;
if (stream->write_to_memory) {
if (stream->chars_written > 0)
return (stream->write_to_memory)[stream->chars_written - 1];
}
return 0;
}
#line 713 "inform7/Chapter 2/Streams.w"
void Streams__set_position(text_stream *stream, int position) {
if (stream == NULL) return;
if (position < 0) position = 0; /* to simplify the implementation of backspacing */
if (stream->write_to_file) internal_error("stream_set_position on file stream");
if (stream->write_to_memory) {
while (position > stream->chars_written) {
position = position - stream->chars_written;
stream = stream->stream_continues;
if (stream == NULL) internal_error("can't set position forwards");
}
stream->chars_written = position;
(stream->write_to_memory)[stream->chars_written] = 0;
if (stream->stream_continues) {
Streams__close(stream->stream_continues);
stream->stream_continues = NULL;
}
}
}
#line 740 "inform7/Chapter 2/Streams.w"
char *Streams__get_text(text_stream *stream) {
if (stream == NULL) return NULL;
if (stream->write_to_file) internal_error("stream_get_text on file stream");
return stream->write_to_memory;
}
int Streams__all_text_accessible(text_stream *stream) {
if (stream == NULL) return FALSE;
if (stream->write_to_file) return FALSE;
if (stream->stream_continues) return FALSE;
return TRUE;
}
#line 757 "inform7/Chapter 2/Streams.w"
void Streams__copy(text_stream *to, text_stream *from) {
if ((from == NULL) || (to == NULL)) return;
if (from->write_to_file) internal_error("stream_copy from file stream");
if (from->write_to_memory) {
int i;
for (i=0; i<from->chars_written; i++) {
int c = (from->write_to_memory)[i];
Streams__putc(c, to);
}
if (from->stream_continues) Streams__copy(to, from->stream_continues);
}
}
#line 268 "inform7/Chapter 2/Debugging Log.w"
void Log__open(void) {
if (STREAM_OPEN_TO_FILE(debug_log_file, filename_of_debugging_log, ISO_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open debug log", filename_of_debugging_log);
dl = debug_log_file;
LOG("Debugging log of %s\n", NI_VERSION);
Problems__Issue__start_problems_report();
}
void Log__close(void) {
Log__show_debugging_contents();
STREAM_CLOSE(debug_log_file); dl = NULL;
if (telmy) {
WRITE_TO(telmy, "End of telemetry for this run.\n");
STREAM_CLOSE(telmy); telmy = NULL;
}
HTML__html_footer(problems_file); STREAM_CLOSE(problems_file);
}
#line 294 "inform7/Chapter 2/Debugging Log.w"
int attempts_to_open_telemetry = 0;
void Log__ensure_telemetry_file(void) {
if (telmy) return;
if (attempts_to_open_telemetry++ > 0) return;
if (STREAM_OPEN_TO_FILE_APPEND(telemetry_file, filename_of_telemetry, ISO_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open telemetry file", filename_of_telemetry);
telmy = telemetry_file;
WRITE_TO(telmy, "\n-- -- -- -- -- -- -- --\n%s build %s: telemetry.\n",
NI_VERSION, NI_BUILD);
int this_month = the_present->tm_mon + 1;
int this_day = the_present->tm_mday;
int this_year = the_present->tm_year + 1900;
WRITE_TO(telmy, "Running on %4d-%02d-%02d at %02d:%02d.\n\n",
this_year, this_month, this_day, the_present->tm_hour, the_present->tm_min);
LOG("Opening telemetry file.\n");
}
void Log__write_to_telemetry_file(char *m) {
Log__ensure_telemetry_file();
WRITE_TO(telmy, "The user says:\n\n%s\n\n", m);
}
#line 320 "inform7/Chapter 2/Debugging Log.w"
wording options_file_wording = EMPTY_WORDING_INIT;
void Log__read_further_mandatory_text(void) {
FILE *FMAN = Platform__iso_fopen(filename_of_options, "r");
if (FMAN == NULL) return;
char line_buffer[300];
feed_t id = Feeds__begin();
while (TRUE) {
int len = Platform__truncated_iso_fgets(FMAN, line_buffer, 255);
if (len < 0) break;
strcat(line_buffer, "\n");
wording W = Feeds__feed_text(line_buffer);
if (Preform__parse_nt_against_word_range(use_option_sentence_shape_NTM, W, NULL, NULL))
UseOptions__set_immediate_option_flags(W, NULL);
}
options_file_wording = Feeds__end(id);
fclose(FMAN);
}
#line 344 "inform7/Chapter 2/Debugging Log.w"
char debug_log_phase[32];
int debug_log_subheading = 1;
void Log__new_phase_of_Informs_run(char *p, char *q) {
strcpy(debug_log_phase, p);
LOG("\n\n-----------------------------------------------------\n");
LOG("Phase %s ... %s", p, q);
LOG("\n-----------------------------------------------------\n\n");
STREAM_FLUSH(dl);
debug_log_subheading = 1;
}
void Log__new_stage_of_Informs_run(char *p) {
LOG("\n\n==== Phase %s.%d ... %s ====\n\n", debug_log_phase, debug_log_subheading, p);
debug_log_subheading++;
STREAM_FLUSH(dl);
}
#line 369 "inform7/Chapter 2/Debugging Log.w"
int Log__aspect_switched_on(int aspect) {
int decision = the_debugging_aspects[aspect].on_or_off;
if (aspect == DEBUGGING_LOG_INCLUSIONS_DA) decision = TRUE;
if (decision) STREAM_FLUSH(dl);
return decision;
}
void Log__set_aspect(int aspect, int state) {
the_debugging_aspects[aspect].on_or_off = state;
}
#line 383 "inform7/Chapter 2/Debugging Log.w"
void Log__set_all_aspects(int new_state) {
int i;
if (dl) LOGIF(DEBUGGING_LOG_INCLUSIONS, "Set debugging aspect: everything -> %s\n",
new_state?"TRUE":"FALSE");
for (i=0; ; i++) {
debugging_aspect *da = &(the_debugging_aspects[i]);
if (*(da->da_word1) == 0) break;
da->on_or_off = new_state;
}
}
#line 413 "inform7/Chapter 2/Debugging Log.w"
int include_in_debugging_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1] | ONLY_DLR; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 416 "inform7/Chapter 2/Debugging Log.w"
int debugging_log_request_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = EVERYTHING_DLR;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = NOTHING_DLR;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = PREFORM_DLR; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = SOMETHING_DLR;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 422 "inform7/Chapter 2/Debugging Log.w"
#line 426 "inform7/Chapter 2/Debugging Log.w"
void Log__set_aspect_from_text(wording W, int new_state) {
LOGIF(DEBUGGING_LOG_INCLUSIONS, "Set contents of debugging log: $w -> %s\n",
W, new_state?"TRUE":"FALSE");
{
#line 451 "inform7/Chapter 2/Debugging Log.w"
Preform__parse_nt_against_word_range(include_in_debugging_sentence_subject_NTM, W, NULL, NULL);
if (most_recent_result & ONLY_DLR) Log__set_all_aspects(1-new_state);
if (most_recent_result & EVERYTHING_DLR) { Log__set_all_aspects(new_state); return; }
if (most_recent_result & NOTHING_DLR) { Log__set_all_aspects(1-new_state); return; }
if (most_recent_result & SOMETHING_DLR) {
wording RQW = GET_RW(debugging_log_request_NTM, 1);
{
#line 464 "inform7/Chapter 2/Debugging Log.w"
int w1 = Wordings__first_wn(RQW);
debugging_aspect *da;
for (int i=0; ; i++) {
da = &(the_debugging_aspects[i]);
if (*(da->da_word1) == 0) break;
if (strcmp(Lexer__word_text(w1), da->da_word1) != 0) continue;
if (Wordings__length(RQW) > 1) {
if (*(da->da_word2) == 0) continue;
if (strcmp(Lexer__word_text(w1+1), da->da_word2) != 0) continue;
}
if (Wordings__length(RQW) > 2) {
if (*(da->da_word3) == 0) continue;
if (strcmp(Lexer__word_text(w1+2), da->da_word3) != 0) continue;
}
if (Wordings__length(RQW) > 3) continue;
da->on_or_off = new_state;
return;
}
}
#line 457 "inform7/Chapter 2/Debugging Log.w"
;
}
if (most_recent_result & PREFORM_DLR) { Preform__watch(most_recent_result_p, new_state); return; }
}
#line 430 "inform7/Chapter 2/Debugging Log.w"
;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_UnknownDA));
Problems__issue_problem_segment(
"In the sentence %1, you asked to include '%2' in the "
"debugging log, but there is no such debugging log topic.");
Problems__issue_problem_end();
}
#line 501 "inform7/Chapter 2/Debugging Log.w"
void Log__set_aspect_from_command_line(char *text) {
int i, parity = TRUE, list_mode = FALSE;
debugging_aspect *da;
if (strcmp(text, "everything") == 0) { Log__set_all_aspects(TRUE); return; }
if (strcmp(text, "nothing") == 0) { Log__set_all_aspects(FALSE); return; }
if (strcmp(text, "list") == 0) list_mode = TRUE;
parity = TRUE;
if ((text[0] == 'n') && (text[1] == 'o') && (text[2] == '-')) {
parity = FALSE;
text += 3;
}
for (i=0; ; i++) {
char tomatch[100];
da = &(the_debugging_aspects[i]);
if (*(da->da_word1) == 0) break;
sprintf(tomatch, "%s", da->da_word1);
if (*(da->da_word2)) sprintf(tomatch+Platform__strlen(tomatch), "-%s", da->da_word2);
if (*(da->da_word3)) sprintf(tomatch+Platform__strlen(tomatch), "-%s", da->da_word3);
if (list_mode) {
WRITE_TO(STDOUT, "--log=%s (%s)\n", tomatch, (da->on_or_off)?"on":"off");
} else {
if (strcmp(text, tomatch) == 0) {
da->on_or_off = parity;
return;
}
}
}
if (list_mode) return;
WRITE_TO(STDOUT, "No such debugging log aspect as '%s'.\n"
"(Try running --log=list for a list of the valid aspects.)\n", text);
Problems__Fatal__issue("No such debugging log aspect.");
}
#line 542 "inform7/Chapter 2/Debugging Log.w"
void Log__tracing_on(int starred, char *heading) {
int i, j;
if (starred) {
LOG("\n*** Entering sentence trace mode: %s ***\n", heading);
} else {
LOG("\n*** Leaving sentence trace mode: %s ***\n\n", heading);
}
for (i=0; ; i++) {
debugging_aspect *da = &(the_debugging_aspects[i]);
if (*(da->da_word1) == 0) break;
j = da->on_or_off;
da->on_or_off = da->alternate;
da->alternate = j;
}
}
#line 561 "inform7/Chapter 2/Debugging Log.w"
int verbose_checking_state = FALSE;
void Log__tracing_phrases(char *text) {
if ((text) && (text[0])) {
verbose_checking_state = TRUE;
debugging_aspect *da;
if (strcmp(text, "everything") == 0) { Log__set_all_aspects(TRUE); return; }
if (strcmp(text, "nothing") == 0) { Log__set_all_aspects(FALSE); return; }
int i;
for (i=0; ; i++) {
char tomatch[100];
da = &(the_debugging_aspects[i]);
if (*(da->da_word1) == 0) break;
sprintf(tomatch, "%s", da->da_word1);
if (*(da->da_word2)) sprintf(tomatch+Platform__strlen(tomatch), " %s", da->da_word2);
if (*(da->da_word3)) sprintf(tomatch+Platform__strlen(tomatch), " %s", da->da_word3);
if (strcmp(text, tomatch) == 0) { Log__set_aspect(i, TRUE); return; }
}
internal_error("unknown *** debugging aspect name");
} else {
verbose_checking_state = (verbose_checking_state)?FALSE:TRUE;
if (verbose_checking_state == FALSE) {
Log__set_all_aspects(FALSE);
} else {
Log__set_aspect(MATCHING_DA, TRUE);
Log__set_aspect(KIND_CHECKING_DA, TRUE);
Log__set_aspect(LOCAL_VARIABLES_DA, TRUE);
}
}
}
#line 598 "inform7/Chapter 2/Debugging Log.w"
void Log__show_debugging_settings_with_state(int state) {
int i, c;
debugging_aspect *da;
for (i=0, c=0; ; i++) {
da = &(the_debugging_aspects[i]);
if (*(da->da_word1) == 0) break;
if (da->on_or_off == state) {
c++;
LOG(" %s %s %s", da->da_word1, da->da_word2, da->da_word3);
if (c % 6 == 0) LOG("\n");
}
}
if (c == 0) { LOG("(Nothing.)\n"); } else { LOG("\n"); }
}
void Log__show_debugging_contents(void) {
if (Log__aspect_switched_on(DEBUGGING_LOG_CONTENTS_DA) == FALSE) return;
LOG("\n\nThat concludes the debugging log from this run of Inform.\n"
"Its contents were as follows, and can be changed by placing\n"
"text like 'Include property creations in the debugging log.'\n"
"or 'Omit everything from the debugging log.' in the source.\n\n");
LOG("Included:\n"); Log__show_debugging_settings_with_state(TRUE);
LOG("Omitted:\n"); Log__show_debugging_settings_with_state(FALSE);
}
#line 626 "inform7/Chapter 2/Debugging Log.w"
void Log__paste_icons(void) {
debugging_aspect *da;
int i;
for (i=0; ; i++) {
da = &(the_debugging_aspects[i]);
if (*(da->da_word1) == 0) break;
char paste_text[256];
sprintf(paste_text, "Include ");
if (da->da_word1[0]) { strcat(paste_text, da->da_word1); strcat(paste_text, " "); }
if (da->da_word2[0]) { strcat(paste_text, da->da_word2); strcat(paste_text, " "); }
if (da->da_word3[0]) { strcat(paste_text, da->da_word3); strcat(paste_text, " "); }
strcat(paste_text, "in the debugging log.");
HTML__Javascript__paste(ifl, paste_text);
INDEX("&nbsp;%s<br>", paste_text);
}
}
#line 651 "inform7/Chapter 2/Debugging Log.w"
void Log__dlprintf(char *fmt, ...) {
va_list ap; /* the variable argument list signified by the dots */
char *p;
if (dl == NULL) return; /* in case logging occurs for an error very early on */
STREAM_FLUSH(dl);
va_start(ap, fmt); /* macro to begin variable argument processing */
for (p = fmt; *p; p++)
switch (*p) {
case '%':
{
#line 679 "inform7/Chapter 2/Debugging Log.w"
int ival; double dval; char *sval;
char format_string[8], category = ' ';
int i = 1;
format_string[0] = '%';
p++;
while (*p) {
format_string[i++] = *p;
if ((islower(*p)) || (isupper(*p)) || (*p == '%')) category = *p;
p++;
if ((category != ' ') || (i==6)) break;
}
format_string[i] = 0; p--;
switch (category) {
case 'c': case 'd': case 'x': /* |char| is promoted to |int| in variable arguments */
ival = va_arg(ap, int); WRITE_TO(dl, format_string, ival); break;
case 'g':
dval = va_arg(ap, double); WRITE_TO(dl, format_string, dval); break;
case 's':
for (sval = va_arg(ap, char *); *sval; sval++) PUT_TO(dl, *sval); break;
case '%': PUT_TO(dl, '%'); break;
case 'f': {
filename *F = va_arg(ap, filename *);
char fn[MAX_FILENAME_LENGTH];
Filenames__to_string(fn, F);
int j;
for (j = 0; fn[j]; j++) PUT_TO(dl, fn[j]);
break;
}
case 'p': {
pathname *P = va_arg(ap, pathname *);
char pn[MAX_FILENAME_LENGTH];
Pathnames__to_string(pn, P);
int j;
for (j = 0; pn[j]; j++) PUT_TO(dl, pn[j]);
break;
}
default:
WRITE_TO(dl, "*** Bad escape: <%s> ***\n", format_string);
internal_error("Unknown % string escape in Log__dlprintf");
}
}
#line 659 "inform7/Chapter 2/Debugging Log.w"
; break;
case '$':
{
#line 725 "inform7/Chapter 2/Debugging Log.w"
p++;
switch (*p) {
case 0: PUT_TO(dl, '$'); p--; break; /* a literal dollar was last character */
case '$': PUT_TO(dl, '$'); break; /* a double dollar means a literal dollar */
SINGLE_ESCAPE('0', pcalc_term *, Calculus__Terms__log)
/* escape |$1| is vacant */
SINGLE_ESCAPE('2', binary_predicate *, BinaryPredicates__log)
SINGLE_ESCAPE('A', action_pattern *, PL__Actions__Patterns__log)
SINGLE_ESCAPE('a', adjectival_phrase *, Adjectives__Phrases__log)
SINGLE_ESCAPE('B', table *, Tables__log)
SINGLE_ESCAPE('b', booking *, Rules__Bookings__log)
SINGLE_ESCAPE('C', table_column *, Tables__Columns__log)
SINGLE_ESCAPE('c', wording, Wordings__log_raw)
SINGLE_ESCAPE('D', pcalc_prop *, Calculus__Propositions__log)
SINGLE_ESCAPE('d', extension_dictionary_entry *, Extensions__Dictionary__log_entry)
SINGLE_ESCAPE('E', parse_node *, Invocations__log_list)
SINGLE_ESCAPE('e', parse_node *, Invocations__log)
SINGLE_ESCAPE('F', wording, Wordings__log_with_whitespace)
SINGLE_ESCAPE('f', word_assemblage *, WordAssemblages__log)
SINGLE_ESCAPE('G', grammar_verb *, PL__Parsing__Verbs__log)
SINGLE_ESCAPE('g', grammar_line *, PL__Parsing__Lines__log)
SINGLE_ESCAPE('H', heading *, Sentences__Headings__log)
SINGLE_ESCAPE('h', ph_type_data *, Phrases__TypeData__Textual__log)
SINGLE_ESCAPE('I', inference *, World__Inferences__log)
SINGLE_ESCAPE('i', i6_schema *, Calculus__Schemas__log)
SINGLE_ESCAPE('J', natural_language *, NaturalLanguages__log)
SINGLE_ESCAPE('j', inference_subject *, InferenceSubjects__log)
SINGLE_ESCAPE('K', rulebook *, Rulebooks__log)
SINGLE_ESCAPE('k', local_variable *, LocalVariables__log)
SINGLE_ESCAPE('L', action_name_list *, PL__Actions__Lists__log)
SINGLE_ESCAPE('l', action_name *, PL__Actions__log)
SINGLE_ESCAPE('M', excerpt_meaning *, Semantics__Nouns__ExcerptMeanings__log)
SINGLE_ESCAPE('m', parse_node *, ParseTree__log_tree)
SINGLE_ESCAPE('N', node_type_t, ParseTree__log_type)
SINGLE_ESCAPE('n', int, World__Inferences__log_kind)
SINGLE_ESCAPE('O', instance *, Instances__log)
SINGLE_ESCAPE('o', pcalc_prop *, Calculus__Atoms__log)
SINGLE_ESCAPE('P', parse_node *, ParseTree__log_node)
SINGLE_ESCAPE('Q', unit_sequence *, Kinds__Dimensions__log_unit_sequence)
SINGLE_ESCAPE('q', equation *, Equations__log)
SINGLE_ESCAPE('R', phrase *, Phrases__log)
SINGLE_ESCAPE('r', adjective_usage *, Adjectives__Usages__log)
SINGLE_ESCAPE('T', parse_node *, ParseTree__log_subtree)
SINGLE_ESCAPE('t', time_period *, TimePeriods__log)
SINGLE_ESCAPE('U', ph_usage_data *, Phrases__Usage__log)
SINGLE_ESCAPE('u', kind *, Kinds__Textual__log)
SINGLE_ESCAPE('V', int, Sentences__VPs__log)
SINGLE_ESCAPE('v', vocabulary_entry *, Vocabulary__log)
SINGLE_ESCAPE('w', wording, Wordings__log)
SINGLE_ESCAPE('x', extension_file *, Extensions__Files__log)
SINGLE_ESCAPE('Y', property *, Properties__log)
SINGLE_ESCAPE('y', wording, Wordings__log_spaceless)
SINGLE_ESCAPE('Z', nonlocal_variable *, NonlocalVariables__log)
SINGLE_ESCAPE('z', nametag *, Nametags__log)
default:
WRITE_TO(dl, "*** Bad escape: '$%c' ***\n", *p);
internal_error("Unknown % string escape in Log__dlprintf");
}
}
#line 660 "inform7/Chapter 2/Debugging Log.w"
; break;
case '"': if (logging_to_I6_text) PUT_TO(dl, '~'); else PUT_TO(dl, '"'); break;
case '\n': if (logging_to_I6_text) PUT_TO(dl, '^'); else PUT_TO(dl, '\n'); break;
default: PUT_TO(dl, *p); break;
}
va_end(ap); /* macro to end variable argument processing */
}
#line 30 "inform7/Chapter 2/Progress Percentages.w"
int last_progress_pc = -100;
int progress_stage_from[] = { 0, 5, 15, 20, 40, 100 };
char *progress_stage_name[] = {
"Reading text",
"Analysing sentences",
"Drawing inferences",
"Binding rulebooks",
"Generating code"
};
void ProgressBar__update_progress_bar(int stage, float proportion) {
int r1 = progress_stage_from[stage], r2 = progress_stage_from[stage+1];
int pc = r1 + ((int) (proportion*(r2-r1)));
if (show_progress_indicator == FALSE) return;
if (pc-last_progress_pc < 3) return;
WRITE_TO(STDERR, "++ %d%% (%s)\n", pc, progress_stage_name[stage]);
STREAM_FLUSH(STDERR);
last_progress_pc = pc;
}
void ProgressBar__final_state_of_progress_bar(void) {
if (show_progress_indicator) {
WRITE_TO(STDERR, "++ 100%% (Finishing work)\n");
STREAM_FLUSH(STDERR);
}
}
#line 61 "inform7/Chapter 2/Progress Percentages.w"
text_stream *ProgressBar__begin_outcome(void) {
if (show_progress_indicator == FALSE) return NULL;
WRITE_TO(STDERR, "++ Ended: ");
return STDERR;
}
void ProgressBar__end_outcome(void) {
if (show_progress_indicator == FALSE) return;
WRITE_TO(STDERR, "\n");
STREAM_FLUSH(STDERR);
}
#line 63 "inform7/Chapter 3/Pathnames.w"
pathname *Pathnames__subfolder(pathname *P, char *folder_name) {
return Pathnames__primitive(folder_name, 0, Platform__strlen(folder_name), P);
}
pathname *Pathnames__primitive(char *c_string, int from, int to, pathname *par) {
pathname *P = CREATE(pathname);
P->pathname_of_parent = par;
P->known_to_exist = FALSE;
if (to-from > MAX_FILENAME_LENGTH-1)
Problems__Fatal__issue_t("a filename grew too long", c_string);
if (to-from <= 0)
internal_error("empty intermediate pathname");
P->intermediate = Memory__I7_malloc(to-from+1, FILENAME_STORAGE_MREASON);
for (int i = from; i < to; i++) P->intermediate[i-from] = c_string[i];
P->intermediate[to-from] = 0;
return P;
}
#line 89 "inform7/Chapter 3/Pathnames.w"
pathname *Pathnames__from_string(char *path) {
return Pathnames__from_string_relative(NULL, path);
}
pathname *Pathnames__from_string_relative(pathname *P, char *path) {
pathname *at = P;
int i = 0, pos = 0;
if ((path[0]) && (P == NULL)) i++;
for (; path[i]; i++)
if (path[i] == FOLDER_SEPARATOR) {
if (i > pos) at = Pathnames__primitive(path, pos, i, at);
pos = i+1;
}
if (i > pos) at = Pathnames__primitive(path, pos, i, at);
return at;
}
#line 110 "inform7/Chapter 3/Pathnames.w"
void Pathnames__to_string(char *to, pathname *P) {
to[0] = 0;
Pathnames__to_string_r(to, P, MAX_FILENAME_LENGTH-1);
}
int Pathnames__to_string_r(char *to, pathname *P, int room_left) {
if (P->pathname_of_parent)
room_left = Pathnames__to_string_r(to, P->pathname_of_parent, room_left);
room_left = room_left - 1 - Platform__strlen(P->intermediate);
if (room_left < 0)
Problems__Fatal__issue_t("a filename grew too long", to);
int pos = Platform__strlen(to);
if (pos > 0) to[pos++] = FOLDER_SEPARATOR;
strcpy(to+pos, P->intermediate);
return room_left;
}
#line 142 "inform7/Chapter 3/Pathnames.w"
void Pathnames__to_string_relative(char *to, pathname *P, pathname *R) {
char rt[MAX_FILENAME_LENGTH], pt[MAX_FILENAME_LENGTH];
Pathnames__to_string(rt, R);
Pathnames__to_string(pt, P);
int n = Platform__strlen(rt);
if ((strncmp(pt, rt, (size_t) n)==0) && ((pt[n]==FOLDER_SEPARATOR) || (pt[n]==0))) {
if (pt[n] == 0) to[0] = 0;
else strcpy(to, pt+n+1);
} else {
LOG("Pathname: %s\nRelative to: %s\n", pt, rt);
internal_error("pathname not relative to pathname");
}
}
#line 161 "inform7/Chapter 3/Pathnames.w"
void Pathnames__start(void) {
char *home = (char *) (getenv("HOME"));
if (home) {
home_path = Pathnames__from_string(home);
home_path->known_to_exist = TRUE;
}
}
#line 174 "inform7/Chapter 3/Pathnames.w"
int Pathnames__create_in_file_system(pathname *P) {
if (P->known_to_exist) return TRUE;
char path[MAX_FILENAME_LENGTH];
Pathnames__to_string(path, P);
P->known_to_exist = Platform__mkdir(path);
if (P->known_to_exist == FALSE) LOG("Unable to force existence of path: %s\n", path);
return P->known_to_exist;
}
#line 198 "inform7/Chapter 3/Pathnames.w"
int Pathnames__write_contents_to_file(filename *writeto, pathname *P) {
char path[MAX_FILENAME_LENGTH];
Pathnames__to_string(path, P);
char transcoded_pathname[2*MAX_FILENAME_LENGTH];
Platform__transcode_ISO_string_to_locale(path, transcoded_pathname);
text_stream CONTS_struct; text_stream *CONTS = &CONTS_struct;
void *FOLDER = Platform__opendir(transcoded_pathname);
char leaf[MAX_FILENAME_LENGTH+1];
if (FOLDER == NULL) return FALSE;
if (STREAM_OPEN_TO_FILE(CONTS, writeto, ISO_ENC) == FALSE) return FALSE;
while (Platform__readdir(FOLDER, transcoded_pathname, leaf)) {
if (leaf[0] == '.') continue;
WRITE_TO(CONTS, "%s\n", leaf);
}
STREAM_CLOSE(CONTS);
Platform__closedir(FOLDER);
return TRUE;
}
#line 221 "inform7/Chapter 3/Pathnames.w"
int Pathnames__write_contents_to_stream(OUTPUT_STREAM, pathname *P) {
char path[MAX_FILENAME_LENGTH];
Pathnames__to_string(path, P);
void *FOLDER = Platform__opendir(path);
if (FOLDER == NULL) return FALSE;
char leaf[MAX_FILENAME_LENGTH+1];
while (Platform__readdir(FOLDER, path, leaf)) {
if (leaf[0] == '.') continue;
WRITE("%s\n", leaf);
}
Platform__closedir(FOLDER);
return TRUE;
}
#line 30 "inform7/Chapter 3/Filenames.w"
filename *Filenames__in_folder(pathname *P, char *file_name) {
return Filenames__primitive(file_name, 0, Platform__strlen(file_name), P);
}
filename *Filenames__primitive(char *c_string, int from, int to, pathname *par) {
filename *F = CREATE(filename);
F->pathname_of_location = par;
if (to-from > MAX_FILENAME_LENGTH-1)
Problems__Fatal__issue_t("a filename grew too long", c_string);
if (to-from <= 0)
internal_error("empty intermediate pathname");
F->leafname = Memory__I7_malloc(to-from+1, FILENAME_STORAGE_MREASON);
for (int i = from; i < to; i++) F->leafname[i-from] = c_string[i];
F->leafname[to-from] = 0;
return F;
}
#line 51 "inform7/Chapter 3/Filenames.w"
filename *Filenames__from_string(pathname *F, char *path) {
int i = 0, pos = 0;
for (; path[i]; i++)
if (path[i] == FOLDER_SEPARATOR)
pos = i;
pathname *at = NULL;
if (pos > 0) at = Pathnames__primitive(path, 0, pos, NULL);
if (pos+1 < i) return Filenames__in_folder(at, path+pos+1);
internal_error("empty leafname");
return NULL;
}
#line 67 "inform7/Chapter 3/Filenames.w"
void Filenames__to_string(char *to, filename *F) {
to[0] = 0;
Pathnames__to_string(to, F->pathname_of_location);
int pos = Platform__strlen(to);
if (pos + 1 + Platform__strlen(F->leafname) + 1 > MAX_FILENAME_LENGTH)
Problems__Fatal__issue_t("a filename grew too long", to);
to[pos] = FOLDER_SEPARATOR;
strcpy(to+pos+1, F->leafname);
}
#line 80 "inform7/Chapter 3/Filenames.w"
void Filenames__to_string_relative(char *to, filename *F, pathname *P) {
char ft[MAX_FILENAME_LENGTH], pt[MAX_FILENAME_LENGTH];
Filenames__to_string(ft, F);
Pathnames__to_string(pt, P);
int n = Platform__strlen(pt);
if ((strncmp(ft, pt, (size_t) n)==0) && (ft[n]==FOLDER_SEPARATOR))
strcpy(to, ft+n+1);
else {
LOG("Filename: %s\nPathname: %s\n", ft, pt);
internal_error("filename not relative to pathname");
}
}
#line 96 "inform7/Chapter 3/Filenames.w"
char *Filenames__get_leafname(filename *F) {
if (F == NULL) return "";
return F->leafname;
}
#line 86 "inform7/Chapter 3/Where Everything Lives.w"
int Locations__command_line_setting(char *option, char *arg) {
if (option == NULL) {
if (filename_of_i7_source) return FALSE;
char temp[MAX_FILENAME_LENGTH];
Platform__truncated_locale_arg(arg, temp, MAX_FILENAME_LENGTH);
filename_of_i7_source = Filenames__in_folder(NULL, temp);
return TRUE;
}
pathname **PP = NULL;
if (strcmp("-project", option) == 0) PP = &pathname_of_project;
if (strcmp("-internal", option) == 0) PP = &(pathname_of_area[INTERNAL_FS_AREA]);
if (strcmp("-external", option) == 0) PP = &(pathname_of_area[EXTERNAL_FS_AREA]);
if (strcmp("-transient", option) == 0) PP = &pathname_of_transient_external_resources;
if (PP) {
char temp[MAX_FILENAME_LENGTH];
Platform__truncated_locale_arg(arg, temp, MAX_FILENAME_LENGTH);
*PP = Pathnames__from_string(temp);
return TRUE;
}
return FALSE;
}
#line 121 "inform7/Chapter 3/Where Everything Lives.w"
int Locations__set_defaults(int census_mode) {
{
#line 152 "inform7/Chapter 3/Where Everything Lives.w"
if (pathname_of_area[INTERNAL_FS_AREA] == NULL)
Problems__Fatal__issue("Did not set -internal when calling");
Locations__EILT_at(INTERNAL_FS_AREA, pathname_of_area[INTERNAL_FS_AREA]);
{
#line 169 "inform7/Chapter 3/Where Everything Lives.w"
pathname *misc = Pathnames__subfolder(pathname_of_area[INTERNAL_FS_AREA], "Miscellany");
filename_of_cblorb_report_model = Filenames__in_folder(misc, "CblorbModel.html");
filename_of_large_default_cover_art = Filenames__in_folder(misc, "Cover.jpg");
filename_of_small_default_cover_art = Filenames__in_folder(misc, "Small Cover.jpg");
filename_of_intro_postcard = Filenames__in_folder(misc, "Postcard.pdf");
filename_of_intro_booklet = Filenames__in_folder(misc, "IntroductionToIF.pdf");
filename_of_extensions_documentation_model = Filenames__in_folder(misc, EXTENSIONS_MODEL_HTML);
filename_of_extension_file_documentation_model = Filenames__in_folder(misc, EXTENSION_FILE_MODEL_HTML);
filename_of_documentation_snippets = Filenames__in_folder(misc, "definitions.html");
}
#line 157 "inform7/Chapter 3/Where Everything Lives.w"
;
}
#line 122 "inform7/Chapter 3/Where Everything Lives.w"
;
{
#line 202 "inform7/Chapter 3/Where Everything Lives.w"
if (pathname_of_area[EXTERNAL_FS_AREA] == NULL) {
pathname_of_area[EXTERNAL_FS_AREA] = home_path;
char *subfolder_within = INFORM_FOLDER_RELATIVE_TO_HOME;
if (subfolder_within[0])
pathname_of_area[EXTERNAL_FS_AREA] =
Pathnames__subfolder(home_path, INFORM_FOLDER_RELATIVE_TO_HOME);
pathname_of_area[EXTERNAL_FS_AREA] =
Pathnames__subfolder(pathname_of_area[EXTERNAL_FS_AREA], "Inform");
}
if (Pathnames__create_in_file_system(pathname_of_area[EXTERNAL_FS_AREA]) == 0) return FALSE;
{
#line 229 "inform7/Chapter 3/Where Everything Lives.w"
Locations__EILT_at(EXTERNAL_FS_AREA, pathname_of_area[EXTERNAL_FS_AREA]);
filename_of_options =
Filenames__in_folder(pathname_of_area[EXTERNAL_FS_AREA], "Options.txt");
}
#line 212 "inform7/Chapter 3/Where Everything Lives.w"
;
if (pathname_of_transient_external_resources == NULL)
pathname_of_transient_external_resources =
pathname_of_area[EXTERNAL_FS_AREA];
if (Pathnames__create_in_file_system(pathname_of_transient_external_resources) == 0) return FALSE;
{
#line 236 "inform7/Chapter 3/Where Everything Lives.w"
{
#line 246 "inform7/Chapter 3/Where Everything Lives.w"
pathname_of_extension_docs =
Pathnames__subfolder(pathname_of_transient_external_resources, "Documentation");
if (Pathnames__create_in_file_system(pathname_of_extension_docs) == 0) return FALSE;
pathname_of_transient_census_data =
Pathnames__subfolder(pathname_of_extension_docs, "Census");
if (Pathnames__create_in_file_system(pathname_of_transient_census_data) == 0) return FALSE;
filename_of_extensions_census_errors =
Filenames__in_folder(pathname_of_transient_census_data, "CensusErrors.txt");
filename_of_extensions_dictionary =
Filenames__in_folder(pathname_of_transient_census_data, "Dictionary.txt");
pathname_of_extension_docs_inner =
Pathnames__subfolder(pathname_of_extension_docs, "Extensions");
if (Pathnames__create_in_file_system(pathname_of_extension_docs_inner) == 0) return FALSE;
}
#line 236 "inform7/Chapter 3/Where Everything Lives.w"
;
{
#line 268 "inform7/Chapter 3/Where Everything Lives.w"
pathname *pathname_of_telemetry_data =
Pathnames__subfolder(pathname_of_transient_external_resources, "Telemetry");
if (Pathnames__create_in_file_system(pathname_of_telemetry_data) == 0) return FALSE;
char leafname_of_telemetry[MAX_FILENAME_LENGTH];
int this_month = the_present->tm_mon + 1;
int this_day = the_present->tm_mday;
int this_year = the_present->tm_year + 1900;
sprintf(leafname_of_telemetry,
"Telemetry %04d-%02d-%02d.txt", this_year, this_month, this_day);
filename_of_telemetry =
Filenames__in_folder(pathname_of_telemetry_data, leafname_of_telemetry);
}
#line 237 "inform7/Chapter 3/Where Everything Lives.w"
;
}
#line 218 "inform7/Chapter 3/Where Everything Lives.w"
;
}
#line 123 "inform7/Chapter 3/Where Everything Lives.w"
;
{
#line 294 "inform7/Chapter 3/Where Everything Lives.w"
{
#line 309 "inform7/Chapter 3/Where Everything Lives.w"
if (filename_of_i7_source == NULL)
if (pathname_of_project)
filename_of_i7_source =
Filenames__in_folder(
Pathnames__subfolder(pathname_of_project, "Source"),
"story.ni");
}
#line 294 "inform7/Chapter 3/Where Everything Lives.w"
;
{
#line 332 "inform7/Chapter 3/Where Everything Lives.w"
pathname *build_folder = pathname_of_transient_census_data;
if (census_mode == FALSE) {
build_folder = Pathnames__subfolder(pathname_of_project, "Build");
if (Pathnames__create_in_file_system(build_folder) == 0) return FALSE;
}
filename_of_report = Filenames__in_folder(build_folder, "Problems.html");
filename_of_debugging_log = Filenames__in_folder(build_folder, "Debug log.txt");
filename_of_parse_tree = Filenames__in_folder(build_folder, "Parse tree.txt");
filename_of_compiled_i6_code = Filenames__in_folder(build_folder, "auto.inf");
char story_file_leafname[128];
sprintf(story_file_leafname, "output.%s", story_filename_extension);
filename_of_story_file = Filenames__in_folder(build_folder, story_file_leafname);
filename_of_cblorb_report = Filenames__in_folder(build_folder, "StatusCblorb.html");
}
#line 295 "inform7/Chapter 3/Where Everything Lives.w"
;
{
#line 361 "inform7/Chapter 3/Where Everything Lives.w"
pathname_of_project_index_folder =
Pathnames__subfolder(pathname_of_project, "Index");
pathname_of_project_index_details_folder =
Pathnames__subfolder(pathname_of_project_index_folder, "Details");
if (census_mode == FALSE)
if ((Pathnames__create_in_file_system(pathname_of_project_index_folder) == 0) ||
(Pathnames__create_in_file_system(pathname_of_project_index_details_folder) == 0))
return FALSE;
filename_of_headings =
Filenames__in_folder(pathname_of_project_index_folder, "Headings.xml");
}
#line 296 "inform7/Chapter 3/Where Everything Lives.w"
;
filename_of_uuid = Filenames__in_folder(pathname_of_project, "uuid.txt");
filename_of_ifiction_record = Filenames__in_folder(pathname_of_project, "Metadata.iFiction");
filename_of_manifest = Filenames__in_folder(pathname_of_project, "manifest.plist");
filename_of_blurb = Filenames__in_folder(pathname_of_project, "Release.blurb");
}
#line 124 "inform7/Chapter 3/Where Everything Lives.w"
;
{
#line 381 "inform7/Chapter 3/Where Everything Lives.w"
if (pathname_of_project) {
char mf[MAX_FILENAME_LENGTH + 10];
strcpy(mf, pathname_of_project->intermediate);
int i = Platform__strlen(mf)-1;
while ((i>0) && (mf[i] != '.')) i--;
if (i>0) strcpy(mf+i, ".materials");
pathname_of_area[MATERIALS_FS_AREA] =
Pathnames__subfolder(pathname_of_project->pathname_of_parent, mf);
if (Pathnames__create_in_file_system(pathname_of_area[MATERIALS_FS_AREA]) == 0) return FALSE;
} else {
pathname_of_area[MATERIALS_FS_AREA] = Pathnames__from_string("inform.materials");
}
Locations__EILT_at(MATERIALS_FS_AREA, pathname_of_area[MATERIALS_FS_AREA]);
{
#line 410 "inform7/Chapter 3/Where Everything Lives.w"
pathname_of_materials_figures = Pathnames__subfolder(pathname_of_area[MATERIALS_FS_AREA], "Figures");
pathname_of_materials_sounds = Pathnames__subfolder(pathname_of_area[MATERIALS_FS_AREA], "Sounds");
filename_of_large_cover_art_jpeg = Filenames__in_folder(pathname_of_area[MATERIALS_FS_AREA], "Cover.jpg");
filename_of_large_cover_art_png = Filenames__in_folder(pathname_of_area[MATERIALS_FS_AREA], "Cover.png");
filename_of_small_cover_art_jpeg = Filenames__in_folder(pathname_of_area[MATERIALS_FS_AREA], "Small Cover.jpg");
filename_of_small_cover_art_png = Filenames__in_folder(pathname_of_area[MATERIALS_FS_AREA], "Small Cover.png");
filename_of_epsfile = Filenames__in_folder(pathname_of_area[MATERIALS_FS_AREA], "Inform Map.eps");
}
#line 396 "inform7/Chapter 3/Where Everything Lives.w"
;
{
#line 426 "inform7/Chapter 3/Where Everything Lives.w"
pathname_of_materials_release = Pathnames__subfolder(pathname_of_area[MATERIALS_FS_AREA], "Release");
pathname_of_released_interpreter = Pathnames__subfolder(pathname_of_materials_release, "interpreter");
pathname_of_released_figures = Pathnames__subfolder(pathname_of_materials_release, "Figures");
pathname_of_released_sounds = Pathnames__subfolder(pathname_of_materials_release, "Sounds");
}
#line 397 "inform7/Chapter 3/Where Everything Lives.w"
;
{
#line 437 "inform7/Chapter 3/Where Everything Lives.w"
char leaf[MAX_FILENAME_LENGTH];
sprintf(leaf, "story.%s", story_filename_extension);
filename_of_existing_story_file =
Filenames__in_folder(pathname_of_area[MATERIALS_FS_AREA], leaf);
}
#line 398 "inform7/Chapter 3/Where Everything Lives.w"
;
}
#line 125 "inform7/Chapter 3/Where Everything Lives.w"
;
if ((census_mode == FALSE) && (filename_of_i7_source == NULL))
Problems__Fatal__issue("Except in census mode, source text must be supplied");
if ((census_mode) && (filename_of_i7_source))
Problems__Fatal__issue("In census mode, no source text may be supplied");
return TRUE;
}
#line 448 "inform7/Chapter 3/Where Everything Lives.w"
void Locations__EILT_at(int area, pathname *P) {
pathname_of_extensions[area] = Pathnames__subfolder(P, "Extensions");
pathname_of_i6t_files[area] = Pathnames__subfolder(P, "I6T");
pathname_of_languages[area] = Pathnames__subfolder(P, "Languages");
pathname_of_website_templates[area] = Pathnames__subfolder(P, "Templates");
}
#line 472 "inform7/Chapter 3/Where Everything Lives.w"
filename *Locations__of_extension(pathname *E, char *title, char *author, int i7x_flag) {
char leaf[MAX_FILENAME_LENGTH + 4];
if (i7x_flag) sprintf(leaf, "%s.i7x", title);
else sprintf(leaf, "%s", title);
return Filenames__in_folder(Pathnames__subfolder(E, author), leaf);
}
#line 482 "inform7/Chapter 3/Where Everything Lives.w"
filename *Locations__of_extension_documentation(char *title, char *author) {
char leaf[MAX_FILENAME_LENGTH + 5];
sprintf(leaf, "%s.html", title);
return Filenames__in_folder(
Pathnames__subfolder(pathname_of_extension_docs_inner, author), leaf);
}
#line 496 "inform7/Chapter 3/Where Everything Lives.w"
filename *Locations__in_index(char *leafname, int sub) {
if (pathname_of_project == NULL) return Filenames__in_folder(NULL, leafname);
if (sub >= 0) {
char full_leafname[MAX_FILENAME_LENGTH+16];
sprintf(full_leafname, "%d_%s", sub, leafname);
return Filenames__in_folder(pathname_of_project_index_details_folder, full_leafname);
} else {
return Filenames__in_folder(pathname_of_project_index_folder, leafname);
}
}
#line 49 "inform7/Chapter 3/Case-Insensitive Filenames.w"
#ifdef POSIX_DIRECTORY_HANDLING
#line 58 "inform7/Chapter 3/Case-Insensitive Filenames.w"
FILE *CIFilingSystem__fopen(const char *path, const char *mode) {
char *topdirpath = NULL, *ciextdirpath = NULL, *cistring = NULL, *ciextname = NULL;
char *workstring = NULL, *workstring2 = NULL;
DIR *topdir = NULL, *extdir = NULL; FILE *handle;
size_t length;
LOGIF(CASE_INSENSITIVE_FILEHANDLING,
"CIFilingSystem__fopen called on '%s' with mode '%s'\n", path, mode);
/* for efficiency's sake, though it's logically equivalent, we try... */
handle = fopen(path, mode); if (handle)
{
#line 154 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: succeeded\n");
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 155 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return handle;
}
#line 68 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
{
#line 180 "inform7/Chapter 3/Case-Insensitive Filenames.w"
length = 0;
if (path) length = (size_t) Platform__strlen(path);
if (length < 1) { errno = ENOENT; return NULL; }
}
#line 70 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
{
#line 138 "inform7/Chapter 3/Case-Insensitive Filenames.w"
workstring = calloc(length+1, sizeof(char));
if (workstring == NULL) { errno = ENOMEM;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 139 "inform7/Chapter 3/Case-Insensitive Filenames.w"
; }
workstring2 = calloc(length+1, sizeof(char));
if (workstring2 == NULL) { errno = ENOMEM;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 141 "inform7/Chapter 3/Case-Insensitive Filenames.w"
; }
topdirpath = calloc(length+1, sizeof(char));
if (topdirpath == NULL) { errno = ENOMEM;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 143 "inform7/Chapter 3/Case-Insensitive Filenames.w"
; }
ciextdirpath = calloc(length+1, sizeof(char));
if (ciextdirpath == NULL) { errno = ENOMEM;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 145 "inform7/Chapter 3/Case-Insensitive Filenames.w"
; }
cistring = calloc(length+1, sizeof(char));
if (cistring == NULL) { errno = ENOMEM;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 147 "inform7/Chapter 3/Case-Insensitive Filenames.w"
; }
ciextname = calloc(length+1, sizeof(char));
if (ciextname == NULL) { errno = ENOMEM;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 149 "inform7/Chapter 3/Case-Insensitive Filenames.w"
; }
}
#line 71 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
{
#line 197 "inform7/Chapter 3/Case-Insensitive Filenames.w"
char *p;
size_t extdirindex, extindex, namelen, dirlen;
p = strrchr(path, FOLDER_SEPARATOR);
extindex = (size_t) (p - path);
namelen = length - extindex - 1;
strncpy(ciextname, path + extindex + 1, namelen);
ciextname[namelen] = 0;
strncpy(workstring, path, (extindex-1));
workstring[extindex-1] = 0;
p = strrchr(workstring, FOLDER_SEPARATOR);
extdirindex = (size_t) (p - workstring);
strncpy(topdirpath, path, extdirindex);
topdirpath[extdirindex] = 0;
dirlen = extindex - extdirindex - 1;
strncpy(ciextdirpath, path + extdirindex + 1, dirlen);
ciextdirpath[dirlen] = 0;
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "topdirpath = %s\n", topdirpath);
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ciextdirpath = %s\n", ciextdirpath);
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ciextname = %s\n", ciextname);
}
#line 72 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
topdir = opendir(topdirpath); /* whose pathname is assumed case-correct... */
if (topdir == NULL)
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 75 "inform7/Chapter 3/Case-Insensitive Filenames.w"
; /* ...so that failure is fatal; |errno| is set by |opendir| */
sprintf(workstring, "%s%c%s", topdirpath, FOLDER_SEPARATOR, ciextdirpath);
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "supplied dir = %s\n", workstring);
extdir = opendir(workstring); /* try with supplied extension directory name */
if (extdir == NULL)
{
#line 96 "inform7/Chapter 3/Case-Insensitive Filenames.w"
int rc = CIFilingSystem__match_in_directory(topdir, ciextdirpath, workstring);
switch (rc) {
case 0:
errno = ENOENT;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 99 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
case 1:
sprintf(cistring, "%s%c%s", topdirpath, FOLDER_SEPARATOR, workstring);
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "real dirname = %s\n", cistring);
extdir = opendir(cistring);
if (extdir == NULL) {
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "%s not found\n", cistring);
errno = ENOENT;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 106 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
}
break;
default:
errno = EBADF;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 110 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
}
}
#line 80 "inform7/Chapter 3/Case-Insensitive Filenames.w"
else strcpy(cistring, workstring);
sprintf(workstring, "%s%c%s", cistring, FOLDER_SEPARATOR, ciextname);
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "supplied name = %s\n", workstring);
handle = fopen(workstring, mode); /* try with supplied name */
if (handle)
{
#line 154 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: succeeded\n");
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 155 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return handle;
}
#line 86 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
{
#line 117 "inform7/Chapter 3/Case-Insensitive Filenames.w"
int rc = CIFilingSystem__match_in_directory(extdir, ciextname, workstring);
switch (rc) {
case 0:
errno = ENOENT;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 121 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
case 1:
sprintf(workstring2, "%s%c%s", cistring, FOLDER_SEPARATOR, workstring);
workstring2[length] = 0;
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "real filename = %s\n", workstring2);
handle = fopen(workstring2, mode);
if (handle)
{
#line 154 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: succeeded\n");
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 155 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return handle;
}
#line 127 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "Couldn't open %s\n", workstring2);
errno = ENOENT;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 129 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
default:
errno = EBADF;
{
#line 161 "inform7/Chapter 3/Case-Insensitive Filenames.w"
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "ci-fopen: failed with errno = %d\n", errno);
{
#line 168 "inform7/Chapter 3/Case-Insensitive Filenames.w"
if (workstring) free(workstring);
if (workstring2) free(workstring2);
if (topdirpath) free(topdirpath);
if (ciextdirpath) free(ciextdirpath);
if (cistring) free(cistring);
if (ciextname) free(ciextname);
if (topdir) closedir(topdir);
if (extdir) closedir(extdir);
}
#line 162 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
return NULL;
}
#line 131 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
}
}
#line 88 "inform7/Chapter 3/Case-Insensitive Filenames.w"
;
}
#line 232 "inform7/Chapter 3/Case-Insensitive Filenames.w"
int CIFilingSystem__match_in_directory(void *vd,
char *name, char *last_match) {
DIR *d = (DIR *) vd;
struct dirent *dirp;
int rc = 0;
last_match[0] = 0;
while ((dirp = readdir(d)) != NULL) {
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "testing: name = %s; entry = %s\n", name, dirp->d_name);
if (strcasecmp(name, dirp->d_name) == 0) {
LOGIF(CASE_INSENSITIVE_FILEHANDLING, "accepted as match %d\n", rc);
rc++;
strcpy(last_match, dirp->d_name);
}
}
LOGIF(CASE_INSENSITIVE_FILEHANDLING,
"CIFilingSystem__match_in_directory rc = %d\n", rc);
return rc;
}
#line 256 "inform7/Chapter 3/Case-Insensitive Filenames.w"
#else
FILE *CIFilingSystem__fopen(const char *path, const char *mode) {
return fopen(path, mode);
}
#endif
#line 11 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_int8(FILE *binary_file, unsigned int *result) {
int c1 = getc(binary_file);
if (c1 == EOF) return FALSE;
*result = (unsigned int) c1;
return TRUE;
}
int BinaryFiles__read_int16(FILE *binary_file, unsigned int *result) {
int c1, c2;
c1 = getc(binary_file);
c2 = getc(binary_file);
if (c1 == EOF || c2 == EOF) return FALSE;
*result = (((unsigned int) c1) << 8) + ((unsigned int) c2);
return TRUE;
}
int BinaryFiles__read_int32(FILE *binary_file, unsigned int *result) {
int c1, c2, c3, c4;
c1 = getc(binary_file);
c2 = getc(binary_file);
c3 = getc(binary_file);
c4 = getc(binary_file);
if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF) return FALSE;
*result = (((unsigned int) c1) << 24) +
(((unsigned int) c2) << 16) +
(((unsigned int) c3) << 8) + ((unsigned int) c4);
return TRUE;
}
int BinaryFiles__read_int64(FILE *binary_file, unsigned long long *result) {
int c1, c2, c3, c4, c5, c6, c7, c8;
c1 = getc(binary_file);
c2 = getc(binary_file);
c3 = getc(binary_file);
c4 = getc(binary_file);
c5 = getc(binary_file);
c6 = getc(binary_file);
c7 = getc(binary_file);
c8 = getc(binary_file);
if (c1 == EOF || c2 == EOF || c3 == EOF || c4 == EOF || c5 == EOF
|| c6 == EOF || c7 == EOF || c8 == EOF) return FALSE;
*result = (((unsigned long long) c1) << 56) +
(((unsigned long long) c2) << 48) +
(((unsigned long long) c3) << 40) +
(((unsigned long long) c4) << 32) +
(((unsigned long long) c5) << 24) +
(((unsigned long long) c6) << 16) +
(((unsigned long long) c7) << 8) +
((unsigned long long) c8);
return TRUE;
}
#line 74 "inform7/Chapter 3/Binary Files.w"
void BinaryFiles__swap_bytes32(unsigned int *value) {
unsigned int result = (((*value & 0xff) << 24) +
((*value & 0xff00) << 8) +
((*value & 0xff0000) >> 8) +
((*value & 0xff000000) >> 24 ) );
*value = result;
}
void BinaryFiles__swap_bytes64(unsigned long long *value) {
unsigned long long result = (((*value & 0xff) << 56) +
((*value & 0xff00) << 40) +
((*value & 0xff0000) << 24) +
((*value & 0xff000000) << 8) +
((*value >> 8) & 0xff000000) +
((*value >> 24) & 0xff0000) +
((*value >> 40) & 0xff00) +
((*value >> 56) & 0xff) );
*value = result;
}
#line 100 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_variable_length_integer(FILE *binary_file, unsigned int *result) {
int c;
*result = 0;
do {
c = getc(binary_file);
if (c == EOF) return FALSE;
*result = (*result << 7) + (((unsigned char) c) & 0x7F);
} while (((unsigned char) c) & 0x80);
return TRUE;
}
#line 117 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_float80(FILE *binary_file, unsigned int *result) {
int c1, c2, exp;
unsigned int prev = 0, mantissa;
c1 = getc(binary_file);
c2 = getc(binary_file);
if (c1 == EOF || c2 == EOF) return FALSE;
if (!BinaryFiles__read_int32(binary_file, &mantissa)) return FALSE;
exp = 30 - c2;
while (exp--) {
prev = mantissa;
mantissa >>= 1;
}
if (prev & 1) mantissa++;
*result = (unsigned int) mantissa;
return TRUE;
}
#line 142 "inform7/Chapter 3/Binary Files.w"
int BinaryFiles__read_string(FILE *binary_file, char *string, unsigned int length) {
if (length > 0) {
if (fread(string, 1, length, binary_file) != length) return FALSE;
}
string[length] = 0;
return TRUE;
}
#line 27 "inform7/Chapter 3/Image Dimensions.w"
int ImageFiles__get_JPEG_dimensions(FILE *JPEG_file, unsigned int *width, unsigned int *height) {
unsigned int sig, length;
int marker;
if (!BinaryFiles__read_int16(JPEG_file, &sig)) return FALSE;
if (sig != 0xFFD8) return FALSE; /* |0xFF| (marker) then |0xD8| (SOI) */
do {
do {
marker = getc(JPEG_file);
if (marker == EOF) return FALSE;
} while (marker != 0xff); /* skip to next |0xFF| byte */
do {
marker = getc(JPEG_file);
} while (marker == 0xff); /* skip to next non |FF| byte */
if (!BinaryFiles__read_int16(JPEG_file, &length)) return FALSE; /* length of marker */
switch(marker) {
/* all variant forms of "start of frame": e.g., |0xC0| is a baseline DCT image */
case 0xc0:
case 0xc1: case 0xc2: case 0xc3:
case 0xc5: case 0xc6: case 0xc7:
case 0xc9: case 0xca: case 0xcb:
case 0xcd: case 0xce: case 0xcf: {
/* fortunately these markers all then open with the same format */
if (getc(JPEG_file) == EOF) return FALSE; /* skip 1 byte of data precision */
if (!BinaryFiles__read_int16(JPEG_file, height)) return FALSE;
if (!BinaryFiles__read_int16(JPEG_file, width)) return FALSE;
return TRUE;
}
default:
if (fseek(JPEG_file, (long) (length - 2), SEEK_CUR) != 0) return FALSE; /* skip rest of marker */
}
}
while (marker != EOF);
return FALSE;
}
#line 80 "inform7/Chapter 3/Image Dimensions.w"
int ImageFiles__get_PNG_dimensions(FILE *PNG_file, unsigned int *width, unsigned int *height) {
unsigned int sig1, sig2, length, type;
/* Check PNG signature */
if (!BinaryFiles__read_int32(PNG_file, &sig1)) return FALSE;
if (!BinaryFiles__read_int32(PNG_file, &sig2)) return FALSE;
if ((sig1 != 0x89504e47) || (sig2 != 0x0d0a1a0a)) return FALSE;
/* Read first chunk */
if (!BinaryFiles__read_int32(PNG_file, &length)) return FALSE;
if (!BinaryFiles__read_int32(PNG_file, &type)) return FALSE;
/* First chunk must be IHDR */
if (type != 0x49484452) return FALSE;
/* Width and height follow */
if (!BinaryFiles__read_int32(PNG_file, width)) return FALSE;
if (!BinaryFiles__read_int32(PNG_file, height)) return FALSE;
return TRUE;
}
#line 15 "inform7/Chapter 3/Sound Durations.w"
int SoundFiles__get_AIFF_duration(FILE *pFile, unsigned int *pDuration,
unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) {
unsigned int sig;
unsigned int chunkID;
unsigned int chunkLength;
unsigned int numSampleFrames;
unsigned int sampleSize;
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x464F524D) return FALSE; /* |"FORM"| indicating an IFF file */
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x41494646) return FALSE; /* |"AIFF"| indicating an AIFF file */
/* Read chunks, skipping over those we are not interested in */
while (TRUE) {
if (!BinaryFiles__read_int32(pFile, &chunkID)) return FALSE;
if (!BinaryFiles__read_int32(pFile, &chunkLength)) return FALSE;
if (chunkID == 0x434F4D4D) { /* |"COMM"| indicates common AIFF data */
if (chunkLength < 18) return FALSE; /* Check we have enough data to read */
if (!BinaryFiles__read_int16(pFile, pChannels)) return FALSE;
if (!BinaryFiles__read_int32(pFile, &numSampleFrames)) return FALSE;
if (!BinaryFiles__read_int16(pFile, &sampleSize)) return FALSE;
if (!BinaryFiles__read_float80(pFile, pSampleRate)) return FALSE;
if (*pSampleRate == 0) return FALSE; /* Sanity check to avoid a divide by zero */
/* Result is in centiseconds */
*pDuration = (unsigned int) (((unsigned long long) numSampleFrames * 100) / *pSampleRate);
*pBitsPerSecond = *pSampleRate * *pChannels * sampleSize;
break;
} else {
/* Skip unwanted chunk */
if (fseek(pFile, (long) chunkLength, SEEK_CUR) != 0) return FALSE;
}
}
return TRUE;
}
#line 62 "inform7/Chapter 3/Sound Durations.w"
int SoundFiles__get_OggVorbis_duration(FILE *pFile, unsigned int *pDuration,
unsigned int *pBitsPerSecond, unsigned int *pChannels, unsigned int *pSampleRate) {
unsigned int sig;
unsigned int version;
unsigned int numSegments;
unsigned int packetType;
unsigned int vorbisSig1;
unsigned int vorbisSig2;
unsigned int seekPos;
unsigned int fileLength, bytesToRead, lastSig, index;
unsigned long long granulePosition;
unsigned char buffer[256];
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x4F676753) return FALSE; /* |"OggS"| indicating an OGG file */
/* Check OGG version is zero */
if (!BinaryFiles__read_int8(pFile, &version)) return FALSE;
if (version != 0) return FALSE;
/* Skip header type, granule position, serial number, page sequence and CRC */
if (fseek(pFile, 21, SEEK_CUR) != 0) return FALSE;
/* Read number of page segments */
if (!BinaryFiles__read_int8(pFile, &numSegments)) return FALSE;
/* Skip segment table */
if (fseek(pFile, (long) numSegments, SEEK_CUR) != 0) return FALSE;
/* Vorbis Identification header */
if (!BinaryFiles__read_int8(pFile, &packetType)) return FALSE;
if (packetType != 1) return FALSE;
if (!BinaryFiles__read_int32(pFile, &vorbisSig1)) return FALSE;
if (vorbisSig1 != 0x766F7262) return FALSE; /* |"VORB"| */
if (!BinaryFiles__read_int16(pFile, &vorbisSig2)) return FALSE;
if (vorbisSig2 != 0x6973) return FALSE; /* |"IS"| */
/* Check Vorbis version is zero */
if (!BinaryFiles__read_int32(pFile, &version)) return FALSE;
if (version != 0) return FALSE;
/* Read number of channels */
if (!BinaryFiles__read_int8(pFile, pChannels)) return FALSE;
/* Read sample rate */
if (!BinaryFiles__read_int32(pFile, pSampleRate)) return FALSE;
BinaryFiles__swap_bytes32(pSampleRate); /* Ogg Vorbis uses LSB first */
/* Skip bitrate maximum */
if (fseek(pFile, 4, SEEK_CUR) != 0) return FALSE;
/* Read Nominal Bitrate */
if (!BinaryFiles__read_int32(pFile, pBitsPerSecond)) return FALSE;
BinaryFiles__swap_bytes32(pBitsPerSecond); /* Ogg Vorbis uses LSB first */
/* Encoders can be unhelpful and give no bitrate in the header */
if (pBitsPerSecond == 0) return FALSE;
/* Search for the final Ogg page (near the end of the file) to read duration, */
/* i.e., read the last 4K of the file and look for the final |"OggS"| sig */
if (fseek(pFile, 0, SEEK_END) != 0) return FALSE;
fileLength = (unsigned int) ftell(pFile);
if (fileLength < 4096) seekPos = 0;
else seekPos = fileLength - 4096;
lastSig = 0xFFFFFFFF;
while (seekPos < fileLength) {
if (fseek(pFile, (long) seekPos, SEEK_SET) != 0) return FALSE;
bytesToRead = fileLength - seekPos;
if (bytesToRead > 256) bytesToRead = 256;
if (fread(buffer, 1, bytesToRead, pFile) != bytesToRead) return FALSE;
for(index = 0; index < bytesToRead; index++) {
if ((buffer[index] == 0x4F) &&
(buffer[index + 1] == 0x67) &&
(buffer[index + 2] == 0x67) &&
(buffer[index + 3] == 0x53)) {
lastSig = seekPos + index;
}
}
/* Next place to read from is 256 bytes further on, but to catch */
/* sigs that span between these blocks, read the last four bytes again */
seekPos += 256 - 4;
}
if (lastSig == 0xFFFFFFFF) return FALSE;
if (fseek(pFile, (long) lastSig, SEEK_SET) != 0) return FALSE;
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
if (sig != 0x4F676753) return FALSE; /* |"OggS"| indicating an OGG file */
/* Check OGG version is zero */
if (!BinaryFiles__read_int8(pFile, &version)) return FALSE;
if (version != 0) return FALSE;
/* Skip header Type */
if (fseek(pFile, 1, SEEK_CUR) != 0) return FALSE;
if (!BinaryFiles__read_int64(pFile, &granulePosition)) return FALSE;
BinaryFiles__swap_bytes64(&granulePosition);
*pDuration = (unsigned int) ((granulePosition * 100) /
(unsigned long long) *pSampleRate);
return TRUE;
}
#line 184 "inform7/Chapter 3/Sound Durations.w"
int SoundFiles__get_MIDI_information(FILE *pFile, unsigned int *pType,
unsigned int *pNumTracks) {
unsigned int sig;
unsigned int length;
unsigned int pulses;
unsigned int frames_per_second;
unsigned int subframes_per_frame;
unsigned int clocks_per_second;
unsigned int start_of_chunk_data;
unsigned int status;
unsigned int clocks;
unsigned int sysex_length;
unsigned int non_midi_event_length;
unsigned int start_of_non_midi_data;
unsigned int non_midi_event;
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
/* |"RIFF"| indicating a RIFF file */
if (sig == 0x52494646) {
/* Skip the filesize and typeID */
if (fseek(pFile, 8, SEEK_CUR) != 0) return FALSE;
/* now read the real MIDI sig */
if (!BinaryFiles__read_int32(pFile, &sig)) return FALSE;
}
/* |"MThd"| indicating a MIDI file */
if (sig != 0x4D546864) return FALSE;
/* Read length of chunk */
if (!BinaryFiles__read_int32(pFile, &length)) return FALSE;
/* Make sure we have enough data to read */
if (length < 6) return FALSE;
/* Read the MIDI type: 0,1 or 2 */
/* 0 means one track containing up to 16 channels to make a single tune */
/* 1 means one or more tracks, commonly each with a single channel, making up a single tune */
/* 2 means one or more tracks, where each is a separate tune in it's own right */
if (!BinaryFiles__read_int16(pFile, pType)) return FALSE;
/* Read the number of tracks */
if (!BinaryFiles__read_int16(pFile, pNumTracks)) return FALSE;
/* Read "Pulses Per Quarter Note" (PPQN) */
if (!BinaryFiles__read_int16(pFile, &pulses)) return FALSE;
/* if top bit set, then number of subframes per second can be deduced */
if (pulses >= 0x8000) {
/* First byte is a negative number for the frames per second */
/* Second byte is the number of subframes in each frame */
frames_per_second = (256 - (pulses & 0xff));
subframes_per_frame = (pulses >> 8);
clocks_per_second = frames_per_second * subframes_per_frame;
LOG("frames_per_second = %d\n", frames_per_second);
LOG("subframes_per_frame = %d\n", subframes_per_frame);
LOG("clocks_per_second = %d\n", clocks_per_second);
/* Number of pulses per quarter note unknown */
pulses = 0;
} else {
/* unknown values */
frames_per_second = 0;
subframes_per_frame = 0;
clocks_per_second = 0;
LOG("pulses per quarter note = %d\n", pulses);
}
/* Skip any remaining bytes in the MThd chunk */
if (fseek(pFile, (long) (length - 6), SEEK_CUR) != 0) return FALSE;
/* Keep reading chunks, looking for |"MTrk"| */
do {
/* Read chunk signature and length */
if (!BinaryFiles__read_int32(pFile, &sig)) {
if (feof(pFile)) return TRUE;
return FALSE;
}
if (!BinaryFiles__read_int32(pFile, &length)) return FALSE;
start_of_chunk_data = (unsigned int) ftell(pFile);
if (sig == 0x4D54726B) { /* |"MTrk"| */
LOG("track starts\n");
/* Read each event, looking for information before the real tune starts, e.g., tempo */
do {
/* Read the number of clocks since the previous event */
if (!BinaryFiles__read_variable_length_integer(pFile, &clocks))
return FALSE;
/* We bail out when the track starts */
if (clocks > 0) break;
/* Read the MIDI Status byte */
if (!BinaryFiles__read_int8(pFile, &status)) return FALSE;
/* Start or continuation of system exclusive data */
if ((status == 0xF0) || (status == 0xF7)) {
/* Read length of system exclusive event data */
if (!BinaryFiles__read_variable_length_integer(pFile, &sysex_length)) return FALSE;
/* Skip sysex event */
if (fseek(pFile, (long) sysex_length, SEEK_CUR) != 0) return FALSE;
} else if (status == 0xFF) { /* Non-MIDI event */
/* Read the Non-MIDI event type and length */
if (!BinaryFiles__read_int8(pFile, &non_midi_event)) return FALSE;
if (!BinaryFiles__read_variable_length_integer(pFile, &non_midi_event_length))
return FALSE;
start_of_non_midi_data = (unsigned int) ftell(pFile);
switch(non_midi_event) {
case 0x01: /* Comment text */
case 0x02: /* Copyright text */
case 0x03: /* Track name */
case 0x04: { /* Instrument name */
char text[257];
if (!BinaryFiles__read_string(pFile, text, non_midi_event_length))
return FALSE;
LOG("%d: %s\n", non_midi_event, text);
break;
}
case 0x51: /* Tempo change */
case 0x58: /* Time signature */
case 0x59: /* Key signature */
break;
}
/* Skip non-midi event */
if (fseek(pFile,
(long) (start_of_non_midi_data + non_midi_event_length), SEEK_SET) != 0)
return FALSE;
} else {
/* Real MIDI data found: we've read all we can so bail out at this point */
break;
}
}
while (TRUE);
}
/* Seek to start of next chunk */
if (fseek(pFile, (long) (start_of_chunk_data + length), SEEK_SET) != 0) return FALSE;
/* Reached end of file */
if (feof(pFile)) return TRUE;
/* Did we try to seek beyond the end of the file? */
unsigned int position_in_file = (unsigned int) ftell(pFile);
if (position_in_file < (start_of_chunk_data + length)) return TRUE;
}
while (TRUE);
return TRUE;
}
#line 104 "inform7/Chapter 4/HTML Files.w"
int source_link_case = 0;
void HTML__set_source_link_case(char *p) {
source_link_case = Platform__toupper(p[0]);
}
void HTML__html_source_link(OUTPUT_STREAM, source_location sl, int nonbreaking_space) {
if (sl.file_of_origin) {
char filename_buffer[MAX_FILENAME_LENGTH];
Filenames__to_string(filename_buffer, SourceFiles__get_filename(sl.file_of_origin));
char *fn = filename_buffer;
if (pathname_of_project) {
char bundle_name[MAX_FILENAME_LENGTH];
Pathnames__to_string(bundle_name, pathname_of_project);
if (strncmp(fn, bundle_name, (size_t) Platform__strlen(bundle_name)) == 0)
fn += Platform__strlen(bundle_name) + 1;
}
if ((strncmp(fn, "Source", 6)==0) && (fn[6]==FOLDER_SEPARATOR))
fn += 7;
if (nonbreaking_space) WRITE("&nbsp;"); else WRITE(" ");
WRITE("<a href=\"source:%s", fn);
if (source_link_case)
WRITE("?case=%c", source_link_case);
WRITE("#line%d\"><img border=0 src=inform:/doc_images/Reveal.%s></a>",
sl.line_number, ICON_EXT);
}
}
#line 132 "inform7/Chapter 4/HTML Files.w"
#line 139 "inform7/Chapter 4/HTML Files.w"
void HTML__html_icon_with_tooltip(OUTPUT_STREAM, char *icon_name, char *tip, char *tip2) {
WRITE("<img border=0 src=inform:/doc_images/%s ", icon_name);
if (tip) {
WRITE("title=\"%s", tip); if (tip2) WRITE(" %s", tip2); WRITE("\"");
}
WRITE(">");
}
#line 193 "inform7/Chapter 4/HTML Files.w"
int outcome_image_style = SIDE_OUTCOME_IMAGE_STYLE;
void HTML__html_outcome_image(OUTPUT_STREAM, char *image, char *verdict) {
char *vn = "";
int c, y, k, i, n, j, l, m, d;
int this_month = the_present->tm_mon + 1;
int this_day = the_present->tm_mday;
int this_year = the_present->tm_year + 1900;
y = this_year;
c = y/100;
n = y-19*(y/19);
k = (c-17)/25;
i = c-c/4-(c-k)/3+19*n+15;
i = i-30*(i/30);
i = i-(i/28)*(1-(i/28)*(29/(i+1))*((21-n)/11));
j = y+y/4+i+2-c+c/4;
j = j-7*(j/7);
l = i-j;
m = 3+(l+40)/44;
d = l+28-31*(m/4);
if ((this_month == m) && (this_day >= d-2) && (this_day <= d+1))
vn = "_3"; /* that is, Good Friday to Easter Monday */
if ((this_year == 2018) && (this_month == 3) && (this_day >= 30))
vn = "_3"; /* Easter Sunday falls on 1 April in 2018 */
if ((this_month == 12) && (this_day >= 25))
vn = "_2"; /* that is, Christmas Day to New Year's Eve */
if (internal_error_thrown) vn = "";
if (vn[0]) outcome_image_style = CENTRED_OUTCOME_IMAGE_STYLE;
Problems__Issue__issue_problems_banner(OUT, verdict);
switch (outcome_image_style) {
case CENTRED_OUTCOME_IMAGE_STYLE:
WRITE("<p><center><img src=inform:/outcome_images/%s%s.png border=0></center></p>",
image, vn);
break;
case SIDE_OUTCOME_IMAGE_STYLE:
HTML__begin_html_table(OUT, NULL, TRUE, 0, 4, 0, 0, 0); WRITE("\n"); INDENT;
HTML__first_html_column(OUT, 110); WRITE("\n"); INDENT;
WRITE("<img src=inform:/outcome_images/%s%s@2x.png "
"border=1 width=100 height=100>\n", image, vn);
OUTDENT; HTML__next_html_column(OUT, 0);
break;
}
WRITE("\n<!--HEADNOTE-->\n");
WRITE("<p style=\"margin-top:0;\">(Each time <b>Go</b> or <b>Replay</b> is clicked, Inform tries to "
"translate the source text into a working story, and updates this report.)</p>\n");
WRITE("<!--PROBLEMS BEGIN-->\n");
}
void HTML__outcome_image_tail(OUTPUT_STREAM) {
if (outcome_image_style == SIDE_OUTCOME_IMAGE_STYLE) {
WRITE("<!--PROBLEMS END-->\n");
HTML__end_html_row(OUT); WRITE("\n");
OUTDENT; HTML__end_html_table(OUT); WRITE("\n");
WRITE("\n<!--FOOTNOTE-->\n");
}
}
#line 267 "inform7/Chapter 4/HTML Files.w"
void HTML__html_header(OUTPUT_STREAM, char *title, char *thumbnail, char *caption) {
WRITE("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
"\"http://www.w3.org/TR/html4/loose.dtd\">\n");
WRITE("<html>\n<head><meta http-equiv=\"content-type\" ");
WRITE("content=\"text/html; charset=UTF-8\">\n"); INDENT;
WRITE("<style type=\"text/css\">\n");
WRITE("<!--\n"); INDENT;
WRITE("*, *:before, *:after {\n"); INDENT;
WRITE("-moz-box-sizing: border-box;\n");
WRITE("-webkit-box-sizing: border-box;\n");
WRITE("box-sizing: border-box;\n");
OUTDENT; WRITE("}\n");
WRITE("h3.tighter {\n"); INDENT;
WRITE("margin-top: 0px;\n");
OUTDENT; WRITE("}\n");
WRITE("p.hang {\n"); INDENT;
WRITE("padding-left: 25px;\n");
WRITE("text-indent: -25px;\n");
WRITE("margin-top: 0px;\n");
WRITE("margin-bottom: 0px;\n");
OUTDENT; WRITE("}\n");
int margin;
for (margin = 1; margin<=9; margin++) {
WRITE("p.in%d {\n", margin); INDENT;
WRITE("padding-left: %dpx;\n", (margin-1)*25);
OUTDENT; WRITE("}\n");
WRITE("p.tightin%d {\n", margin); INDENT;
WRITE("padding-left: %dpx;\n", (margin-1)*25);
WRITE("margin-top: 2px;\n");
WRITE("margin-bottom: 2px;\n");
OUTDENT; WRITE("}\n");
WRITE("p.halftightin%d {\n", margin); INDENT;
WRITE("padding-left: %dpx;\n", (margin-1)*25);
WRITE("margin-bottom: 2px;\n");
OUTDENT; WRITE("}\n");
WRITE("p.hangingin%d {\n", margin); INDENT;
WRITE("padding-left: %dpx;\n", (margin+1)*25);
WRITE("text-indent: -50px;\n");
WRITE("margin-top: 0px;\n");
WRITE("margin-bottom: 1px;\n");
OUTDENT; WRITE("}\n");
}
WRITE("div.hr {\n"); INDENT;
WRITE("border: 0;\n");
WRITE("width: 100%%;\n");
WRITE("color: #707070;\n");
WRITE("background-color: #707070;\n");
WRITE("height: 5px;\n");
OUTDENT; WRITE("}\n");
WRITE(".headingbox {\n");
WRITE(" position: relative;\n");
WRITE(" height: 56px;\n");
WRITE(" padding: 0px;\n");
WRITE(" white-space:nowrap;\n");
WRITE(" background: #eeeeee; /* grey */\n");
WRITE("font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Helvetica, Arial, Verdana, sans-serif;\n");
WRITE("-webkit-font-smoothing: antialiased;\n");
WRITE(" }\n");
WRITE(".headingboxhigh {\n");
WRITE(" position: relative;\n");
WRITE(" height: 117px;\n");
WRITE(" padding: 0px;\n");
WRITE(" white-space:nowrap;\n");
WRITE(" background: #eeeeee; /* grey */\n");
WRITE("font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Helvetica, Arial, Verdana, sans-serif;\n");
WRITE("-webkit-font-smoothing: antialiased;\n");
WRITE(" }\n");
WRITE(".headingboxSucceeded {\n");
WRITE(" position: relative;\n");
WRITE(" height: 56px;\n");
WRITE(" padding: 0px;\n");
WRITE(" white-space:nowrap;\n");
WRITE(" background: #E6FFE6; /* green */\n");
WRITE("font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Helvetica, Arial, Verdana, sans-serif;\n");
WRITE("-webkit-font-smoothing: antialiased;\n");
WRITE(" }\n");
WRITE(".headingboxFailed {\n");
WRITE(" position: relative;\n");
WRITE(" height: 56px;\n");
WRITE(" padding: 0px;\n");
WRITE(" white-space:nowrap;\n");
WRITE(" background: #f69Ca6; /* red */\n");
WRITE("font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Helvetica, Arial, Verdana, sans-serif;\n");
WRITE("-webkit-font-smoothing: antialiased;\n");
WRITE(" }\n");
WRITE(".headingtext {\n");
WRITE(" position: absolute;\n");
WRITE(" top: -4px;\n");
WRITE(" left: -1px;\n");
WRITE(" width: 100%%;\n");
WRITE(" color: #222222;\n");
WRITE(" padding: 14px 10px 0px 10px;\n");
WRITE(" font-size: 20px;\n");
WRITE(" font-weight: bold;\n");
WRITE("}\n");
WRITE(".headingrubric {\n");
WRITE(" position: absolute;\n");
WRITE(" top: 36px;\n");
WRITE(" width: 100%%;\n");
WRITE(" color: #222222;\n");
WRITE(" padding: 0px 10px 0px 10px;\n");
WRITE(" font-size: 11px;\n");
WRITE(" font-weight: bold;\n");
WRITE("}\n");
OUTDENT; WRITE("-->\n");
OUTDENT; WRITE("</style>\n");
WRITE("<script type=\"text/javascript\">\n"); INDENT;
WRITE("function project() {\n"); INDENT;
WRITE("if (\"Project\" in window) return window.Project;\n");
WRITE("return external.Project;\n");
WRITE("}\n");
WRITE("function showExtra(id, imid) {\n"); INDENT;
WRITE("if (document.getElementById(id).style.display == 'block') {\n"); INDENT;
WRITE("document.getElementById(id).style.display = 'none';\n");
WRITE("document.getElementById(imid).src = 'inform:/doc_images/extra.png';\n");
OUTDENT; WRITE("} else {\n"); INDENT;
WRITE("document.getElementById(id).style.display = 'block';\n");
WRITE("document.getElementById(imid).src = 'inform:/doc_images/extraclose.png';\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
WRITE("function showBasic(id) {\n"); INDENT;
WRITE("if (document.getElementById(id).style.display == '') {\n"); INDENT;
WRITE("document.getElementById(id).style.display = 'none';\n");
OUTDENT; WRITE("} else {\n"); INDENT;
WRITE("document.getElementById(id).style.display = '';\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
WRITE("function showResp(id, imid) {\n"); INDENT;
WRITE("if (document.getElementById(id)) {\n"); INDENT;
WRITE("if (document.getElementById(id).style.display == 'block') {\n"); INDENT;
WRITE("document.getElementById(id).style.display = 'none';\n");
WRITE("document.getElementById(imid).src = 'inform:/doc_images/responses.png';\n");
OUTDENT; WRITE("} else {\n"); INDENT;
WRITE("document.getElementById(id).style.display = 'block';\n");
WRITE("document.getElementById(imid).src = 'inform:/doc_images/responsesclose.png';\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
WRITE("function showAllResp() {\n"); INDENT;
WRITE("for (var i=0;i<%d;i++) {\n", NUMBER_CREATED(rule)); INDENT;
WRITE("showResp('extra'+(1000000+i), 'plus'+(1000000+i));\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("</script>\n");
Index__scripting();
OUTDENT; WRITE("</head>\n");
WRITE("<body>\n"); INDENT;
#ifdef JAVASCRIPT_MODEL_1
WRITE("<script language=\"JavaScript\">");
WRITE("function pasteCode(code) { ");
WRITE("var myProject = project(); ");
WRITE("myProject.selectView('source'); ");
WRITE("myProject.pasteCode(code); ");
WRITE("}");
WRITE("</script>\n");
#endif
WRITE("<font %s>\n", DEFAULT_HTML_FONT);
WRITE("<!--CONTENT BEGINS-->\n");
if (thumbnail) {
WRITE("<!--NAVIGATION BEGINS-->\n");
HTML__open_coloured_box(OUT, "e0e0e0", ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
HTML__begin_html_table(OUT, NULL, TRUE, 0, 0, 0, 0, 0);
HTML__first_html_column(OUT, 72);
WRITE("<img border=1 src=inform:/doc_images/%s title=\"%s\"> ", thumbnail, caption);
HTML__next_html_column(OUT, 0);
if (title[0]=='<') { /* used for a details page beneath the page titled thus */
WRITE("<h3 class=\"tighter\"><b>%s</b>: Detail view&nbsp;&nbsp;"
"<a href=../%s.html><font color=\"#002060\"><i>Back to full view</i></font></a></h3><p>",
title+1, title+1);
} else WRITE("<h3 class=\"tighter\"><b>%s</b></h3>", title);
WRITE("\n");
}
}
void HTML__html_header_complete(OUTPUT_STREAM, char *title, char *thumbnail) {
if (thumbnail) {
HTML__end_html_row(OUT); HTML__end_html_table(OUT);
HTML__close_coloured_box(OUT, "e0e0e0", ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
WRITE("</p><p>");
WRITE("\n<!--NAVIGATION ENDS-->\n");
}
}
void HTML__html_footer(OUTPUT_STREAM) {
WRITE("\n<!--CONTENT ENDS-->\n");
WRITE("</font>\n");
OUTDENT; WRITE("</body>\n</html>");
}
#line 459 "inform7/Chapter 4/HTML Files.w"
void HTML__open_para(OUTPUT_STREAM, int depth, char *class) {
int margin = depth;
if (margin < 1) internal_error("minimal HTML indentation is 1");
if (margin > 9) margin = 9;
WRITE("<p class=\"%sin%d\">", class, margin);
while (depth > 9) { depth--; WRITE("&nbsp;&nbsp;&nbsp;&nbsp;"); }
}
#line 470 "inform7/Chapter 4/HTML Files.w"
void HTML__test_html_paragraphs(void) {
int k;
char *text = "Jackdaws love my big sphinx of quartz, "
"jinxed wizards pluck ivy from my quilt.";
for (k=1; k<4; k++) {
HTML__open_para(ifl, k, ""); INDEX(text); INDEX("</p>");
}
for (k=1; k<4; k++) {
HTML__open_para(ifl, k, "tight"); INDEX(text); INDEX("</p>");
}
for (k=1; k<4; k++) {
HTML__open_para(ifl, k, "hanging"); INDEX(text); INDEX("</p>");
}
}
#line 514 "inform7/Chapter 4/HTML Files.w"
char source_ref_paraphrase[MAX_SOURCE_REF_LENGTH]; /* field 1 */
char source_ref_filename[MAX_SOURCE_REF_LENGTH]; /* field 2 */
char source_ref_line[MAX_SOURCE_REF_LENGTH]; /* field 3 */
int source_ref_field = 0; /* which field we are buffering */
int source_ref_marker = -1; /* write position in buffer, or |-1| if not buffering */
void HTML__html_char_out(OUTPUT_STREAM, char c) {
int charcode = (int) ((unsigned char) c);
if (source_ref_field >= 1) {
char *buffer = NULL;
switch (source_ref_field) {
case 1: buffer = source_ref_paraphrase; break;
case 2: buffer = source_ref_filename; break;
case 3: buffer = source_ref_line; break;
}
if (source_ref_marker >= MAX_SOURCE_REF_LENGTH)
internal_error("filenames too long in paths to source text");
if (c == SOURCE_REF_CHAR) {
buffer[source_ref_marker] = 0;
source_ref_marker = -1;
} else {
buffer[source_ref_marker++] = c;
return;
}
}
switch(c) {
case '"': WRITE("&quot;"); return;
case '<': WRITE("&lt;"); return;
case '>': WRITE("&gt;"); return;
case '&': WRITE("&amp;"); break;
case NEWLINE_IN_STRING: WRITE("<br>"); return;
case FORCE_NEW_PARA_CHAR: WRITE("</p><p class=\"in2\">");
HTML__html_icon_with_tooltip(OUT, "ornament_flower.png", NULL, NULL);
WRITE("&nbsp;"); return;
case SOURCE_REF_CHAR:
source_ref_field++; source_ref_marker = 0;
if (source_ref_field == 4) {
source_ref_field = 0; source_ref_marker = -1;
source_location sl;
sl.file_of_origin = SourceFiles__filename_to_source_file(source_ref_filename);
sl.line_number = atoi(source_ref_line);
HTML__html_source_link(OUT, sl, TRUE);
}
return;
default:
PUT(charcode);
return;
}
}
#line 568 "inform7/Chapter 4/HTML Files.w"
void HTML__begin_plain_html_table(OUTPUT_STREAM) {
HTML__begin_html_table(OUT, NULL, FALSE, 0, 0, 0, 0, 0);
}
void HTML__begin_wide_html_table(OUTPUT_STREAM) {
HTML__begin_html_table(OUT, NULL, TRUE, 0, 0, 0, 0, 0);
}
#line 581 "inform7/Chapter 4/HTML Files.w"
void HTML__begin_html_table(OUTPUT_STREAM, char *colour, int full_width,
int border, int cellspacing, int cellpadding, int height, int width) {
WRITE("<table border=\"%d\" cellspacing=\"%d\" cellpadding=\"%d\"",
border, cellspacing, cellpadding);
if (colour) {
if (*colour == '*') WRITE(" style=\"background-image:url('inform:/%s');\"", colour+1);
else WRITE(" bgcolor=\"%s\"", colour);
}
if (full_width) WRITE(" width=100%%");
if (width > 0) WRITE(" width=\"%d\"", width);
if (height > 0) WRITE(" height=\"%d\"", height);
WRITE(">");
}
void HTML__begin_html_table_bg(OUTPUT_STREAM, char *colour, int full_width,
int border, int cellspacing, int cellpadding, int height, int width, char *bg) {
WRITE("<table border=\"%d\" cellspacing=\"%d\" cellpadding=\"%d\"",
border, cellspacing, cellpadding);
if (bg) WRITE(" background=\"inform:/map_icons/%s\"", bg);
if (colour) WRITE(" bgcolor=\"%s\"", colour);
if (full_width) WRITE(" width=100%%");
if (width > 0) WRITE(" width=\"%d\"", width);
if (height > 0) WRITE(" height=\"%d\"", height);
WRITE(">");
}
void HTML__first_html_column(OUTPUT_STREAM, int width) {
WRITE("<tr><td align=\"left\" valign=\"top\"");
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__first_html_column_nowrap(OUTPUT_STREAM, int width, char *colour) {
if (colour) WRITE("<tr bgcolor=\"%s\">", colour); else WRITE("<tr>");
WRITE("<td style=\"white-space:nowrap;\" align=\"left\" valign=\"top\" height=\"20\"");
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__first_html_column_spaced(OUTPUT_STREAM, int width) {
WRITE("<tr><td style=\"padding-top: 3px;\" align=\"left\" valign=\"top\"");
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__first_html_column_coloured(OUTPUT_STREAM, int width, char *col, int cs) {
WRITE("<tr");
if (col) WRITE(" bgcolor=\"%s\"", col);
WRITE("><td nowrap=\"nowrap\" align=\"left\" valign=\"top\"");
if (width > 0) WRITE(" width=\"%d\"", width);
if (cs > 0) WRITE(" colspan=\"%d\"", cs);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__next_html_column(OUTPUT_STREAM, int width) {
WRITE("&nbsp;&nbsp;&nbsp;&nbsp;</font></td>"
"<td align=\"left\" valign=\"top\"");
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__next_html_column_centred(OUTPUT_STREAM, int width) {
WRITE("&nbsp;</font></td>"
"<td align=\"center\" valign=\"top\"");
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__next_html_column_spanning(OUTPUT_STREAM, int width, int sp) {
WRITE("&nbsp;&nbsp;&nbsp;&nbsp;</font></td>"
"<td align=\"left\" valign=\"top\" colspan=\"%d\"", sp);
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__next_html_column_nowrap(OUTPUT_STREAM, int width) {
WRITE("&nbsp;</font></td>"
"<td style=\"white-space:nowrap;\" align=\"left\" valign=\"top\"");
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__next_html_column_spaced(OUTPUT_STREAM, int width) {
WRITE("&nbsp;&nbsp;&nbsp;&nbsp;</font></td>"
"<td style=\"padding-top: 3px;\" align=\"left\" valign=\"top\"");
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__next_html_column_nw(OUTPUT_STREAM, int width) {
WRITE("&nbsp;</font></td>"
"<td nowrap=\"nowrap\" align=\"left\" valign=\"top\"");
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__next_html_column_w(OUTPUT_STREAM, int width) {
WRITE("&nbsp;</font></td><td align=\"left\" valign=\"top\"");
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__next_html_column_right_justified(OUTPUT_STREAM, int width) {
WRITE("</font></td><td align=\"right\" valign=\"top\"");
if (width > 0) WRITE(" width=\"%d\"", width);
WRITE("><font %s>", DEFAULT_HTML_FONT);
}
void HTML__end_html_row(OUTPUT_STREAM) {
WRITE("</font></td></tr>");
}
void HTML__end_html_table(OUTPUT_STREAM) {
WRITE("</table>");
}
#line 689 "inform7/Chapter 4/HTML Files.w"
void HTML__open_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) {
WRITE("<table width=\"100%%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" ");
WRITE("style=\"background-color: #%s\">", html_colour);
WRITE("<tr><td width=\"%d\">", CORNER_SIZE);
if (rounding & ROUND_BOX_TOP) HTML__box_corner(OUT, html_colour, "tl");
WRITE("</td><td></td>");
WRITE("<td width=\"%d\">", CORNER_SIZE);
if (rounding & ROUND_BOX_TOP) HTML__box_corner(OUT, html_colour, "tr");
WRITE("</td></tr>", html_colour);
WRITE("<tr><td width=\"%d\"></td><td>", CORNER_SIZE);
WRITE("<font %s>", DEFAULT_HTML_FONT);
}
void HTML__close_coloured_box(OUTPUT_STREAM, char *html_colour, int rounding) {
WRITE("</font></td><td width=\"%d\"></td></tr>", CORNER_SIZE);
WRITE("<tr><td width=\"%d\">", CORNER_SIZE);
if (rounding & ROUND_BOX_BOTTOM) HTML__box_corner(OUT, html_colour, "bl");
WRITE("</td><td></td>");
WRITE("<td width=\"%d\">", CORNER_SIZE);
if (rounding & ROUND_BOX_BOTTOM) HTML__box_corner(OUT, html_colour, "br");
WRITE("</td></tr>", html_colour);
WRITE("</table>");
}
void HTML__box_corner(OUTPUT_STREAM, char *html_colour, char *corner) {
WRITE("<img src=\"inform:/bg_images/%s_corner_%s.gif\" ", corner, html_colour);
WRITE("width=\"%d\" height=\"%d\" border=\"0\" alt=\"...\" />",
CORNER_SIZE, CORNER_SIZE);
}
#line 724 "inform7/Chapter 4/HTML Files.w"
void HTML__write_xml_safe_text(OUTPUT_STREAM, char *txt) {
int i, charcode;
for (i=0; txt[i]; i++) {
switch(txt[i]) {
case '&': WRITE("&amp;"); break;
case '<': WRITE("&lt;"); break;
case '>': WRITE("&gt;"); break;
default:
charcode = (int) ((unsigned char) txt[i]);
PUT(charcode);
break;
}
}
}
#line 748 "inform7/Chapter 4/HTML Files.w"
void HTML__compile_bibliographic_text(OUTPUT_STREAM, char *p) {
if (p == NULL) return;
if (TEST_COMPILATION_MODE(COMPILE_TEXT_TO_XML_CMODE))
{
#line 765 "inform7/Chapter 4/HTML Files.w"
int i = 0, i2 = Platform__strlen(p)-1, snl, wsc, charcode;
if ((p[0] == '"') && (p[i2] == '"')) { i++; i2--; } /* omit surrounding double-quotes */
while (HTML__is_babel_whitespace(p[i])) i++; /* omit leading whitespace */
while ((i2>=0) && (HTML__is_babel_whitespace(p[i2]))) i2--; /* omit trailing whitespace */
for (snl = FALSE, wsc = 0; i<=i2; i++) {
switch(p[i]) {
case ' ': case '\x0a': case '\x0d': case '\t':
snl = FALSE;
wsc++;
int k = i;
while ((p[k] == ' ') || (p[k] == '\x0a') || (p[k] == '\x0d') || (p[k] == '\t')) k++;
if ((wsc == 1) && (p[k] != NEWLINE_IN_STRING)) WRITE(" ");
break;
case NEWLINE_IN_STRING:
if (snl) break;
WRITE("<br/>");
snl = TRUE; wsc = 1; break;
case '[':
if ((p[i+1] == '\'') && (p[i+2] == ']')) {
i += 2;
WRITE("'"); break;
}
int n = CompiledText__expand_unisub(OUT, p, i);
if (n >= 0) { i = n; break; }
/* and otherwise fall through to the default case */
default:
snl = FALSE;
wsc = 0;
switch(p[i]) {
case '&': WRITE("&amp;"); break;
case '<': WRITE("&lt;"); break;
case '>': WRITE("&gt;"); break;
default:
charcode = (int) (((unsigned char *)p)[i]);
PUT(charcode);
break;
}
break;
}
}
return;
}
#line 751 "inform7/Chapter 4/HTML Files.w"
;
if (TEST_COMPILATION_MODE(TRUNCATE_TEXT_CMODE))
{
#line 893 "inform7/Chapter 4/HTML Files.w"
int i, pos = STREAM_EXTENT(OUT), whitespace_count=0, black_chars_written = 0, charcode;
if (p[0] == '"') p++;
for (i=0; p[i]; i++) {
if (STREAM_EXTENT(OUT) - pos >= BIBLIOGRAPHIC_TEXT_TRUNCATION) break;
if ((p[i] == '"') && (p[i+1] == 0)) break;
switch(p[i]) {
case ' ': case '\x0a': case '\x0d': case '\t': case NEWLINE_IN_STRING:
whitespace_count++;
if (whitespace_count == 1) PUT(' ');
break;
case '?': case '*':
if ((p[i+1]) && (p[i+1] != '\"')) PUT('-');
break;
default:
charcode = (int) (((unsigned char *)p)[i]);
{
#line 926 "inform7/Chapter 4/HTML Files.w"
charcode = HTML__iso_remove_accents(charcode);
}
#line 908 "inform7/Chapter 4/HTML Files.w"
;
whitespace_count = 0;
if (charcode < 128) {
PUT(charcode); black_chars_written++;
}
break;
}
}
if (black_chars_written == 0) WRITE("story");
return;
}
#line 753 "inform7/Chapter 4/HTML Files.w"
;
if (TEST_COMPILATION_MODE(COMPILE_TEXT_TO_I6_CMODE))
{
#line 848 "inform7/Chapter 4/HTML Files.w"
int i, whitespace_count=0, charcode;
if (p[0] == '"') p++;
for (i=0; p[i]; i++) {
if ((p[i] == '"') && (p[i+1] == 0)) break;
switch(p[i]) {
case ' ': case '\x0a': case '\x0d': case '\t': case NEWLINE_IN_STRING:
whitespace_count++;
if (whitespace_count == 1) PUT(' ');
break;
case '[':
if ((p[i+1] == '\'') && (p[i+2] == ']')) {
i += 2;
PUT('\''); break;
} /* and otherwise fall through to the default case */
default:
charcode = (int) (((unsigned char *)p)[i]);
whitespace_count = 0;
PUT(charcode);
break;
}
}
return;
}
#line 755 "inform7/Chapter 4/HTML Files.w"
{
#line 811 "inform7/Chapter 4/HTML Files.w"
int i, whitespace_count=0, charcode;
if (p[0] == '"') p++;
for (i=0; p[i]; i++) {
if ((p[i] == '"') && (p[i+1] == 0)) break;
switch(p[i]) {
case ' ': case '\x0a': case '\x0d': case '\t':
whitespace_count++;
if (whitespace_count == 1) PUT(' ');
break;
case NEWLINE_IN_STRING:
while (p[i+1] == NEWLINE_IN_STRING) i++;
PUT('<');
PUT('p');
PUT('>');
whitespace_count = 1;
break;
case '[':
if ((p[i+1] == '\'') && (p[i+2] == ']')) {
i += 2;
PUT('\''); break;
}
int n = CompiledText__expand_unisub(OUT, p, i);
if (n >= 0) { i = n; break; }
/* and otherwise fall through to the default case */
default:
charcode = (int) (((unsigned char *)p)[i]);
whitespace_count = 0;
PUT(charcode);
break;
}
}
return;
}
#line 756 "inform7/Chapter 4/HTML Files.w"
;
}
#line 932 "inform7/Chapter 4/HTML Files.w"
int HTML__iso_remove_accents(int charcode) {
if (charcode<0) charcode += 256; /* in case |char| is signed */
switch (charcode) {
case '/': case '\\': case ':': case '.': charcode = '-'; break;
case 0xC0: case 0xC1: case 0xC2: case 0xC3:
case 0xC4: case 0xC5: charcode = 'A'; break;
case 0xE0: case 0xE1: case 0xE2: case 0xE3:
case 0xE4: case 0xE5: charcode = 'a'; break;
case 0xC8: case 0xC9: case 0xCA: case 0xCB: charcode = 'E'; break;
case 0xE8: case 0xE9: case 0xEA: case 0xEB: charcode = 'e'; break;
case 0xCC: case 0xCD: case 0xCE: case 0xCF: charcode = 'I'; break;
case 0xEC: case 0xED: case 0xEE: case 0xEF: charcode = 'i'; break;
case 0xD2: case 0xD3: case 0xD4: case 0xD5:
case 0xD6: case 0xD8: charcode = 'O'; break;
case 0xF2: case 0xF3: case 0xF4: case 0xF5:
case 0xF6: case 0xF8: charcode = 'o'; break;
case 0xD9: case 0xDA: case 0xDB: case 0xDC: charcode = 'U'; break;
case 0xF9: case 0xFA: case 0xFB: case 0xFC: charcode = 'u'; break;
case 0xDD: charcode = 'Y'; break;
case 0xFD: charcode = 'y'; break;
case 0xD1: charcode = 'N'; break;
case 0xF1: charcode = 'n'; break;
case 0xC7: charcode = 'C'; break;
case 0xE7: charcode = 'c'; break;
case 0xDF: charcode = 's'; break;
}
if (charcode >= 128) charcode = '-';
return charcode;
}
#line 967 "inform7/Chapter 4/HTML Files.w"
int HTML__combining_accent(int accent, int letter) {
switch(accent) {
case 0x0300: /* Unicode combining grave */
switch(letter) {
case 'a': return 0xE0; case 'e': return 0xE8; case 'i': return 0xEC;
case 'o': return 0xF2; case 'u': return 0xF9;
case 'A': return 0xC0; case 'E': return 0xC8; case 'I': return 0xCC;
case 'O': return 0xD2; case 'U': return 0xD9;
}
break;
case 0x0301: /* Unicode combining acute */
switch(letter) {
case 'a': return 0xE1; case 'e': return 0xE9; case 'i': return 0xED;
case 'o': return 0xF3; case 'u': return 0xFA; case 'y': return 0xFF;
case 'A': return 0xC1; case 'E': return 0xC9; case 'I': return 0xCD;
case 'O': return 0xD3; case 'U': return 0xDA;
}
break;
case 0x0302: /* Unicode combining circumflex */
switch(letter) {
case 'a': return 0xE2; case 'e': return 0xEA; case 'i': return 0xEE;
case 'o': return 0xF4; case 'u': return 0xFB;
case 'A': return 0xC2; case 'E': return 0xCA; case 'I': return 0xCE;
case 'O': return 0xD4; case 'U': return 0xDB;
}
break;
case 0x0303: /* Unicode combining tilde */
switch(letter) {
case 'a': return 0xE3; case 'n': return 0xF1; case 'o': return 0xF5;
case 'A': return 0xC3; case 'N': return 0xD1; case 'O': return 0xD5;
}
break;
case 0x0308: /* Unicode combining diaeresis */
switch(letter) {
case 'a': return 0xE4; case 'e': return 0xEB; case 'u': return 0xFC;
case 'o': return 0xF6; case 'i': return 0xEF;
case 'A': return 0xC4; case 'E': return 0xCB; case 'U': return 0xDC;
case 'O': return 0xD6; case 'I': return 0xCF;
}
break;
case 0x0327: /* Unicode combining cedilla */
switch(letter) {
case 'c': return 0xE7; case 'C': return 0xC7;
}
break;
}
return '?';
}
#line 1020 "inform7/Chapter 4/HTML Files.w"
int HTML__without_accent(int letter) {
switch(letter) {
case 0xE0: return 'a'; case 0xE8: return 'e'; case 0xEC: return 'i';
case 0xF2: return 'o'; case 0xF9: return 'u';
case 0xC0: return 'A'; case 0xC8: return 'E'; case 0xCC: return 'I';
case 0xD2: return 'O'; case 0xD9: return 'U';
case 0xE1: return 'a'; case 0xE9: return 'e'; case 0xED: return 'i';
case 0xF3: return 'o'; case 0xFA: return 'u'; case 0xFF: return 'y';
case 0xC1: return 'A'; case 0xC9: return 'E'; case 0xCD: return 'I';
case 0xD3: return 'O'; case 0xDA: return 'U';
case 0xE2: return 'a'; case 0xEA: return 'e'; case 0xEE: return 'i';
case 0xF4: return 'o'; case 0xFB: return 'u';
case 0xC2: return 'A'; case 0xCA: return 'E'; case 0xCE: return 'I';
case 0xD4: return 'O'; case 0xDB: return 'U';
case 0xE3: return 'a'; case 0xF1: return 'n'; case 0xF5: return 'o';
case 0xC3: return 'A'; case 0xD1: return 'N'; case 0xD5: return 'O';
case 0xE4: return 'a'; case 0xEB: return 'e'; case 0xFC: return 'u';
case 0xC4: return 'A'; case 0xCB: return 'E'; case 0xDC: return 'U';
case 0xE7: return 'c'; case 0xC7: return 'C';
}
return letter;
}
#line 1048 "inform7/Chapter 4/HTML Files.w"
int HTML__is_babel_whitespace(char c) {
if ((c == ' ') || (c == '\t') || (c == '\x0a')
|| (c == '\x0d') || (c == NEWLINE_IN_STRING)) return TRUE;
return FALSE;
}
#line 1062 "inform7/Chapter 4/HTML Files.w"
colour_translation table_of_translations[] = {
{ "Alice Blue", "F0F8FF" },
{ "Antique White", "FAEBD7" },
{ "Aqua", "00FFFF" },
{ "Aquamarine", "7FFFD4" },
{ "Azure", "F0FFFF" },
{ "Beige", "F5F5DC" },
{ "Bisque", "FFE4C4" },
{ "Black", "000000" },
{ "Blanched Almond", "FFEBCD" },
{ "Blue", "0000FF" },
{ "Blue Violet", "8A2BE2" },
{ "Brown", "A52A2A" },
{ "Burly Wood", "DEB887" },
{ "Cadet Blue", "5F9EA0" },
{ "Chartreuse", "7FFF00" },
{ "Chocolate", "D2691E" },
{ "Coral", "FF7F50" },
{ "Cornflower Blue", "6495ED" },
{ "Cornsilk", "FFF8DC" },
{ "Crimson", "DC143C" },
{ "Cyan", "00FFFF" },
{ "Dark Blue", "00008B" },
{ "Dark Cyan", "008B8B" },
{ "Dark Golden Rod", "B8860B" },
{ "Dark Gray", "A9A9A9" },
{ "Dark Green", "006400" },
{ "Dark Khaki", "BDB76B" },
{ "Dark Magenta", "8B008B" },
{ "Dark Olive Green", "556B2F" },
{ "Dark Orange", "FF8C00" },
{ "Dark Orchid", "9932CC" },
{ "Dark Red", "8B0000" },
{ "Dark Salmon", "E9967A" },
{ "Dark Sea Green", "8FBC8F" },
{ "Dark Slate Blue", "483D8B" },
{ "Dark Slate Gray", "2F4F4F" },
{ "Dark Turquoise", "00CED1" },
{ "Dark Violet", "9400D3" },
{ "Deep Pink", "FF1493" },
{ "Deep Sky Blue", "00BFFF" },
{ "Dim Gray", "696969" },
{ "Dodger Blue", "1E90FF" },
{ "Feldspar", "D19275" },
{ "Fire Brick", "B22222" },
{ "Floral White", "FFFAF0" },
{ "Forest Green", "228B22" },
{ "Fuchsia", "FF00FF" },
{ "Gainsboro", "DCDCDC" },
{ "Ghost White", "F8F8FF" },
{ "Gold", "FFD700" },
{ "Golden Rod", "DAA520" },
{ "Gray", "808080" },
{ "Green", "008000" },
{ "Green Yellow", "ADFF2F" },
{ "Honey Dew", "F0FFF0" },
{ "Hot Pink", "FF69B4" },
{ "Indian Red", "CD5C5C" },
{ "Indigo", "4B0082" },
{ "Ivory", "FFFFF0" },
{ "Khaki", "F0E68C" },
{ "Lavender", "E6E6FA" },
{ "Lavender Blush", "FFF0F5" },
{ "Lawn Green", "7CFC00" },
{ "Lemon Chiffon", "FFFACD" },
{ "Light Blue", "ADD8E6" },
{ "Light Coral", "F08080" },
{ "Light Cyan", "E0FFFF" },
{ "Light Golden Rod Yellow", "FAFAD2" },
{ "Light Grey", "D3D3D3" },
{ "Light Green", "90EE90" },
{ "Light Pink", "FFB6C1" },
{ "Light Salmon", "FFA07A" },
{ "Light Sea Green", "20B2AA" },
{ "Light Sky Blue", "87CEFA" },
{ "Light Slate Blue", "8470FF" },
{ "Light Slate Gray", "778899" },
{ "Light Steel Blue", "B0C4DE" },
{ "Light Yellow", "FFFFE0" },
{ "Lime", "00FF00" },
{ "Lime Green", "32CD32" },
{ "Linen", "FAF0E6" },
{ "Magenta", "FF00FF" },
{ "Maroon", "800000" },
{ "Medium Aquamarine", "66CDAA" },
{ "Medium Blue", "0000CD" },
{ "Medium Orchid", "BA55D3" },
{ "Medium Purple", "9370D8" },
{ "Medium Sea Green", "3CB371" },
{ "Medium Slate Blue", "7B68EE" },
{ "Medium Spring Green", "00FA9A" },
{ "Medium Turquoise", "48D1CC" },
{ "Medium Violet Red", "PM_" },
{ "Midnight Blue", "191970" },
{ "Mint Cream", "F5FFFA" },
{ "Misty Rose", "FFE4E1" },
{ "Moccasin", "FFE4B5" },
{ "Navajo White", "FFDEAD" },
{ "Navy", "000080" },
{ "Old Lace", "FDF5E6" },
{ "Olive", "808000" },
{ "Olive Drab", "6B8E23" },
{ "Orange", "FFA500" },
{ "Orange Red", "FF4500" },
{ "Orchid", "DA70D6" },
{ "Pale Golden Rod", "EEE8AA" },
{ "Pale Green", "98FB98" },
{ "Pale Turquoise", "AFEEEE" },
{ "Pale Violet Red", "D87093" },
{ "Papaya Whip", "FFEFD5" },
{ "Peach Puff", "FFDAB9" },
{ "Peru", "CD853F" },
{ "Pink", "FFC0CB" },
{ "Plum", "DDA0DD" },
{ "Powder Blue", "B0E0E6" },
{ "Purple", "800080" },
{ "Red", "FF0000" },
{ "Rosy Brown", "BC8F8F" },
{ "Royal Blue", "4169E1" },
{ "Saddle Brown", "8B4513" },
{ "Salmon", "FA8072" },
{ "Sandy Brown", "F4A460" },
{ "Sea Green", "2E8B57" },
{ "Sea Shell", "FFF5EE" },
{ "Sienna", "A0522D" },
{ "Silver", "PM_C0C0" },
{ "Sky Blue", "87CEEB" },
{ "Slate Blue", "6A5ACD" },
{ "Slate Gray", "708090" },
{ "Snow", "FFFAFA" },
{ "Spring Green", "00FF7F" },
{ "Steel Blue", "4682B4" },
{ "Tan", "D2B48C" },
{ "Teal", "008080" },
{ "Thistle", "D8BFD8" },
{ "Tomato", "FF6347" },
{ "Turquoise", "40E0D0" },
{ "Violet", "EE82EE" },
{ "Violet Red", "D02090" },
{ "Wheat", "F5DEB3" },
{ "White", "FFFFFF" },
{ "White Smoke", "F5F5F5" },
{ "Yellow", "FFFF00" },
{ "Yellow Green", "9ACD32" },
{ "", "" }
};
#line 1214 "inform7/Chapter 4/HTML Files.w"
char *HTML__translate_colour_name(char *original) {
int j;
for (j=0; strcmp(table_of_translations[j].chip_name, ""); j++)
if (strcmp(table_of_translations[j].chip_name, original) == 0)
return table_of_translations[j].html_colour;
return NULL;
}
#line 92 "inform7/Chapter 4/Javascript Pastes.w"
int javascript_fn_counter = 1000;
void HTML__Javascript__paste_W(OUTPUT_STREAM, wording W) {
HTML__Javascript__paste_inner(OUT, Wordings__first_wn(W), Wordings__last_wn(W), NULL);
}
void HTML__Javascript__paste(OUTPUT_STREAM, char *alt_text) {
HTML__Javascript__paste_inner(OUT, -1, -1, alt_text);
}
void HTML__Javascript__paste_inner(OUTPUT_STREAM, int from, int to, char *alt_text) {
#ifdef JAVASCRIPT_MODEL_1 /* OS X style, with long function arguments allowed in links */
WRITE("<a href=\"javascript:pasteCode(");
HTML__Javascript__javascript_string_out(OUT, from, to, alt_text);
WRITE(")\"><img border=0 src=inform:/doc_images/paste.png></a>");
#endif
#ifdef JAVASCRIPT_MODEL_2 /* Windows style, with long function arguments in links unreliable */
WRITE("<script language=\"JavaScript\">\n");
WRITE("function pasteCode%d(code) {\n", javascript_fn_counter); INDENT;
WRITE("var myProject = project();\n\n");
WRITE("myProject.selectView('source');\n");
WRITE("myProject.pasteCode(");
OUTDENT; HTML__Javascript__javascript_string_out(OUT, from, to, alt_text);
WRITE(");\n");
WRITE("}\n");
WRITE("</script>\n");
WRITE("<a href=\"javascript:pasteCode%d()\">"
"<img border=0 src=inform:/doc_images/paste.png></a>",
javascript_fn_counter++);
#endif
}
#line 126 "inform7/Chapter 4/Javascript Pastes.w"
void HTML__Javascript__open_file(OUTPUT_STREAM, pathname *P, char *leaf, char *contents) {
char fn[MAX_FILENAME_LENGTH];
if (leaf) Filenames__to_string(fn, Filenames__in_folder(P, leaf));
else Pathnames__to_string(fn, P);
#ifdef JAVASCRIPT_MODEL_2
for (int i=0; fn[i]; i++)
if (fn[i] == '\\')
fn[i] = '/';
#endif
WRITE("<a href='javascript:project().openFile(\"%s\")'>%s</a>",
fn, contents);
}
#line 148 "inform7/Chapter 4/Javascript Pastes.w"
void HTML__Javascript__javascript_string_out(OUTPUT_STREAM, int from, int to, char *C_string) {
WRITE("'");
if (C_string)
{
#line 158 "inform7/Chapter 4/Javascript Pastes.w"
int i;
for (i=0; C_string[i]; i++)
HTML__Javascript__javascript_char_out(OUT, C_string[i]);
}
#line 150 "inform7/Chapter 4/Javascript Pastes.w"
;
if (from >= 0)
{
#line 185 "inform7/Chapter 4/Javascript Pastes.w"
int i, suppress_space = FALSE, follows_paragraph_break = FALSE;
int close_I6_position = -1;
for (i=from; i<=to; i++) {
int j;
char *p = Lexer__word_raw_text(i);
if (Lexer__word(i) == PARBREAK_V) { /* marker for a paragraph break */
HTML__Javascript__javascript_char_out(OUT, '\n');
HTML__Javascript__javascript_char_out(OUT, '\n');
suppress_space = TRUE;
follows_paragraph_break = TRUE;
while (Lexer__word(i) == PARBREAK_V) i++; i--; /* elide multiple breaks */
continue;
}
int indentation = Lexer__indentation_level(i);
if (indentation > 0) { /* number of tab stops of indentation on this para */
HTML__Javascript__javascript_char_out(OUT, '\n');
for (j=0; j<indentation-1; j++) HTML__Javascript__javascript_char_out(OUT, '\t');
suppress_space = TRUE;
}
if ((Lexer__break_before(i) == '\t') && (follows_paragraph_break == FALSE)) {
HTML__Javascript__javascript_char_out(OUT, '\t');
suppress_space = TRUE;
}
follows_paragraph_break = FALSE;
if (suppress_space==FALSE)
{
#line 223 "inform7/Chapter 4/Javascript Pastes.w"
if ((i>from)
&& ((p[1] != 0) || (Lexer__is_punctuation(p[0]) == FALSE) ||
(p[0] == '(') || (p[0] == '{') || (p[0] == '}'))
&& (compare_word(i-1, OPENBRACKET_V)==FALSE))
HTML__Javascript__javascript_char_out(OUT, ' ');
}
#line 210 "inform7/Chapter 4/Javascript Pastes.w"
;
suppress_space = FALSE;
for (j=0; p[j]; j++) HTML__Javascript__javascript_char_out(OUT, p[j]);
{
#line 238 "inform7/Chapter 4/Javascript Pastes.w"
if (Lexer__word(i) == OPENI6_V) close_I6_position = i+1;
if (close_I6_position == i) {
HTML__Javascript__javascript_char_out(OUT, '-');
HTML__Javascript__javascript_char_out(OUT, ')');
HTML__Javascript__javascript_char_out(OUT, ' ');
}
}
#line 213 "inform7/Chapter 4/Javascript Pastes.w"
;
}
HTML__Javascript__javascript_char_out(OUT, '\n');
HTML__Javascript__javascript_char_out(OUT, '\n');
}
#line 151 "inform7/Chapter 4/Javascript Pastes.w"
;
WRITE("'");
}
#line 253 "inform7/Chapter 4/Javascript Pastes.w"
void HTML__Javascript__javascript_char_out(OUTPUT_STREAM, char c) {
switch(c) {
case '\t': WRITE("[=0x0009=]"); return;
case '\n': case NEWLINE_IN_STRING: WRITE("[=0x000A=]"); return;
case '"': WRITE("[=0x0022=]"); return;
case '&': WRITE("[=0x0026=]"); return;
case '\'': WRITE("[=0x0027=]"); return;
case '<': WRITE("[=0x003C=]"); return;
case '>': WRITE("[=0x003E=]"); return;
case '\\': WRITE("[=0x005C=]"); return;
default: PUT(c); return;
}
}
#line 46 "inform7/Chapter 4/HTML Documentation.w"
void HTML__Documentation__href_of_example(OUTPUT_STREAM, char *base_leafname,
int to_example_variant, int to_example_anchor) {
int i;
for (i=0; base_leafname[i]; i++) {
if ((base_leafname[i] == '-') && (base_leafname[i+1] == 'e')
&& (base_leafname[i+2] == 'g') && (isdigit(base_leafname[i+3]))) break;
WRITE("%c", base_leafname[i]);
}
if (to_example_variant > 0) WRITE("-eg%d", to_example_variant);
WRITE(".html");
if (to_example_anchor > 0) WRITE("#eg%d", to_example_anchor);
}
#line 69 "inform7/Chapter 4/HTML Documentation.w"
int extension_documentation_heading_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 72 "inform7/Chapter 4/HTML Documentation.w"
#line 76 "inform7/Chapter 4/HTML Documentation.w"
int HTML__Documentation__extension_documentation_heading(wording W, int *level, wording *HW) {
if (Preform__parse_nt_against_word_range(extension_documentation_heading_NTM, W, NULL, NULL)) {
if (Wordings__length(W) > 10) return FALSE; /* not enough space: this runs into the end-of-file padding */
*level = most_recent_result;
W = Wordings__trim_first_word(Wordings__trim_first_word(W));
int end = Wordings__first_wn(W);
while ((end<=Wordings__last_wn(W)) && (Lexer__word(end) != PARBREAK_V)) end++;
end--;
*HW = Wordings__up_to(W, end);
return TRUE;
}
return FALSE;
}
#line 99 "inform7/Chapter 4/HTML Documentation.w"
int extension_example_header_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 102 "inform7/Chapter 4/HTML Documentation.w"
int row_of_asterisks_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 3;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 4;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 108 "inform7/Chapter 4/HTML Documentation.w"
#line 112 "inform7/Chapter 4/HTML Documentation.w"
int HTML__Documentation__extension_documentation_example(wording W,
int *asterisks, wording *egn, wording *egr) {
if (Wordings__length(W) > 10) return FALSE; /* not enough space: this runs into the end-of-file padding */
if (Preform__parse_nt_against_word_range(extension_example_header_NTM, W, NULL, NULL)) {
wording NW = GET_RW(extension_example_header_NTM, 1);
wording RW = Wordings__first_word(GET_RW(extension_example_header_NTM, 2));
int r2 = Wordings__first_wn(RW);
while ((r2 <= Wordings__last_wn(W)) && ((Lexer__word(r2) == PARBREAK_V) == FALSE)) r2++;
if (r2 >= Wordings__last_wn(W)) return FALSE;
r2--;
/* a successful match has now been made */
*asterisks = most_recent_result; *egn = NW; *egr = RW;
return TRUE;
}
return FALSE;
}
#line 148 "inform7/Chapter 4/HTML Documentation.w"
void HTML__Documentation__set_table_of_contents(wording W, OUTPUT_STREAM, char *base_leafname) {
int heading_count = 0, chapter_count = 0, section_count = 0, example_count = 0;
LOOP_THROUGH_WORDING(i, W) {
int edhl, asterisks;
wording NW = EMPTY_WORDING, RUBW = EMPTY_WORDING;
if (Lexer__word(i) == PARBREAK_V) { /* the lexer records this to mean a paragraph break */
while (Lexer__word(i) == PARBREAK_V) i++; if (i>Wordings__last_wn(W)) break;
if (HTML__Documentation__extension_documentation_heading(Wordings__from(W, i), &edhl, &NW)) {
heading_count++;
if (heading_count == 1) WRITE("<p><hr><p>"); /* ruled line at top of TOC */
if (edhl == 1) {
chapter_count++; section_count = 0;
if (chapter_count > 1) WRITE("<br>"); /* skip a line between chapters in TOC */
}
if (edhl == 2) section_count++;
{
#line 188 "inform7/Chapter 4/HTML Documentation.w"
char *html_to_close = NULL;
switch (edhl) {
case 1:
WRITE("<b><a %s href=#docsec%d>%sChapter %d: ",
EDOC_TOC_LINK_STYLE, heading_count, EDOC_TOC_LINK_FONT, chapter_count);
html_to_close = "</font></a></b>";
break;
case 2:
if (chapter_count > 0) /* if there are chapters as well as sections... */
WRITE("&nbsp;&nbsp;&nbsp;"); /* ...then set an indentation before entry */
WRITE("<a %s href=#docsec%d>%sSection ",
EDOC_TOC_LINK_STYLE, heading_count, EDOC_TOC_LINK_FONT);
if (chapter_count > 0) /* if there are chapters as well as sections... */
WRITE("%d.%d: ", chapter_count, section_count); /* quote in form S.C */
else
WRITE("%d: ", section_count); /* otherwise quote section number only */
html_to_close = "</font></a>";
break;
default: internal_error("unable to set this heading level in extension TOC");
}
HTML__Documentation__set_body_text(NW, OUT, EDOC_FRAGMENT_ONLY, NULL);
WRITE("%s<br>\n", html_to_close);
}
#line 163 "inform7/Chapter 4/HTML Documentation.w"
;
i = Wordings__last_wn(NW); continue;
}
if ((heading_count > 0) && (example_count < 26) &&
(HTML__Documentation__extension_documentation_example(
Wordings__from(W, i), &asterisks, &NW, &RUBW))) {
if (++example_count == 1) WRITE("<br><b>Examples</b><br>");
{
#line 217 "inform7/Chapter 4/HTML Documentation.w"
WRITE("&nbsp;&nbsp;&nbsp;"); /* always indent TOC entries for examples */
WRITE("<a %s href=\"", EDOC_TOC_LINK_STYLE);
HTML__Documentation__href_of_example(OUT, base_leafname, example_count, example_count);
WRITE("\">%s%c: ", EDOC_TOC_LINK_FONT, 'A'+example_count-1); /* the letter A to Z */
HTML__Documentation__set_body_text(NW, OUT, EDOC_FRAGMENT_ONLY, NULL);
WRITE("</font></a><br>");
}
#line 170 "inform7/Chapter 4/HTML Documentation.w"
;
i = Wordings__last_wn(RUBW); continue;
}
}
}
if (heading_count > 0)
WRITE("<p><hr><p>"); /* ruled line at foot of TOC, if there is one */
}
#line 230 "inform7/Chapter 4/HTML Documentation.w"
int HTML__Documentation__set_body_text(wording W, OUTPUT_STREAM,
int example_which_is_open, char *base_leafname) {
int heading_count = 0, chapter_count = 0, section_count = 0, example_count = 0;
int mid_example = FALSE, skipping_text_of_an_example = FALSE,
start_table_next_line = FALSE, mid_I7_table = FALSE, row_of_table_is_empty = FALSE,
mid_displayed_source_text = FALSE, indentation = 0, close_I6_position = -1;
LOOP_THROUGH_WORDING(i, W) {
int edhl, asterisks;
wording NW = EMPTY_WORDING, RUBW = EMPTY_WORDING;
if (Lexer__word(i) == PARBREAK_V) { /* the lexer records this to mean a paragraph break */
{
#line 285 "inform7/Chapter 4/HTML Documentation.w"
if (mid_displayed_source_text) {
WRITE("</font>");
if (mid_I7_table)
{
#line 511 "inform7/Chapter 4/HTML Documentation.w"
HTML__end_html_row(OUT);
HTML__end_html_table(OUT);
}
#line 287 "inform7/Chapter 4/HTML Documentation.w"
;
WRITE("</blockquote>");
}
WRITE("\n<p>\n");
mid_displayed_source_text = FALSE; mid_I7_table = FALSE;
}
#line 240 "inform7/Chapter 4/HTML Documentation.w"
;
while (Lexer__word(i) == PARBREAK_V) i++;
if (i>Wordings__last_wn(W)) break; /* treat multiple paragraph breaks as one */
{
#line 301 "inform7/Chapter 4/HTML Documentation.w"
indentation = 0; if (Lexer__break_before(i) == '\t') indentation = 1;
}
#line 243 "inform7/Chapter 4/HTML Documentation.w"
;
if (HTML__Documentation__extension_documentation_heading(Wordings__from(W, i), &edhl, &NW)) {
heading_count++;
if (edhl == 1) {
chapter_count++; section_count = 0;
if (chapter_count > 1) WRITE("<p><hr>"); /* rule a line between chapters */
}
if (edhl == 2) section_count++;
{
#line 403 "inform7/Chapter 4/HTML Documentation.w"
switch (edhl) {
case 1:
WRITE("<p><a name=docsec%d><b>%sChapter %d: ",
heading_count, EDOC_TOC_C_HEAD_FONT, chapter_count);
break;
case 2:
WRITE("<p><a name=docsec%d><b>%sSection ",
heading_count, EDOC_TOC_S_HEAD_FONT);
if (chapter_count > 0) WRITE("%d.", chapter_count);
WRITE("%d: ", section_count);
break;
}
HTML__Documentation__set_body_text(NW, OUT, EDOC_FRAGMENT_ONLY, NULL);
WRITE("</b></font>");
}
#line 251 "inform7/Chapter 4/HTML Documentation.w"
;
i = Wordings__last_wn(NW); continue;
}
if ((example_count < 26) && (HTML__Documentation__extension_documentation_example(
Wordings__from(W, i), &asterisks, &NW, &RUBW))) {
skipping_text_of_an_example = FALSE;
if (mid_example)
{
#line 528 "inform7/Chapter 4/HTML Documentation.w"
HTML__end_html_row(OUT);
HTML__end_html_table(OUT);
WRITE("<p>");
}
#line 257 "inform7/Chapter 4/HTML Documentation.w"
;
mid_example = FALSE;
example_count++;
{
#line 425 "inform7/Chapter 4/HTML Documentation.w"
WRITE("<hr><p>"); /* rule a line before the example heading */
WRITE("<a name=eg%d>", example_count); /* provide the anchor point */
HTML__begin_plain_html_table(OUT);
WRITE("<tr>");
/* Left hand cell: the oval icon */
WRITE("<td halign=\"left\" valign=\"top\" cellpadding=0 cellspacing=0 width=38px>");
{
#line 461 "inform7/Chapter 4/HTML Documentation.w"
HTML__begin_plain_html_table(OUT);
WRITE("<tr class=\"oval\"><td width=38px height=30px align=\"left\" valign=\"center\">");
{
#line 475 "inform7/Chapter 4/HTML Documentation.w"
WRITE("<a href=\"");
if (example_count == example_which_is_open) /* this example currently open */
HTML__Documentation__href_of_example(OUT, base_leafname, EDOC_ALL_EXAMPLES_CLOSED, example_count);
else /* this example not yet open */
HTML__Documentation__href_of_example(OUT, base_leafname, example_count, example_count);
WRITE("\" STYLE=\"text-decoration: none\">");
}
#line 463 "inform7/Chapter 4/HTML Documentation.w"
;
WRITE("<div class=\"paragraph Body\" style=\"line-height: 1px; margin-bottom: 0px; "
"margin-top: 0px; padding-bottom: 0pt; padding-top: 0px; text-align: center; "
"color: #202020; font-size: 14px; line-height: 1px;\"><b>%c</b></div>",
'A' + example_count - 1);
WRITE("</a></td></tr>");
HTML__end_html_table(OUT);
}
#line 432 "inform7/Chapter 4/HTML Documentation.w"
;
WRITE("</td>");
/* Right hand cell: the asterisks and title, with rubric underneath */
WRITE("<td cellpadding=0 cellspacing=0 halign=\"left\" valign=\"top\"><font %s>",
DEFAULT_HTML_FONT);
{
#line 475 "inform7/Chapter 4/HTML Documentation.w"
WRITE("<a href=\"");
if (example_count == example_which_is_open) /* this example currently open */
HTML__Documentation__href_of_example(OUT, base_leafname, EDOC_ALL_EXAMPLES_CLOSED, example_count);
else /* this example not yet open */
HTML__Documentation__href_of_example(OUT, base_leafname, example_count, example_count);
WRITE("\" STYLE=\"text-decoration: none\">");
}
#line 438 "inform7/Chapter 4/HTML Documentation.w"
;
while (asterisks-- > 0)
WRITE("<img border=\"0\" src='inform:/doc_images/asterisk.png'>");
WRITE("<b><font color=\"#505050\">&nbsp;Example&nbsp;</font> <font color=\"#000000\">");
HTML__Documentation__set_body_text(NW, OUT, EDOC_FRAGMENT_ONLY, base_leafname);
WRITE("</font></b></a>"); /* end the textual link */
WRITE("<br>");
HTML__Documentation__set_body_text(RUBW, OUT, EDOC_FRAGMENT_ONLY, base_leafname);
WRITE("<p>");
WRITE("</td></tr>");
HTML__end_html_table(OUT);
WRITE("<p>");
}
#line 260 "inform7/Chapter 4/HTML Documentation.w"
;
if (example_count == example_which_is_open) {
{
#line 521 "inform7/Chapter 4/HTML Documentation.w"
HTML__begin_html_table(OUT, "#f0f0f0", TRUE, 0, 0, 0, 0, 0);
HTML__first_html_column(OUT, 0);
WRITE("<p>");
}
#line 262 "inform7/Chapter 4/HTML Documentation.w"
;
mid_example = TRUE;
} else skipping_text_of_an_example = TRUE;
i = Wordings__last_wn(RUBW); continue;
}
}
if (skipping_text_of_an_example) continue;
{
#line 316 "inform7/Chapter 4/HTML Documentation.w"
if (Lexer__indentation_level(i) > 0) indentation = Lexer__indentation_level(i);
if (indentation > 0)
{
#line 372 "inform7/Chapter 4/HTML Documentation.w"
int j;
if (mid_displayed_source_text) {
if (start_table_next_line) {
start_table_next_line = FALSE;
mid_I7_table = TRUE;
{
#line 487 "inform7/Chapter 4/HTML Documentation.w"
WRITE("</font><br>");
HTML__begin_plain_html_table(OUT);
HTML__first_html_column(OUT, 0);
}
#line 377 "inform7/Chapter 4/HTML Documentation.w"
;
} else {
if (mid_I7_table)
{
#line 505 "inform7/Chapter 4/HTML Documentation.w"
HTML__end_html_row(OUT);
HTML__first_html_column(OUT, 0);
}
#line 379 "inform7/Chapter 4/HTML Documentation.w"
else WRITE("<br>");
}
if (mid_I7_table) row_of_table_is_empty = TRUE;
} else {
WRITE("<blockquote><font color=\"#000080\">");
mid_displayed_source_text = TRUE;
if ((Preform__parse_nt_against_word_range(structural_sentence_NTM, Wordings__from(W, i), NULL, NULL)) && (ssnt == TABLE_NT))
start_table_next_line = TRUE;
}
indentation--;
for (j=0; j<indentation; j++) WRITE("&nbsp;&nbsp;&nbsp;&nbsp;");
}
#line 318 "inform7/Chapter 4/HTML Documentation.w"
;
if (Preform__parse_nt_against_word_range(extension_documentation_paste_marker_NTM, Wordings__from(W, i), NULL, NULL)) {
wording W = GET_RW(extension_documentation_paste_marker_NTM, 1);
{
#line 353 "inform7/Chapter 4/HTML Documentation.w"
int x = i+2, y = Wordings__last_wn(W), j;
for (j=x; j<=y; j++) /* first find the end of the quoted passage */
if (Lexer__word(j) == PARBREAK_V) {
int possible_end = j-1;
while (Lexer__word(j) == PARBREAK_V) j++;
if ((j<y) && ((Lexer__break_before(j) == '\t') || (Lexer__indentation_level(j) > 0))) continue;
y = possible_end; break;
}
HTML__Javascript__paste_W(OUT, Wordings__new(x, y));
}
#line 321 "inform7/Chapter 4/HTML Documentation.w"
;
i++; continue;
}
indentation = 0;
if ((mid_I7_table) && ((Lexer__break_before(i) == '\t') || (Lexer__indentation_level(i) == 1))) {
if (row_of_table_is_empty == FALSE)
{
#line 494 "inform7/Chapter 4/HTML Documentation.w"
WRITE("</font>");
HTML__next_html_column(OUT, 0);
}
#line 327 "inform7/Chapter 4/HTML Documentation.w"
;
{
#line 500 "inform7/Chapter 4/HTML Documentation.w"
WRITE("<font color=\"#000080\">");
}
#line 328 "inform7/Chapter 4/HTML Documentation.w"
;
row_of_table_is_empty = FALSE;
}
}
#line 270 "inform7/Chapter 4/HTML Documentation.w"
;
{
#line 335 "inform7/Chapter 4/HTML Documentation.w"
char *p = Lexer__word_raw_text(i); int j;
if ((i>Wordings__first_wn(W))
&& ((p[1] != 0) || (Lexer__is_punctuation(p[0]) == FALSE)
|| (p[0] == '(') || (p[0] == '{') || (p[0] == '}'))
&& (compare_word(i-1, OPENBRACKET_V)==FALSE))
WRITE(" "); /* restore normal spacing around punctuation */
for (j=0; p[j]; j++) HTML__html_char_out(OUT, p[j]); /* set the actual word */
if (Lexer__word(i) == OPENI6_V) close_I6_position = i+1; /* ensure I6 literals are closed */
}
#line 271 "inform7/Chapter 4/HTML Documentation.w"
;
if (close_I6_position == i) WRITE(" -)");
}
if (mid_example)
{
#line 528 "inform7/Chapter 4/HTML Documentation.w"
HTML__end_html_row(OUT);
HTML__end_html_table(OUT);
WRITE("<p>");
}
#line 274 "inform7/Chapter 4/HTML Documentation.w"
;
if (example_which_is_open != EDOC_FRAGMENT_ONLY)
{
#line 285 "inform7/Chapter 4/HTML Documentation.w"
if (mid_displayed_source_text) {
WRITE("</font>");
if (mid_I7_table)
{
#line 511 "inform7/Chapter 4/HTML Documentation.w"
HTML__end_html_row(OUT);
HTML__end_html_table(OUT);
}
#line 287 "inform7/Chapter 4/HTML Documentation.w"
;
WRITE("</blockquote>");
}
WRITE("\n<p>\n");
mid_displayed_source_text = FALSE; mid_I7_table = FALSE;
}
#line 275 "inform7/Chapter 4/HTML Documentation.w"
;
return example_count;
}
#line 307 "inform7/Chapter 4/HTML Documentation.w"
int extension_documentation_paste_marker_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 309 "inform7/Chapter 4/HTML Documentation.w"
#line 53 "inform7/Chapter 5/Index File Services.w"
char current_thumbnail_image[MAX_FILENAME_LENGTH];
char current_thumbnail_caption[MAX_FILENAME_LENGTH];
int cti_set = FALSE;
void Index__set_thumbnail_image(char *image, char *caption) {
cti_set = TRUE;
strcpy(current_thumbnail_image, image);
strcpy(current_thumbnail_caption, caption);
}
index_page *current_index_page = NULL;
void Index__new_page(char *col) {
current_index_page = CREATE(index_page);
current_index_page->no_elements = 0;
int i, piece = 1, from = 0;
for (i=0; col[i]; i++) {
if ((piece == 2) && (col[i] == ' ')) {
col[i] = 0;
strcpy(current_index_page->page_leafname, col+from);
col[i] = ' ';
}
if (col[i] == '=') {
col[i] = 0;
switch (piece++) {
case 1:
if (i > 6) internal_error("colour for index page too long");
strcpy(current_index_page->key_colour, col);
from = i+1;
break;
case 2:
strcpy(current_index_page->page_title, col+from);
from = i+1;
break;
}
}
}
strcpy(current_index_page->page_explanation, col+from);
}
void Index__new_segment(char *abb, char *title, char *explanation) {
if (current_index_page == NULL)
internal_error("template creates index elements improperly");
if (Platform__strlen(abb) > 2)
internal_error("abbreviation for index element too long");
if (Platform__strlen(title) > 16)
internal_error("name for index element too long");
if (Platform__strlen(explanation) > MAX_FILENAME_LENGTH-1)
internal_error("explanation for index element too long");
index_element *ie = CREATE(index_element);
ie->owning_page = current_index_page;
ie->atomic_number = ++(current_index_page->no_elements);
strcpy(ie->chemical_symbol, abb);
strcpy(ie->element_name, title);
strcpy(ie->explanatory_note, explanation);
}
int index_file_counter = 0;
void Index__open_file(char *index_leaf, char *title, int sub, char *explanation) {
filename *F = Locations__in_index(index_leaf, sub);
if (ifl) Index__close_index_file();
if (STREAM_OPEN_TO_FILE(&index_file_struct, F, UTF8_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open index file", F);
ifl = &index_file_struct;
{
#line 138 "inform7/Chapter 5/Index File Services.w"
index_page *ip;
LOOP_OVER(ip, index_page)
if (ip->allocation_id == index_file_counter) {
current_index_page = ip; break;
}
}
#line 118 "inform7/Chapter 5/Index File Services.w"
;
cti_set = FALSE;
HTML__html_header(ifl, title,
(cti_set)?current_thumbnail_image:NULL,
(cti_set)?current_thumbnail_caption:NULL);
index_file_counter++;
if (title[0] == '<') {
Index__index_banner_line(1, "^", "Details",
"A single action in detail.|About the action rulebooks<ARSUMMARY>", "../Actions.html");
INDEX("<hr>");
} else
{
#line 181 "inform7/Chapter 5/Index File Services.w"
int max_elements = 0;
index_page *ip;
LOOP_OVER(ip, index_page)
if (max_elements < ip->no_elements)
max_elements = ip->no_elements;
INDEX("<div id=\"periodictable\">\n");
INDEX("<table cellspacing=\"3\" border=\"0\" width=\"100%%\">\n");
if (strcmp(index_leaf, "Welcome.html") == 0)
{
#line 206 "inform7/Chapter 5/Index File Services.w"
INDEX("<tr id=\"surround0\"><td></td><td colspan=\"2\">");
INDEX("<img src='inform:/doc_images/index@2x.png' border=1 width=115 height=115></td>");
INDEX("<td colspan=\"%d\" style=\"width:100%%;\">\n", max_elements - 1);
INDEX("<div class=\"headingboxhigh\">\n");
INDEX(" <div class=\"headingtext\">%s</div>\n", "Welcome to the Index");
INDEX(" <div class=\"headingrubric\">%s</div>\n",
"A guide which grows with your project");
INDEX("</div></td>\n");
INDEX("</tr>");
}
#line 190 "inform7/Chapter 5/Index File Services.w"
;
LOOP_OVER(ip, index_page)
if (((strcmp(index_leaf, "Welcome.html") == 0) || (ip == current_index_page)) &&
(strcmp(ip->page_leafname, "Welcome") != 0)) {
{
#line 219 "inform7/Chapter 5/Index File Services.w"
if (strcmp(index_leaf, "Welcome.html") == 0) {
INDEX("<tr>");
INDEX("<td onclick=\"window.location='%s.html'; return false;\">",
ip->page_leafname);
INDEX("<div class=\"sidebar\"></div></td>");
} else {
INDEX("<tr id=\"surround%d\">", ip->allocation_id+1);
INDEX("<td onclick=\"window.location='Welcome.html'; return false;\">");
INDEX("<div class=\"sidebar\"></div></td>");
}
}
#line 194 "inform7/Chapter 5/Index File Services.w"
;
index_element *ie;
LOOP_OVER(ie, index_element)
if (ie->owning_page == ip)
{
#line 233 "inform7/Chapter 5/Index File Services.w"
if (ip == current_index_page) {
INDEX("<td onclick=\"click_element_box('segment%d'); return false;\">",
ie->atomic_number);
} else {
INDEX("<td onclick=\"window.location='%s.html?segment%d'; return false;\">",
ip->page_leafname, ie->atomic_number);
}
INDEX("<div id=\"box%d_%d\" class=\"box\">\n", ip->allocation_id+1, ie->atomic_number);
INDEX("<a class=\"symbol\" title=\"%s\" ", ie->element_name);
INDEX("href=\"#\">%s</a>\n", ie->chemical_symbol);
INDEX("<div class=\"indexno\">%d</div>\n", ie->atomic_number);
INDEX("<div class=\"rubric\">%s</div>\n", ie->element_name);
INDEX("</div>\n");
INDEX("</td>");
}
#line 198 "inform7/Chapter 5/Index File Services.w"
;
{
#line 251 "inform7/Chapter 5/Index File Services.w"
if (ip == current_index_page) {
INDEX("<td onclick=\"show_all_elements(); return false;\" ");
} else {
INDEX("<td onclick=\"window.location='%s.html'; return false;\" ",
ip->page_leafname);
}
if (ip->no_elements < max_elements)
INDEX("colspan=\"%d\" ", max_elements - ip->no_elements + 1);
INDEX("style=\"width:100%%\">\n");
INDEX("<div class=\"headingbox\">\n");
INDEX(" <div class=\"headingtext\">%s</div>\n", ip->page_title);
INDEX(" <div class=\"headingrubric\">%s</div>\n", ip->page_explanation);
INDEX("</div></td>\n");
INDEX("</tr>");
}
#line 199 "inform7/Chapter 5/Index File Services.w"
;
}
INDEX("</table></div>");
}
#line 129 "inform7/Chapter 5/Index File Services.w"
;
indexing_stage = TRUE;
if ((title[0] != '<') && (strcmp(index_leaf, "Welcome.html") != 0))
{
#line 272 "inform7/Chapter 5/Index File Services.w"
index_element *ie;
LOOP_OVER(ie, index_element)
if (ie->owning_page == current_index_page) {
INDEX("<div id=\"segment%d\">\n", ie->atomic_number);
INDEX("<hr>");
Index__index_banner_line(ie->atomic_number, ie->chemical_symbol,
ie->element_name, ie->explanatory_note, NULL);
index_page *save_ip = current_index_page;
Index__index_actual_element(ie->chemical_symbol);
current_index_page = save_ip;
INDEX("</div>\n");
}
INDEX("<hr>\n");
}
#line 132 "inform7/Chapter 5/Index File Services.w"
;
}
#line 290 "inform7/Chapter 5/Index File Services.w"
void Index__index_banner_line(int N, char *sym, char *name, char *exp, char *link) {
INDEX("<table cellspacing=\"3\" border=\"0\" style=\"background:#eeeeee;\"><tr>\n");
{
#line 300 "inform7/Chapter 5/Index File Services.w"
INDEX("<td valign=\"top\" align=\"left\">\n");
INDEX("<div id=\"minibox%d_%d\" class=\"smallbox\">\n",
current_index_page->allocation_id+1, N);
INDEX("<a class=\"symbol\" title=\"%s\" ", name);
if (link) INDEX("href=\"%s\"", link);
else INDEX("href=\"#\" onclick=\"click_element_box('segment%d'); return false;\"", N);
INDEX(">%s</a>\n", sym);
INDEX("<div class=\"indexno\">%d</div>\n", N);
INDEX("</div>\n");
INDEX("</td>\n");
}
#line 292 "inform7/Chapter 5/Index File Services.w"
;
{
#line 314 "inform7/Chapter 5/Index File Services.w"
INDEX("<td style=\"width:100%%;\" align=\"left\" valign=\"top\">\n");
INDEX("<p style=\"margin-top:0px;padding-top:0px;");
INDEX("margin-bottom:0px;padding-bottom:0px;line-height:150%%;\"><b>%s</b> &mdash; \n", name);
Index__explain(exp);
INDEX("</p>\n");
INDEX("</td>\n");
}
#line 293 "inform7/Chapter 5/Index File Services.w"
;
INDEX("</tr></table>\n");
}
#line 324 "inform7/Chapter 5/Index File Services.w"
void Index__scripting(void) {
if (current_index_page == NULL) return;
INDEX("<style type=\"text/css\" media=\"screen, print\">\n");
{
#line 353 "inform7/Chapter 5/Index File Services.w"
INDEX("p {\n");
INDEX("font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Helvetica, Arial, Verdana, sans-serif;\n");
INDEX("}\n");
INDEX("\n");
INDEX(".box a:link { text-decoration: none; }\n");
INDEX(".box a:visited { text-decoration: none; }\n");
INDEX(".box a:active { text-decoration: none; }\n");
INDEX(".box a:hover { text-decoration: none; color: #444444; }\n");
INDEX("\n");
INDEX(".smallbox a:link { text-decoration: none; }\n");
INDEX(".smallbox a:visited { text-decoration: none; }\n");
INDEX(".smallbox a:active { text-decoration: none; }\n");
INDEX(".smallbox a:hover { text-decoration: none; color: #444444; }\n");
INDEX("\n");
INDEX(".symbol {\n");
INDEX(" position: absolute;\n");
INDEX(" top: -4px;\n");
INDEX(" left: -1px;\n");
INDEX(" width: 100%%;\n");
INDEX(" color: #ffffff;\n");
INDEX(" padding: 14px 0px 14px 1px;\n");
INDEX(" font-size: 20px;\n");
INDEX(" font-weight: bold;\n");
INDEX(" text-align: center;\n");
INDEX("}\n");
INDEX(".indexno {\n");
INDEX(" position: absolute;\n");
INDEX(" top: 1px;\n");
INDEX(" left: 3px;\n");
INDEX(" color: #ffffff;\n");
INDEX(" font-size: 7pt;\n");
INDEX(" text-align: left;\n");
INDEX("}\n");
INDEX(".rubric {\n");
INDEX(" position: absolute;\n");
INDEX(" top: 35px;\n");
INDEX(" width: 100%%;\n");
INDEX(" color: #ffffff;\n");
INDEX(" font-size: 9px;\n");
INDEX(" font-weight: bold;\n");
INDEX(" text-align: center;\n");
INDEX("}\n");
INDEX("\n");
INDEX(".box {\n");
INDEX(" position: relative;\n");
INDEX(" height: 56px;\n");
INDEX(" width: 56px;\n");
INDEX(" padding: 0px;\n");
INDEX("font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Helvetica, Arial, Verdana, sans-serif;\n");
INDEX("-webkit-font-smoothing: antialiased;\n");
INDEX("}\n");
INDEX(".sidebar {\n");
INDEX(" height: 56px;\n");
INDEX(" width: 16px;\n");
INDEX(" background: #888;\n");
INDEX("font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Helvetica, Arial, Verdana, sans-serif;\n");
INDEX("-webkit-font-smoothing: antialiased;\n");
INDEX("}\n");
INDEX(".sidebar:hover { background: #222; }\n");
INDEX("\n");
INDEX(".smallbox {\n");
INDEX(" position: relative;\n");
INDEX(" height: 40px;\n");
INDEX(" width: 40px;\n");
INDEX(" padding: 0px;\n");
INDEX("font-family: \"Lucida Grande\", \"Lucida Sans Unicode\", Helvetica, Arial, Verdana, sans-serif;\n");
INDEX("-webkit-font-smoothing: antialiased;\n");
INDEX("}\n");
INDEX("\n");
index_page *ip;
LOOP_OVER(ip, index_page) {
index_element *ie;
LOOP_OVER(ie, index_element)
if (ie->owning_page == ip) {
INDEX("#box%d_%d {\n", ip->allocation_id+1, ie->atomic_number);
INDEX(" background: #%s;\n", ip->key_colour);
INDEX(" }\n");
INDEX("#minibox%d_%d {\n", ip->allocation_id+1, ie->atomic_number);
INDEX(" background: #%s;\n", ip->key_colour);
INDEX(" }\n");
}
}
INDEX("\n");
INDEX("ul.leaders {\n");
INDEX(" padding: 0;\n");
INDEX(" margin-top: 1px;\n");
INDEX(" margin-bottom: 0;\n");
INDEX(" overflow-x: hidden;\n");
INDEX(" list-style: none}\n");
INDEX("ul.leaders li.leaded:before {\n");
INDEX(" float: left;\n");
INDEX(" width: 0;\n");
INDEX(" white-space: nowrap;\n");
INDEX(" content:\n");
INDEX(" \". . . . . . . . . . . . . . . . . . . . \"\n");
INDEX(" \". . . . . . . . . . . . . . . . . . . . \"\n");
INDEX(" \". . . . . . . . . . . . . . . . . . . . \"\n");
INDEX(" \". . . . . . . . . . . . . . . . . . . . \"\n");
INDEX(" \". . . . . . . . . . . . . . . . . . . . \"\n");
INDEX(" \". . . . . . . . . . . . . . . . . . . . \"\n");
INDEX(" \". . . . . . . . . . . . . . . . . . . . \"\n");
INDEX(" \". . . . . . . . . . . . . . . . . . . . \"\n");
INDEX(" \". . . . . . . . . . . . . . . . . . . . \"\n");
INDEX(" \". . . . . . . . . . . . . . . . . . . . \"}\n");
INDEX("ul.leaders li.leaded span:first-child {\n");
INDEX(" padding-right: 0.33em;\n");
INDEX(" background: white}\n");
INDEX("ul.leaders li.leaded span + span {\n");
INDEX(" float: right;\n");
INDEX(" padding-left: 0.33em;\n");
INDEX(" background: white}\n");
int i;
for (i=1; i<10; i++) {
INDEX("li.indent%d span:first-child {\n", i);
INDEX(" padding-left: %dpx;\n", 25*i);
INDEX("}\n");
}
INDEX("\n");
INDEX("li.unleaded:before {\n");
INDEX(" content: \"\";\n");
INDEX("}\n");
}
#line 328 "inform7/Chapter 5/Index File Services.w"
;
INDEX("</style>\n");
INDEX("<script type=\"text/javascript\">\n");
INDEX("var qq; window.onload = function() {\n");
INDEX(" if (location.search.length > 0) {\n");
INDEX(" qq = location.search.substring(1, location.search.length);\n");
INDEX(" show_only_one_element(qq);\n");
INDEX(" }\n");
INDEX("}\n");
{
#line 499 "inform7/Chapter 5/Index File Services.w"
INDEX("function click_element_box(id) {\n");
INDEX(" if (document.getElementById(id).style.display == 'none') {\n");
INDEX(" show_only_one_element(id);\n");
INDEX(" } else {\n");
INDEX(" var x = 0;\n");
int i;
for (i=1; i<=current_index_page->no_elements; i++)
INDEX(" if (document.getElementById('segment%d').style.display == '') { x++; }\n", i);
INDEX(" if (x == 1) { show_all_elements(); }\n");
INDEX(" else { show_only_one_element(id); }\n");
INDEX(" }\n");
INDEX("}\n");
}
#line 338 "inform7/Chapter 5/Index File Services.w"
;
{
#line 516 "inform7/Chapter 5/Index File Services.w"
INDEX("function click_sidebar() {\n");
INDEX(" if (document.getElementById('surround0').style.display == 'none') {\n");
INDEX(" enter_periodic_table();\n");
INDEX(" } else {\n");
INDEX(" show_all_elements();\n");
INDEX(" }\n");
INDEX("}\n");
}
#line 339 "inform7/Chapter 5/Index File Services.w"
;
{
#line 528 "inform7/Chapter 5/Index File Services.w"
int i;
INDEX("function show_all_elements() {\n");
for (i=1; i<=current_index_page->no_elements; i++) {
INDEX(" show_element('segment%d');\n", i);
INDEX(" light_up('segment%d');\n", i);
}
INDEX(" }\n");
}
#line 341 "inform7/Chapter 5/Index File Services.w"
;
{
#line 540 "inform7/Chapter 5/Index File Services.w"
int i;
INDEX("function show_only_one_element(id) {\n");
for (i=1; i<=current_index_page->no_elements; i++) {
INDEX(" hide_element('segment%d');\n", i);
INDEX(" light_down('segment%d');\n", i);
}
INDEX(" show_element(id);\n");
INDEX(" light_up(id);\n");
INDEX("}\n");
}
#line 342 "inform7/Chapter 5/Index File Services.w"
;
{
#line 553 "inform7/Chapter 5/Index File Services.w"
int i;
INDEX("function enter_periodic_table() {\n");
for (i=1; i<=current_index_page->no_elements; i++) {
INDEX(" hide_element('segment%d');\n", i);
INDEX(" light_up('segment%d');\n", i);
}
INDEX("}\n");
}
#line 343 "inform7/Chapter 5/Index File Services.w"
;
{
#line 565 "inform7/Chapter 5/Index File Services.w"
INDEX("function show_element(id) {\n");
INDEX(" document.getElementById(id).style.display = '';\n");
INDEX("}\n");
INDEX("function hide_element(id) {\n");
INDEX(" document.getElementById(id).style.display = 'none';\n");
INDEX("}\n");
}
#line 345 "inform7/Chapter 5/Index File Services.w"
;
{
#line 575 "inform7/Chapter 5/Index File Services.w"
INDEX("function light_up(id) {\n");
{
#line 588 "inform7/Chapter 5/Index File Services.w"
int i;
INDEX(" var ic = 'box%d_1';\n", current_index_page->allocation_id+1);
for (i=2; i<=current_index_page->no_elements; i++)
INDEX(" if (id == 'segment%d') { ic = 'box%d_%d';}\n",
i, current_index_page->allocation_id+1, i);
}
#line 576 "inform7/Chapter 5/Index File Services.w"
;
INDEX(" document.getElementById(ic).style.background = '#%s';\n",
current_index_page->key_colour);
INDEX("}\n");
INDEX("function light_down(id) {\n");
{
#line 588 "inform7/Chapter 5/Index File Services.w"
int i;
INDEX(" var ic = 'box%d_1';\n", current_index_page->allocation_id+1);
for (i=2; i<=current_index_page->no_elements; i++)
INDEX(" if (id == 'segment%d') { ic = 'box%d_%d';}\n",
i, current_index_page->allocation_id+1, i);
}
#line 581 "inform7/Chapter 5/Index File Services.w"
;
INDEX(" document.getElementById(ic).style.background = '#cccccc';\n");
INDEX("}\n");
}
#line 346 "inform7/Chapter 5/Index File Services.w"
;
INDEX("</script>\n");
}
#line 597 "inform7/Chapter 5/Index File Services.w"
void Index__index_actual_element(char *elt) {
if (strcmp(elt, "C") == 0) {
Sentences__Headings__index();
Extensions__Files__index();
Extensions__Files__update_census();
return;
}
if (strcmp(elt, "Vl") == 0) {
NonlocalVariables__index_all();
Equations__index();
return;
}
if (strcmp(elt, "Fi") == 0) {
PL__Figures__index_all();
PL__Sounds__index_all();
PL__Files__index_all();
return;
}
if (strcmp(elt, "Tb") == 0) {
Tables__index();
return;
}
if (strcmp(elt, "Cd") == 0) {
PL__Bibliographic__index_library_card();
return;
}
if (strcmp(elt, "In") == 0) {
VirtualMachines__index_innards();
return;
}
if (strcmp(elt, "Ph") == 0) {
Phrases__Index__index_page_Phrasebook();
return;
}
if (strcmp(elt, "Lx") == 0) {
Index__Lexicon__index();
return;
}
if (strcmp(elt, "Rl") == 0) {
Relations__index_table();
return;
}
if (strcmp(elt, "Vb") == 0) {
Index__Lexicon__index_verbs();
return;
}
if (strcmp(elt, "Ch") == 0) {
Data__Objects__page_Kinds();
Kinds__Index__index_kinds(2);
return;
}
if (strcmp(elt, "Ar") == 0) {
Kinds__Dimensions__index_dimensional_rules();
return;
}
if (strcmp(elt, "Mp") == 0) {
Data__Objects__page_World();
return;
}
if (strcmp(elt, "Gz") == 0) {
Index__Lexicon__index_common_nouns();
return;
}
if (strcmp(elt, "Pl") == 0) {
PL__Scenes__Index__index();
return;
}
if (strcmp(elt, "Ev") == 0) {
Phrases__Timed__index(); /* rules which happen at set times of day */
return;
}
if (strcmp(elt, "RS") == 0) {
PL__Scenes__Index__index_rules();
return;
}
if (strcmp(elt, "St") == 0) {
Rulebooks__index_page(1);
return;
}
if (strcmp(elt, "Xt") == 0) {
Rulebooks__index_page(2);
return;
}
if (strcmp(elt, "A1") == 0) {
PL__Actions__Index__page();
return;
}
if (strcmp(elt, "Bh") == 0) {
PL__Actions__Patterns__Named__index();
return;
}
if (strcmp(elt, "Cm") == 0) {
PL__Actions__Index__commands();
return;
}
if (strcmp(elt, "To") == 0) {
PL__Actions__Index__tokens();
return;
}
if (strcmp(elt, "A2") == 0) {
PL__Actions__Index__alphabetical();
return;
}
INDEX("<p>NO CONTENT</p>");
}
#line 713 "inform7/Chapter 5/Index File Services.w"
void Index__explain(char *explanation) {
char temp[MAX_FILENAME_LENGTH];
strcpy(temp, explanation);
int i, len = Platform__strlen(temp), italics_open = FALSE;
for (i=0; i<len; i++) {
switch (temp[i]) {
case '|': INDEX("<br><i>"); italics_open = TRUE; break;
case '<': {
int j = i+1;
INDEX("&nbsp;");
while ((j<len) && (temp[j] != '>')) j++;
temp[j] = 0;
Index__DocReferences__link(temp+i+1);
i = j;
break;
}
case '[': {
int j = i+1;
while ((j<len) && (temp[j] != ']')) j++;
temp[j] = 0;
Index__below_link(temp+i+1);
INDEX("&nbsp;");
i = j;
break;
}
default: INDEX("%c", temp[i]); break;
}
}
if (italics_open) INDEX("</i>");
}
#line 749 "inform7/Chapter 5/Index File Services.w"
void Index__complete(void) {
if (ifl) Index__close_index_file();
PL__Actions__Index__detail_pages();
}
void Index__close_index_file(void) {
if (ifl == NULL) return;
HTML__html_footer(ifl);
STREAM_CLOSE(ifl); ifl = NULL;
}
#line 775 "inform7/Chapter 5/Index File Services.w"
void Index__link(int wn) {
Index__link_to_location(ifl, Lexer__word_location(wn), TRUE);
}
void Index__link_location(source_location sl) {
Index__link_to_location(ifl, sl, TRUE);
}
void Index__link_to(OUTPUT_STREAM, int wn, int nonbreaking_space) {
Index__link_to_location(OUT, Lexer__word_location(wn), nonbreaking_space);
}
void Index__link_to_location(OUTPUT_STREAM, source_location sl, int nonbreaking_space) {
extension_file *ef = SourceFiles__get_extension_corresponding(sl.file_of_origin);
if (ef) {
if (ef != standard_rules_extension) {
if (nonbreaking_space) WRITE("&nbsp;"); else WRITE(" ");
Extensions__IDs__begin_extension_link(OUT, Extensions__Files__get_eid(ef), NULL);
WRITE("<img border=0 src=inform:/doc_images/Revealext.png>");
Extensions__IDs__end_extension_link(OUT, Extensions__Files__get_eid(ef));
}
return;
}
HTML__html_source_link(OUT, sl, nonbreaking_space);
}
#line 807 "inform7/Chapter 5/Index File Services.w"
void Index__detail_link(char *stub, int sub, int down) {
INDEX("&nbsp;<a href=%s%d_%s.html><img border=0 src=inform:/doc_images/Beneath.png></a>",
(down)?"Details/":"", sub, stub);
}
#line 819 "inform7/Chapter 5/Index File Services.w"
void Index__below_link(char *p) {
INDEX("&nbsp;<a href=#%s><img border=0 src=inform:/doc_images/Below.%s></a>",
p, ICON_EXT);
}
void Index__anchor(char *p) {
INDEX("<a name=%s></a>", p);
}
void Index__below_link_numbered(int n) {
INDEX("&nbsp;<a href=#A%d><img border=0 src=inform:/doc_images/Below.%s></a>", n,
ICON_EXT);
}
void Index__anchor_numbered(int n) {
INDEX("<a name=A%d></a>", n);
}
#line 840 "inform7/Chapter 5/Index File Services.w"
void Index__extra_link(int id) {
INDEX("<a href=\"#\" onclick=\"showExtra('extra%d', 'plus%d'); return false;\">"
"<img border=0 id=\"plus%d\" src=inform:/doc_images/extra.png></a>&nbsp;",
id, id, id);
}
void Index__extra_link_with(int id, char *icon) {
if (id == 2000000) {
INDEX("<a href=\"#\" onclick=\"showAllResp(); return false;\">"
"<img border=0 src=inform:/doc_images/%s.png></a>&nbsp;",
icon);
} else {
INDEX("<a href=\"#\" onclick=\"showResp('extra%d', 'plus%d'); return false;\">"
"<img border=0 id=\"plus%d\" src=inform:/doc_images/%s.png></a>&nbsp;",
id, id, id, icon);
}
}
void Index__noextra_link(void) {
INDEX("<img border=0 src=inform:/doc_images/noextra.png>&nbsp;");
}
#line 865 "inform7/Chapter 5/Index File Services.w"
void Index__extra_div_open(int id, int indent, char *colour) {
INDEX("<div id=\"extra%d\" style=\"display: none;\">", id);
HTML__open_para(ifl, indent, "");
HTML__open_coloured_box(ifl, colour, ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
}
void Index__extra_div_close(char *colour) {
HTML__close_coloured_box(ifl, colour, ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
INDEX("</div>\n");
}
void Index__extra_div_open_nested(int id, int indent) {
INDEX("<div id=\"extra%d\" style=\"display: none;\">", id);
HTML__open_para(ifl, indent, "");
}
void Index__extra_div_close_nested(void) {
INDEX("</div>\n");
}
#line 888 "inform7/Chapter 5/Index File Services.w"
void Index__deprecation_icon(int id) {
INDEX("<a href=\"#\" onclick=\"showExtra('extra%d', 'plus%d'); return false;\">"
"<img border=0 src=inform:/doc_images/deprecated.png></a>&nbsp;",
id, id);
}
#line 899 "inform7/Chapter 5/Index File Services.w"
void Index__dequote(char *p) {
int i = 1;
if ((p[0] == 0) || (p[1] == 0)) return;
for (i=1; p[i+1]; i++) {
char c = p[i];
switch(c) {
case '"': INDEX("&quot;"); break;
default: INDEX("%c", c); break;
}
}
}
#line 55 "inform7/Chapter 5/Documentation References.w"
sentence_handler DOC_SH_handler =
{ SENTENCE_NT, DOC_VB, 1, Index__DocReferences__dref_new };
void Index__DocReferences__dref_new(parse_node *p) {
wording SW = ParseTree__get_text(p->down->next);
wording RW = ParseTree__get_text(p->down->next->next);
char *chap = NULL, *sect = NULL;
if ((Wordings__length(RW) > 1) && (Vocabulary__test_flags(Wordings__first_wn(RW)+1, TEXT_MC))) {
Text__dequote_word(Wordings__first_wn(RW)+1);
chap = Lexer__word_text(Wordings__first_wn(RW)+1);
}
if ((Wordings__length(RW) > 2) && (Vocabulary__test_flags(Wordings__first_wn(RW)+2, TEXT_MC))) {
Text__dequote_word(Wordings__first_wn(RW)+2);
sect = Lexer__word_text(Wordings__first_wn(RW)+2);
}
LOOP_THROUGH_WORDING(i, SW) {
documentation_ref *dr = CREATE(documentation_ref);
dr->symbol = i;
dr->section = Wordings__first_wn(RW);
dr->used_already = FALSE;
dr->usage_count = 0;
dr->sr_usage_count = 0;
dr->ext_usage_count = 0;
dr->chapter_reference = chap;
dr->section_reference = sect;
dr->fragment_at = NULL;
dr->fragment_length = 0;
}
}
#line 93 "inform7/Chapter 5/Documentation References.w"
char *Index__DocReferences__validate_if_possible(char *temp) {
documentation_ref *dr;
LOOP_OVER(dr, documentation_ref)
if (Text__compare_word_by_strcmp(dr->symbol, temp))
return Lexer__word_text(dr->symbol);
return NULL;
}
#line 105 "inform7/Chapter 5/Documentation References.w"
char *Index__DocReferences__link_if_possible_once(char *temp, char **chap, char **sec) {
documentation_ref *dr;
LOOP_OVER(dr, documentation_ref)
if (Text__compare_raw_word_by_strcmp(dr->symbol, temp)) {
if (dr->used_already == FALSE) {
char *leaf = Lexer__word_text(dr->section);
*chap = dr->chapter_reference;
*sec = dr->section_reference;
LOOP_OVER(dr, documentation_ref)
if (strcmp(leaf, Lexer__word_text(dr->section)) == 0)
dr->used_already = TRUE;
return leaf;
}
}
return NULL;
}
#line 130 "inform7/Chapter 5/Documentation References.w"
int documentation_symbol_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 133 "inform7/Chapter 5/Documentation References.w"
int documentation_symbol_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = Wordings__first_wn(documentation_symbol_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 136 "inform7/Chapter 5/Documentation References.w"
#line 140 "inform7/Chapter 5/Documentation References.w"
wording Index__DocReferences__position_of_symbol(wording *W) {
if (Preform__parse_nt_against_word_range(documentation_symbol_tail_NTM, *W, NULL, NULL)) {
*W = GET_RW(documentation_symbol_tail_NTM, 1);
return Wordings__one_word(most_recent_result);
}
return EMPTY_WORDING;
}
#line 153 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__doc_mark_used(char *symb, int at_word) {
if (Log__aspect_switched_on(PHRASE_USAGE_DA)) {
documentation_ref *dr;
LOOP_OVER(dr, documentation_ref) {
if (Text__compare_raw_word_by_strcmp(dr->symbol, symb)) {
extension_file *loc = NULL;
if (at_word >= 0) {
source_file *pos = Lexer__file_of_origin(at_word);
loc = SourceFiles__get_extension_corresponding(pos);
if (loc == NULL) dr->usage_count++;
else if (loc == standard_rules_extension) dr->sr_usage_count++;
else dr->ext_usage_count++;
} else dr->sr_usage_count++;
return;
}
}
internal_error("unable to update usage count");
}
}
#line 179 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__log_statistics(void) {
LOGIF(PHRASE_USAGE, "The following shows how often each built-in phrase was used:\n");
documentation_ref *dr;
LOOP_OVER(dr, documentation_ref) {
char *s = Lexer__word_raw_text(dr->symbol);
if ((s[0] == 'p') && (s[1] == 'h')) {
LOGIF(PHRASE_USAGE, "USAGE: %s %d %d %d\n", s,
dr->usage_count, dr->sr_usage_count, dr->ext_usage_count);
}
}
}
#line 195 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__link(char *fn) {
Index__DocReferences__link_to(ifl, fn, FALSE);
}
void Index__DocReferences__fully_link(char *fn) {
Index__DocReferences__link_to(ifl, fn, TRUE);
}
void Index__DocReferences__link_to(OUTPUT_STREAM, char *fn, int full) {
documentation_ref *dr = Index__DocReferences__name_to_dr(fn);
if (dr) {
if (full >= 0) WRITE("&nbsp;"); else WRITE(" ");
WRITE("<a href=inform:/%s.html><img border=0 src=inform:/doc_images/help.png></a>",
Lexer__word_raw_text(dr->section));
if ((full > 0) && (dr->chapter_reference) && (dr->section_reference)) {
WRITE("&nbsp;%s. %s", dr->chapter_reference, dr->section_reference);
}
}
}
#line 222 "inform7/Chapter 5/Documentation References.w"
void Index__DocReferences__doc_fragment(char *fn) {
Index__DocReferences__doc_fragment_to(ifl, fn);
}
int fragments_loaded = FALSE;
void Index__DocReferences__doc_fragment_to(OUTPUT_STREAM, char *fn) {
if (fragments_loaded == FALSE) {
{
#line 245 "inform7/Chapter 5/Documentation References.w"
FILE *FRAGMENTS = Platform__iso_fopen(filename_of_documentation_snippets, "r");
if (FRAGMENTS) {
char *p = Memory__I7_malloc(MAX_EXTENT_OF_FRAGMENTS, DOC_FRAGMENT_MREASON);
{
#line 256 "inform7/Chapter 5/Documentation References.w"
int i = 0;
p[0] = 0;
while (TRUE) {
int c = SourceFiles__utf8_fgetc(FRAGMENTS, NULL, FALSE);
if (c == EOF) break;
if (c == 0xFEFF) continue; /* the Unicode BOM non-character */
if (i == MAX_EXTENT_OF_FRAGMENTS) break;
p[i++] = (char) c;
p[i] = 0;
}
}
#line 248 "inform7/Chapter 5/Documentation References.w"
;
{
#line 270 "inform7/Chapter 5/Documentation References.w"
int i = 0;
documentation_ref *tracking = NULL;
for (i=0; p[i]; i++) {
if ((p[i] == '*') && (p[i+1] == '=')) {
i += 2;
char rn[32]; rn[0] = 0;
int j;
for (j=0; p[i+j]; j++) {
if ((p[i+j] == '=') && (p[i+j+1] == '*')) {
i = i+j+1;
tracking = Index__DocReferences__name_to_dr(rn);
if (tracking) tracking->fragment_at = p+i+1;
break;
} else {
rn[j] = p[i+j];
rn[j+1] = 0;
}
}
} else if (tracking) tracking->fragment_length++;
}
}
#line 249 "inform7/Chapter 5/Documentation References.w"
;
fclose(FRAGMENTS);
}
}
#line 229 "inform7/Chapter 5/Documentation References.w"
;
fragments_loaded = TRUE;
}
documentation_ref *dr = Index__DocReferences__name_to_dr(fn);
if ((dr) && (dr->fragment_at)) {
char *p = dr->fragment_at;
int i;
for (i=0; i<dr->fragment_length; i++) PUT(p[i]);
}
}
#line 295 "inform7/Chapter 5/Documentation References.w"
documentation_ref *Index__DocReferences__name_to_dr(char *fn) {
documentation_ref *dr;
LOOP_OVER(dr, documentation_ref)
if (Text__compare_raw_word_by_strcmp(dr->symbol, fn))
return dr;
{
#line 307 "inform7/Chapter 5/Documentation References.w"
if (problem_count == 0) {
LOG("Bad ref was <%s>. Known references are:\n", fn);
LOOP_OVER(dr, documentation_ref) {
LOG("<%s> = %s\n", Lexer__word_raw_text(dr->symbol), Lexer__word_raw_text(dr->section));
}
internal_error("Bad index documentation reference");
}
}
#line 300 "inform7/Chapter 5/Documentation References.w"
;
return NULL;
}
#line 58 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry *Index__Lexicon__lexicon_new_entry(wording W) {
lexicon_entry *lex = CREATE(lexicon_entry);
lex->wording_of_entry = W;
lex->text_of_entry = WordAssemblages__lit_0();
lex->part_of_speech = MISCELLANEOUS_LEXE;
lex->entry_refers_to = NULL_GENERAL_POINTER;
lex->category = NULL; lex->gloss_note = NULL; lex->verb_defined_at = NULL;
return lex;
}
#line 73 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry *Index__Lexicon__new_entry_with_details(wording W, int pos,
word_assemblage wa, char *category, char *gloss) {
lexicon_entry *lex = Index__Lexicon__lexicon_new_entry(W);
lex->part_of_speech = pos;
lex->text_of_entry = wa;
lex->category = category; lex->gloss_note = gloss;
return lex;
}
lexicon_entry *Index__Lexicon__new_main_verb(word_assemblage infinitive, int part) {
lexicon_entry *lex = Index__Lexicon__lexicon_new_entry(EMPTY_WORDING);
lex->text_of_entry = infinitive;
lex->part_of_speech = part;
lex->category = "verb";
lex->verb_defined_at = current_sentence;
current_main_verb = lex;
return lex;
}
#line 99 "inform7/Chapter 5/Lexicon Index.w"
void Index__Lexicon__lexicon_copy_to_string(lexicon_entry *lex, char *str) {
if (Wordings__nonempty(lex->wording_of_entry))
Wordings__to_string_raw(str, lex->wording_of_entry);
else
WordAssemblages__copy_to_string(&(lex->text_of_entry), str);
}
#line 112 "inform7/Chapter 5/Lexicon Index.w"
void Index__Lexicon__index(void) {
{
#line 141 "inform7/Chapter 5/Lexicon Index.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
wording W = Instances__get_name(I, FALSE);
if (Wordings__nonempty(W)) {
lexicon_entry *lex = Index__Lexicon__lexicon_new_entry(W);
lex->part_of_speech = PROPER_NOUN_LEXE;
lex->category = "noun";
lex->entry_refers_to = STORE_POINTER_instance(I);
}
}
}
#line 113 "inform7/Chapter 5/Lexicon Index.w"
;
{
#line 157 "inform7/Chapter 5/Lexicon Index.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__lt(K, K_object)) {
wording W = Kinds__Behaviour__get_name(K, FALSE);
if (Wordings__nonempty(W)) {
lexicon_entry *lex = Index__Lexicon__lexicon_new_entry(W);
lex->part_of_speech = NOUN_LEXE;
lex->category = "noun";
lex->entry_refers_to = STORE_POINTER_kind(K);
}
}
}
#line 114 "inform7/Chapter 5/Lexicon Index.w"
;
{
#line 172 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry *lex;
adjectival_phrase *adj;
LOOP_OVER(adj, adjectival_phrase) {
wording W = Adjectives__Phrases__get_text(adj, FALSE);
if (Wordings__nonempty(W)) {
lex = Index__Lexicon__lexicon_new_entry(W);
lex->part_of_speech = ADJECTIVAL_PHRASE_LEXE;
lex->category = "adjective";
lex->entry_refers_to = STORE_POINTER_adjectival_phrase(adj);
}
}
}
#line 115 "inform7/Chapter 5/Lexicon Index.w"
;
{
#line 189 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry *lex;
instance *qn;
LOOP_OVER_ENUMERATION_INSTANCES(qn) {
property *prn =
Kinds__Behaviour__get_coinciding_property(Instances__to_kind(qn));
if ((prn) && (Properties__Conditions__of_what(prn))) continue;
wording NW = Instances__get_name(qn, FALSE);
lex = Index__Lexicon__lexicon_new_entry(NW);
lex->part_of_speech = ENUMERATED_CONSTANT_LEXE;
lex->category = "noun";
lex->entry_refers_to = STORE_POINTER_instance(qn);
}
}
#line 116 "inform7/Chapter 5/Lexicon Index.w"
;
{
#line 205 "inform7/Chapter 5/Lexicon Index.w"
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if ((vc->vc_meaning == NULL) && (vc->auxiliary_only == FALSE) && (vc->instance_of_verb))
Index__Lexicon__new_main_verb(vc->infinitive, MVERB_LEXE);
}
#line 117 "inform7/Chapter 5/Lexicon Index.w"
;
{
#line 214 "inform7/Chapter 5/Lexicon Index.w"
Preform__Nonparsing__enter_lexicon(indefinite_article_NTM, MISCELLANEOUS_LEXE,
"indefinite article", NULL);
Preform__Nonparsing__enter_lexicon(definite_article_NTM, MISCELLANEOUS_LEXE,
"definite article", NULL);
Preform__Nonparsing__enter_lexicon(relative_clause_marker_NTM, MISCELLANEOUS_LEXE,
"connective",
"used to place a further condition on a description: like 'which' in "
"'A which is B', or 'A which carries B', for instance.");
}
#line 118 "inform7/Chapter 5/Lexicon Index.w"
;
{
#line 231 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry *lex;
LOOP_OVER(lex, lexicon_entry) {
int i;
char entry_text[MAX_TEXT_FOR_LEXICON_ENTRY];
Index__Lexicon__lexicon_copy_to_string(lex, entry_text); entry_text[31] = 0;
for (i=0; entry_text[i]; i++) entry_text[i] = Platform__tolower(entry_text[i]);
strcpy(lex->reduced_to_lower_case, entry_text);
}
}
#line 120 "inform7/Chapter 5/Lexicon Index.w"
;
{
#line 246 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry *lex;
LOOP_OVER(lex, lexicon_entry) {
lexicon_entry *lex2, *last_lex;
if (sorted_lexicon == NULL) {
sorted_lexicon = lex; lex->sorted_next = NULL; continue;
}
for (last_lex = NULL, lex2 = sorted_lexicon; lex2;
last_lex = lex2, lex2 = lex2->sorted_next)
if (strcmp(lex->reduced_to_lower_case, lex2->reduced_to_lower_case) < 0) {
if (last_lex == NULL) sorted_lexicon = lex;
else last_lex->sorted_next = lex;
lex->sorted_next = lex2; goto Inserted;
}
last_lex->sorted_next = lex; lex->sorted_next = NULL;
Inserted: ;
}
}
#line 121 "inform7/Chapter 5/Lexicon Index.w"
;
int common_nouns_only = FALSE;
Index__anchor("LEXICON");
{
#line 266 "inform7/Chapter 5/Lexicon Index.w"
INDEX("<p><small>For instance, the description 'an unlocked door' is made "
"up from the adjective 'unlocked' and the noun 'door', both of which "
"can be found below. Property adjectives, like 'open', can be used "
"when creating things - 'In the Ballroom is an open container' is "
"allowed because 'open' is a property - but those with complicated "
"definitions, like 'empty', can only be tested during play, e.g. "
"with rules like 'Instead of taking an empty container, ...'.</small></p>");
}
#line 125 "inform7/Chapter 5/Lexicon Index.w"
;
{
#line 285 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry *lex;
char current_initial_letter = '?';
int verb_count = 0, entry_count = 0, c;
for (lex = sorted_lexicon; lex; lex = lex->sorted_next)
if (lex->part_of_speech == PROPER_NOUN_LEXE)
entry_count++;
if (common_nouns_only) {
HTML__begin_html_table(ifl, NULL, TRUE, 0, 0, 0, 0, 0);
HTML__first_html_column(ifl, 0);
}
for (c = 0, lex = sorted_lexicon; lex; lex = lex->sorted_next) {
if (common_nouns_only) { if (lex->part_of_speech != PROPER_NOUN_LEXE) continue; }
else { if (lex->part_of_speech == PROPER_NOUN_LEXE) continue; }
if ((common_nouns_only) && (c == entry_count/2)) HTML__next_html_column(ifl, 0);
if (current_initial_letter != lex->reduced_to_lower_case[0]) {
if (c > 0) { INDEX("<p></p>"); }
current_initial_letter = lex->reduced_to_lower_case[0];
}
c++;
INDEX("<p class=\"hang\">");
{
#line 332 "inform7/Chapter 5/Lexicon Index.w"
char entry_text[MAX_TEXT_FOR_LEXICON_ENTRY];
Index__Lexicon__lexicon_copy_to_string(lex, entry_text);
Text__to_stream(ifl, entry_text);
if (lex->part_of_speech == ABLE_VERB_LEXE) INDEX(", to be able to");
if (lex->part_of_speech == PREP_LEXE) INDEX(", to be");
}
#line 306 "inform7/Chapter 5/Lexicon Index.w"
;
{
#line 350 "inform7/Chapter 5/Lexicon Index.w"
switch(lex->part_of_speech) {
case NOUN_LEXE: {
kind *K = RETRIEVE_POINTER_kind(lex->entry_refers_to);
if ((K) && (Kinds__Behaviour__get_documentation_reference(K)))
Index__DocReferences__link(Kinds__Behaviour__get_documentation_reference(K));
break;
}
case VERB_LEXE:
case ABLE_VERB_LEXE:
case PREP_LEXE:
Index__below_link_numbered(10000+verb_count++);
break;
}
if ((lex->part_of_speech != ADJECTIVAL_PHRASE_LEXE) && (Wordings__nonempty(lex->wording_of_entry)))
Index__link(Wordings__first_wn(lex->wording_of_entry));
}
#line 307 "inform7/Chapter 5/Lexicon Index.w"
;
switch(lex->part_of_speech) {
case ADJECTIVAL_PHRASE_LEXE:
{
#line 403 "inform7/Chapter 5/Lexicon Index.w"
int ac = 0, nc;
adjective_meaning *am;
adjectival_phrase *aph = RETRIEVE_POINTER_adjectival_phrase(lex->entry_refers_to);
{
#line 432 "inform7/Chapter 5/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 406 "inform7/Chapter 5/Lexicon Index.w"
;
INDEX(": ");
LOOP_OVER_SORTED_MEANINGS(aph, am) ac++; nc = ac;
LOOP_OVER_SORTED_MEANINGS(aph, am) {
ac--;
if (nc > 1) INDEX("<br>%d. ", nc-ac);
Adjectives__Meanings__print_to_index(am);
if (ac >= 1) INDEX("; ");
}
{
#line 439 "inform7/Chapter 5/Lexicon Index.w"
INDEX("</i>");
}
#line 415 "inform7/Chapter 5/Lexicon Index.w"
;
}
#line 311 "inform7/Chapter 5/Lexicon Index.w"
; break;
case ENUMERATED_CONSTANT_LEXE:
{
#line 421 "inform7/Chapter 5/Lexicon Index.w"
instance *qn = RETRIEVE_POINTER_instance(lex->entry_refers_to);
kind *K = Instances__to_kind(qn);
{
#line 432 "inform7/Chapter 5/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 423 "inform7/Chapter 5/Lexicon Index.w"
;
INDEX(", value of ");
{
#line 439 "inform7/Chapter 5/Lexicon Index.w"
INDEX("</i>");
}
#line 425 "inform7/Chapter 5/Lexicon Index.w"
;
wording W = Kinds__Behaviour__get_name(K, FALSE);
Wordings__index_raw(W);
}
#line 313 "inform7/Chapter 5/Lexicon Index.w"
; break;
case PROPER_NOUN_LEXE:
{
#line 388 "inform7/Chapter 5/Lexicon Index.w"
instance *I = RETRIEVE_POINTER_instance(lex->entry_refers_to);
kind *K = Instances__to_kind(I);
if (Kinds__Compare__eq(K, K_thing) == FALSE) {
wording W = Kinds__Behaviour__get_name(K, FALSE);
if (Wordings__nonempty(W)) {
{
#line 432 "inform7/Chapter 5/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 393 "inform7/Chapter 5/Lexicon Index.w"
;
Wordings__index_raw(W);
{
#line 439 "inform7/Chapter 5/Lexicon Index.w"
INDEX("</i>");
}
#line 395 "inform7/Chapter 5/Lexicon Index.w"
;
}
}
}
#line 315 "inform7/Chapter 5/Lexicon Index.w"
; break;
case NOUN_LEXE:
{
#line 369 "inform7/Chapter 5/Lexicon Index.w"
kind *K = RETRIEVE_POINTER_kind(lex->entry_refers_to);
if (Kinds__Compare__lt(K, K_object)) {
K = Kinds__Compare__super(K);
wording W = Kinds__Behaviour__get_name(K, FALSE);
if (Wordings__nonempty(W)) {
{
#line 432 "inform7/Chapter 5/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 374 "inform7/Chapter 5/Lexicon Index.w"
;
INDEX(", a kind of ");
{
#line 439 "inform7/Chapter 5/Lexicon Index.w"
INDEX("</i>");
}
#line 376 "inform7/Chapter 5/Lexicon Index.w"
;
Wordings__index_raw(W);
}
} else {
{
#line 432 "inform7/Chapter 5/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 380 "inform7/Chapter 5/Lexicon Index.w"
;
INDEX(", a kind");
{
#line 439 "inform7/Chapter 5/Lexicon Index.w"
INDEX("</i>");
}
#line 382 "inform7/Chapter 5/Lexicon Index.w"
;
}
}
#line 317 "inform7/Chapter 5/Lexicon Index.w"
; break;
}
if (lex->gloss_note) INDEX(" <i>%s</i>", lex->gloss_note);
INDEX("</p>\n");
}
if (common_nouns_only) { HTML__end_html_row(ifl); HTML__end_html_table(ifl); }
}
#line 126 "inform7/Chapter 5/Lexicon Index.w"
;
}
#line 133 "inform7/Chapter 5/Lexicon Index.w"
void Index__Lexicon__index_common_nouns(void) {
int common_nouns_only = TRUE;
{
#line 285 "inform7/Chapter 5/Lexicon Index.w"
lexicon_entry *lex;
char current_initial_letter = '?';
int verb_count = 0, entry_count = 0, c;
for (lex = sorted_lexicon; lex; lex = lex->sorted_next)
if (lex->part_of_speech == PROPER_NOUN_LEXE)
entry_count++;
if (common_nouns_only) {
HTML__begin_html_table(ifl, NULL, TRUE, 0, 0, 0, 0, 0);
HTML__first_html_column(ifl, 0);
}
for (c = 0, lex = sorted_lexicon; lex; lex = lex->sorted_next) {
if (common_nouns_only) { if (lex->part_of_speech != PROPER_NOUN_LEXE) continue; }
else { if (lex->part_of_speech == PROPER_NOUN_LEXE) continue; }
if ((common_nouns_only) && (c == entry_count/2)) HTML__next_html_column(ifl, 0);
if (current_initial_letter != lex->reduced_to_lower_case[0]) {
if (c > 0) { INDEX("<p></p>"); }
current_initial_letter = lex->reduced_to_lower_case[0];
}
c++;
INDEX("<p class=\"hang\">");
{
#line 332 "inform7/Chapter 5/Lexicon Index.w"
char entry_text[MAX_TEXT_FOR_LEXICON_ENTRY];
Index__Lexicon__lexicon_copy_to_string(lex, entry_text);
Text__to_stream(ifl, entry_text);
if (lex->part_of_speech == ABLE_VERB_LEXE) INDEX(", to be able to");
if (lex->part_of_speech == PREP_LEXE) INDEX(", to be");
}
#line 306 "inform7/Chapter 5/Lexicon Index.w"
;
{
#line 350 "inform7/Chapter 5/Lexicon Index.w"
switch(lex->part_of_speech) {
case NOUN_LEXE: {
kind *K = RETRIEVE_POINTER_kind(lex->entry_refers_to);
if ((K) && (Kinds__Behaviour__get_documentation_reference(K)))
Index__DocReferences__link(Kinds__Behaviour__get_documentation_reference(K));
break;
}
case VERB_LEXE:
case ABLE_VERB_LEXE:
case PREP_LEXE:
Index__below_link_numbered(10000+verb_count++);
break;
}
if ((lex->part_of_speech != ADJECTIVAL_PHRASE_LEXE) && (Wordings__nonempty(lex->wording_of_entry)))
Index__link(Wordings__first_wn(lex->wording_of_entry));
}
#line 307 "inform7/Chapter 5/Lexicon Index.w"
;
switch(lex->part_of_speech) {
case ADJECTIVAL_PHRASE_LEXE:
{
#line 403 "inform7/Chapter 5/Lexicon Index.w"
int ac = 0, nc;
adjective_meaning *am;
adjectival_phrase *aph = RETRIEVE_POINTER_adjectival_phrase(lex->entry_refers_to);
{
#line 432 "inform7/Chapter 5/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 406 "inform7/Chapter 5/Lexicon Index.w"
;
INDEX(": ");
LOOP_OVER_SORTED_MEANINGS(aph, am) ac++; nc = ac;
LOOP_OVER_SORTED_MEANINGS(aph, am) {
ac--;
if (nc > 1) INDEX("<br>%d. ", nc-ac);
Adjectives__Meanings__print_to_index(am);
if (ac >= 1) INDEX("; ");
}
{
#line 439 "inform7/Chapter 5/Lexicon Index.w"
INDEX("</i>");
}
#line 415 "inform7/Chapter 5/Lexicon Index.w"
;
}
#line 311 "inform7/Chapter 5/Lexicon Index.w"
; break;
case ENUMERATED_CONSTANT_LEXE:
{
#line 421 "inform7/Chapter 5/Lexicon Index.w"
instance *qn = RETRIEVE_POINTER_instance(lex->entry_refers_to);
kind *K = Instances__to_kind(qn);
{
#line 432 "inform7/Chapter 5/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 423 "inform7/Chapter 5/Lexicon Index.w"
;
INDEX(", value of ");
{
#line 439 "inform7/Chapter 5/Lexicon Index.w"
INDEX("</i>");
}
#line 425 "inform7/Chapter 5/Lexicon Index.w"
;
wording W = Kinds__Behaviour__get_name(K, FALSE);
Wordings__index_raw(W);
}
#line 313 "inform7/Chapter 5/Lexicon Index.w"
; break;
case PROPER_NOUN_LEXE:
{
#line 388 "inform7/Chapter 5/Lexicon Index.w"
instance *I = RETRIEVE_POINTER_instance(lex->entry_refers_to);
kind *K = Instances__to_kind(I);
if (Kinds__Compare__eq(K, K_thing) == FALSE) {
wording W = Kinds__Behaviour__get_name(K, FALSE);
if (Wordings__nonempty(W)) {
{
#line 432 "inform7/Chapter 5/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 393 "inform7/Chapter 5/Lexicon Index.w"
;
Wordings__index_raw(W);
{
#line 439 "inform7/Chapter 5/Lexicon Index.w"
INDEX("</i>");
}
#line 395 "inform7/Chapter 5/Lexicon Index.w"
;
}
}
}
#line 315 "inform7/Chapter 5/Lexicon Index.w"
; break;
case NOUN_LEXE:
{
#line 369 "inform7/Chapter 5/Lexicon Index.w"
kind *K = RETRIEVE_POINTER_kind(lex->entry_refers_to);
if (Kinds__Compare__lt(K, K_object)) {
K = Kinds__Compare__super(K);
wording W = Kinds__Behaviour__get_name(K, FALSE);
if (Wordings__nonempty(W)) {
{
#line 432 "inform7/Chapter 5/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 374 "inform7/Chapter 5/Lexicon Index.w"
;
INDEX(", a kind of ");
{
#line 439 "inform7/Chapter 5/Lexicon Index.w"
INDEX("</i>");
}
#line 376 "inform7/Chapter 5/Lexicon Index.w"
;
Wordings__index_raw(W);
}
} else {
{
#line 432 "inform7/Chapter 5/Lexicon Index.w"
INDEX(" ... <i>");
if ((common_nouns_only == FALSE) && (lex->category))
INDEX("%s", lex->category);
}
#line 380 "inform7/Chapter 5/Lexicon Index.w"
;
INDEX(", a kind");
{
#line 439 "inform7/Chapter 5/Lexicon Index.w"
INDEX("</i>");
}
#line 382 "inform7/Chapter 5/Lexicon Index.w"
;
}
}
#line 317 "inform7/Chapter 5/Lexicon Index.w"
; break;
}
if (lex->gloss_note) INDEX(" <i>%s</i>", lex->gloss_note);
INDEX("</p>\n");
}
if (common_nouns_only) { HTML__end_html_row(ifl); HTML__end_html_table(ifl); }
}
#line 135 "inform7/Chapter 5/Lexicon Index.w"
;
}
#line 445 "inform7/Chapter 5/Lexicon Index.w"
void Index__Lexicon__index_verbs(void) {
INDEX("<p></p>"); /* for spacing */
INDEX("<p>Verbs listed as \"for saying only\" are values of the kind \"verb\" "
"and can be used in adaptive text, but they have no meaning to Inform, so "
"they can't be used in sentences about what's in the story.</p>");
lexicon_entry *lex = sorted_lexicon;
int verb_count = 0;
for (lex = sorted_lexicon; lex; lex = lex->sorted_next)
if ((lex->part_of_speech == VERB_LEXE) ||
(lex->part_of_speech == MVERB_LEXE) ||
(lex->part_of_speech == PREP_LEXE) ||
(lex->part_of_speech == ABLE_VERB_LEXE)) {
char entry_text[MAX_TEXT_FOR_LEXICON_ENTRY];
INDEX("<p class=\"hang\">");
Index__anchor_numbered(10000+verb_count++); /* anchors from 10000: see above */
Index__Lexicon__lexicon_copy_to_string(lex, entry_text);
if (lex->part_of_speech == VERB_LEXE) INDEX("To <b>%s</b>", entry_text);
else if (lex->part_of_speech == MVERB_LEXE) INDEX("To <b>%s</b>", entry_text);
else if (lex->part_of_speech == AVERB_LEXE) INDEX("<b>%s</b>", entry_text);
else if (lex->part_of_speech == PREP_LEXE) INDEX("To be <b>%s</b>", entry_text);
else INDEX("To be able to <b>%s</b>", entry_text);
if (Wordings__nonempty(lex->wording_of_entry))
Index__link(Wordings__first_wn(lex->wording_of_entry));
if (lex->part_of_speech == AVERB_LEXE) INDEX(" ... <i>auxiliary verb</i>");
else if (lex->part_of_speech == MVERB_LEXE) INDEX(" ... for saying only");
else Verbs__tabulate_meaning(lex);
INDEX("</p>");
Verbs__tabulate(lex, IS_TENSE, "present");
Verbs__tabulate(lex, WAS_TENSE, "past");
Verbs__tabulate(lex, HASBEEN_TENSE, "present perfect");
Verbs__tabulate(lex, HADBEEN_TENSE, "past perfect");
}
}
#line 483 "inform7/Chapter 5/Lexicon Index.w"
void Index__Lexicon__list_verbs_in_file(OUTPUT_STREAM, source_file *sf, extension_file *ef) {
int verb_count = 0;
lexicon_entry *lex;
LOOP_OVER(lex, lexicon_entry)
if (((lex->part_of_speech == VERB_LEXE) || (lex->part_of_speech == ABLE_VERB_LEXE))
&& (lex->verb_defined_at)
&& (Lexer__file_of_origin(Wordings__first_wn(ParseTree__get_text(lex->verb_defined_at))) == sf)) {
char entry_text[MAX_TEXT_FOR_LEXICON_ENTRY];
Index__Lexicon__lexicon_copy_to_string(lex, entry_text);
if (verb_count++ == 0) WRITE("Verbs: "); else WRITE(", ");
if (lex->part_of_speech == VERB_LEXE) WRITE("to <b>%s</b>", entry_text);
else WRITE("to be able to <b>%s</b>", entry_text);
Extensions__Dictionary__new_entry_from_string("verb", ef, entry_text);
}
if (verb_count > 0) WRITE("<p>");
}
#line 11 "inform7/Chapter 6/Problems, Level 0.w"
int crash_on_all_errors = FALSE;
int crash_on_internal_errors = FALSE;
void Problems__Fatal__issue(char *message) {
WRITE_TO(STDERR, message);
WRITE_TO(STDERR, "\n");
STREAM_FLUSH(STDERR);
if (crash_on_all_errors) Problems__Fatal__force_crash();
exit(2);
}
void Problems__Fatal__issue_t(char *message, char *fn) {
WRITE_TO(STDERR, message);
WRITE_TO(STDERR, "\nOffending filename: <%s>\n", fn);
STREAM_FLUSH(STDERR);
if (crash_on_all_errors) Problems__Fatal__force_crash();
exit(2);
}
void Problems__Fatal__filename_related(char *message, filename *F) {
char fn[MAX_FILENAME_LENGTH];
Filenames__to_string(fn, F);
Problems__Fatal__issue_t(message, fn);
}
#line 44 "inform7/Chapter 6/Problems, Level 0.w"
void Problems__Fatal__force_crash(void) {
STREAM_FLUSH(STDOUT);
STREAM_FLUSH(dl);
WRITE_TO(STDERR,
"*** Intentionally crashing to force stack backtrace to console logs ***\n");
STREAM_FLUSH(STDERR);
parse_node *PN = NULL; ParseTree__log_subtree(PN->next);
exit(1);
}
#line 17 "inform7/Chapter 6/Problems, Level 1.w"
char problem_buffer[PROBLEM_BUFFER_LENGTH];
#line 33 "inform7/Chapter 6/Problems, Level 1.w"
void Problems__Buffer__copy_text_into_problem_buffer(wording W) {
W = Wordings__truncate(W, QUOTATION_TOLERANCE_LIMIT);
Wordings__to_string_abbreviated(
PROBLEM_BUFFER_LENGTH - Platform__strlen(problem_buffer) - 1, PBUFF, W);
}
#line 42 "inform7/Chapter 6/Problems, Level 1.w"
parse_node *redirected_sentence = NULL;
parse_node *redirected_to_A = NULL, *redirected_to_B = NULL;
void Problems__Buffer__redirect_problem_sentence(parse_node *from, parse_node *A, parse_node *B) {
redirected_sentence = from; redirected_to_A = A; redirected_to_B = B;
}
#line 54 "inform7/Chapter 6/Problems, Level 1.w"
void Problems__Buffer__copy_source_reference_into_problem_buffer(wording W) {
char *paraphrase;
if (Wordings__empty(W)) { sprintf(PBUFF, "<no text>"); return; }
source_file *referred = Lexer__file_of_origin(Wordings__first_wn(W));
char *fn = "(no file)";
char filename_buffer[MAX_FILENAME_LENGTH];
if (referred) {
Filenames__to_string(filename_buffer, SourceFiles__get_filename(referred));
fn = filename_buffer;
if (pathname_of_project) {
char bundle_name[MAX_FILENAME_LENGTH];
Pathnames__to_string(bundle_name, pathname_of_project);
if (strncmp(fn, bundle_name, (size_t) Platform__strlen(bundle_name)) == 0)
fn += Platform__strlen(bundle_name) + 1;
}
} else fn = "(no file)";
sprintf(PBUFF, "'");
Problems__Buffer__copy_text_into_problem_buffer(W);
paraphrase = "source text";
extension_file *ef = SourceFiles__get_extension_corresponding(referred);
if (ef) {
extension_identifier *eid = Extensions__Files__get_eid(ef);
paraphrase = fn;
if (eid) {
if (Extensions__IDs__is_standard_rules(eid)) paraphrase = "the Standard Rules";
}
}
sprintf(PBUFF, "' %c%s%c%s%c%d%c",
SOURCE_REF_CHAR, paraphrase,
SOURCE_REF_CHAR, fn,
SOURCE_REF_CHAR, Wordings__location(W).line_number,
SOURCE_REF_CHAR);
if ((redirected_sentence) &&
(redirected_to_A) &&
(redirected_to_B) &&
(Wordings__eq(ParseTree__get_text(redirected_sentence), W))) {
sprintf(PBUFF, " (which asserts that ");
Problems__Buffer__copy_source_reference_into_problem_buffer(
ParseTree__get_text(redirected_to_A));
sprintf(PBUFF, " is/are ");
Problems__Buffer__copy_source_reference_into_problem_buffer(
ParseTree__get_text(redirected_to_B));
sprintf(PBUFF, ")");
}
}
#line 105 "inform7/Chapter 6/Problems, Level 1.w"
int Problems__Buffer__is_problem_buffer_whitespace(char c) {
if ((c == ' ') || (c == '\t') || (c == '\n')) return TRUE;
return FALSE;
}
#line 119 "inform7/Chapter 6/Problems, Level 1.w"
int problem_count_at_last_in = 1;
void Problems__Buffer__output_problem_buffer_to(OUTPUT_STREAM, int indentation) {
int i, k, line_width = 0, html_flag = FALSE;
if (OUT == problems_file) html_flag = TRUE;
for (k=0; k<indentation; k++) { WRITE(" "); line_width+=2; }
for (i=0; problem_buffer[i] != 0; i++) {
char c = problem_buffer[i];
{
#line 146 "inform7/Chapter 6/Problems, Level 1.w"
if ((html_flag) &&
(problem_buffer[i] == '>') &&
(problem_buffer[i+1] == '-') &&
(problem_buffer[i+2] == '-') &&
(problem_buffer[i+3] == '>')) {
if (problem_count > problem_count_at_last_in) WRITE("</p><hr>");
WRITE("<p class=\"hang\"><b>Problem.</b> ");
i+=3; continue;
}
if ((problem_buffer[i] == '>') &&
(problem_buffer[i+1] == '+') &&
(problem_buffer[i+2] == '+') &&
(problem_buffer[i+3] == '>')) {
if (html_flag) WRITE("<p class=\"in2\">"); else WRITE(" ");
i+=3; continue;
}
if ((problem_buffer[i] == '>') &&
(problem_buffer[i+1] == '-') &&
(problem_buffer[i+2] == '-') &&
(problem_buffer[i+3] == '-') &&
(problem_buffer[i+4] == '>')) {
if (html_flag) WRITE("</p><hr>");
problem_count_at_last_in = problem_count+1;
i+=4; continue;
}
if ((problem_buffer[i] == '>') &&
(problem_buffer[i+1] == '+') &&
(problem_buffer[i+2] == '+') &&
(problem_buffer[i+3] == '+') &&
(problem_buffer[i+4] == '>')) {
if (html_flag) WRITE("<p class=\"halftightin3\">"); else WRITE(" ");
i+=4; continue;
}
if ((problem_buffer[i] == '>') &&
(problem_buffer[i+1] == '+') &&
(problem_buffer[i+2] == '+') &&
(problem_buffer[i+3] == '+') &&
(problem_buffer[i+4] == '+') &&
(problem_buffer[i+5] == '>')) {
if (html_flag) WRITE("<p class=\"tightin3\">"); else WRITE(" ");
i+=5; continue;
}
}
#line 127 "inform7/Chapter 6/Problems, Level 1.w"
;
{
#line 195 "inform7/Chapter 6/Problems, Level 1.w"
if (problem_buffer[i] == '<') {
int j = i+1, ch = 0; char tag_identity[32];
while ((problem_buffer[j]) && (problem_buffer[j] != '>')) {
if (ch >= 0) {
if ((ch == 31) || (problem_buffer[j] == ' ')) { tag_identity[ch] = 0; ch = -1; }
else { tag_identity[ch++] = Platform__tolower(problem_buffer[j]); }
}
j++;
}
if (ch >= 0) tag_identity[ch] = 0;
if ((strcmp(tag_identity, "i") == 0) || (strcmp(tag_identity, "/i") == 0) ||
(strcmp(tag_identity, "b") == 0) || (strcmp(tag_identity, "/b") == 0) ||
(strcmp(tag_identity, "img") == 0) || (strcmp(tag_identity, "/img") == 0) ||
(strcmp(tag_identity, "a") == 0) || (strcmp(tag_identity, "/a") == 0) ||
(strcmp(tag_identity, "font") == 0) || (strcmp(tag_identity, "/font") == 0)) {
for (; i<=j; i++)
if ((html_flag) && (problem_buffer[i]))
WRITE("%c", problem_buffer[i]);
i--; continue;
}
}
}
#line 128 "inform7/Chapter 6/Problems, Level 1.w"
;
if ((html_flag == FALSE) && (c == SOURCE_REF_CHAR))
{
#line 234 "inform7/Chapter 6/Problems, Level 1.w"
WRITE("("); line_width++;
while (problem_buffer[++i] != SOURCE_REF_CHAR)
{
#line 244 "inform7/Chapter 6/Problems, Level 1.w"
c = problem_buffer[i];
if (Problems__Buffer__is_problem_buffer_whitespace(c)) { /* this starts a run of whitespace */
int l = i; while (Problems__Buffer__is_problem_buffer_whitespace(problem_buffer[l])) l++;
if (problem_buffer[l] == 0) break; /* omit any trailing spaces */
i = l - 1; /* skip to final whitespace character of the run */
if (html_flag) HTML__html_char_out(OUT, ' ');
else
{
#line 263 "inform7/Chapter 6/Problems, Level 1.w"
int word_width = 0;
while ((!Problems__Buffer__is_problem_buffer_whitespace(problem_buffer[l])) && (problem_buffer[l] != 0)
&& (problem_buffer[l] != SOURCE_REF_CHAR))
l++, word_width++;
if (line_width + word_width + 1 >= PROBLEM_WORD_WRAP_WIDTH) {
WRITE("\n"); line_width = 0;
for (l=0; l<indentation+1; l++) { line_width+=2; WRITE(" "); }
} else {
WRITE(" "); line_width++;
}
}
#line 250 "inform7/Chapter 6/Problems, Level 1.w"
;
} else {
line_width++;
if (html_flag) HTML__html_char_out(OUT, c);
else if ((c != SOURCE_REF_CHAR) && (c != FORCE_NEW_PARA_CHAR)) WRITE("%c", c);
}
}
#line 235 "inform7/Chapter 6/Problems, Level 1.w"
;
while (problem_buffer[++i] != SOURCE_REF_CHAR) ;
WRITE(", line "); line_width += 7;
while (problem_buffer[++i] != SOURCE_REF_CHAR)
{
#line 244 "inform7/Chapter 6/Problems, Level 1.w"
c = problem_buffer[i];
if (Problems__Buffer__is_problem_buffer_whitespace(c)) { /* this starts a run of whitespace */
int l = i; while (Problems__Buffer__is_problem_buffer_whitespace(problem_buffer[l])) l++;
if (problem_buffer[l] == 0) break; /* omit any trailing spaces */
i = l - 1; /* skip to final whitespace character of the run */
if (html_flag) HTML__html_char_out(OUT, ' ');
else
{
#line 263 "inform7/Chapter 6/Problems, Level 1.w"
int word_width = 0;
while ((!Problems__Buffer__is_problem_buffer_whitespace(problem_buffer[l])) && (problem_buffer[l] != 0)
&& (problem_buffer[l] != SOURCE_REF_CHAR))
l++, word_width++;
if (line_width + word_width + 1 >= PROBLEM_WORD_WRAP_WIDTH) {
WRITE("\n"); line_width = 0;
for (l=0; l<indentation+1; l++) { line_width+=2; WRITE(" "); }
} else {
WRITE(" "); line_width++;
}
}
#line 250 "inform7/Chapter 6/Problems, Level 1.w"
;
} else {
line_width++;
if (html_flag) HTML__html_char_out(OUT, c);
else if ((c != SOURCE_REF_CHAR) && (c != FORCE_NEW_PARA_CHAR)) WRITE("%c", c);
}
}
#line 238 "inform7/Chapter 6/Problems, Level 1.w"
;
WRITE(")"); line_width++;
}
#line 130 "inform7/Chapter 6/Problems, Level 1.w"
else
{
#line 244 "inform7/Chapter 6/Problems, Level 1.w"
c = problem_buffer[i];
if (Problems__Buffer__is_problem_buffer_whitespace(c)) { /* this starts a run of whitespace */
int l = i; while (Problems__Buffer__is_problem_buffer_whitespace(problem_buffer[l])) l++;
if (problem_buffer[l] == 0) break; /* omit any trailing spaces */
i = l - 1; /* skip to final whitespace character of the run */
if (html_flag) HTML__html_char_out(OUT, ' ');
else
{
#line 263 "inform7/Chapter 6/Problems, Level 1.w"
int word_width = 0;
while ((!Problems__Buffer__is_problem_buffer_whitespace(problem_buffer[l])) && (problem_buffer[l] != 0)
&& (problem_buffer[l] != SOURCE_REF_CHAR))
l++, word_width++;
if (line_width + word_width + 1 >= PROBLEM_WORD_WRAP_WIDTH) {
WRITE("\n"); line_width = 0;
for (l=0; l<indentation+1; l++) { line_width+=2; WRITE(" "); }
} else {
WRITE(" "); line_width++;
}
}
#line 250 "inform7/Chapter 6/Problems, Level 1.w"
;
} else {
line_width++;
if (html_flag) HTML__html_char_out(OUT, c);
else if ((c != SOURCE_REF_CHAR) && (c != FORCE_NEW_PARA_CHAR)) WRITE("%c", c);
}
}
#line 131 "inform7/Chapter 6/Problems, Level 1.w"
;
}
if (html_flag) WRITE("</p>");
WRITE("\n");
}
#line 280 "inform7/Chapter 6/Problems, Level 1.w"
int telemetry_recording = FALSE;
void Problems__Buffer__output_problem_buffer(int indentation) {
if (probl == NULL) {
Problems__Buffer__output_problem_buffer_to(problems_file, indentation);
WRITE_TO(problems_file, "\n");
Problems__Buffer__output_problem_buffer_to(STDERR, indentation);
STREAM_FLUSH(STDERR);
WRITE_TO(dl, "\n");
Problems__Buffer__output_problem_buffer_to(dl, indentation);
WRITE_TO(dl, "\n");
if (telemetry_recording) {
WRITE_TO(telmy, "\n");
Problems__Buffer__output_problem_buffer_to(telmy, indentation);
WRITE_TO(telmy, "\n");
}
} else Problems__Buffer__output_problem_buffer_to(probl, indentation);
}
#line 31 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__find_headings_at(parse_node *sentence, parse_node **problem_headings) {
for (int i=0; i<NO_HEADING_LEVELS; i++) problem_headings[i] = NULL;
if (sentence == NULL) return;
ParseTree__traverse_ppn_nocs(Problems__visit_for_headings, &sentence);
parse_node *p = ParseTree__get_problem_falls_under(sentence);
while (p) {
int L = ParseTree__int_annotation(p, heading_level_ANNOT);
problem_headings[L] = p;
p = ParseTree__get_problem_falls_under(p);
}
}
int Problems__visit_for_headings(parse_node *p, parse_node *from, parse_node **sentence) {
if (p == *sentence) {
ParseTree__set_problem_falls_under(p, from);
return TRUE;
}
if (ParseTree__get_type(p) == HEADING_NT) {
ParseTree__set_problem_falls_under(p, from);
}
return FALSE;
}
#line 64 "inform7/Chapter 6/Problems, Level 2.w"
parse_node *last_problem_headings[NO_HEADING_LEVELS];
#line 76 "inform7/Chapter 6/Problems, Level 2.w"
int do_not_locate_problems = FALSE;
void Problems__show_problem_location(void) {
parse_node *problem_headings[NO_HEADING_LEVELS];
int i, f = FALSE;
if (problem_count == 0) {
if (internal_error_thrown)
HTML__html_outcome_image(problems_file, "ni_failed_badly", "Failed");
else
HTML__html_outcome_image(problems_file, "ni_failed", "Failed");
for (i=0; i<NO_HEADING_LEVELS; i++) last_problem_headings[i] = NULL;
}
if (do_not_locate_problems) return;
Problems__find_headings_at(current_sentence, problem_headings);
for (i=0; i<NO_HEADING_LEVELS; i++) if (problem_headings[i] != NULL) f = TRUE;
if (f)
for (i=1; i<NO_HEADING_LEVELS; i++)
if (last_problem_headings[i] != problem_headings[i]) {
{
#line 105 "inform7/Chapter 6/Problems, Level 2.w"
source_file *pos = NULL;
problem_buffer[0] = 0;
if (problem_count > 0) { sprintf(problem_buffer, ">---> "); }
strcat(problem_buffer, "In<b>");
for (f=FALSE; i<NO_HEADING_LEVELS; i++)
if (problem_headings[i] != NULL) {
pos = Lexer__file_of_origin(Wordings__first_wn(ParseTree__get_text(problem_headings[i])));
if (f) strcat(problem_buffer, ", ");
else strcat(problem_buffer, " ");
f = TRUE;
Problems__Buffer__copy_text_into_problem_buffer(ParseTree__get_text(problem_headings[i]));
}
if (f == FALSE) strcat(problem_buffer, " the main source text");
if (pos) {
extension_file *ef = SourceFiles__get_extension_corresponding(pos);
if (ef) {
strcat(problem_buffer, "</b> in the extension <b>");
extension_identifier *eid = Extensions__Files__get_eid(ef);
Extensions__IDs__write_to_C_string(problem_buffer+Platform__strlen(problem_buffer), eid);
}
}
strcat(problem_buffer, "</b>:");
Problems__Buffer__output_problem_buffer(0);
}
#line 94 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
}
for (i=0; i<NO_HEADING_LEVELS; i++) last_problem_headings[i] = problem_headings[i];
}
#line 153 "inform7/Chapter 6/Problems, Level 2.w"
problem_quotation problem_quotations[10];
#line 163 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__problem_quote(int t, char type, void *v) {
if ((t<0) || (t > 10)) internal_error("problem quotation number out of range");
problem_quotations[t].structure_quoted = v;
problem_quotations[t].quotation_type = type;
problem_quotations[t].text_quoted = EMPTY_WORDING;
}
void Problems__problem_quote_textual(int t, char type, wording W) {
if ((t<0) || (t > 10)) internal_error("problem quotation number out of range");
problem_quotations[t].structure_quoted = NULL;
problem_quotations[t].quotation_type = type;
problem_quotations[t].text_quoted = W;
}
#line 181 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_source(int t, parse_node *p) {
if (p == NULL) Problems__problem_quote_textual(t, 'S', EMPTY_WORDING);
else Problems__quote_wording_as_source(t, ParseTree__get_text(p));
}
void Problems__quote_source_eliding_begin(int t, parse_node *p) {
if (p == NULL) Problems__problem_quote_textual(t, 'S', EMPTY_WORDING);
else {
wording W = ParseTree__get_text(p);
if (Preform__parse_nt_against_word_range(phrase_beginning_block_NTM, W, NULL, NULL)) W = GET_RW(phrase_beginning_block_NTM, 1);
Problems__problem_quote_textual(t, 'S', W);
}
}
void Problems__quote_wording(int t, wording W) { Problems__problem_quote_textual(t, 'W', W); }
void Problems__quote_wording_tinted_green(int t, wording W) { Problems__problem_quote_textual(t, 'g', W); }
void Problems__quote_wording_tinted_red(int t, wording W) { Problems__problem_quote_textual(t, 'r', W); }
void Problems__quote_wording_as_source(int t, wording W) { Problems__problem_quote_textual(t, 'S', W); }
#line 201 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_relation(int t, binary_predicate *bp) { Problems__problem_quote(t, 'B', (void *) bp); }
void Problems__quote_extension(int t, extension_file *ef) { Problems__problem_quote(t, 'E', (void *) ef); }
void Problems__quote_phrase(int t, phrase *p) { Problems__problem_quote(t, 'H', (void *) p); }
void Problems__quote_invocation(int t, parse_node *inv) { Problems__problem_quote(t, 'I', (void *) inv); }
void Problems__quote_number(int t, int *num) { Problems__problem_quote(t, 'N', (void *) num); }
void Problems__quote_object(int t, instance *I) { Problems__problem_quote(t, 'O', (void *) I); }
void Problems__quote_subject(int t, inference_subject *infs) {
if (infs == NULL) { Problems__quote_text(t, "something"); return; }
wording W = InferenceSubjects__get_name_text(infs);
if (Wordings__nonempty(W)) { Problems__quote_wording(t, W); return; }
instance *I = InferenceSubjects__as_object_instance(infs);
if (I) { Problems__quote_object(t, I); return; }
Problems__quote_text(t, "something nameless"); /* this never actually happens */
}
void Problems__quote_table(int t, table *tab) {
Problems__quote_source(t, Tables__get_headline(tab));
}
void Problems__quote_property(int t, property *p) { Problems__problem_quote(t, 'P', (void *) p); }
void Problems__quote_text(int t, char *message) { Problems__problem_quote(t, 'T', (void *) message); }
void Problems__quote_wa(int t, word_assemblage *wa) { Problems__problem_quote(t, 'A', (void *) wa); }
void Problems__quote_spec(int t, parse_node *spec) { Problems__problem_quote(t, 'Y', (void *) spec); }
void Problems__quote_extension_id(int t, extension_identifier *eid) { Problems__problem_quote(t, 'X', (void *) eid); }
#line 229 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_kind_of(int t, parse_node *spec) {
if (Rvalues__is_object(spec)) {
if (ParseTree__int_annotation(spec, self_object_ANNOT)) {
Problems__quote_text(t, "implicit object"); /* this is probably never seen, but just in case */
return;
} else if (ParseTree__int_annotation(spec, nothing_object_ANNOT)) {
Problems__quote_text(t, "the 'nothing' non-object"); /* whereas this can certainly happen */
return;
} else {
instance *I = Rvalues__to_instance(spec);
Problems__quote_kind(t, Instances__to_kind(I));
return;
}
}
kind *K = Specifications__to_kind(spec);
if (K) Problems__quote_kind(t, K);
else Problems__quote_spec(t, spec);
}
#line 251 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__quote_kind(int t, kind *K) {
if ((K == NULL) || (Kinds__Compare__eq(K, K_nil))) Problems__quote_text(t, "nothing");
else Problems__problem_quote(t, 'K', (void *) K);
}
#line 264 "inform7/Chapter 6/Problems, Level 2.w"
int shorten_problem_message; /* give short form of this previously-seen problem */
int reading_text_specific_to_short_version; /* modes during problem message writing */
int reading_text_specific_to_long_version;
#line 276 "inform7/Chapter 6/Problems, Level 2.w"
char *explanations[PATIENCE_EXHAUSTION_POINT];
int no_explanations = 0;
int Problems__explained_before(char *explanation) {
int i;
if (no_explanations == PATIENCE_EXHAUSTION_POINT) return TRUE;
for (i=0; i<no_explanations; i++)
if (explanation == explanations[i]) return TRUE;
explanations[no_explanations++] = explanation;
return FALSE;
}
#line 300 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__issue_problem_begin(char *message) {
problem_buffer[0] = 0;
if (strcmp(message, "*") == 0) {
strcpy(problem_buffer, ">++>");
shorten_problem_message = FALSE;
} else if (strcmp(message, "****") == 0) {
strcpy(problem_buffer, ">++++>");
shorten_problem_message = FALSE;
} else if (strcmp(message, "***") == 0) {
strcpy(problem_buffer, ">+++>");
shorten_problem_message = FALSE;
} else if (strcmp(message, "**") == 0) {
shorten_problem_message = FALSE;
} else {
Problems__show_problem_location();
problem_count++;
strcpy(problem_buffer, ">--> ");
shorten_problem_message = Problems__explained_before(message);
}
reading_text_specific_to_short_version = FALSE;
reading_text_specific_to_long_version = FALSE;
}
void Problems__issue_problem_end(void) {
if (compiling_text_routines_mode) Strings__TextSubstitutions__append_text_substitution_proviso();
Problems__Buffer__output_problem_buffer(1);
Problems__Issue__problem_documentation_links(problems_file);
if (crash_on_all_errors) Problems__Fatal__force_crash();
}
#line 348 "inform7/Chapter 6/Problems, Level 2.w"
void Problems__issue_problem_segment(char *message) {
int i;
for (i=0; i<Platform__strlen(message); i++) {
if (message[i] == '%') {
switch (message[i+1]) {
case 'L': reading_text_specific_to_long_version = TRUE; i++; continue;
case 'S': reading_text_specific_to_short_version = TRUE; i++; continue;
case '%': reading_text_specific_to_short_version = FALSE;
reading_text_specific_to_long_version = FALSE; i++; continue;
case '|': reading_text_specific_to_short_version = FALSE;
reading_text_specific_to_long_version = TRUE;
if (shorten_problem_message) strcat(problem_buffer, ".");
i++; continue;
}
}
if ((reading_text_specific_to_short_version) &&
(shorten_problem_message == FALSE)) continue;
if ((reading_text_specific_to_long_version) &&
(shorten_problem_message == TRUE)) continue;
{
#line 381 "inform7/Chapter 6/Problems, Level 2.w"
int len;
if (message[i] == '%') {
switch (message[i+1]) {
case 'P': sprintf(problem_buffer+Platform__strlen(problem_buffer), "%c",
FORCE_NEW_PARA_CHAR);
i++; continue;
}
if (isdigit(message[i+1])) {
int t = ((int) (message[i+1]))-((int) '0'); i++;
if ((t>=1) && (t<=9))
{
#line 401 "inform7/Chapter 6/Problems, Level 2.w"
property *pr;
switch(problem_quotations[t].quotation_type) {
/* Text range-based quotations */
case 'S': Problems__Buffer__copy_source_reference_into_problem_buffer(
problem_quotations[t].text_quoted);
break;
case 'W': Problems__Buffer__copy_text_into_problem_buffer(
problem_quotations[t].text_quoted);
break;
/* Tinted wording */
case 'r':
{
#line 452 "inform7/Chapter 6/Problems, Level 2.w"
TEMPORARY_STREAM;
WRITE_TO(TEMP, "<font color=\"#800000\">");
Wordings__to_stream(TEMP, problem_quotations[t].text_quoted);
WRITE_TO(TEMP, "</font>");
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 413 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
case 'g':
{
#line 462 "inform7/Chapter 6/Problems, Level 2.w"
TEMPORARY_STREAM;
WRITE_TO(TEMP, "<font color=\"#008000\">");
Wordings__to_stream(TEMP, problem_quotations[t].text_quoted);
WRITE_TO(TEMP, "</font>");
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 415 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
/* Binary structure-based quotations */
case 'A':
{
#line 472 "inform7/Chapter 6/Problems, Level 2.w"
word_assemblage *wa = (word_assemblage *) problem_quotations[t].structure_quoted;
TEMPORARY_STREAM;
WordAssemblages__copy_to_stream(TEMP, wa);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 419 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
case 'B':
{
#line 481 "inform7/Chapter 6/Problems, Level 2.w"
binary_predicate *bp = (binary_predicate *) problem_quotations[t].structure_quoted;
TEMPORARY_STREAM;
BinaryPredicates__describe_for_problems(TEMP, bp);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 421 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
case 'E':
{
#line 508 "inform7/Chapter 6/Problems, Level 2.w"
extension_file *ef = (extension_file *) (problem_quotations[t].structure_quoted);
TEMPORARY_STREAM;
Extensions__Files__write_full_title_to_stream(TEMP, ef);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 423 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
case 'H':
{
#line 490 "inform7/Chapter 6/Problems, Level 2.w"
phrase *ph = (phrase *) (problem_quotations[t].structure_quoted);
TEMPORARY_STREAM;
Phrases__write_HTML_representation(TEMP, ph, INDEX_PHRASE_FORMAT);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 425 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
case 'I':
{
#line 499 "inform7/Chapter 6/Problems, Level 2.w"
parse_node *inv = (parse_node *) (problem_quotations[t].structure_quoted);
TEMPORARY_STREAM;
Phrases__TypeData__Textual__inv_write_HTML_representation(TEMP, inv);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 427 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
case 'K':
{
#line 517 "inform7/Chapter 6/Problems, Level 2.w"
kind *K = (kind *) problem_quotations[t].structure_quoted;
TEMPORARY_STREAM;
Kinds__Textual__write_articled(TEMP, K);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 429 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
case 'N':
sprintf(problem_buffer+Platform__strlen(problem_buffer), "%d",
*((int *) (problem_quotations[t].structure_quoted)));
break;
case 'O':
{
#line 550 "inform7/Chapter 6/Problems, Level 2.w"
instance *I = (instance *) problem_quotations[t].structure_quoted;
if (I == NULL) break;
wording W = Instances__get_name(I, FALSE);
if (Wordings__nonempty(W))
Problems__Buffer__copy_text_into_problem_buffer(W);
else {
strcat(problem_buffer, "nameless ");
kind *k = Instances__to_kind(I);
wording KW = Kinds__Behaviour__get_name(k, FALSE);
if (Wordings__nonempty(KW)) Problems__Buffer__copy_text_into_problem_buffer(KW);
else strcat(problem_buffer, "thing");
parse_node *from = Instances__get_creating_sentence(I);
if (from) {
strcat(problem_buffer, " created in the sentence ");
Problems__Buffer__copy_source_reference_into_problem_buffer(ParseTree__get_text(from));
}
}
}
#line 435 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
case 'P': pr = (property *) problem_quotations[t].structure_quoted;
Problems__Buffer__copy_text_into_problem_buffer(pr->name);
break;
case 'T': strcat(problem_buffer, (char *) (problem_quotations[t].structure_quoted));
break;
case 'X':
{
#line 535 "inform7/Chapter 6/Problems, Level 2.w"
extension_identifier *eid = (extension_identifier *) problem_quotations[t].structure_quoted;
TEMPORARY_STREAM;
Extensions__IDs__write_to_HTML_file(TEMP, eid, FALSE);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 442 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
case 'Y':
{
#line 526 "inform7/Chapter 6/Problems, Level 2.w"
parse_node *spec = (parse_node *) problem_quotations[t].structure_quoted;
TEMPORARY_STREAM;
Specifications__write_out_in_English(TEMP, spec);
strcat(problem_buffer, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 444 "inform7/Chapter 6/Problems, Level 2.w"
;
break;
default: internal_error("unknown error token type");
}
}
#line 390 "inform7/Chapter 6/Problems, Level 2.w"
;
continue;
}
}
len = Platform__strlen(problem_buffer);
problem_buffer[len] = message[i]; problem_buffer[len+1] = 0;
}
#line 369 "inform7/Chapter 6/Problems, Level 2.w"
;
}
}
#line 578 "inform7/Chapter 6/Problems, Level 2.w"
int tail_of_report_written = FALSE;
void Problems__write_reports(int disaster_struck) {
int total_words;
if (tail_of_report_written) return;
tail_of_report_written = TRUE;
crash_on_all_errors = FALSE;
if (problem_count > 0) {
probl = problems_file;
Problems__issue_problem_begin("*");
if (disaster_struck)
{
#line 613 "inform7/Chapter 6/Problems, Level 2.w"
Problems__issue_problem_segment(
"What has happened here is that one of the checks Inform carries "
"out internally, to see if it is working properly, has failed. "
"There must be a bug in this copy of Inform. It may be worth "
"checking whether you have the current, up-to-date version. "
"If so, please report this problem via www.inform7.com/bugs. %P"
"As for fixing your source text to avoid this bug, the last thing "
"you changed is probably the cause, if there is a simple cause. "
"Your source text might in fact be wrong, and the problem might be "
"occurring because Inform has failed to find a good way to say so. "
"But even if your source text looks correct, there are "
"probably rephrasings which would achieve the same effect.");
}
#line 588 "inform7/Chapter 6/Problems, Level 2.w"
else
{
#line 629 "inform7/Chapter 6/Problems, Level 2.w"
if (problem_count == 1)
Problems__issue_problem_segment(
"Because of this problem, the source could not be translated "
"into a working game. (Correct the source text to "
"remove the difficulty and click on Go once again.)");
else
Problems__issue_problem_segment(
"Problems occurring in translation prevented the game "
"from being properly created. (Correct the source text to "
"remove these problems and click on Go once again.)");
HTML__outcome_image_tail(problems_file);
text_stream *STATUS = ProgressBar__begin_outcome();
if (STATUS) {
WRITE_TO(STATUS, "Translation failed: %d problem%s found",
problem_count, (problem_count==1)?"":"s");
ProgressBar__end_outcome();
}
}
#line 589 "inform7/Chapter 6/Problems, Level 2.w"
;
Problems__issue_problem_end();
probl = NULL;
} else {
int rooms, things;
HTML__html_outcome_image(problems_file, "ni_succeeded", "Succeeded");
PL__Spatial__get_world_size(&rooms, &things);
Problems__quote_number(1, &rooms);
if (rooms == 1) Problems__quote_text(2, "room"); else Problems__quote_text(2, "rooms");
Problems__quote_number(3, &things);
if (things == 1) Problems__quote_text(4, "thing"); else Problems__quote_text(4, "things");
total_words = SourceFiles__total_word_count(FIRST_OBJECT(source_file));
Problems__quote_number(5, &total_words);
{
#line 662 "inform7/Chapter 6/Problems, Level 2.w"
probl = problems_file;
Problems__issue_problem_begin("**");
Problems__issue_problem_segment(
"The %5-word source text has successfully been translated "
"into a world with %1 %2 and %3 %4, and the index has been "
"brought up to date.");
Problems__issue_problem_end();
HTML__outcome_image_tail(problems_file);
if (telemetry_recording) {
Log__ensure_telemetry_file();
probl = telmy;
Problems__issue_problem_begin("**");
Problems__issue_problem_segment(
"The %5-word source text has successfully been translated "
"into a world with %1 %2 and %3 %4, and the index has been "
"brought up to date.");
Problems__issue_problem_end();
WRITE_TO(telmy, "\n");
}
probl = STDOUT;
WRITE_TO(STDOUT, "\n");
Problems__issue_problem_begin("**");
Problems__issue_problem_segment(
"The %5-word source text has successfully been translated "
"into an intermediate description which can be run through "
"Inform 6 to complete compilation. There were %1 %2 and %3 %4.");
Problems__issue_problem_end();
STREAM_FLUSH(STDOUT);
probl = NULL;
ProgressBar__final_state_of_progress_bar();
text_stream *STATUS = ProgressBar__begin_outcome();
if (STATUS) {
WRITE_TO(STATUS, "Translation succeeded: %d room%s, %d thing%s",
rooms, (rooms==1)?"":"s",
things, (things==1)?"":"s");
ProgressBar__end_outcome();
}
}
#line 602 "inform7/Chapter 6/Problems, Level 2.w"
;
problem_count = 0;
}
}
#line 31 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__internal_error_end(void) {
Problems__issue_problem_end();
Problems__write_reports(TRUE);
if (crash_on_internal_errors) Problems__Fatal__force_crash();
exit(1);
}
#line 46 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__internal_error_fn(char *p, char *filename, int linenum) {
internal_error_thrown = TRUE;
if (current_sentence == NULL) {
Problems__Issue__internal_error_tu_fn(p, filename, linenum);
return;
}
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, p);
Problems__quote_text(3, filename);
Problems__quote_number(4, &linenum);
Problems__issue_problem_begin(p);
Problems__issue_problem_segment(
"An internal error has occurred: %2. The current sentence is %1; the "
"error was detected at line %4 of \"%3\". This should never happen, "
"and I am now halting in abject failure.");
Problems__Issue__internal_error_end();
}
void Problems__Issue__internal_error_tu_fn(char *p, char *filename, int linenum) {
internal_error_thrown = TRUE;
Problems__quote_text(1, p);
Problems__quote_text(2, filename);
Problems__quote_number(3, &linenum);
Problems__issue_problem_begin(p);
Problems__issue_problem_segment(
"An internal error has occurred: %1. The error was detected at "
"line %3 of \"%2\". This should never happen, and I am now halting "
"in abject failure.");
Problems__Issue__internal_error_end();
}
#line 85 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__nodal_error_fn(parse_node *pn, char *p, char *filename, int linenum) {
LOG("Internal nodal error at:\n");
LOG("$T\n", pn);
Problems__Issue__internal_error_fn(p, filename, linenum);
}
#line 94 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__nodal_check(parse_node *pn, node_type_t node_type_required, char *filename, int linenum) {
char internal_message[128];
if (pn == NULL) {
sprintf(internal_message, "NULL node found where type %s expected",
ParseTree__get_type_name(node_type_required));
Problems__Issue__internal_error_tu_fn(internal_message, filename, linenum);
}
if (ParseTree__get_type(pn) == node_type_required) return;
sprintf(internal_message, "Node of type %s found where type %s expected",
ParseTree__get_type_name(ParseTree__get_type(pn)),
ParseTree__get_type_name(node_type_required));
Problems__Issue__nodal_error_fn(pn, internal_message, filename, linenum);
}
#line 113 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__internal_error_on_node_type_fn(parse_node *pn, char *filename,
int linenum) {
char internal_message[128];
if (pn == NULL)
Problems__Issue__internal_error_tu_fn("Unexpected NULL node found", filename, linenum);
sprintf(internal_message, "Unexpectedly found node of type %s",
ParseTree__get_type_name(ParseTree__get_type(pn)));
Problems__Issue__nodal_error_fn(pn, internal_message, filename, linenum);
}
#line 128 "inform7/Chapter 6/Problems, Level 3.w"
parse_node *latest_s_subtree = NULL;
void Problems__Issue__s_subtree_error_set_position(parse_node *p) {
latest_s_subtree = p;
}
void Problems__Issue__s_subtree_error(char *mess) {
char internal_message[128];
sprintf(internal_message, "S-subtree error: %s", mess);
LOG("%s", internal_message);
if (latest_s_subtree) LOG("Applied to the subtree:\n$T", latest_s_subtree);
internal_error(internal_message);
}
#line 195 "inform7/Chapter 6/Problems, Level 3.w"
char *sigil_of_latest_unlinked_problem = NULL;
char *sigil_of_latest_problem = NULL;
void Problems__Issue__problem_documentation_links(OUTPUT_STREAM) {
if (sigil_of_latest_unlinked_problem == NULL) return;
char *chap = NULL, *sec = NULL;
char *leaf = Index__DocReferences__link_if_possible_once(sigil_of_latest_unlinked_problem, &chap, &sec);
if (leaf) {
HTML__open_para(OUT, 2, "tight");
WRITE("<a href=inform:/%s.html><img border=0 src=inform:/doc_images/help.png></a>", leaf);
if ((chap) && (sec)) {
WRITE("&nbsp;<i>See the manual: %s &gt; %s</i></p>\n", chap, sec);
} else {
WRITE("&nbsp;<i>See the manual.</i></p>\n");
}
if (telemetry_recording) {
WRITE_TO(telmy, "See the manual: %s > %s\n\n", chap, sec);
}
}
sigil_of_latest_unlinked_problem = NULL;
}
char *Problems__Issue__latest_sigil(void) {
return sigil_of_latest_problem;
}
#line 228 "inform7/Chapter 6/Problems, Level 3.w"
int echo_problem_message_sigils = FALSE;
#line 234 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__handmade_problem(SIGIL_ARGUMENTS) {
ACT_ON_SIGIL
Problems__issue_problem_begin("");
}
#line 244 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__limit_problem(SIGIL_ARGUMENTS, char *what_has_run_out, int how_many) {
ACT_ON_SIGIL
Problems__quote_text(1, what_has_run_out);
Problems__quote_number(2, &how_many);
Problems__issue_problem_begin("");
Problems__issue_problem_segment(
"I have run out of memory for %1 - there's room for %2, but no more. "
"This is a 'hard limit', hard in the sense of deadlines, or luck: "
"there is no getting around it. You will need to rewrite your source "
"text so that it needs fewer %1.");
Problems__issue_problem_end();
Problems__write_reports(FALSE);
exit(1);
}
void Problems__Issue__memory_allocation_problem(SIGIL_ARGUMENTS, char *what_has_run_out) {
ACT_ON_SIGIL
Problems__quote_text(1, what_has_run_out);
Problems__issue_problem_begin("");
Problems__issue_problem_segment(
"I am unable to persuade this computer to let me have memory in "
"which to store the %1. This rarely happens on a modern desktop or laptop, "
"but might occur on a small handheld device - if so, it may be a "
"symptom that the device isn't powerful enough to run me. (See how "
"I pass the blame?)");
Problems__issue_problem_end();
Problems__write_reports(FALSE);
exit(1);
}
#line 279 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__lexical_problem(SIGIL_ARGUMENTS, char *message, char *concerning, char *exp) {
ACT_ON_SIGIL
char *lexical_explanation =
"This is a low-level problem happening when I am still reading in the "
"source. Such problems sometimes arise because I have been told to "
"read a source file which is not text at all.";
if (exp != NULL) lexical_explanation = exp;
Problems__quote_text(1, message);
if (concerning) Problems__quote_text(2, concerning);
else if (current_sentence) Problems__quote_source(2, current_sentence);
else Problems__quote_text(2, "<text generated internally>");
Problems__quote_text(3, lexical_explanation);
Problems__issue_problem_begin(lexical_explanation);
Problems__issue_problem_segment("%1: %2%L.%%%| %3");
Problems__issue_problem_end();
}
#line 300 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__unlocated_problem(SIGIL_ARGUMENTS, char *message) {
ACT_ON_SIGIL
do_not_locate_problems = TRUE;
Problems__issue_problem_begin(message);
Problems__issue_problem_segment(message);
Problems__issue_problem_end();
do_not_locate_problems = FALSE;
}
void Problems__Issue__unlocated_problem_on_file(SIGIL_ARGUMENTS, char *message, char *fn) {
ACT_ON_SIGIL
do_not_locate_problems = TRUE;
Problems__quote_text(1, fn);
Problems__issue_problem_begin(message);
Problems__issue_problem_segment(message);
Problems__issue_problem_end();
do_not_locate_problems = FALSE;
}
#line 326 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__sentence_problem(SIGIL_ARGUMENTS, char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, message);
Problems__quote_text(3, explanation);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment("You wrote %1: %Sagain, %%%Lbut %%%2%|, %3");
Problems__issue_problem_end();
}
#line 339 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__sentence_problem_with_note(SIGIL_ARGUMENTS,
char *message, char *explanation, char *note) {
ACT_ON_SIGIL
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, message);
Problems__quote_text(3, explanation);
Problems__quote_text(4, note);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment("You wrote %1: %Sagain, %%%Lbut %%%2%|, %3 %P%4");
Problems__issue_problem_end();
}
#line 355 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__sentence_in_detail_problem(SIGIL_ARGUMENTS,
wording W, char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, message);
Problems__quote_text(3, explanation);
Problems__quote_wording(4, W);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment(
"You wrote %1, and in particular '%4': %Sagain, %%%Lbut %%%2%|, %3");
Problems__issue_problem_end();
}
#line 372 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__negative_sentence_problem(SIGIL_ARGUMENTS) {
Problems__Issue__sentence_problem(PASS_SIGIL,
"assertions about the initial state of play must be positive, not negative",
"so 'The cat is an animal' is fine but not 'The cat is not a container'. "
"I have only very feeble powers of deduction - sometimes the implications "
"of a negative statement are obvious to a human reader, but not to me.");
}
#line 392 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__assertion_problem(SIGIL_ARGUMENTS, char *message, char *explanation) {
wording RTW = EMPTY_WORDING; /* "rather than" text */
ACT_ON_SIGIL
if ((current_sentence == NULL) || (current_sentence->down == NULL) ||
(ParseTree__get_type(current_sentence->down) != AVERB_NT)) {
LOG("(Assertion error reverting to sentence error.)\n");
Problems__Issue__sentence_problem(PASS_SIGIL, message, explanation);
return;
}
LOG("(Assertion error: looking for alternative verbs in <$w>.)\n",
ParseTree__get_text(current_sentence));
wording AW = Wordings__trim_both_ends(ParseTree__get_text(current_sentence));
LOOP_THROUGH_WORDING(i, AW)
if ((i != Wordings__first_wn(ParseTree__get_text(current_sentence->down))) &&
(Text__unexpectedly_upper_case(i) == FALSE)) {
int j = Preform__parse_nt_against_word_range(general_verb_NTM, Wordings__from(ParseTree__get_text(current_sentence), i), NULL, NULL);
if (j > 0) RTW = Wordings__new(i, j);
}
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, message);
Problems__quote_text(3, explanation);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment("You wrote %1: %Sagain, %%%Lbut %%%2%|, %3");
if (Wordings__nonempty(RTW)) {
Problems__quote_wording(4, ParseTree__get_text(current_sentence->down));
Problems__quote_wording(5, RTW);
Problems__issue_problem_segment( /* see also PM_AmbiguousVerb */
" %P(It may help to know that I am reading the primary verb here "
"as '%4', not '%5'.)");
}
Problems__Issue__diagnose_further();
Problems__issue_problem_end();
}
void Problems__Issue__diagnose_further(void) {
if (current_sentence == NULL) return;
if (Wordings__empty(ParseTree__get_text(current_sentence))) return;
int sqc = 0;
LOOP_THROUGH_WORDING(i, ParseTree__get_text(current_sentence)) sqc += Text__singly_quoted(i);
if (sqc >= 2)
Problems__issue_problem_segment(
" %P(I notice what look like single quotation marks in this "
"sentence. If you meant to write some quoted text, it needs to "
"be in double quotes, \"like this\" and not 'like this'.)");
control_structure_phrase *csp =
Sentences__RuleSubtrees__detect_control_structure(ParseTree__get_text(current_sentence));
if (csp)
Problems__issue_problem_segment(
" %P(The way this sentence starts makes me think it might have been "
"intended as part of a rule rather than being a statement about the "
"the way things are at the beginning of play. For example, 'If the "
"player is in the Penalty Zone, say \"An alarm sounds.\" is not "
"allowed: it has to be put in the form of a rule showing Inform "
"what circumstances apply - for example 'Every turn: if the player is "
"in the Penalty Zone, say \"An alarm sounds.\")");
}
#line 457 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__definition_problem(SIGIL_ARGUMENTS, parse_node *q,
char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_source(1, q);
Problems__quote_text(2, message);
Problems__quote_text(3, explanation);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment("You gave as a definition %1: %Sagain, %%%Lbut %%%2%|, %3");
Problems__issue_problem_end();
}
void Problems__Issue__adjective_problem(SIGIL_ARGUMENTS, wording IX, wording D,
char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_wording(1, IX);
Problems__quote_wording(2, D);
Problems__quote_text(3, message);
Problems__quote_text(4, explanation);
Problems__quote_source(5, current_sentence);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment("In %5 you defined an adjective by '%1' intending that "
"it would apply to '%2': %Sagain, %%%Lbut %%%3%|, %4");
Problems__issue_problem_end();
}
#line 487 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__two_sentences_problem(SIGIL_ARGUMENTS, parse_node *other_sentence,
char *message, char *explanation) {
ACT_ON_SIGIL
if (current_sentence == other_sentence) {
Problems__Issue__sentence_problem(PASS_SIGIL, message, explanation);
return;
}
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, other_sentence);
Problems__quote_text(3, message);
Problems__quote_text(4, explanation);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment(
"You wrote %1, but in another sentence %2: %Sagain, %%%Lbut %%%3%|, %4");
Problems__issue_problem_end();
}
#line 508 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__contradiction_problem(SIGIL_ARGUMENTS, parse_node *A, parse_node *B,
instance *I, char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_source(1, A);
Problems__quote_source(2, B);
Problems__quote_object(3, I);
Problems__quote_text(4, message);
Problems__quote_text(5, explanation);
Problems__issue_problem_begin(explanation);
if (Wordings__eq(ParseTree__get_text(A), ParseTree__get_text(B)) == FALSE)
Problems__issue_problem_segment("You wrote %1, but in another sentence %2: ");
else
Problems__issue_problem_segment("You wrote %1: ");
Problems__issue_problem_segment("%Sagain, %%%3 %4%|, %5");
Problems__issue_problem_end();
}
void Problems__Issue__infs_contradiction_problem(SIGIL_ARGUMENTS, parse_node *A, parse_node *B,
inference_subject *infs, char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_source(1, A);
Problems__quote_source(2, B);
Problems__quote_subject(3, infs);
Problems__quote_text(4, message);
Problems__quote_text(5, explanation);
Problems__issue_problem_begin(explanation);
if (Wordings__eq(ParseTree__get_text(A), ParseTree__get_text(B)) == FALSE)
Problems__issue_problem_segment("You wrote %1, but in another sentence %2: ");
else Problems__issue_problem_segment("You wrote %1: ");
Problems__issue_problem_segment("%Sagain, %%%3 %4%|, %5");
Problems__issue_problem_end();
}
#line 547 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__table_problem(SIGIL_ARGUMENTS, table *t, table_column *tc, parse_node *data,
char *message) {
ACT_ON_SIGIL
current_sentence = t->headline_fragment;
Problems__quote_table(1, t);
if (tc) Problems__quote_wording(2, tc->name);
if (data) Problems__quote_source(3, data);
Problems__issue_problem_begin("");
Problems__issue_problem_segment(message);
Problems__issue_problem_end();
}
#line 563 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__equation_problem(SIGIL_ARGUMENTS, equation *eqn, char *p, char *text) {
ACT_ON_SIGIL
char plenty[1000];
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, eqn->equation_text);
Problems__quote_text(3, p);
strcpy(plenty, "In %1, you define an equation '%2': but ");
Extensions__IDs__truncated_strcpy(plenty + Platform__strlen(plenty), text, 900);
Problems__issue_problem_begin("");
Problems__issue_problem_segment(plenty);
Problems__issue_problem_end();
}
void Problems__Issue__equation_symbol_problem(SIGIL_ARGUMENTS, equation *eqn, wording W, char *text) {
ACT_ON_SIGIL
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_text(3, text);
Problems__issue_problem_begin("");
Problems__issue_problem_segment(
"In %1, you define an equation which mentions the symbol '%2': but %3");
Problems__issue_problem_end();
}
#line 590 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__inline_problem(SIGIL_ARGUMENTS, phrase *ph, char *definition,
char *message) {
ACT_ON_SIGIL
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, definition);
wording XW = Phrases__Usage__get_preamble_text(&(ph->usage_data));
Problems__quote_wording_as_source(3, XW);
Problems__issue_problem_begin("");
Problems__issue_problem_segment(
"You wrote %1, which I read as making use of the phrase %3. This in turn "
"has what's called an 'inline' definition, written in a technical notation "
"usually needed only by the Standard Rules or other low-level extensions. "
"The definition here is '%2' but it seems to be broken. ");
Problems__issue_problem_segment(message);
Problems__issue_problem_end();
}
#line 611 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__tcp_problem(SIGIL_ARGUMENTS, tc_problem_kit *tck, char *prototype) {
if (tck->issue_error) {
ACT_ON_SIGIL
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, tck->ew_text);
Problems__quote_text(3, tck->intention);
Problems__issue_problem_begin("");
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend '%2' to %3, but ");
Problems__issue_problem_segment(prototype);
Problems__issue_problem_end();
}
tck->flag_problem = TRUE;
}
#line 633 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__object_problem(SIGIL_ARGUMENTS, instance *I,
char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_object(1, I);
Problems__quote_text(2, message);
Problems__quote_text(3, explanation);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment("The %1 %2%|, %3");
Problems__issue_problem_end();
}
void Problems__Issue__object_problem_at_sentence(SIGIL_ARGUMENTS, instance *I,
char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, message);
Problems__quote_text(3, explanation);
Problems__quote_object(4, I);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment("You wrote %1, but the %4 %2%|, %3");
Problems__issue_problem_end();
}
void Problems__Issue__subject_problem_at_sentence(SIGIL_ARGUMENTS, inference_subject *infs,
char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, message);
Problems__quote_text(3, explanation);
Problems__quote_subject(4, infs);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment("You wrote %1, but the %4 %2%|, %3");
Problems__issue_problem_end();
}
#line 674 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__subject_creation_problem(SIGIL_ARGUMENTS, inference_subject *subj,
char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_subject(1, subj);
Problems__quote_text(2, message);
Problems__quote_text(3, explanation);
wording W = InferenceSubjects__get_name_text(subj);
if (Wordings__nonempty(W)) {
Problems__quote_source(4, Sentences__NPs__new_raw(W));
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment(
"I've made something called %4 but it %2%|, %3");
Problems__issue_problem_end();
} else {
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment(
"I've made something called '%1' but it %2%|, %3");
Problems__issue_problem_end();
}
}
#line 702 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__inference_problem(SIGIL_ARGUMENTS, inference_subject *infs, inference *inf,
char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_subject(1, infs);
Problems__quote_source(2, World__Inferences__where_inferred(inf));
Problems__quote_text(3, message);
Problems__quote_text(4, explanation);
Problems__quote_property(5, World__Inferences__get_property(inf));
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment(
"You wrote %2: but the property %5 for the %1 %3%|, %4");
Problems__issue_problem_end();
}
#line 721 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__property_problem(SIGIL_ARGUMENTS, property *prn, char *message, char *explanation) {
ACT_ON_SIGIL
Problems__quote_property(1, prn);
Problems__quote_text(2, message);
Problems__quote_text(3, explanation);
Problems__issue_problem_begin(explanation);
Problems__issue_problem_segment("The %1 %2%|, %3");
Problems__issue_problem_end();
}
#line 735 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__extension_problem(SIGIL_ARGUMENTS, extension_file *ef, char *message) {
ACT_ON_SIGIL
Problems__quote_extension(1, ef);
Problems__quote_text(2, message);
Problems__issue_problem_begin(message);
Problems__issue_problem_segment(
"The extension %1, which your source text makes use of, %2.");
Problems__issue_problem_end();
}
#line 751 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__release_problem(SIGIL_ARGUMENTS, char *message, filename *name) {
ACT_ON_SIGIL
Problems__quote_text(1, message);
char fn[MAX_FILENAME_LENGTH];
Filenames__to_string(fn, name);
Problems__quote_text(2, fn);
Problems__issue_problem_begin(message);
Problems__issue_problem_segment("A problem occurred with the 'Release along with...': "
"instructions: %1 (with the file '%2')");
Problems__issue_problem_end();
}
void Problems__Issue__release_problem_path(SIGIL_ARGUMENTS, char *message, pathname *path) {
ACT_ON_SIGIL
Problems__quote_text(1, message);
char pn[MAX_FILENAME_LENGTH];
Pathnames__to_string(pn, path);
Problems__quote_text(2, pn);
Problems__issue_problem_begin(message);
Problems__issue_problem_segment("A problem occurred with the 'Release along with...': "
"instructions: %1 (with the file '%2')");
Problems__issue_problem_end();
}
void Problems__Issue__release_problem_at_sentence(SIGIL_ARGUMENTS, char *message, filename *name) {
ACT_ON_SIGIL
Problems__quote_text(1, message);
char fn[MAX_FILENAME_LENGTH];
Filenames__to_string(fn, name);
Problems__quote_text(2, fn);
Problems__quote_source(3, current_sentence);
Problems__issue_problem_begin(message);
Problems__issue_problem_segment("A problem occurred with the 'Release along with...': "
"instructions (%3): %1 (with the file '%2')");
Problems__issue_problem_end();
}
#line 793 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__map_problem(SIGIL_ARGUMENTS, parse_node *q, char *message) {
ACT_ON_SIGIL
Problems__quote_source(1, q);
Problems__quote_text(2, message);
Problems__issue_problem_begin("");
Problems__issue_problem_segment("You gave as a hint in map-making: %1. %2");
Problems__issue_problem_end();
}
void Problems__Issue__map_problem_wanted_but(SIGIL_ARGUMENTS, parse_node *q, char *i_wanted_a, int vw1) {
ACT_ON_SIGIL
Problems__quote_source(1, q);
Problems__quote_text(2, i_wanted_a);
Problems__quote_wording(3, Wordings__one_word(vw1));
Problems__issue_problem_begin("");
Problems__issue_problem_segment(
"You gave as a hint in map-making: %1. But the value '%3' did not "
"fit - it should have been %2.");
Problems__issue_problem_end();
}
#line 819 "inform7/Chapter 6/Problems, Level 3.w"
void Problems__Issue__start_problems_report(void) {
if (STREAM_OPEN_TO_FILE(problems_file, filename_of_report, UTF8_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open problem log", filename_of_report);
HTML__html_header(problems_file, "Translating the Source", NULL, NULL);
}
void Problems__Issue__issue_problems_banner(OUTPUT_STREAM, char *verdict) {
WRITE("<!--BANNER BEGINS-->\n");
WRITE("<table cellspacing=\"3\" border=\"0\" width=\"100%%\">\n"); INDENT;
WRITE("<tr id=\"surround0\">\n"); INDENT;
WRITE("<td style=\"width:100%%\">\n"); INDENT;
WRITE("<!--HEADING BEGINS-->\n");
WRITE("<div class=\"headingbox%s\">\n", verdict); INDENT;
WRITE("<div class=\"headingtext\">Report on Translation: %s</div>\n",
verdict);
WRITE("<div class=\"headingrubric\">Produced by %s (build %s)</div>\n",
NI_VERSION, NI_BUILD);
OUTDENT; WRITE("</div>\n");
WRITE("<!--HEADING ENDS-->\n");
OUTDENT; WRITE("</td>\n");
OUTDENT; WRITE("</tr>\n");
OUTDENT; WRITE("</table>\n");
WRITE("<!--BANNER ENDS-->\n");
}
#line 76 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__identify_word(int wn) {
vocabulary_entry *ve = Vocabulary__entry_for_text(Lexer__word_text(wn));
ve->raw_exemplar = Lexer__word_raw_text(wn);
Lexer__set_word(wn, ve);
}
void Vocabulary__identify_word_range(wording W) {
LOOP_THROUGH_WORDING(i, W)
Vocabulary__identify_word(i);
}
#line 91 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__change_text_of_word(int wn, char *new) {
Lexer__set_word_text(wn, new);
Lexer__set_word_raw_text(wn, new);
Vocabulary__identify_word(wn);
}
#line 101 "inform7/Chapter 7/Vocabulary.w"
vocabulary_entry *Vocabulary__vocab_entry_new(char *text, int hash_code, unsigned int flags, int val) {
vocabulary_entry *ve;
int l = Platform__strlen(text);
ve = CREATE(vocabulary_entry);
ve->exemplar = text; ve->raw_exemplar = text;
ve->start_list = NULL; ve->end_list = NULL; ve->middle_list = NULL;
ve->subset_list = NULL; ve->subset_list_length = 0;
ve->next_in_vocab_hash = NULL;
ve->lower_case_form = NULL; ve->upper_case_form = NULL;
ve->hash = hash_code;
ve->nt_incidence = 0;
ve->flags = flags;
if ((l>3) && (text[l-3] == 'i') && (text[l-2] == 'n') && (text[l-1] == 'g'))
ve->flags |= ING_MC;
if (Kinds__Textual__parse_variable(ve)) ve->flags |= KIND_FAST_MC;
if (flags & NUMBER_MC) Preform__mark_as_cardinal(ve);
if (flags & ORDINAL_MC) Preform__mark_as_ordinal(ve);
ve->literal_number_value = val;
ve->one_word_kind = NULL;
return ve;
}
void Vocabulary__log(vocabulary_entry *ve) {
if (ve == NULL) { LOG("NULL"); return; }
if (ve->exemplar == NULL) { LOG("NULL-EXEMPLAR"); return; }
LOG("%08x-%s-%08x", ve->hash, ve->raw_exemplar, ve->flags);
}
#line 154 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__set_raw_exemplar_to_text(int wn) {
Lexer__word(wn)->raw_exemplar = Lexer__word_text(wn);
}
#line 162 "inform7/Chapter 7/Vocabulary.w"
char *Vocabulary__get_exemplar(vocabulary_entry *ve, int raw) {
if (raw) return ve->raw_exemplar;
else return ve->exemplar;
}
#line 171 "inform7/Chapter 7/Vocabulary.w"
int Vocabulary__get_literal_number_value(vocabulary_entry *ve) {
return ve->literal_number_value;
}
void Vocabulary__set_literal_number_value(vocabulary_entry *ve, int val) {
ve->literal_number_value = val;
}
#line 181 "inform7/Chapter 7/Vocabulary.w"
kind *Vocabulary__get_kind(vocabulary_entry *ve) {
return ve->one_word_kind;
}
void Vocabulary__set_kind(vocabulary_entry *ve, kind *K) {
ve->one_word_kind = K;
Vocabulary__set_flags(ve, KIND_FAST_MC);
Preform__mark_vocabulary(ve, k_kind_NTM);
}
#line 198 "inform7/Chapter 7/Vocabulary.w"
int Vocabulary__used_case_sensitively(vocabulary_entry *ve) {
if ((ve->upper_case_form) || (ve->lower_case_form)) return TRUE;
return FALSE;
}
vocabulary_entry *Vocabulary__get_lower_case_form(vocabulary_entry *ve) {
return ve->lower_case_form;
}
vocabulary_entry *Vocabulary__make_case_sensitive(vocabulary_entry *ve) {
if (ve->upper_case_form) return ve->upper_case_form;
ve->upper_case_form =
Vocabulary__vocab_entry_new(ve->exemplar, ve->hash, ve->flags, ve->literal_number_value);
ve->upper_case_form->lower_case_form = ve;
return ve->upper_case_form;
}
#line 217 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__set_flags(vocabulary_entry *ve, unsigned int t) {
ve->flags |= t;
}
unsigned int Vocabulary__test_vflags(vocabulary_entry *ve, unsigned int t) {
return (ve->flags) & t;
}
unsigned int Vocabulary__test_flags(int wn, unsigned int t) {
return (Lexer__word(wn)->flags) & t;
}
#line 233 "inform7/Chapter 7/Vocabulary.w"
unsigned int Vocabulary__disjunction_of_flags(wording W) {
unsigned int d = 0;
LOOP_THROUGH_WORDING(i, W)
d |= (Lexer__word(i)->flags);
return d;
}
#line 243 "inform7/Chapter 7/Vocabulary.w"
void Vocabulary__set_ntb(vocabulary_entry *ve, int R) {
ve->nt_incidence = R;
}
int Vocabulary__get_ntb(vocabulary_entry *ve) {
return ve->nt_incidence;
}
#line 295 "inform7/Chapter 7/Vocabulary.w"
int Vocabulary__hash_code_from_word(char *text) {
unsigned int hash_code = 0;
char *p = text;
switch(*p) {
case '-': if (p[1] == 0) break; /* an isolated minus sign is an ordinary word */
/* and otherwise fall into... */
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
/* the first character may prove to be the start of a number: is this true? */
for (p++; *p; p++) if (isdigit(*p) == FALSE) goto Try_Text;
return NUMBER_HASH;
case ' ': return I6_HASH;
case '(': if (p[1] == '-') return I6_HASH;
break;
case '"': return TEXT_HASH;
}
Try_Text:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-conversion"
for (p=text; *p; p++) hash_code = hash_code*30011 + (*p);
#pragma clang diagnostic pop
return (int) (3+(hash_code % (HASH_TAB_SIZE-3))); /* result of X 30011, plus 3 */
}
#line 325 "inform7/Chapter 7/Vocabulary.w"
vocabulary_entry *list_of_vocab_with_hash[HASH_TAB_SIZE];
void Vocabulary__start_hash_table(void) {
int i;
for (i=0; i<HASH_TAB_SIZE; i++) list_of_vocab_with_hash[i] = NULL;
}
#line 340 "inform7/Chapter 7/Vocabulary.w"
int no_vocabulary_entries = 0;
vocabulary_entry *Vocabulary__entry_for_text(char *text) {
vocabulary_entry *new_entry;
int hash_code = Vocabulary__hash_code_from_word(text), val = 0;
unsigned int f = 0;
switch(hash_code) {
case NUMBER_HASH: f = NUMBER_MC; val = atoi(text); break;
case TEXT_HASH:
switch (Text__perhaps_ill_formed_text_routine(text)) {
case TRUE: f = TEXTWITHSUBS_MC; break;
case FALSE: f = TEXT_MC; break;
case NOT_APPLICABLE: f = TEXT_MC; break;
}
break;
case I6_HASH: f = I6_MC; break;
default:
val = Vocabulary__an_ordinal_number(text);
if (val >= 0) f = NUMBER_MC + ORDINAL_MC; /* so that "4th", say, picks up both */
break;
}
if (list_of_vocab_with_hash[hash_code] == NULL) {
{
#line 385 "inform7/Chapter 7/Vocabulary.w"
new_entry = Vocabulary__vocab_entry_new(text, hash_code, f, val);
if (hash_code != TEXT_HASH) list_of_vocab_with_hash[hash_code] = new_entry;
LOGIF(VOCABULARY, "Word %d <%s> is first vocabulary with hash %d\n",
no_vocabulary_entries++, text, hash_code);
return new_entry;
}
#line 362 "inform7/Chapter 7/Vocabulary.w"
;
} else {
vocabulary_entry *old_entry = NULL;
int n;
/* search the non-empty list of words with this hash code */
for (n=0, new_entry = list_of_vocab_with_hash[hash_code];
new_entry != NULL;
n++, old_entry = new_entry, new_entry = new_entry->next_in_vocab_hash)
if (strcmp(new_entry->exemplar, text) == 0)
return new_entry;
/* and if we do not find |text| in there, then... */
{
#line 395 "inform7/Chapter 7/Vocabulary.w"
new_entry = Vocabulary__vocab_entry_new(text, hash_code, f, val);
old_entry->next_in_vocab_hash = new_entry;
LOGIF(VOCABULARY, "Word %d <%s> is vocabulary entry no. %d with hash %d\n",
no_vocabulary_entries++, text, n, hash_code);
return new_entry;
}
#line 373 "inform7/Chapter 7/Vocabulary.w"
;
}
}
#line 406 "inform7/Chapter 7/Vocabulary.w"
vocabulary_entry *Vocabulary__entry_for_partial_text(char *str, int from, int to) {
TEMPORARY_STREAM;
for (int i=from; i<=to; i++) PUT_TO(TEMP, str[i]);
PUT_TO(TEMP, 0);
wording W = Feeds__feed_text(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
if (Wordings__empty(W)) return NULL;
return Lexer__word(Wordings__first_wn(W));
}
#line 423 "inform7/Chapter 7/Vocabulary.w"
int Vocabulary__an_ordinal_number(char *fw) {
for (int i=0; fw[i] != 0; i++)
if (!(isdigit(fw[i]))) {
if ((i>0) &&
(((fw[i] == 's') && (fw[i+1] == 't') && (fw[i+2] == 0)) ||
((fw[i] == 'n') && (fw[i+1] == 'd') && (fw[i+2] == 0)) ||
((fw[i] == 'r') && (fw[i+1] == 'd') && (fw[i+2] == 0)) ||
((fw[i] == 't') && (fw[i+1] == 'h') && (fw[i+2] == 0))))
return atoi(fw);
break;
}
return -1;
}
#line 69 "inform7/Chapter 7/Tries and Inflections.w"
match_trie *Inflections__new_trie_node(int mc) {
match_trie *T = CREATE(match_trie);
T->match_character = mc;
T->match_outcome = NULL;
T->on_success = NULL;
T->next = NULL;
return T;
}
#line 84 "inform7/Chapter 7/Tries and Inflections.w"
match_avinue *Inflections__new_avinue(int from_start) {
match_avinue *A = CREATE(match_avinue);
A->next = NULL;
A->the_trie = Inflections__new_trie_node(from_start);
return A;
}
match_avinue *Inflections__fresh_avinue(match_avinue *A) {
match_avinue *F = NULL, *FL = NULL;
while (A) {
match_avinue *FN = CREATE(match_avinue);
FN->next = NULL;
FN->the_trie = A->the_trie;
A = A->next;
if (FL) FL->next = FN;
if (F == NULL) F = FN;
FL = FN;
}
return F;
}
#line 132 "inform7/Chapter 7/Tries and Inflections.w"
char *Inflections__search_trie(match_trie *T, char *p, char *add_outcome) {
if (T == NULL) internal_error("no trie to search");
int start, endpoint, delta;
{
#line 198 "inform7/Chapter 7/Tries and Inflections.w"
start = 0; endpoint = Platform__strlen(p); delta = 1;
if (T->match_character == TRIE_END) { start = Platform__strlen(p)-1; endpoint = -1; delta = -1; }
}
#line 136 "inform7/Chapter 7/Tries and Inflections.w"
;
match_trie *prev = NULL, *pos = T;
{
#line 277 "inform7/Chapter 7/Tries and Inflections.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 139 "inform7/Chapter 7/Tries and Inflections.w"
;
int rewind_sp = 0;
int rewind_points[MAX_TRIE_REWIND];
match_trie *rewind_positions[MAX_TRIE_REWIND];
match_trie *rewind_prev_positions[MAX_TRIE_REWIND];
int i;
for (i = start; i != endpoint+delta; i += delta) {
char group[MAX_TRIE_GROUP_SIZE+1];
int g = 0; /* size of group */
int c = (i<0)?0:(p[i]); /* i.e., zero at the two ends of the text */
if ((c >= 0x20) && (c <= 0x7f)) c = Platform__tolower((char) c); /* normalise it within ASCII */
if (c == 0x20) { c = 0; i = endpoint - delta; } /* force any space to be equivalent to the final 0 */
if (add_outcome) {
char pairc = 0;
if (c == '<') pairc = '>';
if (c == '>') pairc = '<';
if (pairc) {
int j;
for (j = i+delta; j != endpoint; j += delta) {
char ch = (j<0)?0:(p[j]);
if (ch == pairc) break;
if (g > MAX_TRIE_GROUP_SIZE) { g = 0; break; }
group[g++] = ch;
}
group[g] = 0;
if (g > 0) i = j;
}
}
if (c == '*') endpoint -= delta;
RewindHere:
{
#line 211 "inform7/Chapter 7/Tries and Inflections.w"
int ambig = 0, unambig = 0;
match_trie *point;
for (point = pos; point; point = point->next)
if (Inflections__trie_node_ambiguous(point)) ambig++;
else unambig++;
FauxWhileLoop:
if (pos) {
if ((add_outcome == NULL) || (Inflections__trie_node_ambiguous(pos) == FALSE))
if (Inflections__trie_node_matches(pos, c)) {
if (pos->match_character == TRIE_ANYTHING) break;
if ((add_outcome == NULL) && (ambig > 0) && (ambig+unambig > 1)
&& (rewind_sp < MAX_TRIE_REWIND)) {
rewind_points[rewind_sp] = i;
rewind_positions[rewind_sp] = pos->next;
rewind_prev_positions[rewind_sp] = prev;
rewind_sp++;
}
{
#line 277 "inform7/Chapter 7/Tries and Inflections.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 229 "inform7/Chapter 7/Tries and Inflections.w"
;
continue;
}
pos = pos->next;
goto FauxWhileLoop;
}
}
#line 172 "inform7/Chapter 7/Tries and Inflections.w"
;
if (add_outcome == NULL) {
if (rewind_sp > 0) {
i = rewind_points[rewind_sp-1];
pos = rewind_positions[rewind_sp-1];
prev = rewind_prev_positions[rewind_sp-1];
rewind_sp--;
goto RewindHere;
}
return NULL; /* failure! */
}
{
#line 239 "inform7/Chapter 7/Tries and Inflections.w"
match_trie *new_pos = NULL;
if (g > 0) {
int nt = TRIE_ANY_GROUP;
char *from = group;
if (group[0] == '!') { from++; nt = TRIE_NOT_GROUP; }
if (group[Platform__strlen(group)-1] == '!') { group[Platform__strlen(group)-1] = 0; nt = TRIE_NOT_GROUP; }
new_pos = Inflections__new_trie_node(nt);
strcpy(new_pos->group_characters, from);
} else if (c == '*') new_pos = Inflections__new_trie_node(TRIE_ANYTHING);
else new_pos = Inflections__new_trie_node(c);
if (prev->on_success == NULL) prev->on_success = new_pos;
else {
match_trie *ppoint = NULL, *point;
for (point = prev->on_success; point; ppoint = point, point = point->next) {
if (new_pos->match_character < point->match_character) {
if (ppoint == NULL) {
new_pos->next = prev->on_success;
prev->on_success = new_pos;
} else {
ppoint->next = new_pos;
new_pos->next = point;
}
break;
}
if (point->next == NULL) {
point->next = new_pos;
break;
}
}
}
pos = new_pos;
{
#line 277 "inform7/Chapter 7/Tries and Inflections.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 272 "inform7/Chapter 7/Tries and Inflections.w"
; continue;
}
#line 183 "inform7/Chapter 7/Tries and Inflections.w"
;
}
if ((pos) && (pos->match_character == TRIE_ANYTHING))
{
#line 277 "inform7/Chapter 7/Tries and Inflections.w"
if (pos == NULL) internal_error("trie invariant broken");
prev = pos; pos = prev->on_success;
}
#line 185 "inform7/Chapter 7/Tries and Inflections.w"
;
if ((pos) && (pos->match_outcome)) return pos->match_outcome; /* success! */
if (add_outcome == NULL) return NULL; /* failure! */
if (pos == NULL)
{
#line 285 "inform7/Chapter 7/Tries and Inflections.w"
prev->on_success = Inflections__new_trie_node(TRIE_STOP);
prev->on_success->match_outcome = add_outcome;
return add_outcome;
}
#line 190 "inform7/Chapter 7/Tries and Inflections.w"
else
{
#line 292 "inform7/Chapter 7/Tries and Inflections.w"
prev->on_success = Inflections__new_trie_node(TRIE_STOP);
prev->on_success->match_outcome = add_outcome;
return add_outcome;
}
#line 192 "inform7/Chapter 7/Tries and Inflections.w"
;
}
#line 300 "inform7/Chapter 7/Tries and Inflections.w"
int Inflections__trie_node_matches(match_trie *pos, int c) {
if (pos->match_character == TRIE_ANYTHING) return TRUE;
if (pos->match_character == TRIE_ANY_GROUP) {
int k;
for (k = 0; pos->group_characters[k]; k++)
if (c == pos->group_characters[k])
return TRUE;
return FALSE;
}
if (pos->match_character == TRIE_NOT_GROUP) {
int k;
for (k = 0; pos->group_characters[k]; k++)
if (c == pos->group_characters[k])
return FALSE;
return TRUE;
}
if (pos->match_character == c) return TRUE;
return FALSE;
}
int Inflections__trie_node_ambiguous(match_trie *pos) {
if (pos->match_character == TRIE_ANYTHING) return TRUE;
if (pos->match_character == TRIE_ANY_GROUP) return TRUE;
if (pos->match_character == TRIE_NOT_GROUP) return TRUE;
return FALSE;
}
#line 330 "inform7/Chapter 7/Tries and Inflections.w"
char *Inflections__search_avinue(match_avinue *T, char *p) {
char *result = NULL;
while ((T) && (result == NULL)) {
result = Inflections__search_trie(T->the_trie, p, NULL);
T = T->next;
}
return result;
}
#line 343 "inform7/Chapter 7/Tries and Inflections.w"
void Inflections__log_avinue(match_avinue *A) {
LOG("Avinue:\n"); LOG_INDENT;
int n = 1;
while (A) {
LOG("Trie %d:\n", n++); LOG_INDENT;
Inflections__log_trie_recursively(A->the_trie);
LOG_OUTDENT;
A = A->next;
}
LOG_OUTDENT;
}
void Inflections__log_trie_recursively(match_trie *T) {
for (; T; T = T->next) {
switch (T->match_character) {
case TRIE_START: LOG("Start"); break;
case TRIE_END: LOG("End"); break;
case TRIE_ANYTHING: LOG("Anything"); break;
case TRIE_ANY_GROUP: LOG("Group <%s>", T->group_characters); break;
case TRIE_NOT_GROUP: LOG("Negated group <%s>", T->group_characters); break;
case TRIE_STOP: LOG("Stop"); break;
case 0: LOG("00"); break;
default: LOG("%c", T->match_character); break;
}
if (T->match_outcome) LOG(" --> %s", T->match_outcome);
LOG("\n");
if (T->on_success) {
LOG_INDENT; Inflections__log_trie_recursively(T->on_success); LOG_OUTDENT;
}
}
}
#line 383 "inform7/Chapter 7/Tries and Inflections.w"
int Inflections__suffix_inflection(match_avinue *T, char *to, char *from, int max_length) {
int success = TRUE;
char *result = Inflections__search_avinue(T, from);
if (result == NULL) { success = FALSE; result = "0"; }
if (Platform__strlen(result) == 0) internal_error("empty trie result");
if (Platform__strlen(result) >= max_length) internal_error("overlong trie result");
int back = result[0] - '0';
if ((back < 0) || (back > 9)) {
strcpy(to, result);
} else {
int i, j, len = Platform__strlen(from);
if (len-back+1 + Platform__strlen(result) >= max_length)
internal_error("no room for inflection");
for (i=0; i<len-back; i++) to[i] = from[i];
j=1;
if (result[j] == '+') { char last = to[i-1]; to[i++] = last; j++; }
for (; result[j]; j++) to[i++] = result[j];
to[i] = 0;
}
int i;
for (i=0; to[i]; i++) if (to[i] == '+') to[i] = ' ';
return success;
}
#line 413 "inform7/Chapter 7/Tries and Inflections.w"
word_assemblage Inflections__apply_trie_to_wa(word_assemblage wa, match_avinue *mt) {
vocabulary_entry **words;
int no_words;
WordAssemblages__as_array(&wa, &words, &no_words);
if (no_words == 0) return wa;
char suffixed[MAX_WORD_LENGTH*2];
char *initial_text = Vocabulary__get_exemplar(words[0], FALSE);
int s = Inflections__suffix_inflection(mt, suffixed, initial_text, MAX_WORD_LENGTH);
if (s == FALSE)
Extensions__IDs__truncated_strcpy(suffixed, initial_text, MAX_WORD_LENGTH+1);
wording W = Feeds__feed_text(suffixed);
WordAssemblages__truncate(&wa, 1);
return WordAssemblages__join(WordAssemblages__from_wording(W), wa);
}
#line 432 "inform7/Chapter 7/Tries and Inflections.w"
match_avinue *indef_trie = NULL;
void Inflections__preface_by_article(OUTPUT_STREAM, text_stream *TEMP) {
char *initial_text = STREAM_TEXT(TEMP);
if (indef_trie == NULL)
indef_trie =
Preform__Nonparsing__define_trie(singular_noun_to_its_indefinite_article_NTM, TRIE_START, NULL);
char *result = Inflections__search_avinue(indef_trie, initial_text);
if (result == NULL) result = "a";
WRITE("%s ", result);
STREAM_COPY(OUT, TEMP);
}
#line 450 "inform7/Chapter 7/Tries and Inflections.w"
int Inflections__pluralize(char *to, char *from, int max_length, natural_language *nl) {
if (nl == NULL) nl = English_language;
match_avinue *plural_trie =
Preform__Nonparsing__define_trie(singular_noun_to_its_plural_NTM, TRIE_END, nl);
return Inflections__suffix_inflection(plural_trie, to, from, max_length);
}
#line 462 "inform7/Chapter 7/Tries and Inflections.w"
match_avinue *past_trie = NULL;
int Inflections__pasturise_participle(char *to, char *from, int max_length) {
if (past_trie == NULL)
past_trie =
Preform__Nonparsing__define_trie(pasturise_participle_NTM, TRIE_START, NULL);
return Inflections__suffix_inflection(past_trie, to, from, max_length);
}
#line 474 "inform7/Chapter 7/Tries and Inflections.w"
void Inflections__test_tries(OUTPUT_STREAM, char *p) {
WRITE("Articled form: ");
TEMPORARY_STREAM;
WRITE_TO(TEMP, "%s", p);
Inflections__preface_by_article(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
WRITE("\n");
WRITE(" - Plural form: ");
char recipient[128];
Inflections__pluralize(recipient, p, 128, English_language);
WRITE("%s\n", recipient);
WRITE(" - Pasturised form: ");
Inflections__pasturise_participle(recipient, p, 128);
WRITE("%s\n", recipient);
}
void Inflections__add_to_avinue(match_avinue *mt, char *from, char *to) {
if ((mt == NULL) || (mt->the_trie == NULL)) internal_error("null trie");
Inflections__search_trie(mt->the_trie, from, to);
}
#line 501 "inform7/Chapter 7/Tries and Inflections.w"
wording Inflections__make_past_of_participle(wording W) {
char pasturised[2*MAX_WORD_LENGTH+1];
feed_t id = Feeds__begin();
LOOP_THROUGH_WORDING(i, W) {
if (*(Lexer__word_text(i)) == '\"') strcpy(pasturised, "some-long-text");
else {
if (Inflections__pasturise_participle(pasturised,
Lexer__word_text(i), 2*MAX_WORD_LENGTH)) {
if (i > Wordings__first_wn(W)) Feeds__feed_wording(Wordings__up_to(W, i-1));
Feeds__feed_text(pasturised);
if (i < Wordings__last_wn(W)) Feeds__feed_wording(Wordings__from(W, i+1));
break;
}
}
}
wording PLW = Feeds__end(id);
LOGIF(CONSTRUCTED_PAST_PARTICIPLES, "[Past participle of $w is $w]\n", W, PLW);
return PLW;
}
wording Inflections__set_past_participle(wording W, int irregular_pp) {
feed_t id = Feeds__begin();
Feeds__feed_wording(Wordings__one_word(irregular_pp));
if (Wordings__length(W) > 1)
Feeds__feed_wording(Wordings__trim_first_word(W));
return Feeds__end(id);
}
#line 534 "inform7/Chapter 7/Tries and Inflections.w"
wording Inflections__make_comparative(wording W) {
char comprised[MAX_WORD_LENGTH+3];
feed_t id = Feeds__begin();
if (*(Lexer__word_text(Wordings__first_wn(W))) == '\"')
strcpy(comprised, "some-long-text");
else
strcpy(comprised, Lexer__word_text(Wordings__first_wn(W)));
if (comprised[Platform__strlen(comprised)-1] == 'y')
comprised[Platform__strlen(comprised)-1] = 'i';
if (comprised[Platform__strlen(comprised)-1] != 'e')
strcat(comprised, "e");
strcat(comprised, "r");
Feeds__feed_text(comprised);
strcpy(comprised, " than ");
Feeds__feed_text(comprised);
wording PW = Feeds__end(id);
LOGIF(CONSTRUCTED_PLURALS, "[Comparative of $w is $w]\n", W, PW);
return PW;
}
wording Inflections__make_superlative(wording W) {
char comprised[MAX_WORD_LENGTH+3];
if (*(Lexer__word_text(Wordings__first_wn(W))) == '\"')
strcpy(comprised, "some-long-text");
else
strcpy(comprised, Lexer__word_text(Wordings__first_wn(W)));
if (comprised[Platform__strlen(comprised)-1] == 'y')
comprised[Platform__strlen(comprised)-1] = 'i';
if (comprised[Platform__strlen(comprised)-1] != 'e')
strcat(comprised, "e");
strcat(comprised, "st");
wording SW = Feeds__feed_text(comprised);
LOGIF(CONSTRUCTED_PLURALS, "[Superlative of $w is $w]\n", W, SW);
return SW;
}
#line 576 "inform7/Chapter 7/Tries and Inflections.w"
wording Inflections__make_quiddity(wording W) {
char comprised[MAX_WORD_LENGTH+3];
if (*(Lexer__word_text(Wordings__first_wn(W))) == '\"')
strcpy(comprised, "some-long-text");
else
strcpy(comprised, Lexer__word_text(Wordings__first_wn(W)));
if (comprised[Platform__strlen(comprised)-1] == 'y')
comprised[Platform__strlen(comprised)-1] = 'i';
strcat(comprised, "ness");
wording QW = Feeds__feed_text(comprised);
LOGIF(CONSTRUCTED_PLURALS, "[Quiddity of $w is $w]\n", W, QW);
return QW;
}
#line 593 "inform7/Chapter 7/Tries and Inflections.w"
void Inflections__test_trie_cases(OUTPUT_STREAM) {
Inflections__test_trie_case("bi");
Inflections__test_trie_case("bit");
Inflections__test_trie_case("big");
Inflections__test_trie_case("bigs");
Inflections__test_trie_case("biggy");
Inflections__test_trie_case("bigger");
Inflections__test_trie_case("biggi");
Inflections__test_trie_case("biggish");
Inflections__test_trie_case("biggistical");
match_avinue *T =
Preform__Nonparsing__define_trie(small_trie_test_NTM, TRIE_START, English_language);
Inflections__log_avinue(T);
}
void Inflections__test_trie_case(char *t) {
match_avinue *T =
Preform__Nonparsing__define_trie(small_trie_test_NTM, TRIE_START, English_language);
char *res = Inflections__search_avinue(T, t);
LOG("Test search on %s --> %s\n", t, (res == NULL)?"NO":res);
}
#line 618 "inform7/Chapter 7/Tries and Inflections.w"
int small_trie_test_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 624 "inform7/Chapter 7/Tries and Inflections.w"
#line 32 "inform7/Chapter 7/Word Assemblages.w"
word_assemblage WordAssemblages__new_assemblage(void) {
word_assemblage wa;
wa.no_indiv_words = 0;
int i;
for (i=0; i<MAX_WORDS_IN_ASSEMBLAGE; i++) wa.indiv_words[i] = NULL;
return wa;
}
#line 43 "inform7/Chapter 7/Word Assemblages.w"
word_assemblage WordAssemblages__from_wording(wording W) {
if ((Wordings__empty(W)) || (Wordings__length(W) > MAX_WORDS_IN_ASSEMBLAGE))
internal_error("assemblage won't fit");
word_assemblage wa = WordAssemblages__new_assemblage();
LOOP_THROUGH_WORDING(i, W)
wa.indiv_words[wa.no_indiv_words++] = Lexer__word(i);
return wa;
}
#line 55 "inform7/Chapter 7/Word Assemblages.w"
word_assemblage WordAssemblages__lit_0(void) {
return WordAssemblages__new_assemblage();
}
word_assemblage WordAssemblages__lit_1(vocabulary_entry *ve1) {
word_assemblage wa = WordAssemblages__new_assemblage();
if (ve1) wa.indiv_words[wa.no_indiv_words++] = ve1;
return wa;
}
#line 68 "inform7/Chapter 7/Word Assemblages.w"
word_assemblage WordAssemblages__join(word_assemblage wa1, word_assemblage wa2) {
if (wa1.no_indiv_words + wa2.no_indiv_words > MAX_WORDS_IN_ASSEMBLAGE)
internal_error("assemblage overflow");
word_assemblage sum = WordAssemblages__new_assemblage();
int i;
for (i=0; i<wa1.no_indiv_words; i++)
sum.indiv_words[sum.no_indiv_words++] = wa1.indiv_words[i];
for (i=0; i<wa2.no_indiv_words; i++)
sum.indiv_words[sum.no_indiv_words++] = wa2.indiv_words[i];
return sum;
}
#line 84 "inform7/Chapter 7/Word Assemblages.w"
wording WordAssemblages__to_wording(word_assemblage *wa) {
if (wa->no_indiv_words == 0) return EMPTY_WORDING;
feed_t id = Feeds__begin();
for (int i=0; i<wa->no_indiv_words; i++) {
char str[MAX_WORD_LENGTH+2];
sprintf(str, " ");
strcpy(str+Platform__strlen(str), Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
sprintf(str+Platform__strlen(str), " ");
Feeds__feed_text(str);
}
return Feeds__end(id);
}
#line 100 "inform7/Chapter 7/Word Assemblages.w"
void WordAssemblages__truncate(word_assemblage *wa, int n) {
if (n <= wa->no_indiv_words) {
for (int i=0; i+n < wa->no_indiv_words; i++)
wa->indiv_words[i] = wa->indiv_words[i+n];
wa->no_indiv_words -= n;
}
}
void WordAssemblages__truncate_to(word_assemblage *wa, int n) {
if (n <= wa->no_indiv_words) {
wa->no_indiv_words = n;
}
}
#line 117 "inform7/Chapter 7/Word Assemblages.w"
int WordAssemblages__nonempty(word_assemblage wa1) {
if (wa1.no_indiv_words > 0) return TRUE;
return FALSE;
}
void WordAssemblages__copy_to_stream(OUTPUT_STREAM, word_assemblage *wa) {
for (int i=0; i<wa->no_indiv_words; i++) {
if (i > 0) WRITE(" ");
WRITE("%s", Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
}
}
void WordAssemblages__copy_to_string(word_assemblage *wa, char *str) {
str[0] = 0;
for (int i=0; i<wa->no_indiv_words; i++) {
if (i > 0) strcpy(str+Platform__strlen(str), " ");
strcpy(str+Platform__strlen(str), Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
}
}
vocabulary_entry *WordAssemblages__hyphenated(word_assemblage *wa) {
if (wa->no_indiv_words > 9) return NULL;
char str[10*(MAX_WORD_LENGTH+1)];
sprintf(str, " ");
int i;
for (i=0; i<wa->no_indiv_words; i++) {
if (i > 0) strcpy(str+Platform__strlen(str), "-");
strcpy(str+Platform__strlen(str), Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
}
sprintf(str+Platform__strlen(str), " ");
wording W = Feeds__feed_text(str);
return Lexer__word(Wordings__first_wn(W));
}
void WordAssemblages__as_array(word_assemblage *wa, vocabulary_entry ***array, int *len) {
*array = wa->indiv_words;
*len = wa->no_indiv_words;
}
#line 159 "inform7/Chapter 7/Word Assemblages.w"
int WordAssemblages__compare(word_assemblage *wa1, word_assemblage *wa2) {
if (wa1 == wa2) return TRUE;
if ((wa1 == NULL) || (wa2 == NULL)) return FALSE;
if (wa1->no_indiv_words != wa2->no_indiv_words) return FALSE;
for (int i=0; i<wa1->no_indiv_words; i++)
if (wa1->indiv_words[i] != wa2->indiv_words[i])
return FALSE;
return TRUE;
}
int WordAssemblages__compare_with_wording(word_assemblage *wa, wording W) {
if (wa == NULL) return FALSE;
if (Wordings__empty(W)) return FALSE;
if (wa->no_indiv_words != Wordings__length(W)) return FALSE;
for (int i=0; i<wa->no_indiv_words; i++)
if (wa->indiv_words[i] != Lexer__word(Wordings__first_wn(W) + i))
return FALSE;
return TRUE;
}
#line 182 "inform7/Chapter 7/Word Assemblages.w"
int WordAssemblages__parse_as_strictly_initial_text(wording W, word_assemblage *wa) {
return WordAssemblages__parse_as_weakly_initial_text(W, wa, EMPTY_WORDING, TRUE, FALSE);
}
int WordAssemblages__parse_as_weakly_initial_text(wording W, word_assemblage *wa,
wording S, int allow_uuc, int allow_to_fill) {
int k, i;
for (i=0, k=Wordings__first_wn(W); i<wa->no_indiv_words; i++)
if ((wa->indiv_words[i] == PARBREAK_V) && (Wordings__nonempty(S))) {
if (Wordings__starts_with(Wordings__from(W, k), S) == FALSE) return -1;
k += Wordings__length(S);
} else if (wa->indiv_words[i]) {
if ((k > Wordings__last_wn(W)) || (wa->indiv_words[i] != Lexer__word(k))) return -1;
if ((allow_uuc == FALSE) && (Text__unexpectedly_upper_case(k))) return -1;
k++;
}
if ((k > Wordings__last_wn(W)) && (allow_to_fill == FALSE)) return -1;
return k;
}
#line 205 "inform7/Chapter 7/Word Assemblages.w"
vocabulary_entry *WordAssemblages__last_word(word_assemblage *wa) {
if ((wa == NULL) || (wa->no_indiv_words == 0)) return NULL;
return wa->indiv_words[wa->no_indiv_words-1];
}
vocabulary_entry *WordAssemblages__first_word(word_assemblage *wa) {
if ((wa == NULL) || (wa->no_indiv_words == 0)) return NULL;
return wa->indiv_words[0];
}
int WordAssemblages__longer(word_assemblage *wa1, word_assemblage *wa2) {
int l1 = 0;
if (wa1) l1 = wa1->no_indiv_words;
int l2 = 0;
if (wa2) l2 = wa2->no_indiv_words;
return l1 - l2;
}
#line 226 "inform7/Chapter 7/Word Assemblages.w"
void WordAssemblages__log(word_assemblage *wa) {
if (wa == NULL) { LOG("<null-words>"); return; }
int i, sp = FALSE;
for (i=0; i<wa->no_indiv_words; i++)
if (wa->indiv_words[i]) {
if (sp) LOG(" "); sp = TRUE;
LOG("%s", Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
}
}
void WordAssemblages__index(word_assemblage *wa) {
if (wa == NULL) return;
int i, sp = FALSE;
for (i=0; i<wa->no_indiv_words; i++)
if (wa->indiv_words[i]) {
if (sp) INDEX(" "); sp = TRUE;
INDEX("%s ", Vocabulary__get_exemplar(wa->indiv_words[i], FALSE));
}
}
#line 44 "inform7/Chapter 7/Clusters.w"
cluster *Clusters__new(void) {
cluster *names = CREATE(cluster);
names->first_name = NULL;
return names;
}
#line 53 "inform7/Chapter 7/Clusters.w"
individual_name *Clusters__add(cluster *names, wording W,
natural_language *foreign_language, int gender, int number, int pluralise) {
individual_name *in = CREATE(individual_name);
in->principal_meaning = NULL;
in->name = W;
if (foreign_language == NULL) in->name_language = English_language;
else in->name_language = foreign_language;
in->name_number = number;
in->name_gender = gender;
in->next = NULL;
if (names->first_name == NULL) names->first_name = in;
else {
individual_name *in2;
for (in2 = names->first_name; ((in2) && (in2->next)); in2 = in2->next) ;
in2->next = in;
}
if ((pluralise) && (number == 1))
{
#line 81 "inform7/Chapter 7/Clusters.w"
plural_dictionary_entry *pde = NULL;
int k = 0;
do {
k++;
wording PW = EMPTY_WORDING;
pde = Plurals__make(W, &PW, pde, foreign_language);
if (Wordings__nonempty(PW)) {
LOGIF(CONSTRUCTED_PLURALS, "(%d) Reading plural of <$w> as <$w>\n", k,
W, PW);
Clusters__add(names, PW, foreign_language, gender, 2, FALSE);
}
} while (pde);
}
#line 70 "inform7/Chapter 7/Clusters.w"
;
return in;
}
#line 104 "inform7/Chapter 7/Clusters.w"
void Clusters__add_with_agreements(cluster *cl, wording W, natural_language *nl) {
if (nl == NULL) nl = language_of_source_text;
if (nl == NULL) nl = English_language;
if (nl == English_language) {
Clusters__add(cl, W, nl, NEUTER_GENDER, 1, FALSE);
} else {
int gna;
for (gna = 0; gna < 6; gna++)
{
#line 120 "inform7/Chapter 7/Clusters.w"
nonterminal *step1 = NULL, *step2 = NULL;
int form_number = 1, form_gender = NEUTER_GENDER;
if (gna >= 3) form_number = 2;
switch (gna) {
case 0: step1 = adjective_to_masculine_singular_NTM;
form_gender = MASCULINE_GENDER; break;
case 1: step1 = adjective_to_feminine_singular_NTM;
form_gender = FEMININE_GENDER; break;
case 2: break;
case 3: step1 = adjective_to_masculine_singular_NTM;
step2 = adjective_to_masculine_plural_NTM;
form_gender = MASCULINE_GENDER; break;
case 4: step1 = adjective_to_feminine_singular_NTM;
step2 = adjective_to_feminine_plural_NTM;
form_gender = FEMININE_GENDER; break;
case 5: step1 = adjective_to_plural_NTM; break;
}
wording FW = EMPTY_WORDING;
{
#line 145 "inform7/Chapter 7/Clusters.w"
word_assemblage wa = WordAssemblages__from_wording(W);
if (step1)
wa = Inflections__apply_trie_to_wa(wa,
Preform__Nonparsing__define_trie(step1, TRIE_END, nl));
if (step2)
wa = Inflections__apply_trie_to_wa(wa,
Preform__Nonparsing__define_trie(step2, TRIE_END, nl));
FW = WordAssemblages__to_wording(&wa);
}
#line 138 "inform7/Chapter 7/Clusters.w"
;
Clusters__add(cl, FW, nl, form_gender, form_number, FALSE);
}
#line 112 "inform7/Chapter 7/Clusters.w"
;
}
}
#line 162 "inform7/Chapter 7/Clusters.w"
void Clusters__set_plural_name(cluster *cl, wording W) {
individual_name *in;
for (in = cl->first_name; in; in = in->next)
if (in->name_number == 2) {
in->name = W;
return;
}
Clusters__add(cl, W, NULL, NEUTER_GENDER, 2, FALSE);
}
#line 180 "inform7/Chapter 7/Clusters.w"
wording Clusters__get_name(cluster *cl, int plural_flag) {
int number_sought = 1;
if (plural_flag) number_sought = 2;
individual_name *in;
for (in = cl->first_name; in; in = in->next)
if (in->name_number == number_sought)
return in->name;
return EMPTY_WORDING;
}
#line 194 "inform7/Chapter 7/Clusters.w"
wording Clusters__get_name_in_play(cluster *cl, int plural_flag) {
int number_sought = 1;
if (plural_flag) number_sought = 2;
individual_name *in;
for (in = cl->first_name; in; in = in->next)
if ((in->name_number == number_sought) &&
(in->name_language == language_of_play))
return in->name;
return Clusters__get_name(cl, plural_flag);
}
#line 208 "inform7/Chapter 7/Clusters.w"
wording Clusters__get_name_general(cluster *cl,
natural_language *nl, int number_sought, int gender_sought) {
individual_name *in;
for (in = cl->first_name; in; in = in->next)
if (((number_sought == -1) || (number_sought == in->name_number)) &&
((gender_sought == -1) || (gender_sought == in->name_gender)) &&
(in->name_language == nl))
return in->name;
return EMPTY_WORDING;
}
#line 225 "inform7/Chapter 7/Clusters.w"
void Clusters__set_principal_meaning(individual_name *in, excerpt_meaning *em) {
if (in == NULL) internal_error("no individual name");
in->principal_meaning = em;
}
excerpt_meaning *Clusters__get_principal_meaning(cluster *cl) {
if (cl->first_name == NULL) return NULL;
return cl->first_name->principal_meaning;
}
#line 39 "inform7/Chapter 7/Plurals Dictionary.w"
sentence_handler PLURAL_SH_handler =
{ SENTENCE_NT, PLURAL_VB, 1, Plurals__handle_definition };
void Plurals__handle_definition(parse_node *p) {
/* do nothing: these sentences have already been caught by the traverse below */
}
void Plurals__traverse_for_definitions(void) {
ParseTree__traverse(Plurals__visit_for_definitions);
}
void Plurals__visit_for_definitions(parse_node *p) {
if ((ParseTree__get_type(p) == SENTENCE_NT)
&& (p->down)
&& (ParseTree__int_annotation(p->down, verb_id_ANNOT) == PLURAL_VB)
&& (p->down->next) && (p->down->next->next))
Plurals__register(ParseTree__get_text(p->down->next), ParseTree__get_text(p->down->next->next));
}
#line 63 "inform7/Chapter 7/Plurals Dictionary.w"
void Plurals__register(wording S, wording P) {
plural_dictionary_entry *pde = CREATE(plural_dictionary_entry);
pde->singular_form = S;
pde->plural_form = P;
{
#line 79 "inform7/Chapter 7/Plurals Dictionary.w"
LOOP_THROUGH_WORDING(i, S)
if (Vocabulary__test_flags(i, TEXT_MC+TEXTWITHSUBS_MC)) {
Problems__Issue__sentence_problem(_p_(PM_PluralOfQuoted),
"declares a plural for a phrase containing quoted text",
"which is forbidden. Sentences like this are supposed to "
"declare plurals without quotation marks: for instance, "
"'The plural of attorney general is attorneys general.'");
return;
}
LOOP_THROUGH_WORDING(i, P)
if (Vocabulary__test_flags(i, TEXT_MC+TEXTWITHSUBS_MC)) {
Problems__Issue__sentence_problem(_p_(PM_PluralIsQuoted),
"declares a plural for a phrase using quoted text",
"which is forbidden. Sentences like this are supposed to "
"declare plurals without quotation marks: for instance, "
"'The plural of procurator fiscal is procurators fiscal.'");
return;
}
}
#line 69 "inform7/Chapter 7/Plurals Dictionary.w"
;
if (Assertions__Creator__vet_name_for_noun(P) == FALSE) return;
LOGIF(CONSTRUCTED_PLURALS, "[Registering plural of $w as $w]\n", S, P);
}
#line 107 "inform7/Chapter 7/Plurals Dictionary.w"
plural_dictionary_entry *Plurals__make(wording W, wording *PW,
plural_dictionary_entry *search_from, natural_language *nl) {
if (nl == NULL) nl = English_language;
char pluralised[2*MAX_WORD_LENGTH+1];
plural_dictionary_entry *pde;
if (Wordings__empty(W)) { *PW = EMPTY_WORDING; return NULL; }
if (search_from == NULL) search_from = FIRST_OBJECT(plural_dictionary_entry);
else search_from = NEXT_OBJECT(search_from, plural_dictionary_entry);
for (pde = search_from; pde; pde = NEXT_OBJECT(pde, plural_dictionary_entry)) {
if (Wordings__match(W, pde->singular_form)) {
*PW = pde->plural_form;
return pde;
}
}
{
#line 143 "inform7/Chapter 7/Plurals Dictionary.w"
feed_t id = Feeds__begin();
if (Wordings__length(W) > 1) Feeds__feed_wording(Wordings__trim_last_word(W));
int last_wn = Wordings__last_wn(W);
if (*(Lexer__word_text(last_wn)) == '\"') strcpy(pluralised, "some-long-text");
else Inflections__pluralize(pluralised, Lexer__word_raw_text(last_wn), 2*MAX_WORD_LENGTH, nl);
Feeds__feed_text(pluralised);
*PW = Feeds__end(id);
LOGIF(CONSTRUCTED_PLURALS, "[Constructing plural of $w as $w]\n", W, *PW);
}
#line 126 "inform7/Chapter 7/Plurals Dictionary.w"
;
return NULL;
}
#line 95 "inform7/Chapter 7/Natural Languages.w"
int bundle_scan_made = FALSE;
void NaturalLanguages__scan(void) {
if (bundle_scan_made == FALSE) {
bundle_scan_made = TRUE;
{
#line 111 "inform7/Chapter 7/Natural Languages.w"
for (int area=0; area<NO_FS_AREAS; area++)
NaturalLanguages__scan_bundles_from(pathname_of_languages[area], AREA_NAME[area]);
}
#line 100 "inform7/Chapter 7/Natural Languages.w"
;
{
#line 174 "inform7/Chapter 7/Natural Languages.w"
natural_language *nl;
LOOP_OVER(nl, natural_language) {
wording W = EMPTY_WORDING;
{
#line 187 "inform7/Chapter 7/Natural Languages.w"
filename *about_file = Filenames__in_folder(nl->nl_bundle_path, "about.txt");
FILE *ABOUT = Platform__iso_fopen(about_file, "r");
if (ABOUT == NULL) {
LOG("Can't find about file: %f\n", about_file);
} else {
char line_buffer[MAX_BUNDLE_ABOUT_LINE_LENGTH+1];
feed_t id = Feeds__begin();
while (TRUE) {
int len = Platform__truncated_iso_fgets(ABOUT, line_buffer,
MAX_BUNDLE_ABOUT_LINE_LENGTH);
if (len < 0) break;
strcat(line_buffer, "\n");
Feeds__feed_text(line_buffer);
}
W = Feeds__end(id);
fclose(ABOUT);
}
}
#line 177 "inform7/Chapter 7/Natural Languages.w"
;
if (Wordings__nonempty(W))
{
#line 210 "inform7/Chapter 7/Natural Languages.w"
int rn = -1, from = -1, to = -1;
LOOP_THROUGH_WORDING(n, W) {
vocabulary_entry *ve = Lexer__word(n);
if (ve == PARBREAK_V) { to = n-1; break; }
int i = -1;
if ((ve) && (Vocabulary__test_vflags(ve, NUMBER_MC)))
i = Vocabulary__get_literal_number_value(ve);
if ((i >= 1) && (i < MAX_LANGUAGE_FIELDS)) {
if (rn >= 0) nl->language_field[rn] = Wordings__new(from, n-1);
rn = i; from = n+1; to = Wordings__last_wn(W);
}
}
if (rn >= 0) nl->language_field[rn] = Wordings__new(from, to);
}
#line 178 "inform7/Chapter 7/Natural Languages.w"
;
}
}
#line 101 "inform7/Chapter 7/Natural Languages.w"
;
}
}
#line 118 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__scan_bundles_from(pathname *P, char *origin) {
TEMPORARY_STREAM;
int s = Pathnames__write_contents_to_stream(TEMP, P);
if (s) {
char directory_text[2048];
Extensions__IDs__truncated_strcpy(directory_text, STREAM_TEXT(TEMP), 2048);
int i, entry_start = 0;
for (i=0; directory_text[i]; i++) {
if (directory_text[i] < 32) {
directory_text[i] = 0;
{
#line 141 "inform7/Chapter 7/Natural Languages.w"
char *entry = directory_text + entry_start;
int i, acceptable = TRUE;
for (i=0; entry[i]; i++) {
if ((entry[i] < 32) || (entry[i] > 126)) acceptable = FALSE; /* contains non-ASCII */
if (entry[i] == FOLDER_SEPARATOR) entry[i] = 0;
}
if (entry[0] == 0) acceptable = FALSE; /* i.e., an empty text */
if (acceptable) {
natural_language *nl = NaturalLanguages__get_nl(entry);
if (nl == NULL)
{
#line 158 "inform7/Chapter 7/Natural Languages.w"
nl = CREATE(natural_language);
char sentence_format[MAX_FILENAME_LENGTH + 20];
sprintf(sentence_format, "%s language\n", entry);
nl->instance_name = Feeds__feed_text(sentence_format);
nl->nl_instance = NULL;
nl->extension_required = FALSE;
nl->adaptive_person = -1; /* i.e., none yet specified */
for (int n=0; n<MAX_LANGUAGE_FIELDS; n++) nl->language_field[n] = EMPTY_WORDING;
}
#line 150 "inform7/Chapter 7/Natural Languages.w"
;
nl->nl_bundle_path = Pathnames__subfolder(P, entry);
LOG("Found language bundle '%s' (%s)\n", entry, origin);
}
}
#line 128 "inform7/Chapter 7/Natural Languages.w"
;
entry_start = i+1;
}
}
{
#line 141 "inform7/Chapter 7/Natural Languages.w"
char *entry = directory_text + entry_start;
int i, acceptable = TRUE;
for (i=0; entry[i]; i++) {
if ((entry[i] < 32) || (entry[i] > 126)) acceptable = FALSE; /* contains non-ASCII */
if (entry[i] == FOLDER_SEPARATOR) entry[i] = 0;
}
if (entry[0] == 0) acceptable = FALSE; /* i.e., an empty text */
if (acceptable) {
natural_language *nl = NaturalLanguages__get_nl(entry);
if (nl == NULL)
{
#line 158 "inform7/Chapter 7/Natural Languages.w"
nl = CREATE(natural_language);
char sentence_format[MAX_FILENAME_LENGTH + 20];
sprintf(sentence_format, "%s language\n", entry);
nl->instance_name = Feeds__feed_text(sentence_format);
nl->nl_instance = NULL;
nl->extension_required = FALSE;
nl->adaptive_person = -1; /* i.e., none yet specified */
for (int n=0; n<MAX_LANGUAGE_FIELDS; n++) nl->language_field[n] = EMPTY_WORDING;
}
#line 150 "inform7/Chapter 7/Natural Languages.w"
;
nl->nl_bundle_path = Pathnames__subfolder(P, entry);
LOG("Found language bundle '%s' (%s)\n", entry, origin);
}
}
#line 132 "inform7/Chapter 7/Natural Languages.w"
;
}
CLOSE_TEMPORARY_STREAM;
}
#line 230 "inform7/Chapter 7/Natural Languages.w"
natural_language *NaturalLanguages__get_nl(char *name) {
NaturalLanguages__scan();
natural_language *nl;
LOOP_OVER(nl, natural_language) {
char *p = Lexer__word_text(Wordings__first_wn(nl->instance_name));
int i, l = Platform__strlen(name), fail = FALSE;
for (i=0; i<=l; i++)
if (Platform__tolower(p[i]) != Platform__tolower(name[i]))
fail = TRUE;
if (fail == FALSE) return nl;
}
return NULL;
}
#line 247 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__log(natural_language *nl) {
if (nl == NULL) { LOG("<null-language>"); }
else { LOG("%s", NaturalLanguages__get_name(nl)); }
}
#line 255 "inform7/Chapter 7/Natural Languages.w"
char *NaturalLanguages__get_name(natural_language *nl) {
if (nl == NULL) nl = English_language;
return Lexer__word_raw_text(Wordings__first_wn(nl->instance_name));
}
#line 266 "inform7/Chapter 7/Natural Languages.w"
int natural_language_NTMR(wording W, int *X, void **XP) {
#line 267 "inform7/Chapter 7/Natural Languages.w"
natural_language *nl;
LOOP_OVER(nl, natural_language)
if (Wordings__match(W, Wordings__first_word(nl->instance_name))) {
*XP = nl; return TRUE;
}
return FALSE;
}
#line 286 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__stock_nl_kind(kind *K) {
natural_language *nl;
LOOP_OVER(nl, natural_language) {
pcalc_prop *prop =
Calculus__Propositions__Abstract__to_create_something(K, nl->instance_name);
Calculus__Propositions__Assert__assert_true(prop, CERTAIN_CE);
nl->nl_instance = latest_instance;
}
}
#line 307 "inform7/Chapter 7/Natural Languages.w"
int NaturalLanguages__adaptive_person(natural_language *nl) {
if ((nl->adaptive_person == -1) && (P_adaptive_text_viewpoint)) {
instance *I = nl->nl_instance;
parse_node *spec = World__Inferences__get_prop_state(
Instances__as_subject(I), P_adaptive_text_viewpoint);
if (ParseTree__is(spec, CONSTANT_VNT)) {
instance *V = ParseTree__get_constant_instance(spec);
nl->adaptive_person = Instances__get_numerical_value(V)-1;
}
}
if (nl->adaptive_person == -1) return FIRST_PERSON_PLURAL;
return nl->adaptive_person;
}
#line 325 "inform7/Chapter 7/Natural Languages.w"
natural_language *NaturalLanguages__English(void) {
natural_language *nl = NaturalLanguages__get_nl("english");
if (nl == NULL) internal_error("unable to find English language bundle");
nl->extension_required = TRUE;
English_language = nl;
return nl;
}
void NaturalLanguages__set_language_of_play(natural_language *nl) {
language_of_play = nl;
if (nl) nl->extension_required = TRUE;
}
#line 344 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__write_language_code(OUTPUT_STREAM, natural_language *nl) {
if (nl == NULL) nl = English_language;
if (Wordings__nonempty(nl->language_field[ISO_639_CODE_LFIELD]))
Wordings__to_stream_raw(OUT, nl->language_field[ISO_639_CODE_LFIELD]);
else WRITE("en");
}
#line 363 "inform7/Chapter 7/Natural Languages.w"
void NaturalLanguages__include_required(void) {
natural_language *nl;
feed_t id = Feeds__begin();
int icount = 0;
LOOP_OVER(nl, natural_language)
if (nl->extension_required) {
TEMPORARY_STREAM;
if (icount++ > 0) WRITE_TO(TEMP, ". ");
WRITE_TO(TEMP, "Include %s Language by ",
NaturalLanguages__get_name(nl));
if (Wordings__nonempty(nl->language_field[TRANSLATOR_LFIELD]))
Wordings__to_stream_raw(TEMP, nl->language_field[TRANSLATOR_LFIELD]);
else WRITE_TO(TEMP, "Unknown Translator");
Feeds__feed_text(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
ParseTree__set_attachment_point_one_off(first_extension_inclusion);
wording W = Feeds__end(id);
Sentences__break(W, NULL);
ParseTree__set_attachment_point_one_off(NULL);
}
#line 391 "inform7/Chapter 7/Natural Languages.w"
wording NaturalLanguages__load_preform(natural_language *nl) {
if (nl == NULL) internal_error("can't load preform from null language");
feed_t id = Feeds__begin();
filename *preform_file = Filenames__in_folder(nl->nl_bundle_path, "Syntax.preform");
LOG("Reading language definition from <%f>\n", preform_file);
FILE *PREFORM = Platform__iso_fopen(preform_file, "r");
if (PREFORM == NULL) internal_error("Unable to open Preform definition");
char line_buffer[MAX_PREFORM_LINE_LENGTH+1];
while (TRUE) {
int len = Platform__truncated_iso_fgets(PREFORM, line_buffer, MAX_PREFORM_LINE_LENGTH);
if (len < 0) break;
strcat(line_buffer, "\n");
Feeds__feed_text_for_preform(line_buffer);
}
fclose(PREFORM);
return Feeds__end(id);
}
#line 367 "inform7/Chapter 7/Preform.w"
void Preform__log_language(void) {
int detailed = FALSE;
nonterminal *nt;
LOOP_OVER(nt, nonterminal) {
#ifdef INSTRUMENTED_PREFORM
LOG("%d/%d: ", nt->nonterminal_matches, nt->nonterminal_tries);
#endif
LOG("%s: ", Vocabulary__get_exemplar(nt->nonterminal_id, FALSE));
Preform__log_range_requirement(&(nt->nonterminal_req));
LOG("\n");
if (nt->internal_definition) LOG(" (internal)\n");
else {
production_list *pl;
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
LOG(" $J:\n", pl->definition_language);
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
LOG(" "); Preform__log_production(pr, detailed);
#ifdef INSTRUMENTED_PREFORM
LOG(" %d/%d: ", pr->production_matches, pr->production_tries);
if (Wordings__nonempty(pr->sample_text)) LOG("<$w>", pr->sample_text);
if (pr->sample_sentence)
LOG(" in <$w>", ParseTree__get_text(pr->sample_sentence));
#endif
LOG(" ==> ");
Preform__log_range_requirement(&(pr->production_req));
LOG("\n");
}
}
}
LOG(" min %d, max %d\n\n", nt->min_nt_words, nt->max_nt_words);
}
LOG("%d req bits.\n", no_req_bits);
}
#line 405 "inform7/Chapter 7/Preform.w"
void Preform__log_production(production *pr, int detailed) {
if (pr->first_ptoken == NULL) LOG("<empty-production>");
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
Preform__log_ptoken(pt, detailed);
LOG(" ");
}
}
#line 417 "inform7/Chapter 7/Preform.w"
void Preform__log_ptoken(ptoken *pt, int detailed) {
if ((detailed) && (pt->ptoken_position != 0)) LOG("(@%d)", pt->ptoken_position);
if ((detailed) && (pt->strut_number >= 0)) LOG("(S%d)", pt->strut_number);
if (pt->disallow_unexpected_upper) LOG("_");
if (pt->negated_ptoken) LOG("^");
if (pt->range_starts >= 0) { LOG("{"); if (detailed) LOG("%d:", pt->range_starts); }
ptoken *alt;
for (alt = pt; alt; alt = alt->alternative_ptoken) {
if (alt->nt_pt) {
LOG("%s", Vocabulary__get_exemplar(alt->nt_pt->nonterminal_id, FALSE));
if (detailed) LOG("=%d", alt->result_index);
} else {
LOG("%s", Vocabulary__get_exemplar(alt->ve_pt, FALSE));
}
if (alt->alternative_ptoken) LOG("/");
}
if (pt->range_ends >= 0) { if (detailed) LOG(":%d", pt->range_ends); LOG("}"); }
}
#line 439 "inform7/Chapter 7/Preform.w"
void Preform__write_ptoken(OUTPUT_STREAM, ptoken *pt) {
if (pt->disallow_unexpected_upper) WRITE("_");
if (pt->negated_ptoken) WRITE("^");
if (pt->range_starts >= 0) WRITE("{");
ptoken *alt;
for (alt = pt; alt; alt = alt->alternative_ptoken) {
if (alt->nt_pt) {
WRITE("%s", Vocabulary__get_exemplar(alt->nt_pt->nonterminal_id, FALSE));
} else {
WRITE("%s", Vocabulary__get_exemplar(alt->ve_pt, FALSE));
}
if (alt->alternative_ptoken) WRITE("/");
}
if (pt->range_ends >= 0) WRITE("}");
}
#line 460 "inform7/Chapter 7/Preform.w"
int preform_nonterminal_NTMR(wording W, int *X, void **XP) {
#line 461 "inform7/Chapter 7/Preform.w"
nonterminal *nt = Preform__detect_nonterminal(Lexer__word(Wordings__first_wn(W)));
if (nt) { *XP = nt; return TRUE; }
return FALSE;
}
#line 469 "inform7/Chapter 7/Preform.w"
void Preform__watch(nonterminal *nt, int state) {
nt->watched = state;
}
#line 478 "inform7/Chapter 7/Preform.w"
vocabulary_entry *AMPERSAND_V;
vocabulary_entry *BACKSLASH_V;
vocabulary_entry *CARET_V;
vocabulary_entry *COLONCOLONEQUALS_V;
vocabulary_entry *QUESTIONMARK_V;
vocabulary_entry *QUOTEQUOTE_V;
vocabulary_entry *SIXDOTS_V;
vocabulary_entry *THREEASTERISKS_V;
vocabulary_entry *THREEDOTS_V;
vocabulary_entry *THREEHASHES_V;
vocabulary_entry *UNDERSCORE_V;
vocabulary_entry *language_V;
vocabulary_entry *internal_V;
#line 495 "inform7/Chapter 7/Preform.w"
void Preform__read_definition(void) {
{
#line 527 "inform7/Chapter 7/Preform.w"
CAPITAL_K_V = Vocabulary__entry_for_text("k");
CAPITAL_L_V = Vocabulary__entry_for_text("l");
CLOSEBRACE_V = Vocabulary__entry_for_text("}");
CLOSEBRACKET_V = Vocabulary__entry_for_text(")");
COLON_V = Vocabulary__entry_for_text(":");
COMMA_V = Vocabulary__entry_for_text(",");
DOUBLEDASH_V = Vocabulary__entry_for_text("--");
FORWARDSLASH_V = Vocabulary__entry_for_text("/");
FULLSTOP_V = Vocabulary__entry_for_text(".");
OPENBRACE_V = Vocabulary__entry_for_text("{");
OPENBRACKET_V = Vocabulary__entry_for_text("(");
OPENI6_V = Vocabulary__entry_for_text("(-");
PARBREAK_V = Vocabulary__entry_for_text(PARAGRAPH_BREAK);
SEMICOLON_V = Vocabulary__entry_for_text(";");
STROKE_V = Vocabulary__entry_for_text("|");
}
#line 496 "inform7/Chapter 7/Preform.w"
;
{
#line 547 "inform7/Chapter 7/Preform.w"
register_tangled_nonterminals();
;
nonterminal *nt;
LOOP_OVER(nt, nonterminal)
if ((nt->marked_internal) && (nt->internal_definition == NULL))
internal_error("internal undefined");
}
#line 497 "inform7/Chapter 7/Preform.w"
;
{
#line 574 "inform7/Chapter 7/Preform.w"
cardinal_number_in_words_NTM->number_words_by_production = TRUE;
cardinal_number_in_words_NTM->flag_words_in_production = NUMBER_MC;
ordinal_number_in_words_NTM->number_words_by_production = TRUE;
ordinal_number_in_words_NTM->flag_words_in_production = ORDINAL_MC;
relative_clause_marker_NTM->flag_words_in_production = PREPOSITION_MC;
}
#line 498 "inform7/Chapter 7/Preform.w"
;
AMPERSAND_V = Vocabulary__entry_for_text("&");
BACKSLASH_V = Vocabulary__entry_for_text("\\");
CARET_V = Vocabulary__entry_for_text("^");
COLONCOLONEQUALS_V = Vocabulary__entry_for_text(":" ":=");
QUESTIONMARK_V = Vocabulary__entry_for_text("?");
QUOTEQUOTE_V = Vocabulary__entry_for_text("\"\"");
SIXDOTS_V = Vocabulary__entry_for_text("......");
THREEASTERISKS_V = Vocabulary__entry_for_text("***");
THREEDOTS_V = Vocabulary__entry_for_text("...");
THREEHASHES_V = Vocabulary__entry_for_text("###");
UNDERSCORE_V = Vocabulary__entry_for_text("_");
language_V = Vocabulary__entry_for_text("language");
internal_V = Vocabulary__entry_for_text("internal");
NaturalLanguages__scan();
language_being_read_by_Preform = NaturalLanguages__English();
wording W = NaturalLanguages__load_preform(language_being_read_by_Preform);
int nonterminals_declared = Preform__parse_preform(W, FALSE);
language_definition_top = lexer_wordcount - 1;
LOG("%d declarations read (%d words)\n", nonterminals_declared, Wordings__length(W));
}
#line 587 "inform7/Chapter 7/Preform.w"
int Preform__parse_preform(wording W, int break_first) {
if (break_first)
W = Feeds__feed_text_for_preform(Lexer__word_raw_text(Wordings__first_wn(W)));
int nonterminals_declared = 0;
LOOP_THROUGH_WORDING(wn, W) {
if (Lexer__word(wn) == PARBREAK_V) continue;
if ((Wordings__last_wn(W) >= wn+1) && (Lexer__word(wn) == language_V)) {
{
#line 617 "inform7/Chapter 7/Preform.w"
natural_language *nl = NaturalLanguages__get_nl(Lexer__word_text(wn+1));
if (nl == NULL) {
LOG("Missing: $w\n", Wordings__one_word(wn+1));
internal_error("tried to define for missing language");
}
language_being_read_by_Preform = nl;
wn++;
}
#line 594 "inform7/Chapter 7/Preform.w"
;
continue;
}
if ((Wordings__last_wn(W) >= wn+1) && (Lexer__word(wn+1) == internal_V)) {
{
#line 628 "inform7/Chapter 7/Preform.w"
nonterminal *nt = Preform__find_nonterminal(Lexer__word(wn));
if (nt->first_production_list) internal_error("internal is defined");
nt->marked_internal = TRUE;
wn++;
}
#line 598 "inform7/Chapter 7/Preform.w"
;
nonterminals_declared++;
continue;
}
if ((Wordings__last_wn(W) >= wn+2) && (Lexer__word(wn+1) == COLONCOLONEQUALS_V)) {
{
#line 637 "inform7/Chapter 7/Preform.w"
nonterminal *nt = Preform__find_nonterminal(Lexer__word(wn));
production_list *pl;
{
#line 658 "inform7/Chapter 7/Preform.w"
for (pl = nt->first_production_list; pl; pl = pl->next_production_list)
if (pl->definition_language == language_being_read_by_Preform)
break;
if (pl == NULL) {
pl = CREATE(production_list);
pl->definition_language = language_being_read_by_Preform;
pl->first_production = NULL;
pl->as_avinue = NULL;
{
#line 672 "inform7/Chapter 7/Preform.w"
if (nt->first_production_list == NULL) nt->first_production_list = pl;
else {
production_list *p = nt->first_production_list;
while ((p) && (p->next_production_list)) p = p->next_production_list;
p->next_production_list = pl;
}
}
#line 666 "inform7/Chapter 7/Preform.w"
;
}
}
#line 639 "inform7/Chapter 7/Preform.w"
;
wn += 2;
int pc = 0;
while (TRUE) {
int x = wn;
while ((x <= Wordings__last_wn(W)) && (Lexer__word(x) != STROKE_V) && (Lexer__word(x) != PARBREAK_V)) x++;
if (wn < x) {
production *pr = Preform__new_production(Wordings__new(wn, x-1), nt, pc++);
wn = x;
{
#line 682 "inform7/Chapter 7/Preform.w"
if (pl->first_production == NULL) pl->first_production = pr;
else {
production *p = pl->first_production;
while ((p) && (p->next_production)) p = p->next_production;
p->next_production = pr;
}
}
#line 648 "inform7/Chapter 7/Preform.w"
;
}
if ((wn > Wordings__last_wn(W)) || (Lexer__word(x) == PARBREAK_V)) break; /* reached end */
wn++; /* advance past the stroke and continue */
}
wn--;
}
#line 603 "inform7/Chapter 7/Preform.w"
;
nonterminals_declared++;
continue;
}
LOG("At: <$w>\n", Wordings__new(wn, wn+10));
internal_error("language definition failed");
}
Preform__optimise_counts();
return nonterminals_declared;
}
#line 692 "inform7/Chapter 7/Preform.w"
nonterminal *Preform__detect_nonterminal(vocabulary_entry *ve) {
nonterminal *nt;
LOOP_OVER(nt, nonterminal)
if (ve == nt->nonterminal_id)
return nt;
return NULL;
}
nonterminal *Preform__find_nonterminal(vocabulary_entry *ve) {
nonterminal *nt = Preform__detect_nonterminal(ve);
if (nt) return nt;
nt = CREATE(nonterminal);
nt->nonterminal_id = ve;
nt->voracious = FALSE;
nt->multiplicitous = FALSE;
nt->optimised_in_this_pass = FALSE;
nt->min_nt_words = 1; nt->max_nt_words = INFINITE_WORD_COUNT;
nt->nt_req_bit = -1;
nt->first_production_list = NULL;
nt->marked_internal = FALSE;
nt->internal_definition = NULL;
nt->result_compositor = NULL;
nt->number_words_by_production = FALSE;
nt->flag_words_in_production = 0;
for (int i=0; i<MAX_RANGES_PER_PRODUCTION; i++)
nt->range_result[i] = EMPTY_WORDING;
nt->watched = FALSE;
nt->nonterminal_tries = 0; nt->nonterminal_matches = 0;
return nt;
}
#line 733 "inform7/Chapter 7/Preform.w"
production *Preform__new_production(wording W, nonterminal *nt, int pc) {
production *pr = CREATE(production);
pr->match_number = pc;
pr->next_production = NULL;
pr->no_ranges = 1; /* so that they count from 1; range 0 is unused */
pr->no_struts = 0; /* they will be detected later */
pr->min_pr_words = 1; pr->max_pr_words = INFINITE_WORD_COUNT;
pr->production_tries = 0; pr->production_matches = 0;
pr->sample_sentence = NULL; pr->sample_text = EMPTY_WORDING;
ptoken *head = NULL, *tail = NULL;
{
#line 760 "inform7/Chapter 7/Preform.w"
int result_count = 1;
int negation_modifier = FALSE, lower_case_modifier = FALSE;
int unescaped = TRUE;
int bracing_mode = OUTSIDE_PTBRACE;
ptoken *bracing_begins_at = NULL;
int tc = 0;
LOOP_THROUGH_WORDING(i, W) {
if (unescaped)
{
#line 785 "inform7/Chapter 7/Preform.w"
if (Lexer__word(i) == CARET_V) { negation_modifier = TRUE; continue; }
if (Lexer__word(i) == UNDERSCORE_V) { lower_case_modifier = TRUE; continue; }
if (Lexer__word(i) == BACKSLASH_V) { unescaped = FALSE; continue; }
switch (bracing_mode) {
case OUTSIDE_PTBRACE:
if (Lexer__word(i) == OPENBRACE_V) {
bracing_mode = ABOUT_TO_OPEN_PTBRACE; continue;
}
break;
case INSIDE_PTBRACE:
if (Lexer__word(i) == CLOSEBRACE_V) {
if (bracing_begins_at) {
int rnum = pr->no_ranges++;
if ((i+2 <= Wordings__last_wn(W)) && (Lexer__word(i+1) == QUESTIONMARK_V) &&
(Vocabulary__test_flags(i+2, NUMBER_MC))) {
rnum = Vocabulary__get_literal_number_value(Lexer__word(i+2));
i += 2;
}
bracing_begins_at->range_starts = rnum;
tail->range_ends = rnum;
}
bracing_mode = OUTSIDE_PTBRACE; bracing_begins_at = NULL; continue;
}
break;
}
}
#line 767 "inform7/Chapter 7/Preform.w"
;
ptoken *pt = Preform__parse_slashed_chain(nt, pr, i, unescaped);
if (pt == NULL) continue; /* we have set the production match number instead */
if (pt->ptoken_category == NONTERMINAL_PTC)
{
#line 842 "inform7/Chapter 7/Preform.w"
if (result_count < MAX_RESULTS_PER_PRODUCTION) {
if ((i+2 <= Wordings__last_wn(W)) && (Lexer__word(i+1) == QUESTIONMARK_V) &&
(Vocabulary__test_flags(i+2, NUMBER_MC))) {
pt->result_index = Vocabulary__get_literal_number_value(Lexer__word(i+2));
i += 2;
} else {
pt->result_index = result_count;
}
result_count++;
}
}
#line 772 "inform7/Chapter 7/Preform.w"
;
{
#line 814 "inform7/Chapter 7/Preform.w"
if (negation_modifier) pt->negated_ptoken = TRUE;
if (lower_case_modifier) pt->disallow_unexpected_upper = TRUE;
unescaped = TRUE;
negation_modifier = FALSE;
lower_case_modifier = FALSE;
switch (bracing_mode) {
case OUTSIDE_PTBRACE:
if (((pt->ptoken_category == SINGLE_WILDCARD_PTC) ||
(pt->ptoken_category == MULTIPLE_WILDCARD_PTC) ||
(pt->ptoken_category == POSSIBLY_EMPTY_WILDCARD_PTC))
&& (pr->no_ranges < MAX_RANGES_PER_PRODUCTION)) {
int rnum = pr->no_ranges++;
pt->range_starts = rnum;
pt->range_ends = rnum;
}
break;
case ABOUT_TO_OPEN_PTBRACE:
if (pr->no_ranges < MAX_RANGES_PER_PRODUCTION)
bracing_begins_at = pt;
bracing_mode = INSIDE_PTBRACE;
break;
}
}
#line 774 "inform7/Chapter 7/Preform.w"
;
if (tc++ < MAX_PTOKENS_PER_PRODUCTION) {
if (head == NULL) head = pt; else tail->next_ptoken = pt;
tail = pt;
}
}
}
#line 748 "inform7/Chapter 7/Preform.w"
;
pr->first_ptoken = head;
return pr;
}
#line 856 "inform7/Chapter 7/Preform.w"
ptoken *Preform__parse_slashed_chain(nonterminal *nt, production *pr, int wn, int unescaped) {
wording AW = Wordings__one_word(wn);
{
#line 867 "inform7/Chapter 7/Preform.w"
char *p = Lexer__word_raw_text(wn);
int k, breakme = FALSE;
if (unescaped) {
if ((p[0] == '/') && (islower(p[1])) && (p[2] == '/') && (p[3] == 0)) {
pr->match_number = p[1] - 'a';
return NULL;
}
if ((p[0] == '/') && (islower(p[1])) && (p[2] == p[1]) && (p[3] == '/') && (p[4] == 0)) {
pr->match_number = p[1] - 'a' + 26;
return NULL;
}
for (k=0; (p[k]) && (p[k+1]); k++)
if ((k > 0) && (p[k] == '/'))
breakme = TRUE;
}
if (breakme) AW = Feeds__feed_text_full(p, FALSE, "/"); /* break only at slashes */
}
#line 858 "inform7/Chapter 7/Preform.w"
;
ptoken *pt = NULL;
{
#line 887 "inform7/Chapter 7/Preform.w"
ptoken *alt = NULL;
for (; Wordings__nonempty(AW); AW = Wordings__trim_first_word(AW))
if (Lexer__word(Wordings__first_wn(AW)) != FORWARDSLASH_V) {
int mode = unescaped;
if (Wordings__length(AW) > 1) mode = FALSE;
ptoken *latest = Preform__new_ptoken(Lexer__word(Wordings__first_wn(AW)), mode, nt, pr->match_number);
if (alt == NULL) pt = latest;
else alt->alternative_ptoken = latest;
alt = latest;
}
}
#line 860 "inform7/Chapter 7/Preform.w"
;
return pt;
}
#line 906 "inform7/Chapter 7/Preform.w"
ptoken *Preform__new_ptoken(vocabulary_entry *ve, int unescaped, nonterminal *nt, int pc) {
ptoken *pt = CREATE(ptoken);
pt->next_ptoken = NULL;
pt->alternative_ptoken = NULL;
pt->negated_ptoken = FALSE;
pt->disallow_unexpected_upper = FALSE;
pt->result_index = 1;
pt->range_starts = -1; pt->range_ends = -1;
pt->ptoken_position = 0;
pt->strut_number = -1;
pt->ve_pt = NULL;
pt->nt_pt = NULL;
pt->balanced_wildcard = FALSE;
pt->ptoken_is_fast = FALSE;
char *p = Vocabulary__get_exemplar(ve, FALSE);
if ((unescaped) && (p) && (p[0] == '<') && (p[Platform__strlen(p)-1] == '>')) {
pt->nt_pt = Preform__find_nonterminal(ve);
pt->ptoken_category = NONTERMINAL_PTC;
} else {
pt->ve_pt = ve;
pt->ptoken_category = FIXED_WORD_PTC;
if (unescaped) {
if (ve == SIXDOTS_V) {
pt->ptoken_category = MULTIPLE_WILDCARD_PTC;
pt->balanced_wildcard = TRUE;
}
if (ve == THREEDOTS_V) pt->ptoken_category = MULTIPLE_WILDCARD_PTC;
if (ve == THREEHASHES_V) pt->ptoken_category = SINGLE_WILDCARD_PTC;
if (ve == THREEASTERISKS_V) pt->ptoken_category = POSSIBLY_EMPTY_WILDCARD_PTC;
}
}
if (pt->ptoken_category == FIXED_WORD_PTC) {
ve->flags |= (nt->flag_words_in_production);
if (nt->number_words_by_production) ve->literal_number_value = pc;
}
return pt;
}
#line 957 "inform7/Chapter 7/Preform.w"
int first_round_of_nt_optimisation_made = FALSE;
void Preform__optimise_counts(void) {
nonterminal *nt;
LOOP_OVER(nt, nonterminal) {
Preform__clear_rreq(&(nt->nonterminal_req));
if (nt->marked_internal) {
nt->optimised_in_this_pass = TRUE;
} else {
nt->optimised_in_this_pass = FALSE;
nt->min_nt_words = 1; nt->max_nt_words = INFINITE_WORD_COUNT;
}
}
if (first_round_of_nt_optimisation_made == FALSE) {
for (int wn = 0; wn < lexer_wordcount; wn++) {
if (Vocabulary__test_flags(wn, NUMBER_MC))
Preform__mark_as_cardinal(Lexer__word(wn));
if (Vocabulary__test_flags(wn, ORDINAL_MC))
Preform__mark_as_ordinal(Lexer__word(wn));
}
first_round_of_nt_optimisation_made = TRUE;
Preform__mark_nt_as_requiring_itself_conj(cardinal_number_NTM);
Preform__mark_nt_as_requiring_itself_conj(ordinal_number_NTM);
Preform__mark_nt_as_requiring_itself_first(general_verb_NTM);
Preform__mark_nt_as_requiring_itself_first(general_verb_present_positive_NTM);
Preform__mark_nt_as_requiring_itself_first(copular_verb_NTM);
Preform__mark_nt_as_requiring_itself_first(copular_verb_present_positive_NTM);
Preform__mark_nt_as_requiring_itself_first(negated_noncopular_verb_present_NTM);
Preform__mark_nt_as_requiring_itself_first(universal_verb_NTM);
Preform__mark_nt_as_requiring_itself_first(possession_verb_present_positive_NTM);
Preform__mark_nt_as_requiring_itself_first(negated_verb_NTM);
Preform__mark_nt_as_requiring_itself_first(past_tense_verb_NTM);
Preform__mark_nt_as_requiring_itself(preposition_NTM);
Preform__mark_nt_as_requiring_itself(preposition_implying_player_NTM);
Preform__mark_nt_as_requiring_itself_conj(s_adjective_NTM);
Preform__mark_nt_as_requiring_itself_articled(s_instance_name_NTM);
Preform__mark_nt_as_requiring_itself_articled(k_kind_variable_NTM);
Preform__mark_nt_as_requiring_itself_articled(k_formal_kind_variable_NTM);
Preform__mark_nt_as_requiring_itself_articled(k_base_kind_NTM);
Preform__mark_nt_as_requiring_itself_articled(k_kind_construction_NTM);
}
LOOP_OVER(nt, nonterminal) Preform__optimise_nt(nt);
LOOP_OVER(nt, nonterminal) Preform__optimise_nt_reqs(nt);
}
void Preform__optimise_nt(nonterminal *nt) {
if (nt->optimised_in_this_pass) return;
nt->optimised_in_this_pass = TRUE;
{
#line 1026 "inform7/Chapter 7/Preform.w"
int min = -1, max = -1;
production_list *pl;
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
int min_p = 0, max_p = 0;
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
int min_t, max_t;
Preform__ptoken_extrema(pt, &min_t, &max_t);
min_p += min_t; max_p += max_t;
if (min_p > INFINITE_WORD_COUNT) min_p = INFINITE_WORD_COUNT;
if (max_p > INFINITE_WORD_COUNT) max_p = INFINITE_WORD_COUNT;
}
pr->min_pr_words = min_p; pr->max_pr_words = max_p;
if ((min == -1) && (max == -1)) { min = min_p; max = max_p; }
else {
if (min_p < min) min = min_p;
if (max_p > max) max = max_p;
}
}
}
if (min >= 1) {
nt->min_nt_words = min; nt->max_nt_words = max;
}
}
#line 1005 "inform7/Chapter 7/Preform.w"
;
production_list *pl;
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
ptoken *last = NULL; /* this will point to the last ptoken in the production */
{
#line 1066 "inform7/Chapter 7/Preform.w"
int posn = 1;
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
last = pt;
int L = Preform__ptoken_width(pt);
if ((posn != 0) && (L != PTOKEN_ELASTIC)) {
pt->ptoken_position = posn;
posn += L;
} else {
pt->ptoken_position = 0; /* thus clearing any expired positions from earlier */
posn = 0;
}
}
}
#line 1012 "inform7/Chapter 7/Preform.w"
;
{
#line 1088 "inform7/Chapter 7/Preform.w"
int posn = -1;
ptoken *pt;
for (pt = last; pt; ) {
if (pt->ptoken_position != 0) break; /* don't use a back-end position if there's a front one */
int L = Preform__ptoken_width(pt);
if ((posn != 0) && (L != PTOKEN_ELASTIC)) {
pt->ptoken_position = posn;
posn -= L;
} else break;
ptoken *prevt = NULL;
for (prevt = pr->first_ptoken; prevt; prevt = prevt->next_ptoken)
if (prevt->next_ptoken == pt)
break;
pt = prevt;
}
}
#line 1013 "inform7/Chapter 7/Preform.w"
;
{
#line 1110 "inform7/Chapter 7/Preform.w"
pr->no_struts = 0;
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
if ((pt->ptoken_position == 0) && (Preform__ptoken_width(pt) != PTOKEN_ELASTIC)) {
if (pr->no_struts >= MAX_STRUTS_PER_PRODUCTION) continue;
pr->struts[pr->no_struts] = pt;
pr->strut_lengths[pr->no_struts] = 0;
while ((pt->ptoken_position == 0) && (Preform__ptoken_width(pt) != PTOKEN_ELASTIC)) {
pt->strut_number = pr->no_struts;
pr->strut_lengths[pr->no_struts] += Preform__ptoken_width(pt);
if (pt->next_ptoken == NULL) break; /* should be impossible */
pt = pt->next_ptoken;
}
pr->no_struts++;
}
}
}
#line 1014 "inform7/Chapter 7/Preform.w"
;
{
#line 1130 "inform7/Chapter 7/Preform.w"
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken)
if ((pt->ptoken_category == FIXED_WORD_PTC) && (pt->ptoken_position != 0)
&& (pt->range_starts < 0) && (pt->range_ends < 0))
pt->ptoken_is_fast = TRUE;
}
#line 1015 "inform7/Chapter 7/Preform.w"
;
}
}
{
#line 1140 "inform7/Chapter 7/Preform.w"
int first_production = TRUE;
Preform__clear_rreq(&(nt->nonterminal_req));
if (nt == k_kind_NTM) Preform__mark_nt_as_requiring_itself_articled(nt); /* to break a horrible circularity */
if (nt == k_kind_of_kind_NTM) Preform__mark_nt_as_requiring_itself_articled(nt); /* to break a horrible circularity */
range_requirement nnt;
Preform__clear_rreq(&nnt);
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
if ((pt->ptoken_category == FIXED_WORD_PTC) && (pt->negated_ptoken == FALSE)) {
ptoken *alt;
for (alt = pt; alt; alt = alt->alternative_ptoken)
Preform__set_nt_incidence(alt->ve_pt, nt);
}
}
}
}
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
range_requirement prt;
Preform__clear_rreq(&prt);
int all = TRUE, first = TRUE;
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
Preform__clear_rreq(&(pt->token_req));
if ((pt->ptoken_category == FIXED_WORD_PTC) && (pt->negated_ptoken == FALSE)) {
ptoken *alt;
for (alt = pt; alt; alt = alt->alternative_ptoken)
Preform__set_nt_incidence(alt->ve_pt, nt);
Preform__atomic_rreq(&(pt->token_req), nt);
} else all = FALSE;
int self_referential = FALSE, empty = FALSE;
if ((pt->ptoken_category == NONTERMINAL_PTC) &&
(pt->nt_pt->min_nt_words == 0) && (pt->nt_pt->max_nt_words == 0))
empty = TRUE; /* even if negated, notice */
if ((pt->ptoken_category == NONTERMINAL_PTC) && (pt->negated_ptoken == FALSE)) {
/* if (pt->nt_pt == nt) self_referential = TRUE; */
Preform__optimise_nt(pt->nt_pt);
pt->token_req = pt->nt_pt->nonterminal_req;
}
if ((self_referential == FALSE) && (empty == FALSE)) {
if (first) {
prt = pt->token_req;
} else {
Preform__concatenate_rreq(&prt, &(pt->token_req));
}
first = FALSE;
}
}
if (first_production) {
nnt = prt;
} else {
Preform__disjoin_rreq(&nnt, &prt);
}
first_production = FALSE;
pr->production_req = prt;
}
}
nt->nonterminal_req = nnt;
if (nt == k_kind_NTM) Preform__mark_nt_as_requiring_itself_articled(nt); /* to break a horrible circularity */
if (nt == k_kind_of_kind_NTM) Preform__mark_nt_as_requiring_itself_articled(nt); /* to break a horrible circularity */
}
#line 1018 "inform7/Chapter 7/Preform.w"
;
}
#line 1212 "inform7/Chapter 7/Preform.w"
void Preform__optimise_nt_reqs(nonterminal *nt) {
production_list *pl;
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
production *pr;
range_requirement *prev_req = NULL;
for (pr = pl->first_production; pr; pr = pr->next_production) {
Preform__optimise_req(&(pr->production_req), prev_req);
prev_req = &(pr->production_req);
}
}
Preform__optimise_req(&(nt->nonterminal_req), NULL);
}
void Preform__optimise_req(range_requirement *req, range_requirement *prev) {
if ((req->DS_req & req->FS_req) == req->DS_req) req->DS_req = 0;
if ((req->DW_req & req->FW_req) == req->DW_req) req->DW_req = 0;
if ((req->CS_req & req->FS_req) == req->FS_req) req->FS_req = 0;
if ((req->CW_req & req->FW_req) == req->FW_req) req->FW_req = 0;
if ((req->CS_req & req->DS_req) == req->DS_req) req->DS_req = 0;
if ((req->CW_req & req->DW_req) == req->DW_req) req->DW_req = 0;
if ((req->FW_req & req->FS_req) == req->FW_req) req->FW_req = 0;
if ((req->DW_req & req->DS_req) == req->DW_req) req->DW_req = 0;
if ((req->CW_req & req->CS_req) == req->CW_req) req->CW_req = 0;
req->no_requirements = TRUE;
if ((req->DS_req) || (req->DW_req) || (req->CS_req) || (req->CW_req) || (req->FS_req) || (req->FW_req))
req->no_requirements = FALSE;
req->ditto_flag = FALSE;
if ((prev) &&
(req->DS_req == prev->DS_req) && (req->DW_req == prev->DW_req) &&
(req->CS_req == prev->CS_req) && (req->CW_req == prev->CW_req) &&
(req->FS_req == prev->FS_req) && (req->FW_req == prev->FW_req))
req->ditto_flag = TRUE;
}
#line 1253 "inform7/Chapter 7/Preform.w"
void Preform__mark_as_preposition(vocabulary_entry *ve) {
Vocabulary__set_flags(ve, PREPOSITION_MC);
Preform__set_nt_incidence(ve, preposition_NTM);
Preform__set_nt_incidence(ve, preposition_implying_player_NTM);
}
void Preform__mark_as_verb(vocabulary_entry *ve) {
Preform__set_nt_incidence(ve, general_verb_NTM);
Preform__set_nt_incidence(ve, general_verb_present_positive_NTM);
Preform__set_nt_incidence(ve, foreign_verb_present_positive_NTM);
Preform__set_nt_incidence(ve, copular_verb_NTM);
Preform__set_nt_incidence(ve, copular_verb_present_positive_NTM);
Preform__set_nt_incidence(ve, negated_noncopular_verb_present_NTM);
Preform__set_nt_incidence(ve, universal_verb_NTM);
Preform__set_nt_incidence(ve, possession_verb_present_positive_NTM);
Preform__set_nt_incidence(ve, negated_verb_NTM);
Preform__set_nt_incidence(ve, past_tense_verb_NTM);
}
void Preform__mark_as_cardinal(vocabulary_entry *ve) {
Preform__set_nt_incidence(ve, cardinal_number_NTM);
}
void Preform__mark_as_ordinal(vocabulary_entry *ve) {
Preform__set_nt_incidence(ve, ordinal_number_NTM);
}
void Preform__mark_nt_as_requiring_itself(nonterminal *nt) {
nt->nonterminal_req.DS_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.DW_req |= (Preform__nt_bitmap_bit(nt));
}
void Preform__mark_nt_as_requiring_itself_first(nonterminal *nt) {
nt->nonterminal_req.DS_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.DW_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.FS_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.FW_req |= (Preform__nt_bitmap_bit(nt));
}
void Preform__mark_nt_as_requiring_itself_conj(nonterminal *nt) {
nt->nonterminal_req.DS_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.DW_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.CS_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.CW_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.FS_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.FW_req |= (Preform__nt_bitmap_bit(nt));
}
void Preform__mark_nt_as_requiring_itself_articled(nonterminal *nt) {
nt->nonterminal_req.DS_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.DW_req |= (Preform__nt_bitmap_bit(nt));
nt->nonterminal_req.CW_req |= (Preform__nt_bitmap_bit(nt) + Preform__nt_bitmap_bit(article_NTM));
nt->nonterminal_req.FW_req |= (Preform__nt_bitmap_bit(nt) + Preform__nt_bitmap_bit(article_NTM));
}
void Preform__set_nt_incidence(vocabulary_entry *ve, nonterminal *nt) {
int R = Vocabulary__get_ntb(ve);
R |= (Preform__nt_bitmap_bit(nt));
Vocabulary__set_ntb(ve, R);
}
#line 1319 "inform7/Chapter 7/Preform.w"
int Preform__nt_bitmap_bit(nonterminal *nt) {
if (nt->nt_req_bit == -1) {
int b;
if (nt == cardinal_number_NTM) b = 0;
else if (nt == ordinal_number_NTM) b = 1;
else if (nt == article_NTM) b = 2;
else if (nt == definite_article_NTM) b = 2;
else if (nt == indefinite_article_NTM) b = 2;
else if (nt == s_adjective_NTM) b = 3;
else if (nt == s_instance_name_NTM) b = 5;
else if (nt == k_kind_NTM) b = 5;
else if (nt == k_kind_of_kind_NTM) b = 5;
else if (nt == k_base_kind_NTM) b = 5;
else if (nt == k_kind_construction_NTM) b = 5;
else if (nt == k_kind_variable_texts_NTM) b = 5;
else if (nt == k_kind_variable_NTM) b = 5;
else if (nt == k_formal_kind_variable_NTM) b = 5;
else if (nt == k_irregular_kind_construction_NTM) b = 5;
else if (nt == k_variable_definition_NTM) b = 5;
else if (nt == k_single_material_NTM) b = 5;
else if (nt == k_optional_material_NTM) b = 5;
else if (nt == k_tupled_material_NTM) b = 5;
else if (nt == k_tuple_list_NTM) b = 5;
else b = RESERVED_NT_BITS + ((no_req_bits++)%(32-RESERVED_NT_BITS));
nt->nt_req_bit = (1 << b);
}
return nt->nt_req_bit;
}
int Preform__test_word(int wn, nonterminal *nt) {
int b = Preform__nt_bitmap_bit(nt);
if ((Vocabulary__get_ntb(Lexer__word(wn))) & b) return TRUE;
return FALSE;
}
void Preform__mark_word(int wn, nonterminal *nt) {
Preform__set_nt_incidence(Lexer__word(wn), nt);
}
void Preform__mark_vocabulary(vocabulary_entry *ve, nonterminal *nt) {
Preform__set_nt_incidence(ve, nt);
}
int Preform__test_vocabulary(vocabulary_entry *ve, nonterminal *nt) {
int b = Preform__nt_bitmap_bit(nt);
if ((Vocabulary__get_ntb(ve)) & b) return TRUE;
return FALSE;
}
int Preform__get_range_disjunction(wording W) {
int R = 0;
LOOP_THROUGH_WORDING(i, W)
R |= Vocabulary__get_ntb(Lexer__word(i));
return R;
}
int Preform__get_range_conjunction(wording W) {
int R = 0;
LOOP_THROUGH_WORDING(i, W) {
if (i == Wordings__first_wn(W)) R = Vocabulary__get_ntb(Lexer__word(i));
else R &= Vocabulary__get_ntb(Lexer__word(i));
}
return R;
}
#line 1387 "inform7/Chapter 7/Preform.w"
int Preform__nt_bitmap_violates(wording W, range_requirement *req) {
if (req->no_requirements) return FALSE;
if (Wordings__length(W) == 1) {
int bm = Vocabulary__get_ntb(Lexer__word(Wordings__first_wn(W)));
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
if (((bm) & (req->DS_req)) != (req->DS_req)) return TRUE;
if ((((bm) & (req->DW_req)) == 0) && (req->DW_req)) return TRUE;
if (((bm) & (req->CS_req)) != (req->CS_req)) return TRUE;
if ((((bm) & (req->CW_req)) == 0) && (req->CW_req)) return TRUE;
return FALSE;
}
int C_set = ((req->CS_req) | (req->CW_req));
int D_set = ((req->DS_req) | (req->DW_req));
int F_set = ((req->FS_req) | (req->FW_req));
if ((C_set) && (D_set)) {
int disj = 0;
LOOP_THROUGH_WORDING(i, W) {
int bm = Vocabulary__get_ntb(Lexer__word(i));
disj |= bm;
if (((bm) & (req->CS_req)) != (req->CS_req)) return TRUE;
if ((((bm) & (req->CW_req)) == 0) && (req->CW_req)) return TRUE;
if ((i == Wordings__first_wn(W)) && (F_set)) {
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
}
}
if (((disj) & (req->DS_req)) != (req->DS_req)) return TRUE;
if ((((disj) & (req->DW_req)) == 0) && (req->DW_req)) return TRUE;
} else if (C_set) {
LOOP_THROUGH_WORDING(i, W) {
int bm = Vocabulary__get_ntb(Lexer__word(i));
if (((bm) & (req->CS_req)) != (req->CS_req)) return TRUE;
if ((((bm) & (req->CW_req)) == 0) && (req->CW_req)) return TRUE;
if ((i == Wordings__first_wn(W)) && (F_set)) {
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
}
}
} else if (D_set) {
int disj = 0;
LOOP_THROUGH_WORDING(i, W) {
int bm = Vocabulary__get_ntb(Lexer__word(i));
disj |= bm;
if ((i == Wordings__first_wn(W)) && (F_set)) {
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
}
}
if (((disj) & (req->DS_req)) != (req->DS_req)) return TRUE;
if ((((disj) & (req->DW_req)) == 0) && (req->DW_req)) return TRUE;
} else if (F_set) {
int bm = Vocabulary__get_ntb(Lexer__word(Wordings__first_wn(W)));
if (((bm) & (req->FS_req)) != (req->FS_req)) return TRUE;
if ((((bm) & (req->FW_req)) == 0) && (req->FW_req)) return TRUE;
}
return FALSE;
}
#line 1450 "inform7/Chapter 7/Preform.w"
void Preform__concatenate_rreq(range_requirement *req, range_requirement *with) {
req->DS_req = Preform__concatenate_ds(req->DS_req, with->DS_req);
req->DW_req = Preform__concatenate_dw(req->DW_req, with->DW_req);
req->CS_req = Preform__concatenate_cs(req->CS_req, with->CS_req);
req->CW_req = Preform__concatenate_cw(req->CW_req, with->CW_req);
req->FS_req = Preform__concatenate_fs(req->FS_req, with->FS_req);
req->FW_req = Preform__concatenate_fw(req->FW_req, with->FW_req);
}
#line 1465 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_ds(int m1, int m2) {
return m1 | m2;
}
#line 1474 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_cs(int m1, int m2) {
return m1 & m2;
}
#line 1485 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_dw(int m1, int m2) {
if (m1 == 0) return m2; /* the case where we have no information about X */
if (m2 == 0) return m1; /* and about Y */
return m1; /* the general case discussed above */
}
#line 1496 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_cw(int m1, int m2) {
if (m1 == 0) return 0; /* the case where we have no information about X */
if (m2 == 0) return 0; /* and about Y */
return m1 | m2; /* the general case discussed above */
}
#line 1505 "inform7/Chapter 7/Preform.w"
int Preform__concatenate_fs(int m1, int m2) {
return m1;
}
int Preform__concatenate_fw(int m1, int m2) {
return m1;
}
#line 1518 "inform7/Chapter 7/Preform.w"
void Preform__disjoin_rreq(range_requirement *req, range_requirement *with) {
req->DS_req = Preform__disjoin_ds(req->DS_req, with->DS_req);
req->DW_req = Preform__disjoin_dw(req->DW_req, with->DW_req);
req->CS_req = Preform__disjoin_cs(req->CS_req, with->CS_req);
req->CW_req = Preform__disjoin_cw(req->CW_req, with->CW_req);
req->FS_req = Preform__disjoin_fs(req->FS_req, with->FS_req);
req->FW_req = Preform__disjoin_fw(req->FW_req, with->FW_req);
}
#line 1533 "inform7/Chapter 7/Preform.w"
int Preform__disjoin_ds(int m1, int m2) {
return m1 & m2;
}
#line 1542 "inform7/Chapter 7/Preform.w"
int Preform__disjoin_cs(int m1, int m2) {
return m1 & m2;
}
#line 1551 "inform7/Chapter 7/Preform.w"
int Preform__disjoin_dw(int m1, int m2) {
if (m1 == 0) return 0; /* the case where we have no information about X */
if (m2 == 0) return 0; /* and about Y */
return m1 | m2; /* the general case discussed above */
}
#line 1560 "inform7/Chapter 7/Preform.w"
int Preform__disjoin_cw(int m1, int m2) {
if (m1 == 0) return 0; /* the case where we have no information about X */
if (m2 == 0) return 0; /* and about Y */
return m1 | m2; /* the general case discussed above */
}
int Preform__disjoin_fw(int m1, int m2) {
return Preform__disjoin_cw(m1, m2);
}
int Preform__disjoin_fs(int m1, int m2) {
return Preform__disjoin_cs(m1, m2);
}
void Preform__clear_rreq(range_requirement *req) {
req->DS_req = 0; req->DW_req = 0;
req->CS_req = 0; req->CW_req = 0;
req->FS_req = 0; req->FW_req = 0;
}
void Preform__atomic_rreq(range_requirement *req, nonterminal *nt) {
int b = Preform__nt_bitmap_bit(nt);
req->DS_req = b; req->DW_req = b;
req->CS_req = b; req->CW_req = b;
req->FS_req = 0; req->FW_req = 0;
}
void Preform__log_range_requirement(range_requirement *req) {
if (req->DW_req) { LOG(" DW: %08x", req->DW_req); }
if (req->DS_req) { LOG(" DS: %08x", req->DS_req); }
if (req->CW_req) { LOG(" CW: %08x", req->CW_req); }
if (req->CS_req) { LOG(" CS: %08x", req->CS_req); }
if (req->FW_req) { LOG(" FW: %08x", req->FW_req); }
if (req->FS_req) { LOG(" FS: %08x", req->FS_req); }
}
#line 1601 "inform7/Chapter 7/Preform.w"
int Preform__ptoken_width(ptoken *pt) {
int min, max;
Preform__ptoken_extrema(pt, &min, &max);
if (min != max) return PTOKEN_ELASTIC;
return min;
}
#line 1615 "inform7/Chapter 7/Preform.w"
void Preform__ptoken_extrema(ptoken *pt, int *min_t, int *max_t) {
*min_t = 1; *max_t = 1;
if (pt->negated_ptoken) {
if (pt->ptoken_category != FIXED_WORD_PTC) { *min_t = 0; *max_t = INFINITE_WORD_COUNT; }
return;
}
switch (pt->ptoken_category) {
case NONTERMINAL_PTC:
Preform__optimise_nt(pt->nt_pt); /* recurse as needed to find its extrema */
*min_t = pt->nt_pt->min_nt_words;
*max_t = pt->nt_pt->max_nt_words;
break;
case MULTIPLE_WILDCARD_PTC:
*max_t = INFINITE_WORD_COUNT;
break;
case POSSIBLY_EMPTY_WILDCARD_PTC:
*min_t = 0;
*max_t = INFINITE_WORD_COUNT;
break;
}
}
#line 1672 "inform7/Chapter 7/Preform.w"
int ptraci = FALSE; /* in this mode, we trace parsing to the debugging log */
int preform_lookahead_mode = FALSE; /* in this mode, we are looking ahead */
int fail_nonterminal_quantum = 0; /* jump forward by this many words in lookahead */
void *preform_backtrack = NULL; /* position to backtrack from in voracious internal */
int Preform__parse_nt_against_word_range(nonterminal *nt, wording W, int *result,
void **result_p) {
time_t start_of_nt = time(0);
if (nt == NULL) internal_error("can't parse a null nonterminal");
#ifdef INSTRUMENTED_PREFORM
nt->nonterminal_tries++;
#endif
int success_rval = TRUE; /* what to return in the event of a successful match */
fail_nonterminal_quantum = 0;
int teppic = ptraci; /* Teppic saves Ptraci */
ptraci = nt->watched;
if (ptraci) {
if (preform_lookahead_mode) ptraci = FALSE;
else LOG("%s: <$w>\n", Vocabulary__get_exemplar(nt->nonterminal_id, FALSE), W);
}
int input_length = Wordings__length(W);
if ((nt->max_nt_words == 0) ||
((input_length >= nt->min_nt_words) && (input_length <= nt->max_nt_words))) {
{
#line 1731 "inform7/Chapter 7/Preform.w"
int unoptimised = FALSE;
if ((Wordings__empty(W)) || (input_length >= RANGE_OPTIMISATION_LENGTH))
unoptimised = TRUE;
if (nt->internal_definition) {
if (nt->voracious) unoptimised = TRUE;
if ((unoptimised) || (Preform__nt_bitmap_violates(W, &(nt->nonterminal_req)) == FALSE)) {
int r, Q; void *QP = NULL;
if (Wordings__first_wn(W) >= 0) r = (*(nt->internal_definition))(W, &Q, &QP);
else { r = FALSE; Q = 0; }
if (r) {
if (nt->voracious) success_rval = r;
if (ptraci) LOG("Succeeded %d\n", time(0)-start_of_nt);
{
#line 1716 "inform7/Chapter 7/Preform.w"
if (result) *result = Q; if (result_p) *result_p = QP;
most_recent_result = Q; most_recent_result_p = QP;
#ifdef INSTRUMENTED_PREFORM
nt->nonterminal_matches++;
#endif
ptraci = teppic;
return success_rval;
}
#line 1743 "inform7/Chapter 7/Preform.w"
;
}
} else {
if (ptraci) {
LOG("%s: <$w> violates ",
Vocabulary__get_exemplar(nt->nonterminal_id, FALSE),
W);
Preform__log_range_requirement(&(nt->nonterminal_req));
LOG("\n");
}
}
} else {
if ((unoptimised) || (Preform__nt_bitmap_violates(W, &(nt->nonterminal_req)) == FALSE)) {
parse_node *acc_result = NULL;
production_list *pl;
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
natural_language *nl = pl->definition_language;
if ((language_of_source_text == NULL) || (language_of_source_text == nl)) {
production *pr;
int last_v = FALSE;
for (pr = pl->first_production; pr; pr = pr->next_production) {
int violates = FALSE;
if (unoptimised == FALSE) {
if (pr->production_req.ditto_flag) violates = last_v;
else violates = Preform__nt_bitmap_violates(W, &(pr->production_req));
last_v = violates;
}
if (violates == FALSE) {
{
#line 1804 "inform7/Chapter 7/Preform.w"
if (ptraci) {
LOG_INDENT;
{
#line 1851 "inform7/Chapter 7/Preform.w"
if (pr->match_number >= 26) {
LOG("production /%c%c/: ", 'a'+pr->match_number-26, 'a'+pr->match_number-26);
} else {
LOG("production /%c/: ", 'a'+pr->match_number);
}
}
#line 1806 "inform7/Chapter 7/Preform.w"
;
Preform__log_production(pr, FALSE); LOG("\n");
}
#ifdef INSTRUMENTED_PREFORM
pr->production_tries++;
#endif
int slow_scan_needed = FALSE; parse_node *added_to_result = NULL;
if ((input_length >= pr->min_pr_words) && (input_length <= pr->max_pr_words)) {
int Q; void *QP = NULL;
{
#line 1870 "inform7/Chapter 7/Preform.w"
int checked[MAX_PTOKENS_PER_PRODUCTION];
int intermediates[MAX_RESULTS_PER_PRODUCTION];
void *intermediate_ps[MAX_RESULTS_PER_PRODUCTION];
int parsed_open_pos = -1, parsed_close_pos = -1;
{
#line 1919 "inform7/Chapter 7/Preform.w"
ptoken *pt;
int wn = -1, tc;
for (pt = pr->first_ptoken, tc = 0; pt; pt = pt->next_ptoken, tc++) {
if (pt->ptoken_is_fast) {
int p = pt->ptoken_position;
if (p > 0) wn = Wordings__first_wn(W)+p-1;
else if (p < 0) wn = Wordings__last_wn(W)+p+1;
if (Preform__parse_fixed_word_ptoken(wn, pt) == FALSE) {
slow_scan_needed = FALSE;
goto Fail; /* the word should have been here, and it wasn't */
}
if (pt->ve_pt == OPENBRACKET_V) parsed_open_pos = wn;
if (pt->ve_pt == CLOSEBRACKET_V) parsed_close_pos = wn;
checked[tc] = wn;
} else {
slow_scan_needed = TRUE;
checked[tc] = -1;
}
}
if ((slow_scan_needed == FALSE) && (wn != Wordings__last_wn(W))) goto Fail; /* input text goes on further */
}
#line 1875 "inform7/Chapter 7/Preform.w"
;
if (slow_scan_needed)
{
#line 1946 "inform7/Chapter 7/Preform.w"
int spos[MAX_STRUTS_PER_PRODUCTION]; /* word numbers for where we are trying the struts */
int NS = pr->no_struts;
{
#line 1969 "inform7/Chapter 7/Preform.w"
if (NS == 1) {
spos[0] = Preform__next_strut_posn_after(W, pr->struts[0], pr->strut_lengths[0], Wordings__first_wn(W));
if (spos[0] == -1) goto Fail;
} else if (NS > 1) {
int s, from = Wordings__first_wn(W);
for (s=0; s<NS; s++) {
spos[s] = Preform__next_strut_posn_after(W, pr->struts[s], pr->strut_lengths[s], from);
if (spos[s] == -1) goto Fail;
from = spos[s] + pr->strut_lengths[s] + 1;
}
}
}
#line 1948 "inform7/Chapter 7/Preform.w"
;
ptoken *backtrack_token = NULL;
int backtrack_index = -1, backtrack_to = -1, backtrack_tc = -1;
while (TRUE) {
{
#line 2010 "inform7/Chapter 7/Preform.w"
int wn = Wordings__first_wn(W), tc;
ptoken *pt, *nextpt;
if (backtrack_token) {
pt = backtrack_token; nextpt = backtrack_token->next_ptoken;
tc = backtrack_tc; wn = backtrack_to;
goto Reenter;
}
for (pt = pr->first_ptoken, nextpt = (pt)?(pt->next_ptoken):NULL, tc = 0;
pt;
pt = nextpt, nextpt = (pt)?(pt->next_ptoken):NULL, tc++) {
Reenter: ;
int known_pos = checked[tc];
if (known_pos >= 0) {
if (wn > known_pos) goto Fail; /* a theoretical possibility if strut lookahead overreaches */
wn = known_pos+1;
} else {
if (pt->range_starts >= 0) nt->range_result[pt->range_starts] = Wordings__one_word(wn);
switch (pt->ptoken_category) {
case FIXED_WORD_PTC:
{
#line 2043 "inform7/Chapter 7/Preform.w"
int q = Preform__parse_fixed_word_ptoken(wn, pt);
if (q == FALSE) goto FailThisStrutPosition;
if (pt->ve_pt == OPENBRACKET_V) parsed_open_pos = wn;
if (pt->ve_pt == CLOSEBRACKET_V) parsed_close_pos = wn;
wn++;
}
#line 2028 "inform7/Chapter 7/Preform.w"
; break;
case SINGLE_WILDCARD_PTC:
{
#line 2052 "inform7/Chapter 7/Preform.w"
wn++;
}
#line 2029 "inform7/Chapter 7/Preform.w"
; break;
case MULTIPLE_WILDCARD_PTC:
{
#line 2057 "inform7/Chapter 7/Preform.w"
if (wn > Wordings__last_wn(W)) goto FailThisStrutPosition;
int wt;
{
#line 2140 "inform7/Chapter 7/Preform.w"
ptoken *lookahead = nextpt;
if (lookahead == NULL) wt = Wordings__last_wn(W);
else {
int p = lookahead->ptoken_position;
if (p > 0) wt = Wordings__first_wn(W)+p-2;
else if (p < 0) wt = Wordings__last_wn(W)+p;
else if (lookahead->strut_number >= 0) wt = spos[lookahead->strut_number]-1;
else if ((lookahead->nt_pt)
&& (pt->negated_ptoken == FALSE)
&& (Preform__ptoken_width(pt) == PTOKEN_ELASTIC)) {
wt = -1;
nonterminal *target = lookahead->nt_pt;
int save_preform_lookahead_mode = preform_lookahead_mode;
preform_lookahead_mode = TRUE;
for (int j = wn+1; j <= Wordings__last_wn(W); j++) {
if (Preform__parse_nt_against_word_range(target, Wordings__new(j, Wordings__last_wn(W)), NULL, NULL)) {
if ((pt->nt_pt == NULL) ||
(Preform__parse_nt_against_word_range(pt->nt_pt, Wordings__new(wn, j-1), NULL, NULL))) {
wt = j-1; break;
}
} else {
if (fail_nonterminal_quantum > 0) j += fail_nonterminal_quantum - 1;
}
}
preform_lookahead_mode = save_preform_lookahead_mode;
if (wt < 0) goto FailThisStrutPosition;
} else wt = wn;
}
}
#line 2059 "inform7/Chapter 7/Preform.w"
;
if (wn > wt) goto FailThisStrutPosition; /* zero length */
if (pt->balanced_wildcard) {
int i, bl = 0;
for (i=wn; i<=wt; i++) {
if ((Lexer__word(i) == OPENBRACKET_V) || (Lexer__word(i) == OPENBRACE_V)) bl++;
if ((Lexer__word(i) == CLOSEBRACKET_V) || (Lexer__word(i) == CLOSEBRACE_V)) {
bl--;
if (bl < 0) goto FailThisStrutPosition;
}
}
if (bl != 0) goto FailThisStrutPosition;
}
wn = wt+1;
}
#line 2030 "inform7/Chapter 7/Preform.w"
; break;
case POSSIBLY_EMPTY_WILDCARD_PTC:
{
#line 2077 "inform7/Chapter 7/Preform.w"
int wt;
{
#line 2140 "inform7/Chapter 7/Preform.w"
ptoken *lookahead = nextpt;
if (lookahead == NULL) wt = Wordings__last_wn(W);
else {
int p = lookahead->ptoken_position;
if (p > 0) wt = Wordings__first_wn(W)+p-2;
else if (p < 0) wt = Wordings__last_wn(W)+p;
else if (lookahead->strut_number >= 0) wt = spos[lookahead->strut_number]-1;
else if ((lookahead->nt_pt)
&& (pt->negated_ptoken == FALSE)
&& (Preform__ptoken_width(pt) == PTOKEN_ELASTIC)) {
wt = -1;
nonterminal *target = lookahead->nt_pt;
int save_preform_lookahead_mode = preform_lookahead_mode;
preform_lookahead_mode = TRUE;
for (int j = wn+1; j <= Wordings__last_wn(W); j++) {
if (Preform__parse_nt_against_word_range(target, Wordings__new(j, Wordings__last_wn(W)), NULL, NULL)) {
if ((pt->nt_pt == NULL) ||
(Preform__parse_nt_against_word_range(pt->nt_pt, Wordings__new(wn, j-1), NULL, NULL))) {
wt = j-1; break;
}
} else {
if (fail_nonterminal_quantum > 0) j += fail_nonterminal_quantum - 1;
}
}
preform_lookahead_mode = save_preform_lookahead_mode;
if (wt < 0) goto FailThisStrutPosition;
} else wt = wn;
}
}
#line 2078 "inform7/Chapter 7/Preform.w"
;
wn = wt+1;
}
#line 2031 "inform7/Chapter 7/Preform.w"
; break;
case NONTERMINAL_PTC:
{
#line 2088 "inform7/Chapter 7/Preform.w"
if ((wn > Wordings__last_wn(W)) && (pt->nt_pt->min_nt_words > 0)) goto FailThisStrutPosition;
int wt;
if (pt->nt_pt->voracious) wt = Wordings__last_wn(W);
else if ((pt->nt_pt->min_nt_words > 0) && (pt->nt_pt->min_nt_words == pt->nt_pt->max_nt_words))
wt = wn + pt->nt_pt->min_nt_words - 1;
else
{
#line 2140 "inform7/Chapter 7/Preform.w"
ptoken *lookahead = nextpt;
if (lookahead == NULL) wt = Wordings__last_wn(W);
else {
int p = lookahead->ptoken_position;
if (p > 0) wt = Wordings__first_wn(W)+p-2;
else if (p < 0) wt = Wordings__last_wn(W)+p;
else if (lookahead->strut_number >= 0) wt = spos[lookahead->strut_number]-1;
else if ((lookahead->nt_pt)
&& (pt->negated_ptoken == FALSE)
&& (Preform__ptoken_width(pt) == PTOKEN_ELASTIC)) {
wt = -1;
nonterminal *target = lookahead->nt_pt;
int save_preform_lookahead_mode = preform_lookahead_mode;
preform_lookahead_mode = TRUE;
for (int j = wn+1; j <= Wordings__last_wn(W); j++) {
if (Preform__parse_nt_against_word_range(target, Wordings__new(j, Wordings__last_wn(W)), NULL, NULL)) {
if ((pt->nt_pt == NULL) ||
(Preform__parse_nt_against_word_range(pt->nt_pt, Wordings__new(wn, j-1), NULL, NULL))) {
wt = j-1; break;
}
} else {
if (fail_nonterminal_quantum > 0) j += fail_nonterminal_quantum - 1;
}
}
preform_lookahead_mode = save_preform_lookahead_mode;
if (wt < 0) goto FailThisStrutPosition;
} else wt = wn;
}
}
#line 2093 "inform7/Chapter 7/Preform.w"
;
if (pt == backtrack_token) {
if (ptraci) {
LOG("Reached backtrack position %s: <$w>\n",
Vocabulary__get_exemplar(pt->nt_pt->nonterminal_id, FALSE), Wordings__new(wn, wt));
}
preform_backtrack = intermediate_ps[pt->result_index];
}
if (ptraci) LOG_INDENT;
int q = Preform__parse_nt_against_word_range(pt->nt_pt, Wordings__new(wn, wt),
&(intermediates[pt->result_index]), &(intermediate_ps[pt->result_index]));
if (ptraci) LOG_OUTDENT;
if (pt == backtrack_token) { preform_backtrack = NULL; backtrack_token = NULL; }
if (pt->nt_pt->voracious) {
if (q > 0) { wt = q; q = TRUE; }
else if (q < 0) { wt = -q; q = TRUE;
backtrack_index = pt->result_index; backtrack_to = wn;
backtrack_token = pt; backtrack_tc = tc;
if (ptraci) {
LOG("Set backtrack position %s: <$w>\n",
Vocabulary__get_exemplar(pt->nt_pt->nonterminal_id, FALSE),
Wordings__new(wn, wt));
}
} else { wt = wn; }
}
if (pt->negated_ptoken) q = q?FALSE:TRUE;
if (q == FALSE) goto FailThisStrutPosition;
if (pt->nt_pt->max_nt_words > 0) wn = wt+1;
}
#line 2032 "inform7/Chapter 7/Preform.w"
; break;
}
if (pt->range_ends >= 0)
nt->range_result[pt->range_ends] = Wordings__up_to(nt->range_result[pt->range_ends], wn-1);
}
}
if (wn != Wordings__last_wn(W)+1) goto FailThisStrutPosition;
}
#line 1952 "inform7/Chapter 7/Preform.w"
;
break;
FailThisStrutPosition: ;
if (backtrack_token) continue;
{
#line 1987 "inform7/Chapter 7/Preform.w"
if (NS == 0) goto Fail;
else if (NS == 1) {
spos[0] = Preform__next_strut_posn_after(W, pr->struts[0], pr->strut_lengths[0], spos[0]+1);
if (spos[0] == -1) goto Fail;
} else if (NS > 1) {
int s;
for (s=NS-1; s>=0; s--) {
int n = Preform__next_strut_posn_after(W, pr->struts[s], pr->strut_lengths[s], spos[s]+1);
if (n != -1) { spos[s] = n; break; }
}
if (s == -1) goto Fail;
int from = spos[s] + 1; s++;
for (; s<NS; s++) {
spos[s] = Preform__next_strut_posn_after(W, pr->struts[s], pr->strut_lengths[s], from);
if (spos[s] == -1) goto Fail;
from = spos[s] + pr->strut_lengths[s] + 1;
}
}
}
#line 1956 "inform7/Chapter 7/Preform.w"
;
}
}
#line 1876 "inform7/Chapter 7/Preform.w"
;
if ((parsed_open_pos >= 0) && (parsed_close_pos >= 0))
if (Wordings__paired_brackets(Wordings__new(parsed_open_pos, parsed_close_pos)) == FALSE)
goto Fail;
{
#line 1898 "inform7/Chapter 7/Preform.w"
if (nt->result_compositor) {
intermediates[0] = pr->match_number;
int f = (*(nt->result_compositor))(&Q, &QP, intermediates, intermediate_ps, W);
if (f == FALSE) goto Fail;
if (nt->multiplicitous) {
added_to_result = QP;
acc_result = ParseTree__add_possible_reading(acc_result, QP, W);
goto Fail;
}
if ((f >= FAIL_NONTERMINAL) && (f < FAIL_NONTERMINAL_TO)) {
fail_nonterminal_quantum = f - FAIL_NONTERMINAL;
{
#line 1707 "inform7/Chapter 7/Preform.w"
if (ptraci) LOG("Failed %s (time %d)\n",
Vocabulary__get_exemplar(nt->nonterminal_id, FALSE), time(0)-start_of_nt);
ptraci = teppic;
return FALSE;
}
#line 1909 "inform7/Chapter 7/Preform.w"
;
}
} else {
Q = pr->match_number; QP = NULL;
}
}
#line 1881 "inform7/Chapter 7/Preform.w"
;
}
#line 1816 "inform7/Chapter 7/Preform.w"
;
#ifdef INSTRUMENTED_PREFORM /* record the sentence containing the longest example */
pr->production_matches++;
if ((current_sentence) &&
(Wordings__within(W, ParseTree__get_text(current_sentence))) &&
((pr->sample_sentence == NULL) ||
(Wordings__length(pr->sample_text) < Wordings__length(W)))) {
pr->sample_sentence = current_sentence;
pr->sample_text = W;
} else if (Wordings__empty(pr->sample_text)) {
pr->sample_text = W;
}
#endif
if (ptraci) {
{
#line 1851 "inform7/Chapter 7/Preform.w"
if (pr->match_number >= 26) {
LOG("production /%c%c/: ", 'a'+pr->match_number-26, 'a'+pr->match_number-26);
} else {
LOG("production /%c/: ", 'a'+pr->match_number);
}
}
#line 1832 "inform7/Chapter 7/Preform.w"
;
LOG("succeeded (%s): ", (slow_scan_needed)?"slowly":"quickly");
LOG("result: %d\n", Q); LOG_OUTDENT;
}
{
#line 1716 "inform7/Chapter 7/Preform.w"
if (result) *result = Q; if (result_p) *result_p = QP;
most_recent_result = Q; most_recent_result_p = QP;
#ifdef INSTRUMENTED_PREFORM
nt->nonterminal_matches++;
#endif
ptraci = teppic;
return success_rval;
}
#line 1836 "inform7/Chapter 7/Preform.w"
;
}
Fail:
if (ptraci) {
{
#line 1851 "inform7/Chapter 7/Preform.w"
if (pr->match_number >= 26) {
LOG("production /%c%c/: ", 'a'+pr->match_number-26, 'a'+pr->match_number-26);
} else {
LOG("production /%c/: ", 'a'+pr->match_number);
}
}
#line 1841 "inform7/Chapter 7/Preform.w"
;
if (added_to_result) LOG("added to result (%s): $P\n",
(slow_scan_needed)?"slowly":"quickly", added_to_result);
else LOG("failed (%s)\n", (slow_scan_needed)?"slowly":"quickly");
LOG_OUTDENT;
}
}
#line 1771 "inform7/Chapter 7/Preform.w"
;
} else {
if (ptraci) {
LOG("production in %s: ",
Vocabulary__get_exemplar(nt->nonterminal_id, FALSE));
Preform__log_production(pr, FALSE);
LOG(": <$w> violates ", W);
Preform__log_range_requirement(&(pr->production_req));
LOG("\n");
}
}
}
}
}
if ((nt->multiplicitous) && (acc_result)) {
int Q = TRUE; void *QP = acc_result;
{
#line 1716 "inform7/Chapter 7/Preform.w"
if (result) *result = Q; if (result_p) *result_p = QP;
most_recent_result = Q; most_recent_result_p = QP;
#ifdef INSTRUMENTED_PREFORM
nt->nonterminal_matches++;
#endif
ptraci = teppic;
return success_rval;
}
#line 1787 "inform7/Chapter 7/Preform.w"
;
}
} else {
if (ptraci) {
LOG("%s: <$w> violates ",
Vocabulary__get_exemplar(nt->nonterminal_id, FALSE),
W);
Preform__log_range_requirement(&(nt->nonterminal_req));
LOG("\n");
}
}
}
}
#line 1698 "inform7/Chapter 7/Preform.w"
;
}
{
#line 1707 "inform7/Chapter 7/Preform.w"
if (ptraci) LOG("Failed %s (time %d)\n",
Vocabulary__get_exemplar(nt->nonterminal_id, FALSE), time(0)-start_of_nt);
ptraci = teppic;
return FALSE;
}
#line 1701 "inform7/Chapter 7/Preform.w"
;
}
#line 2180 "inform7/Chapter 7/Preform.w"
int Preform__next_strut_posn_after(wording W, ptoken *start, int len, int from) {
int last_legal_position = Wordings__last_wn(W) - len + 1;
while (from <= last_legal_position) {
ptoken *pt;
int pos = from;
for (pt = start; pt; pt = pt->next_ptoken) {
if (pt->ptoken_category == FIXED_WORD_PTC) {
if (Preform__parse_fixed_word_ptoken(pos, pt)) pos++;
else break;
} else {
int q = Preform__parse_nt_against_word_range(pt->nt_pt,
Wordings__new(pos, pos+pt->nt_pt->max_nt_words-1),
NULL, NULL);
if (pt->negated_ptoken) q = q?FALSE:TRUE;
if (q) pos += pt->nt_pt->max_nt_words;
else break;
}
if (pos-from >= len) return from;
}
from++;
}
return -1;
}
#line 2207 "inform7/Chapter 7/Preform.w"
int Preform__parse_fixed_word_ptoken(int wn, ptoken *pt) {
vocabulary_entry *ve = Lexer__word(wn);
int m = pt->disallow_unexpected_upper;
ptoken *alt;
for (alt = pt; alt; alt = alt->alternative_ptoken)
if ((ve == alt->ve_pt) &&
((m == FALSE) || (Text__unexpectedly_upper_case(wn) == FALSE)))
return (pt->negated_ptoken)?FALSE:TRUE;
return (pt->negated_ptoken)?TRUE:FALSE;
}
#line 83 "inform7/Chapter 7/Non-Parsing Preform.w"
word_assemblage Preform__Nonparsing__merge(nonterminal *nt, int pnum, word_assemblage ingredient) {
production_list *pl;
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
int N = 0;
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
if (N == pnum) {
word_assemblage wa = WordAssemblages__lit_0();
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
if (pt->ptoken_category == FIXED_WORD_PTC) {
wa = WordAssemblages__join(wa, WordAssemblages__lit_1(pt->ve_pt));
} else if (pt->ptoken_category == MULTIPLE_WILDCARD_PTC) {
wa = WordAssemblages__join(wa, ingredient);
}
}
return wa;
}
N++;
}
}
return WordAssemblages__lit_0(); /* give up, in other words */
}
#line 111 "inform7/Chapter 7/Non-Parsing Preform.w"
word_assemblage Preform__Nonparsing__wording(nonterminal *nt, int pnum) {
return Preform__Nonparsing__merge(nt, pnum, WordAssemblages__lit_0());
}
#line 118 "inform7/Chapter 7/Non-Parsing Preform.w"
vocabulary_entry *Preform__Nonparsing__word(nonterminal *nt, int pnum) {
word_assemblage wa = Preform__Nonparsing__merge(nt, pnum, WordAssemblages__lit_0());
vocabulary_entry **words;
int num_words;
WordAssemblages__as_array(&wa, &words, &num_words);
if (num_words == 1) return words[0];
return NULL;
}
#line 132 "inform7/Chapter 7/Non-Parsing Preform.w"
vocabulary_entry *Preform__Nonparsing__replace_word(vocabulary_entry *ve,
nonterminal *nt_from, nonterminal *nt_to) {
production_list *pl_from, *pl_to;
for (pl_from = nt_from->first_production_list,
pl_to = nt_to->first_production_list;
((pl_from) && (pl_to));
pl_from = pl_from->next_production_list,
pl_to = pl_to->next_production_list) {
production *pr_from, *pr_to;
for (pr_from = pl_from->first_production,
pr_to = pl_to->first_production;
((pr_from) && (pr_to));
pr_from = pr_from->next_production,
pr_to = pr_to->next_production) {
ptoken *pt_from, *pt_to;
for (pt_from = pr_from->first_ptoken,
pt_to = pr_to->first_ptoken;
((pt_from) && (pt_to));
pt_from = pt_from->next_ptoken,
pt_to = pt_to->next_ptoken) {
if ((pt_from->ptoken_category == FIXED_WORD_PTC) &&
(pt_to->ptoken_category == FIXED_WORD_PTC)) {
if (ve == pt_from->ve_pt) return pt_to->ve_pt;
}
}
}
}
return ve; /* no change, in other words */
}
#line 166 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__enter_lexicon(nonterminal *nt_from, int pos, char *category, char *gloss) {
production_list *pl;
for (pl = nt_from->first_production_list; pl; pl = pl->next_production_list) {
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
ptoken *alt;
for (alt = pt; alt; alt = alt->alternative_ptoken) {
vocabulary_entry *ve = alt->ve_pt;
if (ve) {
Index__Lexicon__new_entry_with_details(EMPTY_WORDING, pos,
WordAssemblages__lit_1(ve), category, gloss);
}
}
}
}
}
}
#line 194 "inform7/Chapter 7/Non-Parsing Preform.w"
match_avinue *Preform__Nonparsing__define_trie(nonterminal *nt, int end, natural_language *nl) {
if (nl == NULL) nl = English_language;
match_avinue *ave = NULL;
production_list *pl;
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
if (pl->definition_language == nl) {
if (pl->as_avinue) return pl->as_avinue;
{
#line 214 "inform7/Chapter 7/Non-Parsing Preform.w"
int list_grammar = NOT_APPLICABLE; /* i.e., we don't know yet */
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
ptoken *first = pr->first_ptoken;
if (first == NULL) continue;
ptoken *second = first->next_ptoken;
if ((second) && (second->next_ptoken)) {
Preform__log_production(pr, FALSE);
Preform__Nonparsing__trie_definition_error(nt, pr, "trie line with more than 2 words");
}
{
#line 241 "inform7/Chapter 7/Non-Parsing Preform.w"
int this_end = end;
ptoken *entry = NULL;
if ((first->ptoken_category == MULTIPLE_WILDCARD_PTC) &&
(second) && (second->ptoken_category == NONTERMINAL_PTC)) {
entry = second; this_end = TRIE_END;
}
if ((first->ptoken_category == NONTERMINAL_PTC) &&
(second) && (second->ptoken_category == MULTIPLE_WILDCARD_PTC)) {
entry = first; this_end = TRIE_START;
}
if ((first->ptoken_category == NONTERMINAL_PTC) && (second == NULL)) {
entry = first;
}
if (entry) {
if (list_grammar == FALSE)
{
#line 271 "inform7/Chapter 7/Non-Parsing Preform.w"
Preform__Nonparsing__trie_definition_error(nt, pr,
"this should either be a list of other nonterminals, or a list of patterns "
"and instructions, but not a mixture");
}
#line 256 "inform7/Chapter 7/Non-Parsing Preform.w"
;
{
#line 278 "inform7/Chapter 7/Non-Parsing Preform.w"
match_avinue *next_mt =
Inflections__fresh_avinue(Preform__Nonparsing__define_trie(entry->nt_pt, this_end, nl));
if (ave == NULL) ave = next_mt;
else {
match_avinue *m = ave;
while (m->next) m = m->next;
m->next = next_mt;
}
}
#line 257 "inform7/Chapter 7/Non-Parsing Preform.w"
;
list_grammar = TRUE;
} else {
if (list_grammar == TRUE)
{
#line 271 "inform7/Chapter 7/Non-Parsing Preform.w"
Preform__Nonparsing__trie_definition_error(nt, pr,
"this should either be a list of other nonterminals, or a list of patterns "
"and instructions, but not a mixture");
}
#line 260 "inform7/Chapter 7/Non-Parsing Preform.w"
;
if (second == NULL)
Preform__Nonparsing__trie_definition_error(nt, pr,
"there should be two words here, a pattern and an instruction");
{
#line 290 "inform7/Chapter 7/Non-Parsing Preform.w"
if (ave == NULL) ave = Inflections__new_avinue(end);
Inflections__add_to_avinue(ave,
Vocabulary__get_exemplar(first->ve_pt, FALSE),
Vocabulary__get_exemplar(second->ve_pt, FALSE));
}
#line 264 "inform7/Chapter 7/Non-Parsing Preform.w"
;
list_grammar = FALSE;
}
}
#line 224 "inform7/Chapter 7/Non-Parsing Preform.w"
;
}
}
#line 201 "inform7/Chapter 7/Non-Parsing Preform.w"
;
pl->as_avinue = ave;
}
}
return ave;
}
#line 298 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__log_avinues(void) {
nonterminal *nt;
LOOP_OVER(nt, nonterminal) {
production_list *pl;
for (pl = nt->first_production_list; pl; pl = pl->next_production_list) {
if (pl->as_avinue) {
LOG("\n\n%s ($J)\n",
Vocabulary__get_exemplar(nt->nonterminal_id, FALSE),
pl->definition_language);
Inflections__log_avinue(pl->as_avinue);
}
}
}
}
#line 327 "inform7/Chapter 7/Non-Parsing Preform.w"
verb_conjugation *Preform__Nonparsing__conjugate_verb(word_assemblage base_text,
word_assemblage *overrides, int no_overrides, natural_language *nl) {
if (nl == NULL) nl = English_language;
if (WordAssemblages__nonempty(base_text) == FALSE)
internal_error("No base text for verb conjugation");
word_assemblage verb_forms[MAX_FORM_TYPES+1];
{
#line 348 "inform7/Chapter 7/Non-Parsing Preform.w"
int k;
for (k=0; k<=MAX_FORM_TYPES; k++) verb_forms[k] = base_text;
}
#line 335 "inform7/Chapter 7/Non-Parsing Preform.w"
;
int n = 1, aux_len = 0, avo_flag = FALSE, niv_flag = FALSE;
nonterminal *tabulation =
Preform__Nonparsing__follow_conjugation_instructions(verb_forms, &n, &aux_len, &avo_flag, &niv_flag, nl);
{
#line 365 "inform7/Chapter 7/Non-Parsing Preform.w"
int k;
for (k=1; k<no_overrides; k++)
if (WordAssemblages__nonempty(overrides[k]))
verb_forms[k] = overrides[k];
}
#line 341 "inform7/Chapter 7/Non-Parsing Preform.w"
;
{
#line 373 "inform7/Chapter 7/Non-Parsing Preform.w"
verb_conjugation *vc = CREATE(verb_conjugation);
vc->vc_meaning = NULL;
vc->infinitive = verb_forms[INFINITIVE_FORM_TYPE];
vc->present_participle = verb_forms[PRESENT_PARTICIPLE_FORM_TYPE];
vc->past_participle = verb_forms[PAST_PARTICIPLE_FORM_TYPE];
vc->defined_in = nl;
vc->auxiliary_only = avo_flag;
vc->instance_of_verb = (niv_flag)?FALSE:TRUE;
vc->where_vc_created = current_sentence;
{
#line 394 "inform7/Chapter 7/Non-Parsing Preform.w"
vc->active_tabulation.to_be_auxiliary = WordAssemblages__lit_0();
vc->passive_tabulation.to_be_auxiliary = WordAssemblages__lit_0();
int i, tense, sense;
for (tense=0; tense<NO_KNOWN_TENSES; tense++)
for (sense=0; sense<2; sense++)
for (i=0; i<6; i++) {
vc->active_tabulation.vc_text[tense][sense][i] = WordAssemblages__lit_0();
vc->passive_tabulation.vc_text[tense][sense][i] = WordAssemblages__lit_0();
}
}
#line 383 "inform7/Chapter 7/Non-Parsing Preform.w"
;
{
#line 414 "inform7/Chapter 7/Non-Parsing Preform.w"
production_list *pl;
for (pl = tabulation->first_production_list; pl; pl = pl->next_production_list) {
if (nl == pl->definition_language) {
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
ptoken *selector = pr->first_ptoken;
ptoken *line = (selector)?(selector->next_ptoken):NULL;
if ((selector) && (selector->ptoken_category == FIXED_WORD_PTC) && (line)) {
{
#line 432 "inform7/Chapter 7/Non-Parsing Preform.w"
int active_set = NOT_APPLICABLE, tense_set = -1, sense_set = -1, set_tba = FALSE;
{
#line 460 "inform7/Chapter 7/Non-Parsing Preform.w"
vocabulary_entry *ve = selector->ve_pt;
char *p = Vocabulary__get_exemplar(ve, FALSE);
if (p[0] == 'a') active_set = TRUE;
if (p[0] == 'p') active_set = FALSE;
if (active_set == NOT_APPLICABLE)
Preform__Nonparsing__conjugation_error(base_text, tabulation, pr,
"tabulation row doesn't begin with 'a' or 'p'");
int at = 1;
if (isdigit(p[at])) { tense_set = p[at++]-'1'; }
if (p[at] == '+') { sense_set = 0; at++; }
else if (p[at] == '-') { sense_set = 1; at++; }
else if ((p[at] == '*') && (tense_set == -1) && (active_set == FALSE)) {
set_tba = TRUE; at++;
}
if (p[at] != 0) {
LOG("The selector here is: <%s>\n", p);
Preform__Nonparsing__conjugation_error(base_text, tabulation, pr,
"unrecognised selector in tabulation row");
}
}
#line 433 "inform7/Chapter 7/Non-Parsing Preform.w"
;
if (set_tba)
vc->passive_tabulation.to_be_auxiliary =
Preform__Nonparsing__merge_verb_material(line, 0, 0, 0, MAX_FORM_TYPES+1, verb_forms, nl, NULL);
int person, tense, sense;
for (tense=0; tense<NO_KNOWN_TENSES; tense++)
for (sense=0; sense<2; sense++)
for (person=0; person<6; person++) {
if ((sense_set >= 0) && (sense != sense_set)) continue;
if ((tense_set >= 0) && (tense != tense_set)) continue;
if (active_set)
vc->active_tabulation.vc_text[tense][sense][person] =
Preform__Nonparsing__merge_verb_material(line, sense, tense, person, MAX_FORM_TYPES+1, verb_forms, nl,
&(vc->active_tabulation.modal_auxiliary_usage[tense][sense][person]));
else
vc->passive_tabulation.vc_text[tense][sense][person] =
Preform__Nonparsing__merge_verb_material(line, sense, tense, person, MAX_FORM_TYPES+1, verb_forms, nl,
&(vc->passive_tabulation.modal_auxiliary_usage[tense][sense][person]));
}
}
#line 422 "inform7/Chapter 7/Non-Parsing Preform.w"
;
} else Preform__Nonparsing__conjugation_error(base_text, tabulation, pr,
"tabulation row doesn't consist of a selector and then text");
}
}
}
}
#line 384 "inform7/Chapter 7/Non-Parsing Preform.w"
;
if (tabulation == to_be_tabulation_NTM) to_be_conjugation = vc;
/* Preform__Nonparsing__write_conjugation(dl, vc); */
return vc;
}
#line 342 "inform7/Chapter 7/Non-Parsing Preform.w"
;
}
#line 494 "inform7/Chapter 7/Non-Parsing Preform.w"
nonterminal *Preform__Nonparsing__follow_conjugation_instructions(word_assemblage *verb_forms, int *highest_form_written,
int *aux_len, int *avo_flag, int *niv_flag, natural_language *nl) {
nonterminal *instructions_nt = verb_conjugation_instructions_NTM;
nonterminal *tabulation_nt = NULL, *conjugation_nt = NULL;
*highest_form_written = 1;
*aux_len = 0; *avo_flag = FALSE; *niv_flag = FALSE;
{
#line 514 "inform7/Chapter 7/Non-Parsing Preform.w"
vocabulary_entry **base_text_words;
int base_text_word_count;
WordAssemblages__as_array(&(verb_forms[BASE_FORM_TYPE]), &base_text_words, &base_text_word_count);
production_list *pl;
for (pl = instructions_nt->first_production_list; pl; pl = pl->next_production_list) {
if (nl == pl->definition_language) {
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
{
#line 545 "inform7/Chapter 7/Non-Parsing Preform.w"
ptoken *pt, *last = NULL;
int len = 0, malformed = FALSE;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) { last = pt; len++; }
if ((len >= 1) && (last->ptoken_category == NONTERMINAL_PTC)) {
if (conjugation_nt == NULL) { /* i.e., if we have not yet chosen a conjugation */
int failed_to_match = FALSE, wildcard_from = -1;
{
#line 568 "inform7/Chapter 7/Non-Parsing Preform.w"
int word_count = 0;
for (pt = pr->first_ptoken; ((pt) && (pt != last)); pt = pt->next_ptoken) {
if (pt->ptoken_category == FIXED_WORD_PTC) {
if ((word_count < base_text_word_count) &&
(Preform__Nonparsing__compare_ve_with_tails(base_text_words[word_count], pt->ve_pt)))
word_count++;
else failed_to_match = TRUE;
} else if (pt->ptoken_category == MULTIPLE_WILDCARD_PTC) {
wildcard_from = word_count;
if (base_text_word_count <= word_count)
failed_to_match = TRUE; /* must match at least one word */
} else malformed = TRUE;
}
if (wildcard_from == -1) {
if (word_count != base_text_word_count) failed_to_match = TRUE;
wildcard_from = 0;
}
}
#line 551 "inform7/Chapter 7/Non-Parsing Preform.w"
;
if (failed_to_match == FALSE) {
conjugation_nt = last->nt_pt;
verb_forms[ADJOINT_INFINITIVE_FORM_TYPE] = verb_forms[BASE_FORM_TYPE];
if (wildcard_from > 0)
WordAssemblages__truncate(&(verb_forms[ADJOINT_INFINITIVE_FORM_TYPE]), wildcard_from);
*aux_len = wildcard_from;
}
}
} else malformed = TRUE;
if (malformed)
Preform__Nonparsing__conjugation_error(verb_forms[BASE_FORM_TYPE], verb_conjugation_instructions_NTM, pr,
"malformed line");
}
#line 523 "inform7/Chapter 7/Non-Parsing Preform.w"
;
}
}
}
}
#line 500 "inform7/Chapter 7/Non-Parsing Preform.w"
;
if (conjugation_nt == NULL)
Preform__Nonparsing__conjugation_error(verb_forms[0], instructions_nt, NULL,
"the instructions here failed to choose a conjugation");
{
#line 591 "inform7/Chapter 7/Non-Parsing Preform.w"
production_list *pl;
for (pl = conjugation_nt->first_production_list; pl; pl = pl->next_production_list) {
if (nl == pl->definition_language) {
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
ptoken *pt;
int len = 0, malformed = FALSE;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) len++;
switch (len) {
case 1:
if (pr->first_ptoken->ptoken_category == NONTERMINAL_PTC) {
if (pr->first_ptoken->nt_pt == auxiliary_verb_only_NTM)
*avo_flag = TRUE;
else if (pr->first_ptoken->nt_pt == not_instance_of_verb_at_run_time_NTM)
*niv_flag = TRUE;
else
tabulation_nt = pr->first_ptoken->nt_pt;
} else malformed = TRUE;
break;
case 2:
{
#line 630 "inform7/Chapter 7/Non-Parsing Preform.w"
ptoken *number_token = pr->first_ptoken;
ptoken *content_token = number_token->next_ptoken;
int n = Preform__Nonparsing__ptoken_to_verb_form_number(number_token);
if (n >= 0) {
if (n > *highest_form_written) { *highest_form_written = n; }
if (content_token->ptoken_category == NONTERMINAL_PTC)
verb_forms[n] =
Inflections__apply_trie_to_wa(
verb_forms[BASE_FORM_TYPE],
Preform__Nonparsing__define_trie(content_token->nt_pt, TRIE_END, nl));
else if (content_token->ptoken_category == FIXED_WORD_PTC)
verb_forms[n] =
Preform__Nonparsing__expand_wa_with_endings(content_token->ve_pt, verb_forms);
else malformed = TRUE;
} else malformed = TRUE;
}
#line 611 "inform7/Chapter 7/Non-Parsing Preform.w"
;
break;
default: malformed = TRUE; break;
}
if (malformed)
Preform__Nonparsing__conjugation_error(verb_forms[BASE_FORM_TYPE], conjugation_nt, pr,
"malformed line");
}
}
}
}
#line 504 "inform7/Chapter 7/Non-Parsing Preform.w"
;
if (tabulation_nt == NULL)
Preform__Nonparsing__conjugation_error(verb_forms[0], conjugation_nt, NULL,
"the conjugation here failed to choose a tabulation");
return tabulation_nt;
}
#line 669 "inform7/Chapter 7/Non-Parsing Preform.w"
word_assemblage Preform__Nonparsing__merge_verb_material(ptoken *row,
int sense, int tense, int person, int num_ingredients, word_assemblage *ingredients,
natural_language *nl, int *modal_following) {
if (modal_following) { *modal_following = 0; }
word_assemblage wa = WordAssemblages__lit_0();
int verb_form_to_lift = -1;
ptoken *chunk;
for (chunk = row; chunk; chunk = chunk->next_ptoken) {
{
#line 786 "inform7/Chapter 7/Non-Parsing Preform.w"
if (chunk->ptoken_category == FIXED_WORD_PTC) {
char *p = Vocabulary__get_exemplar(chunk->ve_pt, TRUE);
if ((p[0] == '+') && (p[1] == '+') && (isdigit(p[2])) && (p[3] == 0)) {
if (modal_following) {
*modal_following = ((int) p[2]) - ((int) '0');
}
continue;
}
}
}
#line 677 "inform7/Chapter 7/Non-Parsing Preform.w"
;
{
#line 731 "inform7/Chapter 7/Non-Parsing Preform.w"
int X = Preform__Nonparsing__ptoken_to_verb_form_number(chunk);
if ((X >= 0) && (Preform__Nonparsing__ptoken_as_bracket(chunk->next_ptoken))) {
verb_form_to_lift = X;
continue;
}
}
#line 678 "inform7/Chapter 7/Non-Parsing Preform.w"
;
{
#line 752 "inform7/Chapter 7/Non-Parsing Preform.w"
if (Preform__Nonparsing__ptoken_as_bracket(chunk) == 1) {
chunk = chunk->next_ptoken; /* move past open bracket */
/* if there is a tense/sense indicator, use it, and move forward */
int S = -1;
int T = Preform__Nonparsing__ptoken_to_tense_indicator(chunk, &S) - 1;
if (T >= 0) chunk = chunk->next_ptoken; else T = tense;
if (S == -1) S = sense;
/* extract the text of the infinitive */
word_assemblage verb_lifted = WordAssemblages__lit_0();
while ((chunk) && (Preform__Nonparsing__ptoken_as_bracket(chunk) != -1)) {
verb_lifted = WordAssemblages__join(verb_lifted,
Preform__Nonparsing__expand_wa_with_endings(chunk->ve_pt, ingredients));
chunk = chunk->next_ptoken;
}
verb_conjugation *aux = Verbs__find_vc_by_infinitive(verb_lifted);
if (aux == NULL) aux = Preform__Nonparsing__conjugate_verb(verb_lifted, NULL, 0, nl);
if (aux == NULL) internal_error("can't conjugate lifted verb");
switch (verb_form_to_lift) {
case 1: wa = WordAssemblages__join(wa, aux->infinitive); break;
case 2: wa = WordAssemblages__join(wa, aux->present_participle); break;
case 3: wa = WordAssemblages__join(wa, aux->past_participle); break;
case -1: wa = WordAssemblages__join(wa, aux->active_tabulation.vc_text[T][S][person]);
break;
default: internal_error("only parts 1, 2, 3 can be extracted");
}
continue;
}
}
#line 679 "inform7/Chapter 7/Non-Parsing Preform.w"
;
{
#line 692 "inform7/Chapter 7/Non-Parsing Preform.w"
if (chunk->ptoken_category == FIXED_WORD_PTC) {
wa = WordAssemblages__join(wa, Preform__Nonparsing__expand_wa_with_endings(chunk->ve_pt, ingredients));
continue;
}
}
#line 680 "inform7/Chapter 7/Non-Parsing Preform.w"
;
{
#line 705 "inform7/Chapter 7/Non-Parsing Preform.w"
if (chunk->ptoken_category == NONTERMINAL_PTC) {
production_list *pl;
for (pl = chunk->nt_pt->first_production_list; pl; pl = pl->next_production_list) {
int N = 0;
production *pr;
for (pr = pl->first_production; pr; pr = pr->next_production) {
if (N == person)
wa = WordAssemblages__join(wa,
Preform__Nonparsing__merge_verb_material(pr->first_ptoken,
sense, tense, person, num_ingredients, ingredients, nl, NULL));
N++;
}
}
continue;
}
}
#line 681 "inform7/Chapter 7/Non-Parsing Preform.w"
;
internal_error("Error in merge material line");
}
return Preform__Nonparsing__shorten_wa_with_contractions(wa);
}
#line 803 "inform7/Chapter 7/Non-Parsing Preform.w"
word_assemblage Preform__Nonparsing__expand_wa_with_endings(vocabulary_entry *ve, word_assemblage *verb_forms) {
if (ve == NULL) return WordAssemblages__lit_0();
char *p = Vocabulary__get_exemplar(ve, TRUE);
int i;
for (i=0; p[i]; i++)
if ((i>0) && (p[i+1]) && ((p[i] == '+') || (p[i] == '~'))) {
vocabulary_entry *front =
Vocabulary__entry_for_partial_text(p, 0, i-1);
vocabulary_entry *back =
Vocabulary__entry_for_partial_text(p, i+1, Platform__strlen(p)-1);
word_assemblage front_wa = Preform__Nonparsing__expand_wa_with_endings(front, verb_forms);
word_assemblage back_wa = Preform__Nonparsing__expand_wa_with_endings(back, verb_forms);
TEMPORARY_STREAM;
WordAssemblages__copy_to_stream(TEMP, &front_wa);
if (p[i] == '~') PUT_TO(TEMP, ' ');
WordAssemblages__copy_to_stream(TEMP, &back_wa);
wording W = Feeds__feed_text(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
return WordAssemblages__from_wording(W);
}
int X = Preform__Nonparsing__ve_to_verb_form_number(ve);
if (X >= 0) return verb_forms[X];
return WordAssemblages__lit_1(ve);
}
#line 854 "inform7/Chapter 7/Non-Parsing Preform.w"
word_assemblage Preform__Nonparsing__shorten_wa_with_contractions(word_assemblage wa) {
vocabulary_entry **words;
int word_count;
WordAssemblages__as_array(&wa, &words, &word_count);
int i;
for (i=0; i<word_count-1; i++) {
char *p = Vocabulary__get_exemplar(words[i], TRUE);
char *q = Vocabulary__get_exemplar(words[i+1], TRUE);
int j = Platform__strlen(p)-2;
if ((j >= 0) && (p[j] == '-') && (p[j+1] == '\'')) {
TEMPORARY_STREAM;
int contract_this = FALSE;
{
#line 894 "inform7/Chapter 7/Non-Parsing Preform.w"
int incipit = ((unsigned char) q[0]);
int first = tolower(HTML__without_accent(incipit));
if ((first == 'a') || (first == 'e') || (first == 'i') ||
(first == 'o') || (first == 'u') || (first == 'y'))
contract_this = TRUE;
}
#line 866 "inform7/Chapter 7/Non-Parsing Preform.w"
;
if (contract_this) {
int k;
for (k=0; k<j-1; k++) { WRITE_TO(TEMP, "%c", p[k]); }
WRITE_TO(TEMP, "'%s", q);
wording W = Feeds__feed_text(STREAM_TEXT(TEMP));
words[i] = Lexer__word(Wordings__first_wn(W));
for (k=i+1; k<word_count; k++) words[k] = words[k+1];
word_count--;
WordAssemblages__truncate_to(&wa, word_count);
} else {
int k;
for (k=0; k<j; k++) { WRITE_TO(TEMP, "%c", p[k]); }
wording W = Feeds__feed_text(STREAM_TEXT(TEMP));
words[i] = Lexer__word(Wordings__first_wn(W));
}
CLOSE_TEMPORARY_STREAM;
}
}
return wa;
}
#line 904 "inform7/Chapter 7/Non-Parsing Preform.w"
int Preform__Nonparsing__ptoken_to_verb_form_number(ptoken *pt) {
if ((pt) && (pt->ptoken_category == FIXED_WORD_PTC))
return Preform__Nonparsing__ve_to_verb_form_number(pt->ve_pt);
return -1;
}
int Preform__Nonparsing__ve_to_verb_form_number(vocabulary_entry *ve) {
if (Vocabulary__test_vflags(ve, NUMBER_MC)) {
int X = Vocabulary__get_literal_number_value(ve);
if ((X >= 0) && (X < MAX_FORM_TYPES)) return X;
}
return -1;
}
#line 922 "inform7/Chapter 7/Non-Parsing Preform.w"
int Preform__Nonparsing__ptoken_to_tense_indicator(ptoken *pt, int *set_sense) {
if ((pt) && (pt->ptoken_category == FIXED_WORD_PTC)) {
vocabulary_entry *ve = pt->ve_pt;
char *p = Vocabulary__get_exemplar(ve, FALSE);
if ((p[0] == 't') && (isdigit(p[1])) && (p[2] == 0)) {
int N = p[1] - '1' + 1;
if ((N >= 1) && (N <= NO_KNOWN_TENSES)) return N;
}
if ((p[0] == 't') && (isdigit(p[1])) && (p[2] == '+') && (p[3] == 0)) {
int N = p[1] - '1' + 1;
if ((N >= 1) && (N <= NO_KNOWN_TENSES)) {
*set_sense = 0; return N;
}
}
if ((p[0] == 't') && (isdigit(p[1])) && (p[2] == '-') && (p[3] == 0)) {
int N = p[1] - '1' + 1;
if ((N >= 1) && (N <= NO_KNOWN_TENSES)) {
*set_sense = 1; return N;
}
}
}
return -1;
}
#line 949 "inform7/Chapter 7/Non-Parsing Preform.w"
int Preform__Nonparsing__ptoken_as_bracket(ptoken *pt) {
if ((pt) && (pt->ptoken_category == FIXED_WORD_PTC)) {
vocabulary_entry *ve = pt->ve_pt;
if (ve == OPENBRACKET_V) return 1;
if (ve == CLOSEBRACKET_V) return -1;
}
return 0;
}
#line 962 "inform7/Chapter 7/Non-Parsing Preform.w"
int Preform__Nonparsing__compare_ve_with_tails(vocabulary_entry *ve, vocabulary_entry *pattern) {
if (ve == pattern) return TRUE;
char *p = Vocabulary__get_exemplar(pattern, FALSE);
if (p[0] == '-') {
char *q = Vocabulary__get_exemplar(ve, FALSE);
int i, j = Platform__strlen(q)-(Platform__strlen(p)-1);
for (i=1; p[i]; i++, j++)
if ((j<0) || (p[i] != q[j]))
return FALSE;
return TRUE;
}
return FALSE;
}
#line 983 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__trie_definition_error(nonterminal *nt, production *pr, char *message) {
Preform__Nonparsing__general_npp_error(WordAssemblages__lit_0(), nt, pr, message);
}
#line 990 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__conjugation_error(word_assemblage base_text, nonterminal *nt,
production *pr, char *message) {
Preform__Nonparsing__general_npp_error(base_text, nt, pr, message);
exit(1);
}
#line 999 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__general_npp_error(word_assemblage base_text, nonterminal *nt,
production *pr, char *message) {
if (pr) {
LOG("The production at fault is:\n");
Preform__log_production(pr, FALSE); LOG("\n");
}
if (nt == NULL)
Problems__quote_text(1, "(no nonterminal)");
else
Problems__quote_text(1, Vocabulary__get_exemplar(nt->nonterminal_id, FALSE));
Problems__quote_text(2, message);
Problems__Issue__handmade_problem(_p_(Untestable));
if (WordAssemblages__nonempty(base_text)) {
Problems__quote_wa(5, &base_text);
Problems__issue_problem_segment(
"I'm having difficulties conjugating the verb '%5'. ");
}
TEMPORARY_STREAM;
if (pr) {
Problems__quote_number(3, &(pr->match_number));
ptoken *pt;
for (pt = pr->first_ptoken; pt; pt = pt->next_ptoken) {
Preform__write_ptoken(TEMP, pt);
if (pt->next_ptoken) WRITE_TO(TEMP, " ");
}
Problems__quote_text(4, STREAM_TEXT(TEMP));
Problems__issue_problem_segment(
"There's a problem in Inform's linguistic grammar, which is probably "
"set by a translation extension. The problem occurs in line %3 of "
"%1 ('%4'): %2.");
} else {
Problems__issue_problem_segment(
"There's a problem in Inform's linguistic grammar, which is probably "
"set by a translation extension. The problem occurs in the definition of "
"%1: %2.");
}
Problems__issue_problem_end();
CLOSE_TEMPORARY_STREAM;
}
#line 1047 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__test_conjugation(OUTPUT_STREAM, wording W) {
verb_conjugation *vc = Preform__Nonparsing__conjugate_verb(
WordAssemblages__from_wording(W), NULL, 0, language_of_play);
if (vc == NULL) { WRITE("Failed test\n"); return; }
Preform__Nonparsing__write_conjugation(OUT, vc);
DESTROY(vc, verb_conjugation);
}
void Preform__Nonparsing__write_conjugation(OUTPUT_STREAM, verb_conjugation *vc) {
WRITE("Infinitive: ");
WordAssemblages__copy_to_stream(OUT, &(vc->infinitive));
WRITE(" / Present participle: ");
WordAssemblages__copy_to_stream(OUT, &(vc->present_participle));
WRITE(" / Past participle: ");
WordAssemblages__copy_to_stream(OUT, &(vc->past_participle));
WRITE("^");
int mood_count = 2;
if (WordAssemblages__nonempty(vc->passive_tabulation.to_be_auxiliary)) mood_count = 1;
int mood, sense, tense, person;
for (mood=0; mood<mood_count; mood++) {
for (sense=0; sense<2; sense++) {
if (mood == 0) WRITE("Active "); else WRITE("Passive ");
if (sense == 0) WRITE("positive^"); else WRITE("negative^");
for (tense=0; tense<7; tense++) {
WRITE("Tense %d: ", tense);
for (person=0; person<6; person++) {
word_assemblage *wa;
if (mood == 0) wa = &(vc->active_tabulation.vc_text[tense][sense][person]);
else wa = &(vc->passive_tabulation.vc_text[tense][sense][person]);
if (person > 0) WRITE(" / ");
if (WordAssemblages__nonempty(*wa)) {
WordAssemblages__copy_to_stream(OUT, wa);
} else {
WRITE("--");
}
}
WRITE("^");
}
}
}
if (WordAssemblages__nonempty(vc->passive_tabulation.to_be_auxiliary)) {
WRITE("Form passive as to be + ");
WordAssemblages__copy_to_stream(OUT, &(vc->passive_tabulation.to_be_auxiliary));
WRITE("\n");
}
}
#line 1098 "inform7/Chapter 7/Non-Parsing Preform.w"
void Preform__Nonparsing__test_participle(OUTPUT_STREAM, wording W) {
verb_conjugation *vc = Preform__Nonparsing__conjugate_verb(
WordAssemblages__from_wording(W), NULL, 0, English_language);
if (vc == NULL) { WRITE("Failed test\n"); return; }
Preform__Nonparsing__write_participle(OUT, vc);
DESTROY(vc, verb_conjugation);
}
void Preform__Nonparsing__write_participle(OUTPUT_STREAM, verb_conjugation *vc) {
WRITE("To ");
WordAssemblages__copy_to_stream(OUT, &(vc->infinitive));
WRITE(": he is ");
WordAssemblages__copy_to_stream(OUT, &(vc->present_participle));
WRITE(".\n");
}
#line 74 "inform7/Chapter 7/English Inflections.w"
int singular_noun_to_its_indefinite_article_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 78 "inform7/Chapter 7/English Inflections.w"
#line 82 "inform7/Chapter 7/English Inflections.w"
int en_trie_indef_a_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 89 "inform7/Chapter 7/English Inflections.w"
#line 93 "inform7/Chapter 7/English Inflections.w"
int en_trie_indef_b_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 157 "inform7/Chapter 7/English Inflections.w"
#line 161 "inform7/Chapter 7/English Inflections.w"
int en_trie_indef_c_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 215 "inform7/Chapter 7/English Inflections.w"
#line 248 "inform7/Chapter 7/English Inflections.w"
int singular_noun_to_its_plural_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 257 "inform7/Chapter 7/English Inflections.w"
#line 262 "inform7/Chapter 7/English Inflections.w"
int en_trie_plural_uninflected_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 313 "inform7/Chapter 7/English Inflections.w"
#line 317 "inform7/Chapter 7/English Inflections.w"
int en_trie_plural_pronouns_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 340 "inform7/Chapter 7/English Inflections.w"
#line 345 "inform7/Chapter 7/English Inflections.w"
int en_trie_plural_irregular_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 359 "inform7/Chapter 7/English Inflections.w"
#line 365 "inform7/Chapter 7/English Inflections.w"
int en_trie_plural_irregular_inflections_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 377 "inform7/Chapter 7/English Inflections.w"
#line 382 "inform7/Chapter 7/English Inflections.w"
int en_trie_plural_assimilated_classical_inflections_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 407 "inform7/Chapter 7/English Inflections.w"
#line 413 "inform7/Chapter 7/English Inflections.w"
int en_trie_plural_irregular_o_suffixes_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 446 "inform7/Chapter 7/English Inflections.w"
#line 451 "inform7/Chapter 7/English Inflections.w"
int en_trie_plural_regular_inflections_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 530 "inform7/Chapter 7/English Inflections.w"
#line 535 "inform7/Chapter 7/English Inflections.w"
int en_trie_plural_append_s_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 537 "inform7/Chapter 7/English Inflections.w"
#line 655 "inform7/Chapter 7/English Inflections.w"
int verb_conjugation_instructions_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 681 "inform7/Chapter 7/English Inflections.w"
#line 724 "inform7/Chapter 7/English Inflections.w"
int to_have_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 730 "inform7/Chapter 7/English Inflections.w"
#line 814 "inform7/Chapter 7/English Inflections.w"
int to_have_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 819 "inform7/Chapter 7/English Inflections.w"
#line 825 "inform7/Chapter 7/English Inflections.w"
int to_have_present_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 827 "inform7/Chapter 7/English Inflections.w"
#line 862 "inform7/Chapter 7/English Inflections.w"
int to_do_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 866 "inform7/Chapter 7/English Inflections.w"
int to_do_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 877 "inform7/Chapter 7/English Inflections.w"
int to_do_present_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 880 "inform7/Chapter 7/English Inflections.w"
#line 901 "inform7/Chapter 7/English Inflections.w"
int regular_verb_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 907 "inform7/Chapter 7/English Inflections.w"
#line 919 "inform7/Chapter 7/English Inflections.w"
int regular_verb_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 929 "inform7/Chapter 7/English Inflections.w"
#line 937 "inform7/Chapter 7/English Inflections.w"
int regular_verb_present_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 939 "inform7/Chapter 7/English Inflections.w"
#line 943 "inform7/Chapter 7/English Inflections.w"
int to_be_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 947 "inform7/Chapter 7/English Inflections.w"
int to_be_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 957 "inform7/Chapter 7/English Inflections.w"
int to_be_present_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 960 "inform7/Chapter 7/English Inflections.w"
int to_be_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 963 "inform7/Chapter 7/English Inflections.w"
#line 983 "inform7/Chapter 7/English Inflections.w"
int to_be_able_to_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 987 "inform7/Chapter 7/English Inflections.w"
int to_be_able_to_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 997 "inform7/Chapter 7/English Inflections.w"
#line 1024 "inform7/Chapter 7/English Inflections.w"
int to_be_able_to_auxiliary_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1028 "inform7/Chapter 7/English Inflections.w"
int to_be_able_to_auxiliary_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1032 "inform7/Chapter 7/English Inflections.w"
#line 1039 "inform7/Chapter 7/English Inflections.w"
int modal_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1043 "inform7/Chapter 7/English Inflections.w"
int modal_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1055 "inform7/Chapter 7/English Inflections.w"
#line 1083 "inform7/Chapter 7/English Inflections.w"
int contracted_to_be_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1088 "inform7/Chapter 7/English Inflections.w"
int contracted_to_be_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1100 "inform7/Chapter 7/English Inflections.w"
int contracted_to_be_present_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1103 "inform7/Chapter 7/English Inflections.w"
int contracted_to_be_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1106 "inform7/Chapter 7/English Inflections.w"
int contracted_to_be_past_negated_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1109 "inform7/Chapter 7/English Inflections.w"
#line 1123 "inform7/Chapter 7/English Inflections.w"
int contracted_to_have_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1128 "inform7/Chapter 7/English Inflections.w"
int contracted_to_have_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1140 "inform7/Chapter 7/English Inflections.w"
int contracted_to_have_present_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1143 "inform7/Chapter 7/English Inflections.w"
#line 1157 "inform7/Chapter 7/English Inflections.w"
int arent_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1162 "inform7/Chapter 7/English Inflections.w"
int arent_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1169 "inform7/Chapter 7/English Inflections.w"
int arent_present_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1172 "inform7/Chapter 7/English Inflections.w"
int arent_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1175 "inform7/Chapter 7/English Inflections.w"
int arent_perfect_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1178 "inform7/Chapter 7/English Inflections.w"
#line 1188 "inform7/Chapter 7/English Inflections.w"
int informal_negated_modal_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1196 "inform7/Chapter 7/English Inflections.w"
int informal_negated_modal_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1203 "inform7/Chapter 7/English Inflections.w"
int informal_negated_modal_present_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1206 "inform7/Chapter 7/English Inflections.w"
#line 1210 "inform7/Chapter 7/English Inflections.w"
int cant_modal_conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1215 "inform7/Chapter 7/English Inflections.w"
int cant_modal_tabulation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1222 "inform7/Chapter 7/English Inflections.w"
#line 1232 "inform7/Chapter 7/English Inflections.w"
int en_trie_modal_contracted_present_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1243 "inform7/Chapter 7/English Inflections.w"
int en_trie_modal_contracted_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1255 "inform7/Chapter 7/English Inflections.w"
int en_trie_modal_contracted_future_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1267 "inform7/Chapter 7/English Inflections.w"
#line 1316 "inform7/Chapter 7/English Inflections.w"
int en_trie_present_participle_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1322 "inform7/Chapter 7/English Inflections.w"
#line 1330 "inform7/Chapter 7/English Inflections.w"
int en_trie_irregular_present_participle_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1516 "inform7/Chapter 7/English Inflections.w"
#line 1520 "inform7/Chapter 7/English Inflections.w"
int en_trie_irregular_compound_present_participle_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1535 "inform7/Chapter 7/English Inflections.w"
#line 1539 "inform7/Chapter 7/English Inflections.w"
int en_trie_regular_a_present_participle_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1585 "inform7/Chapter 7/English Inflections.w"
#line 1589 "inform7/Chapter 7/English Inflections.w"
int en_trie_regular_b_present_participle_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1593 "inform7/Chapter 7/English Inflections.w"
int en_trie_regular_c_present_participle_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1597 "inform7/Chapter 7/English Inflections.w"
#line 1606 "inform7/Chapter 7/English Inflections.w"
int en_trie_past_participle_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1609 "inform7/Chapter 7/English Inflections.w"
int en_trie_irregular_past_participle_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1762 "inform7/Chapter 7/English Inflections.w"
#line 1770 "inform7/Chapter 7/English Inflections.w"
int en_trie_present_verb_form_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1773 "inform7/Chapter 7/English Inflections.w"
int en_trie_irregular_third_person_present_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1778 "inform7/Chapter 7/English Inflections.w"
#line 1786 "inform7/Chapter 7/English Inflections.w"
int en_trie_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1792 "inform7/Chapter 7/English Inflections.w"
int en_trie_irregular_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2336 "inform7/Chapter 7/English Inflections.w"
int en_trie_irregular_compound_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2352 "inform7/Chapter 7/English Inflections.w"
int en_trie_regular_a_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2399 "inform7/Chapter 7/English Inflections.w"
int en_trie_regular_b_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2404 "inform7/Chapter 7/English Inflections.w"
int en_trie_regular_c_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2409 "inform7/Chapter 7/English Inflections.w"
#line 2432 "inform7/Chapter 7/English Inflections.w"
int pasturise_participle_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2436 "inform7/Chapter 7/English Inflections.w"
int en_trie_pasturise_exceptions_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2901 "inform7/Chapter 7/English Inflections.w"
int en_trie_pasturise_regular_y_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2907 "inform7/Chapter 7/English Inflections.w"
int en_trie_pasturise_regular_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2910 "inform7/Chapter 7/English Inflections.w"
#line 2916 "inform7/Chapter 7/English Inflections.w"
int adjective_to_plural_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2918 "inform7/Chapter 7/English Inflections.w"
int adjective_to_masculine_singular_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2921 "inform7/Chapter 7/English Inflections.w"
int adjective_to_feminine_singular_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2924 "inform7/Chapter 7/English Inflections.w"
int adjective_to_masculine_plural_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2927 "inform7/Chapter 7/English Inflections.w"
int adjective_to_feminine_plural_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 2930 "inform7/Chapter 7/English Inflections.w"
#line 13 "inform7/Chapter 8/Articles and Pronouns.w"
int pronoun_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 16 "inform7/Chapter 8/Articles and Pronouns.w"
int nominative_pronoun_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1 /* singular */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2 /* plural */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 20 "inform7/Chapter 8/Articles and Pronouns.w"
int accusative_pronoun_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1 /* singular */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2 /* plural */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 24 "inform7/Chapter 8/Articles and Pronouns.w"
#line 33 "inform7/Chapter 8/Articles and Pronouns.w"
int possessive_first_person_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1 /* singular */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2 /* plural */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 36 "inform7/Chapter 8/Articles and Pronouns.w"
int possessive_second_person_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1 /* singular */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2 /* plural */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 40 "inform7/Chapter 8/Articles and Pronouns.w"
int possessive_third_person_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1 /* singular */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2 /* plural */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 44 "inform7/Chapter 8/Articles and Pronouns.w"
#line 52 "inform7/Chapter 8/Articles and Pronouns.w"
int relative_clause_marker_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 54 "inform7/Chapter 8/Articles and Pronouns.w"
#line 58 "inform7/Chapter 8/Articles and Pronouns.w"
int article_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 61 "inform7/Chapter 8/Articles and Pronouns.w"
#line 73 "inform7/Chapter 8/Articles and Pronouns.w"
int definite_article_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 75 "inform7/Chapter 8/Articles and Pronouns.w"
int indefinite_article_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 79 "inform7/Chapter 8/Articles and Pronouns.w"
#line 83 "inform7/Chapter 8/Articles and Pronouns.w"
int optional_definite_article_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 86 "inform7/Chapter 8/Articles and Pronouns.w"
int optional_article_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 90 "inform7/Chapter 8/Articles and Pronouns.w"
int compulsory_article_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 93 "inform7/Chapter 8/Articles and Pronouns.w"
#line 97 "inform7/Chapter 8/Articles and Pronouns.w"
wording Articles__remove_the(wording W) {
if ((Wordings__length(W) > 1) &&
(Preform__parse_nt_against_word_range(optional_definite_article_NTM, W, NULL, NULL))) return GET_RW(optional_definite_article_NTM, 1);
return W;
}
wording Articles__remove_article(wording W) {
if (Wordings__nonempty(W)) {
Preform__parse_nt_against_word_range(optional_article_NTM, W, NULL, NULL);
return GET_RW(optional_article_NTM, 1);
}
return W;
}
#line 118 "inform7/Chapter 8/Articles and Pronouns.w"
int non_participles_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 120 "inform7/Chapter 8/Articles and Pronouns.w"
int probable_participle_NTMR(wording W, int *X, void **XP) {
#line 122 "inform7/Chapter 8/Articles and Pronouns.w"
if (Vocabulary__test_flags(Wordings__first_wn(W), ING_MC)) {
if (Preform__parse_nt_against_word_range(non_participles_NTM, W, NULL, NULL)) return FALSE;
return TRUE;
}
return FALSE;
}
#line 132 "inform7/Chapter 8/Articles and Pronouns.w"
int negated_clause_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 134 "inform7/Chapter 8/Articles and Pronouns.w"
#line 111 "inform7/Chapter 8/Determiners and Quantifiers.w"
quantifier *Quantifiers__quant_new(char *op, int T, int is_comp, char *text) {
quantifier *quant = CREATE(quantifier);
quant->operator = op;
quant->T_coefficient = T; quant->is_complementary = is_comp;
quant->can_be_used_in_now = FALSE;
quant->can_be_used_in_assertions = FALSE;
quant->negated_quant = NULL;
quant->log_text = text;
return quant;
}
#line 162 "inform7/Chapter 8/Determiners and Quantifiers.w"
void Quantifiers__quants_negate_each_other(quantifier *qx, quantifier *qy) {
qx->negated_quant = qy; qy->negated_quant = qx;
}
quantifier *Quantifiers__get_negation(quantifier *quant) {
return quant->negated_quant;
}
#line 172 "inform7/Chapter 8/Determiners and Quantifiers.w"
void Quantifiers__log(quantifier *quant, int parameter) {
if (quant == NULL) { LOG("<NULL-QUANTIFIER>"); return; }
LOG(quant->log_text, parameter);
}
#line 204 "inform7/Chapter 8/Determiners and Quantifiers.w"
void Quantifiers__compile_test(OUTPUT_STREAM, quantifier *quant, int index,
int quantification_parameter) {
int TC = quant->T_coefficient;
switch (TC) {
case -1:
if (quant->is_complementary)
WRITE("qcy_%d %s qcn_%d-%d",
index, quant->operator, index, quantification_parameter);
else
WRITE("qcy_%d %s %d",
index, quant->operator, quantification_parameter);
break;
case 10:
WRITE("qcy_%d %s qcn_%d", index, quant->operator, index);
break;
case 0:
WRITE("qcy_%d %s 0", index, quant->operator);
break;
default:
if (strcmp(quant->operator, "==") != 0)
WRITE("qcy_%d*10 %s %d*qcn_%d", index, quant->operator, TC, index);
else
WRITE("qcy_%d %s %d*qcn_%d/10", index, quant->operator, TC, index);
break;
}
}
#line 240 "inform7/Chapter 8/Determiners and Quantifiers.w"
int Quantifiers__is_now_assertable(quantifier *quant) {
return quant->can_be_used_in_now;
}
#line 250 "inform7/Chapter 8/Determiners and Quantifiers.w"
int Quantifiers__can_be_used_in_assertions(quantifier *quant) {
return quant->can_be_used_in_assertions;
}
#line 281 "inform7/Chapter 8/Determiners and Quantifiers.w"
determiner *Quantifiers__det_new(int not, int pr, int num, quantifier *quant, char *text) {
word_assemblage wa;
if (pr < 0) wa = WordAssemblages__lit_0();
else wa = Preform__Nonparsing__wording(determiner_names_NTM, pr);
determiner *det = CREATE(determiner);
det->text_of_det = wa;
det->takes_number = num;
det->allows_prefixed_not = not;
det->quantifier_meant = quant;
if (quant == NULL) internal_error("created meaningless quantifier");
det->index_text = text;
if (text)
Index__Lexicon__new_entry_with_details(
EMPTY_WORDING, MISCELLANEOUS_LEXE, wa, "determiner", text);
return det;
}
#line 305 "inform7/Chapter 8/Determiners and Quantifiers.w"
int determiner_names_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 327 "inform7/Chapter 8/Determiners and Quantifiers.w"
#line 339 "inform7/Chapter 8/Determiners and Quantifiers.w"
int Quantifiers__parse_against_text(wording W, int *which_P, quantifier **which_quant) {
if (Preform__parse_nt_against_word_range(excluded_from_determiners_NTM, W, NULL, NULL)) return -1;
int not_flag = Preform__parse_nt_against_word_range(negated_clause_NTM, W, NULL, NULL);
if (not_flag) W = GET_RW(negated_clause_NTM, 1);
*which_P = -1; *which_quant = NULL;
determiner *det;
LOOP_BACKWARDS_OVER(det, determiner) {
if ((not_flag) && (det->allows_prefixed_not == FALSE)) continue;
wording XW = Quantifiers__det_parse_against_text(W, det, which_P);
if (Wordings__nonempty(XW)) {
if (not_flag) *which_quant = det->quantifier_meant->negated_quant;
else *which_quant = det->quantifier_meant;
return Wordings__first_wn(XW);
}
}
return -1;
}
#line 373 "inform7/Chapter 8/Determiners and Quantifiers.w"
int determination_of_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE; return FAIL_NONTERMINAL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 377 "inform7/Chapter 8/Determiners and Quantifiers.w"
#line 391 "inform7/Chapter 8/Determiners and Quantifiers.w"
int excluded_from_determiners_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 393 "inform7/Chapter 8/Determiners and Quantifiers.w"
#line 401 "inform7/Chapter 8/Determiners and Quantifiers.w"
wording Quantifiers__det_parse_against_text(wording W, determiner *det, int *which_P) {
int parameter = -1;
if (Wordings__empty(W)) return W;
int x = WordAssemblages__parse_as_weakly_initial_text(W, &(det->text_of_det),
EMPTY_WORDING, TRUE, FALSE);
W = Wordings__from(W, x);
if (Wordings__empty(W)) return W;
if (det->takes_number) {
if ((Preform__parse_nt_against_word_range(cardinal_number_NTM, Wordings__one_word(x), NULL, NULL) == FALSE) ||
(Text__unexpectedly_upper_case(x))) return EMPTY_WORDING;
W = Wordings__trim_first_word(W);
if (Wordings__empty(W)) return W;
parameter = most_recent_result;
}
if (Preform__parse_nt_against_word_range(determination_of_NTM, W, NULL, NULL)) {
W = GET_RW(determination_of_NTM, 1);
*which_P = parameter;
W = Articles__remove_the(W);
} else W = EMPTY_WORDING;
return W;
}
#line 429 "inform7/Chapter 8/Determiners and Quantifiers.w"
void Quantifiers__make_built_in(void) {
{
#line 470 "inform7/Chapter 8/Determiners and Quantifiers.w"
for_all_quantifier = Quantifiers__quant_new("==", 10, FALSE, "ForAll");
not_for_all_quantifier = Quantifiers__quant_new("<", 10, FALSE, "NotAll");
exists_quantifier = Quantifiers__quant_new(">", 0, FALSE, "Exists");
not_exists_quantifier = Quantifiers__quant_new("==", 0, FALSE, "DoesNotExist");
for_all_quantifier->can_be_used_in_now = TRUE;
for_all_quantifier->can_be_used_in_assertions = TRUE;
not_exists_quantifier->can_be_used_in_now = TRUE;
Quantifiers__quants_negate_each_other(for_all_quantifier, not_for_all_quantifier);
Quantifiers__quants_negate_each_other(exists_quantifier, not_exists_quantifier);
Quantifiers__det_new(TRUE, ALL_DET_NAME, FALSE, for_all_quantifier,
"used in conditions: 'if all of the doors are open'");
Quantifiers__det_new(FALSE, EACH_DET_NAME, FALSE, for_all_quantifier,
"- see </i>all<i>");
Quantifiers__det_new(TRUE, EVERY_DET_NAME, FALSE, for_all_quantifier,
"- see </i>all<i>, and can also be used in generalisations such as "
"'A nose is part of every person.'");
Quantifiers__det_new(FALSE, NO_DET_NAME, FALSE, not_exists_quantifier,
"opposite of 'all': 'if no door is open...'");
Quantifiers__det_new(FALSE, NONE_DET_NAME, FALSE, not_exists_quantifier,
"opposite of 'all of': 'if none of the doors is open...'");
Quantifiers__det_new(FALSE, SOME_DET_NAME, FALSE, exists_quantifier, NULL);
Quantifiers__det_new(FALSE, ANY_DET_NAME, FALSE, exists_quantifier, NULL);
}
#line 430 "inform7/Chapter 8/Determiners and Quantifiers.w"
;
{
#line 506 "inform7/Chapter 8/Determiners and Quantifiers.w"
all_but_quantifier = Quantifiers__quant_new("==", -1, TRUE, "AllBut%d");
not_all_but_quantifier = Quantifiers__quant_new("~=", -1, TRUE, "NotAllBut%d");
Quantifiers__quants_negate_each_other(all_but_quantifier, not_all_but_quantifier);
Quantifiers__det_new(FALSE, ALL_BUT_DET_NAME, TRUE, all_but_quantifier,
"used to count things: 'all but three containers'");
Quantifiers__det_new(FALSE, ALL_EXCEPT_DET_NAME, TRUE, all_but_quantifier,
"- see </i>all but<i>");
}
#line 431 "inform7/Chapter 8/Determiners and Quantifiers.w"
;
{
#line 522 "inform7/Chapter 8/Determiners and Quantifiers.w"
almost_all_quantifier = Quantifiers__quant_new(">=", 8, FALSE, "Proportion>=80%%");
almost_no_quantifier = Quantifiers__quant_new("<", 2, FALSE, "Proportion<20%%");
most_quantifier = Quantifiers__quant_new(">", 5, FALSE, "Proportion>50%%");
under_half_quantifier = Quantifiers__quant_new("<=", 5, FALSE, "Proportion<=50%%");
Quantifiers__quants_negate_each_other(almost_all_quantifier, almost_no_quantifier);
Quantifiers__quants_negate_each_other(most_quantifier, under_half_quantifier);
Quantifiers__det_new(FALSE, ALMOST_ALL_DET_NAME, FALSE, almost_all_quantifier,
"used in conditions: true if 80 percent or more possibilities work");
Quantifiers__det_new(FALSE, ALMOST_NO_DET_NAME, FALSE, almost_no_quantifier,
"used in conditions: true if fewer than 20 percent of possibilities work");
Quantifiers__det_new(FALSE, MOST_DET_NAME, FALSE, most_quantifier,
"used in conditions: true if a simple majority of possibilities work");
Quantifiers__det_new(FALSE, UNDER_HALF_DET_NAME, FALSE, under_half_quantifier,
"used in conditions: true if fewer than half of possibilities work");
}
#line 432 "inform7/Chapter 8/Determiners and Quantifiers.w"
;
{
#line 560 "inform7/Chapter 8/Determiners and Quantifiers.w"
at_least_quantifier = Quantifiers__quant_new(">=", -1, FALSE, "Card>=%d");
at_most_quantifier = Quantifiers__quant_new("<=", -1, FALSE, "Card<=%d");
exactly_quantifier = Quantifiers__quant_new("==", -1, FALSE, "Card=%d");
less_than_quantifier = Quantifiers__quant_new("<", -1, FALSE, "Card<%d");
more_than_quantifier = Quantifiers__quant_new(">", -1, FALSE, "Card>%d");
other_than_quantifier = Quantifiers__quant_new("~=", -1, FALSE, "Card~=%d");
at_least_quantifier->can_be_used_in_assertions = TRUE;
Quantifiers__quants_negate_each_other(at_least_quantifier, less_than_quantifier);
Quantifiers__quants_negate_each_other(at_most_quantifier, more_than_quantifier);
Quantifiers__quants_negate_each_other(exactly_quantifier, other_than_quantifier);
Quantifiers__det_new(FALSE, AT_LEAST_DET_NAME, TRUE, at_least_quantifier,
"used to count things: 'at least five doors'");
Quantifiers__det_new(FALSE, AT_MOST_DET_NAME, TRUE, at_most_quantifier,
"- see </i>at least<i>");
Quantifiers__det_new(FALSE, EXACTLY_DET_NAME, TRUE, exactly_quantifier,
"whereas 'if two doors are open' implicitly means 'if at least two "
"doors are open', 'if exactly two...' makes the count precise");
Quantifiers__det_new(TRUE, FEWER_THAN_DET_NAME, TRUE, less_than_quantifier,
"pedantic way to say </i>less than<i> when counting");
Quantifiers__det_new(TRUE, LESS_THAN_DET_NAME, TRUE, less_than_quantifier,
"- see </i>more than<i>");
Quantifiers__det_new(TRUE, MORE_THAN_DET_NAME, TRUE, more_than_quantifier,
"used to count things: 'more than three rooms'");
Quantifiers__det_new(TRUE, GREATER_THAN_DET_NAME, TRUE, more_than_quantifier,
"used to count things: 'greater than three rooms'");
Quantifiers__det_new(FALSE, OTHER_THAN_DET_NAME, TRUE, other_than_quantifier, NULL);
Quantifiers__det_new(FALSE, -1, TRUE, at_least_quantifier, NULL);
}
#line 433 "inform7/Chapter 8/Determiners and Quantifiers.w"
;
}
#line 595 "inform7/Chapter 8/Determiners and Quantifiers.w"
int Quantifiers__quant_requires_at_least_one_true_case(quantifier *quant, int parameter) {
if (quant == exists_quantifier) return TRUE;
if (((quant == exactly_quantifier) || (quant == at_least_quantifier)) &&
(parameter > 0)) return TRUE;
if ((quant == more_than_quantifier) && (parameter >= 0)) return TRUE;
if ((quant == other_than_quantifier) && (parameter == 0)) return TRUE;
return FALSE;
}
#line 44 "inform7/Chapter 8/Time Periods.w"
time_period TimePeriods__new(void) {
time_period tp;
tp.valid_tp = 0;
tp.length = -1;
tp.until = -1;
tp.units = TIMES_UNIT;
tp.inform6_operator = NULL;
tp.tense = IS_TENSE;
return tp;
}
time_period TimePeriods__new_tense_marker(int t) {
time_period tp = TimePeriods__new();
tp.tense = t;
return tp;
}
time_period *TimePeriods__store(time_period tp) {
time_period *ntp = CREATE(time_period);
*ntp = tp;
return ntp;
}
void TimePeriods__log_tense_number(int t) {
switch (t) {
case IS_TENSE: LOG("IS_TENSE"); break;
case WAS_TENSE: LOG("WAS_TENSE"); break;
case HASBEEN_TENSE: LOG("HASBEEN_TENSE"); break;
case HADBEEN_TENSE: LOG("HADBEEN_TENSE"); break;
default: LOG("<invalid-tense>"); break;
}
}
void TimePeriods__log(time_period *tp) {
if (tp->valid_tp == FALSE) { LOG("---"); return; }
LOG("<");
if (tp->inform6_operator) LOG("%s", tp->inform6_operator);
if (tp->until >= 0) LOG("%d", tp->until); else LOG("%d", tp->length);
switch(tp->units) {
case TURNS_UNIT: LOG(" turns"); break;
case TIMES_UNIT: LOG(" times"); break;
default: LOG(": <invalid-units>"); break;
}
if (tp->tense != IS_TENSE) {
LOG(": "); TimePeriods__log_tense_number(tp->tense);
}
LOG(">");
}
int TimePeriods__is_valid(time_period *tp) {
return tp->valid_tp;
}
void TimePeriods__make_invalid(time_period *tp) {
tp->valid_tp = FALSE;
}
int TimePeriods__get_tense(time_period *tp) {
return tp->tense;
}
void TimePeriods__set_tense(time_period *tp, int t) {
tp->tense = t;
}
int TimePeriods__duration_count(time_period *tp) {
int L = tp->length;
if (L < 0) L = 0;
if (tp->until >= 0) {
return tp->until - L + 1;
} else {
if (tp->inform6_operator == NULL) return 1;
if (strcmp(tp->inform6_operator, "==") == 0) return 1;
if (strcmp(tp->inform6_operator, "<=") == 0) return L;
if (strcmp(tp->inform6_operator, "<") == 0) return L - 1;
if (strcmp(tp->inform6_operator, ">=") == 0) return 1000000 - L;
if (strcmp(tp->inform6_operator, ">") == 0) return 1000000 - (L - 1);
}
return 0;
}
int TimePeriods__compare_specificity(time_period *tp1, time_period *tp2) {
if ((tp1) && (tp1->valid_tp == FALSE)) tp1 = NULL;
if ((tp2) && (tp2->valid_tp == FALSE)) tp2 = NULL;
if ((tp1 == NULL) && (tp2 == NULL)) return 0;
if ((tp1) && (tp2 == NULL)) return 1;
if ((tp2) && (tp1 == NULL)) return -1;
int dc1 = TimePeriods__duration_count(tp1);
int dc2 = TimePeriods__duration_count(tp2);
if (dc1 > dc2) return -1;
if (dc1 < dc2) return 1;
return 0;
}
#line 162 "inform7/Chapter 8/Time Periods.w"
int historical_reference_possible_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 164 "inform7/Chapter 8/Time Periods.w"
#line 168 "inform7/Chapter 8/Time Periods.w"
int historical_reference_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 171 "inform7/Chapter 8/Time Periods.w"
int repetition_specification_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = EQ_REPM;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = LE_REPM;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = LT_REPM;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = GE_REPM;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = GT_REPM;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = LT_REPM;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = GT_REPM;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = NO_REPM;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 181 "inform7/Chapter 8/Time Periods.w"
int repetitions_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; from_NTMV = R[1]; unit_NTMV = TIMES_UNIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; from_NTMV = R[1]; unit_NTMV = TURNS_UNIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 185 "inform7/Chapter 8/Time Periods.w"
int iteration_repetitions_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 3;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = R[1]; to_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 192 "inform7/Chapter 8/Time Periods.w"
int turn_repetitions_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; to_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 196 "inform7/Chapter 8/Time Periods.w"
int rep_number_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 201 "inform7/Chapter 8/Time Periods.w"
#line 205 "inform7/Chapter 8/Time Periods.w"
time_period TimePeriods__parse(wording W) {
time_period tp = TimePeriods__new();
if (Preform__parse_nt_against_word_range(historical_reference_possible_NTM, W, NULL, NULL)) {
LOOP_THROUGH_WORDING(k, W) {
to_NTMV = -1;
if (Preform__parse_nt_against_word_range(historical_reference_NTM, Wordings__from(W, k), NULL, NULL)) {
switch (most_recent_result) {
case EQ_REPM: tp.inform6_operator = "=="; break;
case LT_REPM: tp.inform6_operator = "<"; break;
case LE_REPM: tp.inform6_operator = "<="; break;
case GT_REPM: tp.inform6_operator = ">"; break;
case GE_REPM: tp.inform6_operator = ">="; break;
case NO_REPM: tp.inform6_operator = NULL; break;
}
tp.length = from_NTMV;
tp.until = to_NTMV;
tp.units = unit_NTMV;
tp.valid_tp = k-1;
LOGIF(TIME_PERIODS, "Parsed time period: <$w> = $t\n", Wordings__from(W, k), &tp);
break;
}
}
}
return tp;
}
#line 63 "inform7/Chapter 9/Adjectives.w"
int adjective_name_NTMR(wording W, int *X, void **XP) {
#line 64 "inform7/Chapter 9/Adjectives.w"
parse_node *p = SParser__parse_excerpt(ADJECTIVE_MC, W);
if (p) {
*XP = RETRIEVE_POINTER_adjectival_phrase(
Semantics__Nouns__ExcerptMeanings__data(ParseTree__get_meaning(p)));
return TRUE;
}
return FALSE;
}
#line 79 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase *Adjectives__Phrases__parse(wording W) {
if (Preform__parse_nt_against_word_range(adjective_name_NTM, W, NULL, NULL)) return most_recent_result_p;
return NULL;
}
#line 88 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase *Adjectives__Phrases__from_word_range(wording W, natural_language *nl) {
adjectival_phrase *aph = NULL;
if (Wordings__nonempty(W)) aph = Adjectives__Phrases__parse(W);
if (aph) return aph;
aph = CREATE(adjectival_phrase);
aph->adjective_names = Clusters__new();
Clusters__add_with_agreements(aph->adjective_names, W, nl);
aph->possible_meanings = NULL; aph->sorted_meanings = NULL;
if ((nl == NULL) && (Wordings__nonempty(W))) {
if (Preform__parse_nt_against_word_range(article_NTM, W, NULL, NULL)) {
Problems__Issue__sentence_problem(_p_(PM_ArticleAsAdjective),
"a defined adjective cannot consist only of an article such as "
"'a' or 'the'",
"since this will lead to parsing ambiguities.");
} else if (Preform__parse_nt_against_word_range(unsuitable_name_NTM, W, NULL, NULL)) {
if (problem_count == 0) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_AdjectivePunctuated));
Problems__issue_problem_segment(
"The sentence %1 seems to create an adjective with the name "
"'%2', but adjectives have to be contain only unpunctuated "
"words.");
Problems__issue_problem_end();
}
} else {
Semantics__Nouns__ExcerptMeanings__register(ADJECTIVE_MC,
W, STORE_POINTER_adjectival_phrase(aph));
LOOP_THROUGH_WORDING(n, W)
Preform__mark_word(n, s_adjective_NTM);
}
}
LOGIF(VARIABLE_CREATIONS, "Created adjectival phrase: $a\n", aph);
return aph;
}
#line 127 "inform7/Chapter 9/Adjectives.w"
wording Adjectives__Phrases__get_text(adjectival_phrase *aph, int plural) {
return Clusters__get_name(aph->adjective_names, plural);
}
#line 134 "inform7/Chapter 9/Adjectives.w"
sentence_handler NEW_ADJ_SH_handler =
{ SENTENCE_NT, NEW_ADJ_VB, 1, Adjectives__Phrases__declare_meaningless };
#line 140 "inform7/Chapter 9/Adjectives.w"
void Adjectives__Phrases__declare_meaningless(parse_node *p) {
if (!(Preform__parse_nt_against_word_range(adaptive_adjective_NTM, ParseTree__get_text(p->down->next), NULL, NULL)))
Adjectives__Phrases__declare_textually(ParseTree__get_text(p->down->next));
}
adjectival_phrase *Adjectives__Phrases__declare_textually(wording W) {
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
wording C = Clusters__get_name_in_play(aph->adjective_names, FALSE);
if (Wordings__match(C, W)) return aph;
}
return Adjectives__Phrases__from_word_range(W, language_of_play);
}
void Adjectives__Phrases__test_adjective(OUTPUT_STREAM, wording W) {
adjectival_phrase *aph = Adjectives__Phrases__declare_textually(W);
if (aph == NULL) { WRITE("Failed test\n"); return; }
int g, n;
for (g = NEUTER_GENDER; g <= FEMININE_GENDER; g++) {
switch (g) {
case NEUTER_GENDER: WRITE("neuter "); break;
case MASCULINE_GENDER: WRITE("masculine "); break;
case FEMININE_GENDER: WRITE("feminine "); break;
}
for (n = 1; n <= 2; n++) {
if (n == 1) WRITE("singular: "); else WRITE(" / plural: ");
wording C = Clusters__get_name_general(aph->adjective_names,
language_of_play, n, g);
Wordings__to_stream(OUT, C);
}
WRITE("^");
}
}
#line 180 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase *Adjectives__Phrases__declare(adjective_meaning *am,
wording W) {
adjectival_phrase *aph = Adjectives__Phrases__from_word_range(W, NULL);
adjective_meaning *aml = aph->possible_meanings;
if (aml == NULL) aph->possible_meanings = am;
else {
while (aml->next_meaning) aml = aml->next_meaning;
aml->next_meaning = am;
}
am->next_meaning = NULL;
am->owning_adjective = aph;
return aph;
}
#line 199 "inform7/Chapter 9/Adjectives.w"
adjectival_phrase *Adjectives__Phrases__get_aph_from_am(adjective_meaning *am) {
return am->owning_adjective;
}
#line 208 "inform7/Chapter 9/Adjectives.w"
void Adjectives__Phrases__sortrandom_meanings(adjectival_phrase *aph) {
if (aph == NULL) internal_error("tried to sort meanings for null APH");
aph->sorted_meanings = Adjectives__Meanings__list_sort(aph->possible_meanings);
}
#line 216 "inform7/Chapter 9/Adjectives.w"
adjective_meaning *Adjectives__Phrases__get_sorted_definition_list(adjectival_phrase *aph) {
return aph->sorted_meanings;
}
#line 223 "inform7/Chapter 9/Adjectives.w"
adjective_meaning *Adjectives__Phrases__first_meaning(adjectival_phrase *aph) {
return aph->possible_meanings;
}
#line 231 "inform7/Chapter 9/Adjectives.w"
void Adjectives__Phrases__log(adjectival_phrase *aph) {
if (aph == NULL) { LOG("<null adjectival phrase>"); return; }
wording W = Adjectives__Phrases__get_text(aph, FALSE);
if (logging_to_I6_text) LOG("'$w'", W);
else LOG("A%d'$w'", aph->allocation_id, W);
}
#line 241 "inform7/Chapter 9/Adjectives.w"
void Adjectives__Phrases__log_meanings(adjectival_phrase *aph) {
adjective_meaning *am;
int n;
if (aph == NULL) { LOG("<null-APH>\n"); return; }
for (n=1, am = aph->possible_meanings; am; n++, am = am->next_meaning)
LOG("%d: $w (domain:$j) (dk:$u)\n", n, am->adjective_index_text,
am->domain_infs, am->domain_kind);
}
#line 280 "inform7/Chapter 9/Adjectives.w"
int Adjectives__Phrases__applicable_to(adjectival_phrase *aph,
kind *K) {
if (aph) {
adjective_meaning *am;
for (am = aph->possible_meanings; am; am = am->next_meaning) {
if (am->domain_infs == NULL) {
if (am->setting_domain)
{
#line 308 "inform7/Chapter 9/Adjectives.w"
if (problem_count == 0) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, Clusters__get_name(aph->adjective_names, FALSE));
Problems__Issue__handmade_problem(_p_(PM_AdjectiveCircular));
Problems__issue_problem_segment(
"In the sentence %1, it looks as if the definition of the adjective "
"'%2' may be circular.");
Problems__issue_problem_end();
}
return FALSE;
}
#line 286 "inform7/Chapter 9/Adjectives.w"
;
am->setting_domain = TRUE;
Adjectives__Meanings__set_definition_domain(am, TRUE);
am->setting_domain = FALSE;
}
kind *am_kind = Adjectives__Meanings__get_domain(am);
if (Kinds__Compare__le(am_kind, K_object)) {
if (K == NULL) return TRUE;
if (Kinds__Compare__le(K, K_object)) return TRUE;
} else {
if ((K) && (Kinds__Compare__le(K, K_object) == FALSE) &&
(Kinds__Compare__compatible(K, am_kind) == ALWAYS_MATCH))
return TRUE;
}
}
}
return FALSE;
}
#line 324 "inform7/Chapter 9/Adjectives.w"
instance *Adjectives__Phrases__has_ENUMERATIVE_meaning(adjectival_phrase *aph) {
adjective_meaning *am;
for (am = aph->possible_meanings; am; am = am->next_meaning)
if (am->adjective_form == ENUMERATIVE_KADJ)
return RETRIEVE_POINTER_instance(am->detailed_meaning);
return NULL;
}
property *Adjectives__Phrases__has_EORP_meaning(adjectival_phrase *aph, int *sense) {
if (aph)
for (adjective_meaning *am = aph->possible_meanings; am; am = am->next_meaning)
if (am->adjective_form == EORP_KADJ) {
if (sense) *sense = am->meaning_parity;
return RETRIEVE_POINTER_property(am->detailed_meaning);
}
return NULL;
}
#line 372 "inform7/Chapter 9/Adjectives.w"
int Adjectives__Phrases__assert(adjectival_phrase *aph, kind *kind_domain,
inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) {
adjective_meaning *am;
Adjectives__Phrases__sortrandom_meanings(aph);
for (am = aph->sorted_meanings; am; am = am->next_sorted) {
if (Adjectives__Meanings__domain_weak_match(kind_domain,
Adjectives__Meanings__get_domain(am)) == FALSE) continue;
if (Adjectives__Meanings__domain_subj_compare(infs_to_assert_on, am) == FALSE) continue;
if (Adjectives__Meanings__assert(am, infs_to_assert_on, val_to_assert_on, parity)) return TRUE;
}
return FALSE;
}
#line 120 "inform7/Chapter 9/Adjective Meanings.w"
adjective_meaning *Adjectives__Meanings__list_sort(adjective_meaning *unsorted_head) {
adjective_meaning *sorted_head = NULL;
adjective_meaning *am, *am2;
for (am = unsorted_head; am; am = am->next_meaning)
if (am->domain_infs == NULL)
Adjectives__Meanings__set_definition_domain(am, TRUE);
for (am = unsorted_head; am; am = am->next_meaning) {
if (sorted_head == NULL) {
sorted_head = am;
am->next_sorted = NULL;
} else {
adjective_meaning *lastdef = NULL;
for (am2 = sorted_head; am2; am2 = am2->next_sorted) {
if (Adjectives__Meanings__compare(am, am2) == 1) {
if (lastdef == NULL) {
sorted_head = am;
am->next_sorted = am2;
} else {
lastdef->next_sorted = am;
am->next_sorted = am2;
}
break;
}
if (am2->next_sorted == NULL) {
am2->next_sorted = am;
am->next_sorted = NULL;
break;
}
lastdef = am2;
}
}
}
return sorted_head;
}
#line 169 "inform7/Chapter 9/Adjective Meanings.w"
adjective_meaning *Adjectives__Meanings__new(int form, general_pointer details, wording W) {
adjective_meaning *am = CREATE(adjective_meaning);
am->defined_at = current_sentence;
am->adjective_index_text = W;
am->owning_adjective = NULL;
am->next_meaning = NULL;
am->next_sorted = NULL;
am->domain_text = EMPTY_WORDING;
am->domain_infs = NULL; am->domain_kind = NULL; am->setting_domain = FALSE;
am->adjective_form = form;
am->detailed_meaning = details;
am->defined_already = FALSE;
am->problems_thrown = 0;
am->meaning_parity = TRUE;
am->am_ready_flag = FALSE;
for (int i=1; i<=NO_ADJECTIVE_TASKS; i++) {
am->task_via_support_routine[i] = NOT_APPLICABLE;
Calculus__Schemas__modify(&(am->i6s_for_runtime_task[i]), "");
Calculus__Schemas__modify(&(am->i6s_to_transfer_to_SR[i]), "");
}
am->am_negated_from = NULL;
return am;
}
#line 202 "inform7/Chapter 9/Adjective Meanings.w"
adjective_meaning *Adjectives__Meanings__negate(adjective_meaning *am) {
adjective_meaning *neg = CREATE(adjective_meaning);
neg->defined_at = current_sentence;
neg->adjective_index_text = am->adjective_index_text;
neg->owning_adjective = NULL;
neg->next_meaning = NULL;
neg->next_sorted = NULL;
neg->domain_text = am->domain_text;
neg->domain_infs = am->domain_infs; neg->domain_kind = am->domain_kind;
neg->adjective_form = am->adjective_form;
neg->detailed_meaning = am->detailed_meaning;
neg->defined_already = FALSE;
neg->problems_thrown = 0;
neg->am_ready_flag = FALSE;
neg->meaning_parity = (am->meaning_parity)?FALSE:TRUE;
for (int i=1; i<=NO_ADJECTIVE_TASKS; i++) {
int j = i;
if (i == NOW_ADJECTIVE_TRUE_TASK) j = NOW_ADJECTIVE_FALSE_TASK;
if (i == NOW_ADJECTIVE_FALSE_TASK) j = NOW_ADJECTIVE_TRUE_TASK;
neg->task_via_support_routine[j] = am->task_via_support_routine[i];
neg->i6s_for_runtime_task[j] = am->i6s_for_runtime_task[i];
Calculus__Schemas__modify(&(neg->i6s_to_transfer_to_SR[j]), "");
}
neg->am_negated_from = am;
return neg;
}
int Adjectives__Meanings__get_form(adjective_meaning *am) {
if (am == NULL) return -1;
return am->adjective_form;
}
#line 257 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__domain_weak_match(kind *K1, kind *K2) {
if (Kinds__RunTime__weak_id(K1) == Kinds__RunTime__weak_id(K2))
return TRUE;
return FALSE;
}
#line 267 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__domain_subj_compare(inference_subject *infs, adjective_meaning *am) {
instance *I = InferenceSubjects__as_object_instance(infs);
if (I == NULL) return TRUE;
if (am->domain_infs == Kinds__Behaviour__as_subject(K_object)) return TRUE;
while (infs) {
if (am->domain_infs == infs) return TRUE;
infs = InferenceSubjects__narrowest_broader_subject(infs);
}
return FALSE;
}
#line 296 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__set_domain_text(adjective_meaning *am, wording W) {
am->domain_infs = NULL; am->domain_kind = NULL;
am->domain_text = W;
Adjectives__Meanings__set_definition_domain(am, TRUE);
}
void Adjectives__Meanings__set_domain_from_instance(adjective_meaning *am,
instance *I) {
if (I == NULL) {
am->domain_infs = Kinds__Behaviour__as_subject(K_object);
am->domain_kind = K_object;
} else {
am->domain_infs = Instances__as_subject(I);
am->domain_kind = Kinds__weaken(Instances__to_kind(I));
}
am->domain_text = EMPTY_WORDING;
}
#line 319 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__set_domain_from_kind(adjective_meaning *am, kind *K) {
if ((K == NULL) || (Kinds__Compare__le(K, K_object))) K = K_object;
am->domain_infs = Kinds__Behaviour__as_subject(K);
am->domain_kind = K;
am->domain_text = EMPTY_WORDING;
}
#line 329 "inform7/Chapter 9/Adjective Meanings.w"
kind *Adjectives__Meanings__get_domain(adjective_meaning *am) {
if (am->domain_infs == NULL) return NULL;
return am->domain_kind;
}
kind *Adjectives__Meanings__get_domain_forcing(adjective_meaning *am) {
Adjectives__Meanings__set_definition_domain(am, TRUE);
if (am->domain_infs == NULL) return NULL;
return am->domain_kind;
}
#line 346 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__set_definition_domain(adjective_meaning *am, int early) {
if (am->domain_infs) return;
current_sentence = am->defined_at;
if (Wordings__empty(am->domain_text)) internal_error("undeclared domain kind for AM");
parse_node *supplied = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, am->domain_text, NULL, NULL))
supplied = most_recent_result_p;
if (supplied == NULL)
{
#line 373 "inform7/Chapter 9/Adjective Meanings.w"
if ((early) || (am->problems_thrown++ > 0)) return;
current_sentence = am->defined_at;
Problems__Issue__adjective_problem(_p_(PM_AdjDomainUnknown),
am->adjective_index_text, am->domain_text,
"this isn't a thing, a kind of thing or a kind of value",
"and indeed doesn't have any meaning I can make sense of.");
return;
}
#line 353 "inform7/Chapter 9/Adjective Meanings.w"
;
{
#line 407 "inform7/Chapter 9/Adjective Meanings.w"
if ((ParseTree__is(supplied, CONSTANT_VNT)) &&
(Specifications__is_description_like(supplied) == FALSE) &&
(Rvalues__to_instance(supplied) == NULL)) {
if ((early) || (am->problems_thrown++ > 0)) return;
current_sentence = am->defined_at;
Problems__Issue__adjective_problem(_p_(PM_AdjDomainSurreal),
am->adjective_index_text, am->domain_text,
"this isn't allowed as the domain of a definition",
"since adjectives like this can be applied only to specific things, "
"kinds of things or kinds of values: so 'Definition: a door is ajar "
"if...' is fine, because a door is a kind of thing, and 'Definition: "
"a number is prime if ...' is fine too, but 'Definition: 5 is prime "
"if ...' is not allowed.");
return;
}
}
#line 354 "inform7/Chapter 9/Adjective Meanings.w"
;
kind *K = NULL;
if (ParseTree__is_condition(supplied)) {
if (Specifications__to_kind(supplied))
K = Specifications__to_kind(supplied);
else K = K_object;
{
#line 426 "inform7/Chapter 9/Adjective Meanings.w"
if (Descriptions__is_qualified(supplied)) {
if (am->problems_thrown++ > 0) return;
current_sentence = am->defined_at;
Problems__Issue__adjective_problem(_p_(PM_AdjDomainSlippery),
am->adjective_index_text, am->domain_text,
"this is slippery",
"because it can change during play. Definitions can only be "
"made in cases where it's clear for any given value or object "
"what definition will apply. For instance, 'Definition: a "
"door is shiny if ...' is fine, but 'Definition: an open "
"door is shiny if ...' is not allowed - Inform wouldn't know "
"whether or not to apply it to the Big Blue Door (say), since "
"it would only apply some of the time.");
return;
}
}
#line 360 "inform7/Chapter 9/Adjective Meanings.w"
;
} else if (ParseTree__is_rvalue(supplied))
K = Rvalues__to_kind(supplied);
if (K == NULL)
{
#line 373 "inform7/Chapter 9/Adjective Meanings.w"
if ((early) || (am->problems_thrown++ > 0)) return;
current_sentence = am->defined_at;
Problems__Issue__adjective_problem(_p_(PM_AdjDomainUnknown),
am->adjective_index_text, am->domain_text,
"this isn't a thing, a kind of thing or a kind of value",
"and indeed doesn't have any meaning I can make sense of.");
return;
}
#line 363 "inform7/Chapter 9/Adjective Meanings.w"
;
if (Kinds__Behaviour__is_kind_of_kind(K))
{
#line 384 "inform7/Chapter 9/Adjective Meanings.w"
if ((early) || (am->problems_thrown++ > 0)) return;
current_sentence = am->defined_at;
Problems__Issue__adjective_problem(_p_(PM_AdjDomainVague),
am->adjective_index_text, am->domain_text,
"this isn't allowed as the domain of a definition",
"since it potentially describes many different kinds, not just one.");
return;
}
#line 364 "inform7/Chapter 9/Adjective Meanings.w"
;
if (Kinds__Compare__eq(K, K_understanding))
{
#line 395 "inform7/Chapter 9/Adjective Meanings.w"
if ((early) || (am->problems_thrown++ > 0)) return;
current_sentence = am->defined_at;
Problems__Issue__adjective_problem(_p_(PM_AdjDomainTopic),
am->adjective_index_text, am->domain_text,
"this isn't allowed as the domain of a definition",
"because 'topic' doesn't behave the way other kinds of value do when "
"it comes to making comparisons.");
return;
}
#line 365 "inform7/Chapter 9/Adjective Meanings.w"
;
{
#line 445 "inform7/Chapter 9/Adjective Meanings.w"
instance *I = Rvalues__to_object_instance(supplied);
if (I) supplied = Rvalues__from_instance(I);
else if (Kinds__Compare__lt(K, K_object))
supplied = Specifications__from_kind(K);
am->domain_infs = InferenceSubjects__from_specification(supplied);
am->domain_kind = K;
}
#line 366 "inform7/Chapter 9/Adjective Meanings.w"
;
}
#line 474 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__compare(adjective_meaning *am1, adjective_meaning *am2) {
if (am1 == am2) return 0;
if ((am1->domain_infs) && (am2->domain_infs == NULL)) return 1;
if ((am1->domain_infs == NULL) && (am2->domain_infs)) return -1;
if (InferenceSubjects__is_strictly_within(am1->domain_infs, am2->domain_infs)) return 1;
if (InferenceSubjects__is_strictly_within(am2->domain_infs, am1->domain_infs)) return -1;
kind *K1 = InferenceSubjects__as_nonobject_kind(am1->domain_infs);
kind *K2 = InferenceSubjects__as_nonobject_kind(am2->domain_infs);
if ((K1) && (K2)) {
int c1 = Kinds__Compare__compatible(K1, K2);
int c2 = Kinds__Compare__compatible(K2, K1);
if ((c1 == ALWAYS_MATCH) && (c2 != ALWAYS_MATCH)) return 1;
if ((c1 != ALWAYS_MATCH) && (c2 == ALWAYS_MATCH)) return -1;
}
if (am1->domain_infs == am2->domain_infs)
{
#line 504 "inform7/Chapter 9/Adjective Meanings.w"
if ((Wordings__nonempty(ParseTree__get_text(am1->defined_at))) &&
(Wordings__nonempty(ParseTree__get_text(am2->defined_at))) &&
(am1->adjective_form != ENUMERATIVE_KADJ) &&
(am2->adjective_form != ENUMERATIVE_KADJ)) {
extension_file *ef1 =
SourceFiles__get_extension_corresponding(
Lexer__file_of_origin(Wordings__first_wn(ParseTree__get_text(am1->defined_at))));
extension_file *ef2 =
SourceFiles__get_extension_corresponding(
Lexer__file_of_origin(Wordings__first_wn(ParseTree__get_text(am2->defined_at))));
if ((ef1 == ef2) || ((ef1) && (ef2))) {
current_sentence = am1->defined_at;
Problems__quote_wording_as_source(1, am1->adjective_index_text);
Problems__quote_wording_as_source(2, am2->adjective_index_text);
Problems__Issue__handmade_problem(_p_(PM_AdjDomainDuplicated));
Problems__issue_problem_segment(
"The definitions %1 and %2 both try to cover the same situation: "
"the same adjective applied to the exact same range. %P"
"It's okay to override a definition in an extension with another "
"one in the main source text, but it's not okay to define the same "
"adjective twice over the same domain in the same file.");
Problems__issue_problem_end();
}
if (ef1 == NULL) return 1;
if (ef2 == NULL) return -1;
}
}
#line 491 "inform7/Chapter 9/Adjective Meanings.w"
;
return am2->allocation_id - am1->allocation_id;
}
#line 579 "inform7/Chapter 9/Adjective Meanings.w"
i6_schema *Adjectives__Meanings__set_i6_schema(adjective_meaning *am,
int T, int via_support) {
kind *K = Adjectives__Meanings__get_domain(am);
if (K == NULL) K = K_object;
if (Kinds__Compare__le(K, K_object)) via_support = TRUE;
am->task_via_support_routine[T] = via_support;
return &(am->i6s_for_runtime_task[T]);
}
#line 599 "inform7/Chapter 9/Adjective Meanings.w"
i6_schema *Adjectives__Meanings__get_i6_schema(adjectival_phrase *aph,
kind *kind_domain, int T) {
adjective_meaning *am;
if (kind_domain == NULL) kind_domain = K_object;
aph->sorted_meanings = Adjectives__Meanings__list_sort(aph->possible_meanings);
for (am = aph->sorted_meanings; am; am = am->next_sorted) {
kind *am_kind = Adjectives__Meanings__get_domain(am);
if (am_kind == NULL) Adjectives__Meanings__set_definition_domain(am, FALSE);
if (Adjectives__Meanings__domain_weak_match(kind_domain, am_kind) == FALSE) continue;
Adjectives__Meanings__compiling_soon(am, T);
switch (am->task_via_support_routine[T]) {
case FALSE: return &(am->i6s_for_runtime_task[T]);
case TRUE:
if (Calculus__Schemas__empty(&(am->i6s_to_transfer_to_SR[T])))
{
#line 625 "inform7/Chapter 9/Adjective Meanings.w"
int adj_number = aph->allocation_id, task = T; char *negation_operator = "";
if (am->am_negated_from) {
adj_number = am->am_negated_from->owning_adjective->allocation_id;
switch (T) {
case TEST_ADJECTIVE_TASK: negation_operator = "~~"; break;
case NOW_ADJECTIVE_TRUE_TASK: task = NOW_ADJECTIVE_FALSE_TASK; break;
case NOW_ADJECTIVE_FALSE_TASK: task = NOW_ADJECTIVE_TRUE_TASK; break;
}
}
Calculus__Schemas__modify(&(am->i6s_to_transfer_to_SR[T]), "*=-(%sAdj_%d_t%d_v%d(*1))",
negation_operator, adj_number, task, Kinds__RunTime__weak_id(am_kind));
}
#line 613 "inform7/Chapter 9/Adjective Meanings.w"
;
return &(am->i6s_to_transfer_to_SR[T]);
}
}
return NULL;
}
#line 644 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__write_adjective_test_routine(OUTPUT_STREAM,
adjectival_phrase *aph) {
i6_schema *sch;
int weak_id = Kinds__RunTime__weak_id(K_object);
sch = Adjectives__Meanings__get_i6_schema(aph, NULL,
TEST_ADJECTIVE_TASK);
if (sch == NULL) {
if (aph->possible_meanings == NULL) return FALSE;
kind *am_kind =
Adjectives__Meanings__get_domain(aph->possible_meanings);
if (am_kind == NULL) return FALSE;
weak_id = Kinds__RunTime__weak_id(am_kind);
}
WRITE("Adj_%d_t%d_v%d", aph->allocation_id, TEST_ADJECTIVE_TASK, weak_id);
return TRUE;
}
#line 665 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__pass_task_to_support_routine(adjective_meaning *am,
int T) {
Adjectives__Meanings__set_i6_schema(am, T, TRUE);
}
#line 674 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__get_ready_flag(adjective_meaning *am) {
return am->am_ready_flag;
}
void Adjectives__Meanings__set_ready_flag(adjective_meaning *am) {
am->am_ready_flag = TRUE;
}
#line 688 "inform7/Chapter 9/Adjective Meanings.w"
adjective_meaning *Adjectives__Meanings__list_next_domain_kind(adjective_meaning *am, kind **K, int T) {
while ((am) && ((am->defined_already) || (Adjectives__Meanings__compile(am, T, NULL, NULL) == FALSE)))
am = am->next_sorted;
if (am == NULL) return NULL;
*K = Adjectives__Meanings__get_domain(am);
return am->next_sorted;
}
#line 704 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__compile_support_code(OUTPUT_STREAM) {
{
#line 728 "inform7/Chapter 9/Adjective Meanings.w"
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
adjective_meaning *am;
for (am = aph->possible_meanings; am; am = am->next_meaning) {
Adjectives__Meanings__set_definition_domain(am, FALSE);
am->defined_already = FALSE;
}
aph->sorted_meanings = Adjectives__Meanings__list_sort(aph->possible_meanings);
}
}
#line 705 "inform7/Chapter 9/Adjective Meanings.w"
;
int T;
for (T=1; T<=NO_ADJECTIVE_TASKS; T++) {
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
adjective_meaning *am;
for (am = aph->possible_meanings; am; am = am->next_meaning)
am->defined_already = FALSE;
for (am = aph->sorted_meanings; am; ) {
kind *K = NULL;
am = Adjectives__Meanings__list_next_domain_kind(am, &K, T);
if (K)
{
#line 741 "inform7/Chapter 9/Adjective Meanings.w"
wording W = Adjectives__Phrases__get_text(aph, FALSE);
LOGIF(VARIABLE_CREATIONS, "Compiling support code for $w applying to $u, task %d\n",
W, K, T);
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "Adj_%d_t%d_v%d", aph->allocation_id, T,
Kinds__RunTime__weak_id(K));
OUT = Routines__begin(OUT, i6_routine_identifier);
{
#line 789 "inform7/Chapter 9/Adjective Meanings.w"
kind *add_K = K_number;
adjective_meaning *am;
for (am = aph->sorted_meanings; am; am = am->next_sorted)
if ((am->adjective_form != I6_ROUTINE_KADJ) &&
(Adjectives__Meanings__domain_weak_match(K, Adjectives__Meanings__get_domain(am))))
add_K = K;
LocalVariables__add_pronoun(Frames__current_stack_frame(), EMPTY_WORDING, add_K);
LocalVariables__enable_possessive_form_of_it();
}
#line 750 "inform7/Chapter 9/Adjective Meanings.w"
;
WRITE("! meaning of \"");
if (Wordings__nonempty(W)) Wordings__to_stream_raw_within_i6_literal(OUT, W);
else WRITE("<nameless>");
WRITE("\"\n");
if (problem_count == 0)
Adjectives__Meanings__list_compile(aph->sorted_meanings, OUT, Frames__current_stack_frame(), K, T);
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
}
#line 717 "inform7/Chapter 9/Adjective Meanings.w"
;
}
}
}
}
#line 805 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__list_compile(adjective_meaning *list_head, OUTPUT_STREAM,
ph_stack_frame *phsf, kind *K, int T) {
adjective_meaning *am;
for (am = list_head; am; am = am->next_sorted)
if ((Adjectives__Meanings__compile(am, T, NULL, NULL)) &&
(Adjectives__Meanings__domain_weak_match(K, Adjectives__Meanings__get_domain(am)))) {
current_sentence = am->defined_at;
char cond[1024]; cond[0] = 0;
InferenceSubjects__write_element_of_condition(am->domain_infs, cond);
if (cond[0] != 0) WRITE(" if (%s) ", cond);
WRITE("return ");
if ((am->meaning_parity == FALSE) && (T == TEST_ADJECTIVE_TASK)) WRITE("(~~(");
Adjectives__Meanings__compile(am, T, OUT, phsf);
if ((am->meaning_parity == FALSE) && (T == TEST_ADJECTIVE_TASK)) WRITE("))");
WRITE(";\n");
am->defined_already = TRUE;
}
}
#line 851 "inform7/Chapter 9/Adjective Meanings.w"
adjective_meaning *Adjectives__Meanings__parse(parse_node *q,
int sense, wording AW, wording DNW, wording CONW, wording CALLW) {
adjective_meaning *am = NULL;
if (am == NULL) am = Properties__EitherOr__ADJ_parse(q, sense, AW, DNW, CONW, CALLW);
if (am == NULL) am = Instances__ADJ_parse(q, sense, AW, DNW, CONW, CALLW);
if (am == NULL) am = Properties__Measurement__ADJ_parse(q, sense, AW, DNW, CONW, CALLW);
if (am == NULL) am = Phrases__RawCondition__ADJ_parse(q, sense, AW, DNW, CONW, CALLW);
if (am == NULL) am = Phrases__RawPhrasal__ADJ_parse(q, sense, AW, DNW, CONW, CALLW);
if (am == NULL) am = Phrases__Phrasal__ADJ_parse(q, sense, AW, DNW, CONW, CALLW);
if (am == NULL) am = Phrases__Condition__ADJ_parse(q, sense, AW, DNW, CONW, CALLW);
return am;
}
#line 870 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__compiling_soon(adjective_meaning *am, int T) {
switch (am->adjective_form) {
case CONDITION_KADJ: Phrases__Condition__ADJ_compiling_soon(am,
RETRIEVE_POINTER_definition(am->detailed_meaning), T); break;
case I6_CONDITION_KADJ: Phrases__RawCondition__ADJ_compiling_soon(am,
RETRIEVE_POINTER_definition(am->detailed_meaning), T); break;
case I6_ROUTINE_KADJ: Phrases__RawPhrasal__ADJ_compiling_soon(am,
RETRIEVE_POINTER_definition(am->detailed_meaning), T); break;
case PHRASE_KADJ: Phrases__Phrasal__ADJ_compiling_soon(am,
RETRIEVE_POINTER_definition(am->detailed_meaning), T); break;
case MEASUREMENT_KADJ: Properties__Measurement__ADJ_compiling_soon(am,
RETRIEVE_POINTER_measurement_definition(am->detailed_meaning), T); break;
case ENUMERATIVE_KADJ: Instances__ADJ_compiling_soon(am,
RETRIEVE_POINTER_instance(am->detailed_meaning), T); break;
case EORP_KADJ: Properties__EitherOr__ADJ_compiling_soon(am,
RETRIEVE_POINTER_property(am->detailed_meaning), T); break;
}
}
#line 898 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__compile(adjective_meaning *am, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
Adjectives__Meanings__compiling_soon(am, T);
{
#line 926 "inform7/Chapter 9/Adjective Meanings.w"
if (Calculus__Schemas__empty(&(am->i6s_for_runtime_task[T])) == FALSE) {
parse_node *it_var = Lvalues__new_LOCAL_VARIABLE(EMPTY_WORDING,
LocalVariables__it_variable());
pcalc_term it_term = Calculus__Terms__new_constant(it_var);
WRITE("(");
Calculus__Schemas__expand(&(am->i6s_for_runtime_task[T]), OUT, &it_term, NULL);
WRITE(")");
return TRUE;
}
}
#line 900 "inform7/Chapter 9/Adjective Meanings.w"
;
switch (am->adjective_form) {
case CONDITION_KADJ: return Phrases__Condition__ADJ_compile(
RETRIEVE_POINTER_definition(am->detailed_meaning), T, OUT, phsf);
case I6_ROUTINE_KADJ: return Phrases__RawPhrasal__ADJ_compile(
RETRIEVE_POINTER_definition(am->detailed_meaning), T, OUT, phsf);
case I6_CONDITION_KADJ: return Phrases__RawCondition__ADJ_compile(
RETRIEVE_POINTER_definition(am->detailed_meaning), T, OUT, phsf);
case PHRASE_KADJ: return Phrases__Phrasal__ADJ_compile(
RETRIEVE_POINTER_definition(am->detailed_meaning), T, OUT, phsf);
case MEASUREMENT_KADJ: return Properties__Measurement__ADJ_compile(
RETRIEVE_POINTER_measurement_definition(am->detailed_meaning), T, OUT, phsf);
case ENUMERATIVE_KADJ: return Instances__ADJ_compile(
RETRIEVE_POINTER_instance(am->detailed_meaning), T, OUT, phsf);
case EORP_KADJ: return Properties__EitherOr__ADJ_compile(
RETRIEVE_POINTER_property(am->detailed_meaning), T, OUT, phsf);
}
internal_error("unknown KADJ code");
return FALSE;
}
#line 942 "inform7/Chapter 9/Adjective Meanings.w"
int Adjectives__Meanings__assert(adjective_meaning *am, inference_subject *infs_to_assert_on,
parse_node *val_to_assert_on, int parity) {
if (am->meaning_parity == FALSE) {
am = am->am_negated_from; parity = (parity)?FALSE:TRUE;
}
switch (am->adjective_form) {
case CONDITION_KADJ: return Phrases__Condition__ADJ_assert(
RETRIEVE_POINTER_definition(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case I6_CONDITION_KADJ: return Phrases__RawCondition__ADJ_assert(
RETRIEVE_POINTER_definition(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case I6_ROUTINE_KADJ: return Phrases__RawPhrasal__ADJ_assert(
RETRIEVE_POINTER_definition(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case PHRASE_KADJ: return Phrases__Phrasal__ADJ_assert(
RETRIEVE_POINTER_definition(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case MEASUREMENT_KADJ: return Properties__Measurement__ADJ_assert(
RETRIEVE_POINTER_measurement_definition(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case ENUMERATIVE_KADJ: return Instances__ADJ_assert(
RETRIEVE_POINTER_instance(am->detailed_meaning),
infs_to_assert_on, val_to_assert_on, parity);
case EORP_KADJ: return Properties__EitherOr__ADJ_assert(
RETRIEVE_POINTER_property(am->detailed_meaning),
infs_to_assert_on, NULL, parity);
}
internal_error("unknown KADJ code");
return FALSE;
}
#line 983 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__print_to_index(adjective_meaning *am) {
int rv;
{
#line 1022 "inform7/Chapter 9/Adjective Meanings.w"
if (am->domain_infs) {
wording W = InferenceSubjects__get_name_text(am->domain_infs);
INDEX("(of </i>");
Wordings__index_raw(W);
INDEX("<i>) ");
}
}
#line 985 "inform7/Chapter 9/Adjective Meanings.w"
;
if (am->am_negated_from) {
INDEX(" opposite of </i>");
wording W = Adjectives__Phrases__get_text(
am->am_negated_from->owning_adjective, FALSE);
Wordings__index_raw(W);
INDEX("<i>");
} else {
switch (am->adjective_form) {
case CONDITION_KADJ: rv = Phrases__Condition__ADJ_index(
RETRIEVE_POINTER_definition(am->detailed_meaning)); break;
case I6_CONDITION_KADJ: rv = Phrases__RawCondition__ADJ_index(
RETRIEVE_POINTER_definition(am->detailed_meaning)); break;
case I6_ROUTINE_KADJ: rv = Phrases__RawPhrasal__ADJ_index(
RETRIEVE_POINTER_definition(am->detailed_meaning)); break;
case PHRASE_KADJ: rv = Phrases__Phrasal__ADJ_index(
RETRIEVE_POINTER_definition(am->detailed_meaning)); break;
case MEASUREMENT_KADJ: rv = Properties__Measurement__ADJ_index(
RETRIEVE_POINTER_measurement_definition(am->detailed_meaning)); break;
case ENUMERATIVE_KADJ: rv = Instances__ADJ_index(
RETRIEVE_POINTER_instance(am->detailed_meaning)); break;
case EORP_KADJ: rv = Properties__EitherOr__ADJ_index(
RETRIEVE_POINTER_property(am->detailed_meaning)); break;
default: rv = FALSE; break;
}
if ((rv == FALSE) && (Wordings__nonempty(am->adjective_index_text)))
Wordings__index_raw(am->adjective_index_text);
}
if (Wordings__nonempty(am->adjective_index_text))
Index__link(Wordings__first_wn(am->adjective_index_text));
}
#line 1032 "inform7/Chapter 9/Adjective Meanings.w"
int adaptive_adjective_NTMR(wording W, int *X, void **XP) {
#line 1033 "inform7/Chapter 9/Adjective Meanings.w"
if (language_of_play == English_language) return FALSE;
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
wording AW = Clusters__get_name_general(aph->adjective_names, language_of_play, 1, -1);
if (Wordings__match(AW, W)) {
*XP = aph; *X = FALSE; return TRUE;
}
}
return FALSE;
}
#line 1047 "inform7/Chapter 9/Adjective Meanings.w"
void Adjectives__Meanings__agreements(OUTPUT_STREAM) {
if (language_of_play == English_language) return;
adjectival_phrase *aph;
LOOP_OVER(aph, adjectival_phrase) {
wording PW = Clusters__get_name_general(aph->adjective_names, language_of_play, 1, -1);
if (Wordings__empty(PW)) continue;
OUT = Routines__begin_numbered(OUT, "AgreeAdjective_%d", aph->allocation_id);
LocalVariables__add_named_call("o");
LocalVariables__add_named_call("force_plural");
LocalVariables__add_internal_local("gna");
WRITE("if (o == nothing) gna = 6; else gna = GetGNAOfObject(o);\n");
WRITE("if (force_plural) {\n"); INDENT;
WRITE("if (prior_named_list_gender ~= -1) gna = 3 + prior_named_list_gender;\n");
WRITE("else gna = 3;\n");
OUTDENT; WRITE("}\n");
WRITE("gna = gna %% 6;\n");
WRITE("switch (gna) {\n"); INDENT;
int gna;
for (gna=0; gna<6; gna++) {
WRITE("%d: print \"", gna);
int number_sought = 1, gender_sought = NEUTER_GENDER;
if (gna%3 == 0) gender_sought = MASCULINE_GENDER;
if (gna%3 == 1) gender_sought = FEMININE_GENDER;
if (gna >= 3) number_sought = 2;
wording AW = Clusters__get_name_general(aph->adjective_names,
language_of_play, number_sought, gender_sought);
if (Wordings__nonempty(AW)) Wordings__to_stream(OUT, AW);
else Wordings__to_stream(OUT, PW);
WRITE("\"; ! %d, %d\n", number_sought, gender_sought);
}
OUTDENT; WRITE("}\n");
OUT = Routines__end(OUT);
}
}
void Adjectives__Meanings__invoke(OUTPUT_STREAM, adjectival_phrase *aph) {
WRITE("AgreeAdjective_%d(prior_named_noun, (prior_named_list >= 2)); say__p=1; ",
aph->allocation_id);
}
#line 25 "inform7/Chapter 9/Adjective Usages.w"
adjective_usage *Adjectives__Usages__new(adjectival_phrase *aph, int pos) {
adjective_usage *au = CREATE(adjective_usage);
au->ref_to = aph;
au->ref_positive = pos;
return au;
}
void Adjectives__Usages__log(adjective_usage *au) {
adjectival_phrase *aph = Adjectives__Usages__get_aph(au);
if (au->ref_positive == FALSE) LOG("~");
wording W = Adjectives__Phrases__get_text(aph, FALSE);
LOG("<adj:$w>", W);
}
adjective_usage *Adjectives__Usages__copy(adjective_usage *au_from) {
return Adjectives__Usages__new(au_from->ref_to, au_from->ref_positive);
}
adjectival_phrase *Adjectives__Usages__get_aph(adjective_usage *au) {
if (au == NULL) return NULL;
return au->ref_to;
}
int Adjectives__Usages__get_parity(adjective_usage *au) {
if (au == NULL) internal_error("null adjective tested for positivity");
return au->ref_positive;
}
void Adjectives__Usages__flip_parity(adjective_usage *au) {
if (au == NULL) internal_error("null adjective flipped");
au->ref_positive = (au->ref_positive)?FALSE:TRUE;
}
#line 177 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *LiteralPatterns__lp_new(kind *K, wording W) {
literal_pattern *lp = CREATE(literal_pattern);
lp->plural_form_only = FALSE;
lp->singular_form_only = FALSE;
lp->kind_specified = K;
lp->prototype_text = W;
lp->next_for_this_kind = NULL;
lp->primary_alternative = FALSE;
lp->next_alternative_lp = NULL;
lp->no_lp_elements = 0;
lp->no_lp_tokens = 0;
lp->number_signed = FALSE;
lp->scaling = Kinds__Scalings__new(TRUE, LP_SCALED_AT, 1, 1.0, 0, 0.0);
lp->equivalent_unit = FALSE;
lp->benchmark = FALSE;
return lp;
}
#line 198 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_token LiteralPatterns__lpt_new(int t, int nw) {
literal_pattern_token lpt;
lpt.new_word_at = nw;
lpt.lpt_type = t;
lpt.token_char = 0;
lpt.token_wn = -1;
return lpt;
}
#line 210 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_element LiteralPatterns__lpe_new(int i, int r, int sgn) {
literal_pattern_element lpe;
if (i == 0) lpe.element_range = -1; else lpe.element_range = r;
lpe.element_multiplier = 1;
lpe.element_index = i;
lpe.element_name = EMPTY_WORDING;
lpe.preamble_optional = FALSE;
lpe.element_optional = FALSE;
lpe.without_leading_zeros = FALSE;
return lpe;
}
#line 229 "inform7/Chapter 10/Literal Patterns.w"
int PM_ZMachineOverflow2_issued = FALSE;
literal_pattern *LiteralPatterns__list_add(literal_pattern *list_head,
literal_pattern *new_lp, int using_integer_scaling) {
if (list_head == NULL)
{
#line 246 "inform7/Chapter 10/Literal Patterns.w"
Kinds__Scalings__determine_M(&(new_lp->scaling), NULL,
TRUE, new_lp->equivalent_unit, new_lp->primary_alternative);
list_head = new_lp;
}
#line 233 "inform7/Chapter 10/Literal Patterns.w"
else
{
#line 255 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *lp;
scaling_transformation *benchmark_sc = NULL;
for (lp = list_head; lp; lp = lp->next_for_this_kind)
if (lp->benchmark) benchmark_sc = &(lp->scaling);
int rescale_factor = Kinds__Scalings__determine_M(&(new_lp->scaling), benchmark_sc,
FALSE, new_lp->equivalent_unit, new_lp->primary_alternative);
if (rescale_factor != 1)
for (lp = list_head; lp; lp = lp->next_for_this_kind)
if ((lp != new_lp) && (lp->equivalent_unit == FALSE))
lp->scaling =
Kinds__Scalings__enlarge(lp->scaling, rescale_factor);
list_head = LiteralPatterns__lp_list_add_inner(list_head, new_lp);
if ((VirtualMachines__is_16_bit()) && (PM_ZMachineOverflow2_issued == FALSE))
for (lp = list_head; lp; lp = lp->next_for_this_kind)
if (Kinds__Scalings__quantum(lp->scaling) > 32767) {
Problems__Issue__sentence_problem(_p_(PM_ZMachineOverflow2),
"you've set up literal specifications needing a range of "
"values too broad to be stored at run-time",
"at least with the Settings for this project as they currently are. "
"(Change to Glulx to be allowed to use much larger numbers; "
"or for really enormous values, use real arithmetic.)");
PM_ZMachineOverflow2_issued = TRUE;
break;
}
}
#line 234 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 289 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *lp, *last_resorter = NULL;
for (lp = list_head; lp; lp = lp->next_for_this_kind) {
lp->last_resort = FALSE;
if (lp->equivalent_unit == FALSE) last_resorter = lp;
}
if (last_resorter) last_resorter->last_resort = TRUE;
}
#line 236 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 303 "inform7/Chapter 10/Literal Patterns.w"
int scalings_exist = FALSE;
literal_pattern *lp;
for (lp = list_head; lp; lp = lp->next_for_this_kind)
if (Kinds__Scalings__involves_scale_change(lp->scaling))
scalings_exist = TRUE;
if (scalings_exist)
for (lp = list_head; lp; lp = lp->next_for_this_kind)
lp->number_signed = TRUE;
}
#line 237 "inform7/Chapter 10/Literal Patterns.w"
;
return list_head;
}
#line 317 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *LiteralPatterns__lp_list_add_inner(literal_pattern *list_head, literal_pattern *new_lp) {
literal_pattern *lp, *lp_prev;
new_lp->next_for_this_kind = NULL;
if (list_head == NULL) return new_lp;
lp = list_head; lp_prev = NULL;
while (lp) {
if (LiteralPatterns__lp_precedes(new_lp, lp)) {
new_lp->next_for_this_kind = lp;
if (lp_prev) lp_prev->next_for_this_kind = new_lp;
else list_head = new_lp;
return list_head;
}
lp_prev = lp;
lp = lp->next_for_this_kind;
}
lp_prev->next_for_this_kind = new_lp;
return list_head;
}
#line 341 "inform7/Chapter 10/Literal Patterns.w"
int LiteralPatterns__lp_precedes(literal_pattern *A, literal_pattern *B) {
int s = Kinds__Scalings__compare(A->scaling, B->scaling);
if (s > 0) return TRUE;
if (s < 0) return FALSE;
if ((A->primary_alternative) && (B->primary_alternative == FALSE)) return TRUE;
if ((A->primary_alternative == FALSE) && (B->primary_alternative)) return FALSE;
if ((A->plural_form_only) && (B->plural_form_only == FALSE)) return TRUE;
if ((A->plural_form_only == FALSE) && (B->plural_form_only)) return FALSE;
if ((A->singular_form_only) && (B->singular_form_only == FALSE)) return TRUE;
if ((A->singular_form_only == FALSE) && (B->singular_form_only)) return FALSE;
if (A->allocation_id < B->allocation_id) return TRUE;
return FALSE;
}
#line 358 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *LiteralPatterns__get_benchmark(kind *K) {
literal_pattern *lp;
LITERAL_FORMS_LOOP(lp, K)
if (lp->benchmark)
return lp;
return NULL;
}
#line 370 "inform7/Chapter 10/Literal Patterns.w"
int LiteralPatterns__scale_factor(kind *K) {
literal_pattern *benchmark_lp = LiteralPatterns__get_benchmark(K);
if (benchmark_lp) return Kinds__Scalings__get_integer_multiplier(benchmark_lp->scaling);
return 1;
}
#line 381 "inform7/Chapter 10/Literal Patterns.w"
int LiteralPatterns__at_optional_break_point(literal_pattern *lp, int ec, int tc) {
if ((ec<lp->no_lp_elements) && /* i.e., if there are still numerical elements to supply */
(lp->lp_elements[ec].element_optional) && /* but which are optional */
((lp->lp_elements[ec].preamble_optional) || /* and either the preamble tokens are also optional */
(lp->lp_tokens[tc].lpt_type == ELEMENT_LPT))) /* or we're at the number token */
return TRUE;
return FALSE;
}
#line 396 "inform7/Chapter 10/Literal Patterns.w"
int waive_lp_overflows = FALSE;
int last_LP_problem_at = -1;
double latest_constructed_real = 0.0;
kind *LiteralPatterns__match(literal_pattern *lp, wording W, int *found) {
int matched_number = 0, overflow_16_bit_flag = FALSE, overflow_32_bit_flag = FALSE;
literal_pattern_element *sign_used_at = NULL, *element_overflow_at = NULL;
/* if the excerpt is longer than the maximum length of such a notation, give up quickly: */
if (Wordings__length(W) > Wordings__length(lp->prototype_text)) return NULL;
{
#line 425 "inform7/Chapter 10/Literal Patterns.w"
int tc, wn = Wordings__first_wn(W), wpos = -1, ec = 0, matched_scaledown = 1, parsed_as_real = FALSE;
char *wd = Lexer__word_text(Wordings__first_wn(W));
for (tc=0; tc<lp->no_lp_tokens; tc++) {
if (wn > Wordings__last_wn(W)) {
if ((wpos == -1) /* i.e., if we are cleanly at a word boundary */
&& (LiteralPatterns__at_optional_break_point(lp, ec, tc))) break;
return NULL;
}
switch (lp->lp_tokens[tc].lpt_type) {
case WORD_LPT:
{
#line 463 "inform7/Chapter 10/Literal Patterns.w"
if (wpos >= 0) return NULL; /* if we're still in the middle of the last word, we must fail */
if (compare_words(wn, lp->lp_tokens[tc].token_wn) == FALSE) return NULL;
wn++;
}
#line 434 "inform7/Chapter 10/Literal Patterns.w"
; break;
case CHARACTER_LPT:
{
#line 471 "inform7/Chapter 10/Literal Patterns.w"
if (wpos == -1) { wpos = 0; wd = Lexer__word_text(wn); } /* start parsing the interior of a word */
if (Platform__tolower(wd[wpos++]) != Platform__tolower(lp->lp_tokens[tc].token_char)) return NULL;
if (wd[wpos] == 0) { wn++; wpos = -1; } /* and stop parsing the interior of a word */
}
#line 435 "inform7/Chapter 10/Literal Patterns.w"
; break;
case ELEMENT_LPT:
{
#line 478 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_element *lpe = &(lp->lp_elements[ec++]); /* fetch details of next number */
if (wpos == -1) { wpos = 0; wd = Lexer__word_text(wn); } /* start parsing the interior of a word */
if (wd[wpos] == '-') { sign_used_at = lpe; wpos++; }
if (Kinds__FloatingPoint__uses_floating_point(lp->kind_specified))
{
#line 534 "inform7/Chapter 10/Literal Patterns.w"
char real_buffer[MAX_REAL_LITERAL_LENGTH+8];
int j=0, point_at = -1, mult_at = -1;
while ((isdigit(wd[wpos])) || ((wd[wpos] == '.') && (point_at == -1))) {
if (wd[wpos] == '.') point_at = j;
real_buffer[j++] = wd[wpos++];
if (j == MAX_REAL_LITERAL_LENGTH) return NULL;
}
if ((j == 0) || (point_at == j-1)) return NULL;
if (Literals__ismultiplicationsign(wd[wpos])) {
mult_at = wpos;
real_buffer[j++] = wd[wpos++];
if (wd[wpos] == '1') real_buffer[j++] = wd[wpos++]; else return NULL;
if (wd[wpos] == '0') real_buffer[j++] = wd[wpos++]; else return NULL;
if (wd[wpos] == '^') real_buffer[j++] = wd[wpos++]; else return NULL;
if (wd[wpos] == '+') real_buffer[j++] = wd[wpos++];
else if (wd[wpos] == '-') real_buffer[j++] = wd[wpos++];
while (isdigit(wd[wpos])) {
real_buffer[j++] = wd[wpos++];
if (j == MAX_REAL_LITERAL_LENGTH) return NULL;
}
}
real_buffer[j++] = 0;
wording W = Feeds__feed_text(real_buffer);
if ((point_at == -1) && (mult_at == -1)) {
if (Preform__parse_nt_against_word_range(cardinal_number_NTM, Wordings__first_word(W), NULL, NULL) == FALSE) return NULL;
matched_number = most_recent_result;
int signbit = 0;
if (matched_number < 0) { signbit = 1; matched_number = -matched_number; }
matched_number = Literals__construct_float(signbit, matched_number, 0, 0);
} else {
if (Preform__parse_nt_against_word_range(literal_real_in_digits_NTM, Wordings__first_word(W), NULL, NULL) == FALSE) return NULL;
matched_number = most_recent_result;
}
latest_constructed_real =
Kinds__Scalings__real_quanta_to_value(lp->scaling, latest_constructed_real);
int signbit = FALSE;
if (latest_constructed_real < 0) {
latest_constructed_real = -latest_constructed_real;
signbit = TRUE;
}
matched_number = Literals__construct_float(signbit, latest_constructed_real, 0, 0);
parsed_as_real = TRUE;
}
#line 481 "inform7/Chapter 10/Literal Patterns.w"
else
{
#line 502 "inform7/Chapter 10/Literal Patterns.w"
long long int tot = 0, max_32_bit, max_16_bit;
int digits_found = 0, point_at = -1;
max_16_bit = 32767LL; if (sign_used_at) max_16_bit = 32768LL;
max_32_bit = 2147483647LL; if (sign_used_at) max_32_bit = 2147483648LL;
while ((isdigit(wd[wpos])) ||
((wd[wpos] == '.') && (Kinds__Scalings__get_integer_multiplier(lp->scaling) > 1) && (point_at == -1))) {
if (wd[wpos] == '.') { point_at = digits_found; wpos++; continue; }
tot = 10*tot + (wd[wpos++] - '0');
if (tot > max_16_bit) overflow_16_bit_flag = TRUE;
if (tot > max_32_bit) overflow_32_bit_flag = TRUE;
digits_found++;
}
if ((point_at == 0) || (point_at == digits_found)) return NULL;
if (digits_found == 0) return NULL;
while ((point_at > 0) && (point_at < digits_found)) {
matched_scaledown *= 10; point_at++;
}
if ((tot >= lpe->element_range) && (lpe->element_index > 0)) element_overflow_at = lpe;
tot = (lpe->element_multiplier)*tot;
if (tot > max_16_bit) overflow_16_bit_flag = TRUE;
if (tot > max_32_bit) overflow_32_bit_flag = TRUE;
tot = matched_number + tot;
if (tot > max_16_bit) overflow_16_bit_flag = TRUE;
if (tot > max_32_bit) overflow_32_bit_flag = TRUE;
matched_number = (int) tot;
}
#line 482 "inform7/Chapter 10/Literal Patterns.w"
;
if (wd[wpos] == 0) { wn++; wpos = -1; } /* and stop parsing the interior of a word */
}
#line 436 "inform7/Chapter 10/Literal Patterns.w"
; break;
default: internal_error("unknown literal pattern token type");
}
}
if (wpos >= 0) return NULL; /* we need to end cleanly, not in mid-word */
if (wn <= Wordings__last_wn(W)) return NULL; /* and we need to have used up all of the excerpt */
if (parsed_as_real == FALSE) {
int loses_accuracy = FALSE;
scaling_transformation sc =
Kinds__Scalings__contract(lp->scaling, matched_scaledown, &loses_accuracy);
matched_number = Kinds__Scalings__quanta_to_value(sc, matched_number);
if (loses_accuracy)
{
#line 663 "inform7/Chapter 10/Literal Patterns.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_wording(3, lp->prototype_text);
Problems__Issue__handmade_problem(_p_(PM_LPTooLittleAccuracy));
Problems__issue_problem_segment(
"In the sentence %1, you use the notation '%2' to write a constant value. "
"But to store that, I would need greater accuracy than this kind of "
"value has - see the Kinds page of the Index for the range it has.");
Problems__issue_problem_end();
return NULL;
}
#line 448 "inform7/Chapter 10/Literal Patterns.w"
;
long long int max_16_bit = 32767LL, max_32_bit = 2147483647LL;
if (matched_number > max_16_bit) overflow_16_bit_flag = TRUE;
if (matched_number > max_32_bit) overflow_32_bit_flag = TRUE;
if (sign_used_at) matched_number = -matched_number;
} else {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-conversion"
if (sign_used_at) matched_number = matched_number | 0x80000000;
#pragma clang diagnostic pop
}
}
#line 407 "inform7/Chapter 10/Literal Patterns.w"
;
if (sign_used_at)
{
#line 589 "inform7/Chapter 10/Literal Patterns.w"
if (Kinds__FloatingPoint__uses_floating_point(lp->kind_specified) == FALSE) {
if (sign_used_at->element_index != 0) {
ISSUING_LP_PROBLEM;
Problems__Issue__sentence_problem(_p_(PM_NegationInternal),
"a negative number can't be used in the middle of a constant",
"and the minus sign makes it look as if that's what you are "
"trying here.");
return NULL;
}
if (lp->number_signed == FALSE) {
ISSUING_LP_PROBLEM;
Problems__Issue__sentence_problem(_p_(PM_NegationForbidden),
"the minus sign is not allowed here",
"since this is a kind of value which only allows positive "
"values to be written.");
return NULL;
}
}
}
#line 409 "inform7/Chapter 10/Literal Patterns.w"
;
if (waive_lp_overflows == FALSE) {
if (element_overflow_at)
{
#line 634 "inform7/Chapter 10/Literal Patterns.w"
int max = element_overflow_at->element_range - 1;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_wording(3, lp->prototype_text);
Problems__quote_number(4, &max);
switch (element_overflow_at->element_index) {
case 0: Problems__quote_text(5, "first"); break;
case 1: Problems__quote_text(5, "second"); break;
case 2: Problems__quote_text(5, "third"); break;
case 3: Problems__quote_text(5, "fourth"); break;
case 4: Problems__quote_text(5, "fifth"); break;
case 5: Problems__quote_text(5, "sixth"); break;
case 6: Problems__quote_text(5, "seventh"); break;
case 7: Problems__quote_text(5, "eighth"); break;
case 8: Problems__quote_text(5, "ninth"); break;
case 9: Problems__quote_text(5, "tenth"); break;
default: Problems__quote_text(5, "eventual"); break;
}
Problems__Issue__handmade_problem(_p_(PM_ElementOverflow));
Problems__issue_problem_segment(
"In the sentence %1, you use the notation '%2' to write a constant value. "
"But the notation was specified as '%3', which means that the %5 numerical "
"part should range between 0 and %4.");
Problems__issue_problem_end();
return NULL;
}
#line 412 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 611 "inform7/Chapter 10/Literal Patterns.w"
if (overflow_32_bit_flag) {
ISSUING_LP_PROBLEM;
Problems__Issue__sentence_problem(_p_(PM_EvenOverflow-G),
"you use a literal specification to make a value which is too large",
"even for a story file compiled with the Glulx setting. (You can "
"see the size limits for each way of writing a value on the Kinds "
"page of the Index.)");
return NULL;
}
if ((overflow_16_bit_flag) && (VirtualMachines__is_16_bit())) {
ISSUING_LP_PROBLEM;
Problems__Issue__sentence_problem(_p_(PM_ZMachineOverflow),
"you use a literal specification to make a value which is too large",
"at least with the Settings for this project as they currently are. "
"(Change to Glulx to be allowed to use much larger numbers; "
"meanwhile, you can see the size limits for each way of writing a "
"value on the Kinds page of the Index.)");
return NULL;
}
}
#line 413 "inform7/Chapter 10/Literal Patterns.w"
;
}
*found = matched_number;
return lp->kind_specified;
}
#line 684 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__gpr_locals(void) {
LocalVariables__add_internal_local("wpos");
LocalVariables__add_internal_local("mid_word");
LocalVariables__add_internal_local("matched_number");
LocalVariables__add_internal_local("cur_word");
LocalVariables__add_internal_local("cur_len");
LocalVariables__add_internal_local("cur_addr");
LocalVariables__add_internal_local("sgn");
LocalVariables__add_internal_local("tot");
LocalVariables__add_internal_local("f");
LocalVariables__add_internal_local("x");
}
#line 703 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__gpr(OUTPUT_STREAM, literal_pattern *lp) {
int label = lp->allocation_id;
int tc, ec;
LiteralPatterns__comment_use_of_lp(OUT, lp);
WRITE("wpos = 0; mid_word = false; matched_number = 0;\n");
for (tc=0, ec=0; tc<lp->no_lp_tokens; tc++) {
int lookahead = -1;
if ((tc+1<lp->no_lp_tokens) && (lp->lp_tokens[tc+1].lpt_type == CHARACTER_LPT))
lookahead = lp->lp_tokens[tc+1].token_char;
WRITE("if (mid_word == false) {\n"); INDENT;
WRITE("cur_word = NextWordStopped(); wn--;\n");
WRITE("if (cur_word == -1) ");
if ((lp->lp_elements[ec].preamble_optional) && (lp->lp_tokens[tc].lpt_type == ELEMENT_LPT))
WRITE("jump Failed_LP_%d;\n", label);
else if (LiteralPatterns__at_optional_break_point(lp, ec, tc))
WRITE("jump Succeeded_LP_%d;\n", label);
else
WRITE("jump Failed_LP_%d;\n", label);
OUTDENT; WRITE("}\n");
switch (lp->lp_tokens[tc].lpt_type) {
case WORD_LPT:
{
#line 751 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (mid_word) jump Failed_LP_%d;\n", label);
WRITE("if (cur_word ~= ");
DictionaryWords__compile(OUT,
Lexer__word_text(lp->lp_tokens[tc].token_wn), FALSE);
WRITE(") jump Failed_LP_%d;\n", label);
WRITE("wn++;\n");
}
#line 724 "inform7/Chapter 10/Literal Patterns.w"
; break;
case CHARACTER_LPT:
{
#line 761 "inform7/Chapter 10/Literal Patterns.w"
{
#line 864 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (mid_word == false) {\n"); INDENT;
WRITE("mid_word = true;\n");
WRITE("wpos = 0;\n");
WRITE("cur_addr = WordAddress(wn);\n");
WRITE("cur_len = WordLength(wn);\n");
OUTDENT; WRITE("}\n");
}
#line 761 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("if (cur_addr->wpos++ ~= '%c' or '%c') jump Failed_LP_%d;\n",
Platform__tolower(lp->lp_tokens[tc].token_char),
Platform__toupper(lp->lp_tokens[tc].token_char),
label);
{
#line 874 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (wpos == cur_len) {\n"); INDENT;
WRITE("wn++; mid_word = false;\n");
OUTDENT; WRITE("}\n");
}
#line 766 "inform7/Chapter 10/Literal Patterns.w"
;
}
#line 725 "inform7/Chapter 10/Literal Patterns.w"
; break;
case ELEMENT_LPT:
{
#line 771 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_element *lpe = &(lp->lp_elements[ec++]);
{
#line 864 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (mid_word == false) {\n"); INDENT;
WRITE("mid_word = true;\n");
WRITE("wpos = 0;\n");
WRITE("cur_addr = WordAddress(wn);\n");
WRITE("cur_len = WordLength(wn);\n");
OUTDENT; WRITE("}\n");
}
#line 772 "inform7/Chapter 10/Literal Patterns.w"
;
if (ec == 1) WRITE("sgn = 1;\n");
if ((lp->number_signed) && (ec == 1))
WRITE("if (cur_addr->wpos == '-') { sgn = -1; wpos++; }\n");
else
WRITE("if (cur_addr->wpos == '-') jump Failed_LP_%d;\n", label);
if (Kinds__FloatingPoint__uses_floating_point(lp->kind_specified))
{
#line 787 "inform7/Chapter 10/Literal Patterns.w"
WRITE("f = 0; x = cur_addr + wpos;\n");
WRITE("while ((wpos < cur_len) && (DigitToValue(cur_addr->wpos)>=0)) { f++, wpos++; }\n");
WRITE("if (f == 0) jump Failed_LP_%d;\n", label);
WRITE("if (wpos == cur_len) {\n"); INDENT;
WRITE("wn++;\n");
WRITE("cur_word = NextWordStopped();\n");
WRITE("wn = wn - 2;\n");
WRITE("if (cur_word == THEN1__WD) {\n"); INDENT;
WRITE("wn = wn + 2; f++;\n");
WRITE("mid_word = false;\n");
WRITE("wpos++;\n");
{
#line 864 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (mid_word == false) {\n"); INDENT;
WRITE("mid_word = true;\n");
WRITE("wpos = 0;\n");
WRITE("cur_addr = WordAddress(wn);\n");
WRITE("cur_len = WordLength(wn);\n");
OUTDENT; WRITE("}\n");
}
#line 798 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("while ((wpos < cur_len) && (DigitToValue(cur_addr->wpos)>=0)) { f++, wpos++; }\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
WRITE("tot = 0; if (wpos == cur_len) {\n"); INDENT;
WRITE("tot++;\n");
WRITE("cur_word = NextWordStopped();\n");
WRITE("mid_word = false;\n");
{
#line 864 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (mid_word == false) {\n"); INDENT;
WRITE("mid_word = true;\n");
WRITE("wpos = 0;\n");
WRITE("cur_addr = WordAddress(wn);\n");
WRITE("cur_len = WordLength(wn);\n");
OUTDENT; WRITE("}\n");
}
#line 806 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("}");
WRITE("if ((wpos < cur_len) && (cur_addr->wpos == 'x')) { f = f + tot + 1, wpos++;\n");
WRITE("if (wpos == cur_len) {\n"); INDENT;
WRITE("f++;\n");
WRITE("cur_word = NextWordStopped();\n");
WRITE("mid_word = false;\n");
{
#line 864 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (mid_word == false) {\n"); INDENT;
WRITE("mid_word = true;\n");
WRITE("wpos = 0;\n");
WRITE("cur_addr = WordAddress(wn);\n");
WRITE("cur_len = WordLength(wn);\n");
OUTDENT; WRITE("}\n");
}
#line 813 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("}");
WRITE("if ((wpos+3 < cur_len) && (cur_addr->wpos == '1') && "
"(cur_addr->(wpos+1) == '0') && (cur_addr->(wpos+2) == '^')) "
"{ f = f + 3; wpos = wpos + 3;\n");
WRITE("if ((wpos < cur_len) && (cur_addr->wpos == '+' or '-')) { f++, wpos++; }\n");
WRITE("while ((wpos < cur_len) && (DigitToValue(cur_addr->wpos)>=0)) { f++, wpos++; }\n");
WRITE("} else f--; }\n");
WRITE("x = FloatParse(x, f, true);\n");
WRITE("if (x == FLOAT_NAN) jump Failed_LP_%d;\n", label);
WRITE("if (wpos == 0) { mid_word = false; }\n");
WRITE("matched_number = x;\n");
}
#line 779 "inform7/Chapter 10/Literal Patterns.w"
else
{
#line 829 "inform7/Chapter 10/Literal Patterns.w"
WRITE("tot = 0; f = false;\n");
WRITE("while ((wpos < cur_len) && (DigitToValue(cur_addr->wpos)>=0)) {\n"); INDENT;
WRITE("f = DigitToValue(cur_addr->wpos);\n");
Kinds__Scalings__compile_scale_and_add(OUT, "tot", 10, "f", label);
WRITE("f = true;\n");
WRITE("wpos++;\n");
OUTDENT; WRITE("}\n");
WRITE("if (f == false) jump Failed_LP_%d;\n", label);
if (lpe->element_index > 0)
WRITE("if (tot >= %d) jump Failed_LP_%d;\n",
lpe->element_range, label);
Kinds__Scalings__compile_scale_and_add(OUT, "tot", lpe->element_multiplier, "matched_number", label);
WRITE("matched_number = tot;\n");
int M = Kinds__Scalings__get_integer_multiplier(lp->scaling);
if (M > 1) {
WRITE("if (wpos == cur_len) {\n"); INDENT;
WRITE("wn++;\n");
WRITE("cur_word = NextWordStopped();\n");
WRITE("wn = wn - 2;\n");
WRITE("if (cur_word == THEN1__WD) {\n"); INDENT;
WRITE("wn = wn + 2;\n");
WRITE("mid_word = false;\n");
{
#line 864 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (mid_word == false) {\n"); INDENT;
WRITE("mid_word = true;\n");
WRITE("wpos = 0;\n");
WRITE("cur_addr = WordAddress(wn);\n");
WRITE("cur_len = WordLength(wn);\n");
OUTDENT; WRITE("}\n");
}
#line 851 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("for (x = 0, f = %d; (f>1) && (f%%10 == 0) && (DigitToValue(cur_addr->wpos) >= 0);"
"f = f/10) {\n", M); INDENT;
Kinds__Scalings__compile_scale_and_add(OUT, "x", 1, "DigitToValue(cur_addr->wpos)*f/10", label);
WRITE("wpos++;\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
}
}
#line 781 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 874 "inform7/Chapter 10/Literal Patterns.w"
WRITE("if (wpos == cur_len) {\n"); INDENT;
WRITE("wn++; mid_word = false;\n");
OUTDENT; WRITE("}\n");
}
#line 782 "inform7/Chapter 10/Literal Patterns.w"
;
}
#line 726 "inform7/Chapter 10/Literal Patterns.w"
; break;
default: internal_error("unknown literal pattern token type");
}
}
WRITE(".Succeeded_LP_%d;\n", label);
WRITE("if (mid_word) jump Failed_LP_%d;\n", label);
if (Kinds__FloatingPoint__uses_floating_point(lp->kind_specified))
WRITE("if (sgn<0) matched_number = matched_number | $80000000;\n");
else
WRITE("if (sgn<0) matched_number = -1*matched_number;\n");
WRITE("parsed_number = matched_number;\n");
Kinds__Scalings__compile_quanta_to_value(OUT, lp->scaling, "parsed_number", label);
WRITE("#ifdef DEBUG;\n");
WRITE("if (parser_trace >= 3) { print \" [parsed value \", parsed_number, \" by: ");
Wordings__to_stream(OUT, lp->prototype_text);
WRITE("]^\"; }\n");
WRITE("#endif;\n");
WRITE("return GPR_NUMBER;\n");
WRITE(".Failed_LP_%d;\n", label);
}
#line 881 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__index_all(kind *K) {
literal_pattern *lp, *benchmark_lp = LiteralPatterns__get_benchmark(K);
int B = 1, scalings_exist = FALSE;
if (benchmark_lp) B = Kinds__Scalings__get_integer_multiplier(benchmark_lp->scaling);
LITERAL_FORMS_LOOP(lp, K)
if (Kinds__Scalings__involves_scale_change(lp->scaling))
scalings_exist = TRUE;
{
#line 901 "inform7/Chapter 10/Literal Patterns.w"
int f = FALSE;
LITERAL_FORMS_LOOP(lp, K)
if ((lp->primary_alternative) && (lp->equivalent_unit == FALSE)) {
if (f) INDEX("<br>");
else INDEX("<i>Written as:</i><br>");
if ((scalings_exist) && (benchmark_lp)) {
LiteralPatterns__index_lp_possibilities(lp, benchmark_lp);
} else {
Wordings__index_raw(lp->prototype_text);
}
f = TRUE;
}
}
#line 890 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 917 "inform7/Chapter 10/Literal Patterns.w"
int f = FALSE;
LITERAL_FORMS_LOOP(lp, K)
if ((lp->primary_alternative) && (lp->equivalent_unit)) {
if (f) INDEX("<br>");
else INDEX("<br><i>With these equivalent units:</i><br>");
LiteralPatterns__index_lp_possibilities(lp, benchmark_lp);
f = TRUE;
}
}
#line 891 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 929 "inform7/Chapter 10/Literal Patterns.w"
int f = FALSE;
literal_pattern_name *lpn;
LOOP_OVER(lpn, literal_pattern_name)
if (Wordings__nonempty(lpn->notation_name)) {
LITERAL_FORMS_LOOP(lp, K) {
literal_pattern_name *lpn2;
for (lpn2 = lpn; lpn2; lpn2 = lpn2->next)
if (lp == lpn2->can_use_this_lp) {
if (f) INDEX("; ");
else {
INDEX("<br><i>Can be printed back:</i><br>");
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;");
}
f = TRUE;
Wordings__index_raw(lpn->notation_name);
goto NextLPN;
}
}
NextLPN: ;
}
}
#line 892 "inform7/Chapter 10/Literal Patterns.w"
;
}
#line 954 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__index_lp_possibilities(literal_pattern *lp, literal_pattern *benchmark_lp) {
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;");
LiteralPatterns__index_lp_possibility(lp, benchmark_lp);
if (lp->equivalent_unit) {
INDEX(" <i>where</i> ");
LiteralPatterns__lp_index_quantum_value(lp, lp->scaling);
INDEX(" = ");
LiteralPatterns__lp_index_quantum_value(benchmark_lp, lp->scaling);
} else {
if (Kinds__Scalings__compare(lp->scaling, benchmark_lp->scaling) < 0) {
INDEX(" <i>where</i> ");
LiteralPatterns__lp_index_quantum_value(lp, benchmark_lp->scaling);
INDEX(" = ");
LiteralPatterns__lp_index_quantum_value(benchmark_lp, benchmark_lp->scaling);
}
if (Kinds__Scalings__compare(lp->scaling, benchmark_lp->scaling) > 0) {
INDEX(" <i>where</i> ");
LiteralPatterns__lp_index_quantum_value(lp, lp->scaling);
INDEX(" = ");
LiteralPatterns__lp_index_quantum_value(benchmark_lp, lp->scaling);
}
}
}
#line 982 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__index_lp_possibility(literal_pattern *lp, literal_pattern *benchmark_lp) {
if (lp == benchmark_lp) INDEX("<b>");
if (lp->plural_form_only)
LiteralPatterns__lp_index_quantum_value(lp, Kinds__Scalings__enlarge(lp->scaling, 2));
else
LiteralPatterns__lp_index_quantum_value(lp, lp->scaling);
if (lp == benchmark_lp) INDEX("</b>");
if (lp->next_alternative_lp) {
INDEX(" <i>or</i> ");
LiteralPatterns__index_lp_possibility(lp->next_alternative_lp, benchmark_lp);
}
}
#line 1001 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__index_value(literal_pattern *lp_list, int v) {
literal_pattern *lp;
literal_pattern *lp_possibility = NULL;
int k = 0;
for (lp = lp_list; lp; lp = lp->next_for_this_kind) {
if (v == 0) {
if (lp->benchmark) {
LiteralPatterns__lp_index_value_specific(lp, v); return;
}
} else {
if ((lp->primary_alternative) && (lp->equivalent_unit == FALSE)) {
if ((lp_possibility == NULL) || (Kinds__Scalings__quantum(lp->scaling) != k)) {
lp_possibility = lp;
k = Kinds__Scalings__quantum(lp->scaling);
}
if (v >= Kinds__Scalings__quantum(lp->scaling)) {
LiteralPatterns__lp_index_value_specific(lp, v); return;
}
}
}
}
if (lp_possibility) LiteralPatterns__lp_index_value_specific(lp_possibility, v);
else LiteralPatterns__lp_index_value_specific(lp_list, v);
}
#line 1032 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__index_benchmark_value(kind *K) {
literal_pattern *lp;
LITERAL_FORMS_LOOP(lp, K)
if (lp->benchmark) {
LiteralPatterns__lp_index_quantum_value(lp, lp->scaling);
return;
}
INDEX("1");
}
#line 1046 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__lp_index_quantum_value(literal_pattern *lp, scaling_transformation sc) {
int v = 0;
double real_v = 0.0;
if (Kinds__FloatingPoint__uses_floating_point(lp->kind_specified))
real_v = Kinds__Scalings__real_quantum(sc);
else
v = Kinds__Scalings__quantum(sc);
LiteralPatterns__lp_index_value_specific_inner(lp, v, real_v);
}
void LiteralPatterns__lp_index_value_specific(literal_pattern *lp, double alt_value) {
int v = (int) alt_value;
double real_v = alt_value;
LiteralPatterns__lp_index_value_specific_inner(lp, v, real_v);
}
void LiteralPatterns__lp_index_value_specific_inner(literal_pattern *lp, int v, double real_v) {
if (lp == NULL) { INDEX("--"); return; }
int tc, ec;
for (tc=0, ec=0; tc<lp->no_lp_tokens; tc++) {
if ((tc>0) && (lp->lp_tokens[tc].new_word_at)) INDEX(" ");
switch (lp->lp_tokens[tc].lpt_type) {
case WORD_LPT:
{
#line 1080 "inform7/Chapter 10/Literal Patterns.w"
if (tc > 0) INDEX(" ");
Text__to_stream(ifl, Lexer__word_raw_text(lp->lp_tokens[tc].token_wn));
}
#line 1068 "inform7/Chapter 10/Literal Patterns.w"
; break;
case CHARACTER_LPT:
{
#line 1086 "inform7/Chapter 10/Literal Patterns.w"
HTML__html_char_out(ifl, lp->lp_tokens[tc].token_char);
}
#line 1069 "inform7/Chapter 10/Literal Patterns.w"
; break;
case ELEMENT_LPT:
{
#line 1091 "inform7/Chapter 10/Literal Patterns.w"
if (Kinds__FloatingPoint__uses_floating_point(lp->kind_specified)) {
INDEX("%g", Kinds__Scalings__real_value_to_quanta(real_v, lp->scaling));
} else {
int remainder;
Kinds__Scalings__value_to_quanta(v, lp->scaling, &v, &remainder);
literal_pattern_element *lpe = &(lp->lp_elements[ec]);
if (ec == 0) INDEX("%d", v/(lpe->element_multiplier));
else {
char *prototype = "%d";
if ((lp->lp_tokens[tc].new_word_at == FALSE) && (lpe->without_leading_zeros == FALSE))
prototype = LiteralPatterns__leading_zero_prototype(lpe->element_range);
INDEX(prototype, (v/(lpe->element_multiplier)) % (lpe->element_range));
}
if (ec == 0)
{
#line 1111 "inform7/Chapter 10/Literal Patterns.w"
int ranger = 1, M = Kinds__Scalings__get_integer_multiplier(lp->scaling);
while (M > ranger) ranger = ranger*10;
remainder = remainder*(ranger/M);
while ((remainder > 0) && ((remainder % 10) == 0)) {
ranger = ranger/10; remainder = remainder/10;
}
if (remainder > 0) {
INDEX(".");
INDEX(LiteralPatterns__leading_zero_prototype(ranger), remainder);
}
}
#line 1104 "inform7/Chapter 10/Literal Patterns.w"
;
}
ec++;
}
#line 1070 "inform7/Chapter 10/Literal Patterns.w"
; break;
default: internal_error("unknown literal pattern token type");
}
}
}
#line 1125 "inform7/Chapter 10/Literal Patterns.w"
char *LiteralPatterns__leading_zero_prototype(int range) {
if (range > 1000000000) return "%010d";
if (range > 100000000) return "%09d";
if (range > 10000000) return "%08d";
if (range > 1000000) return "%07d";
if (range > 100000) return "%06d";
if (range > 10000) return "%05d";
if (range > 1000) return "%04d";
if (range > 100) return "%03d";
if (range > 10) return "%02d";
return "%d";
}
#line 1141 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__printing_routine(OUTPUT_STREAM, literal_pattern *lp_list) {
literal_pattern_name *lpn;
literal_pattern *lp;
int k;
LocalVariables__add_named_call("which");
LocalVariables__add_internal_local("rem");
LocalVariables__add_internal_local("S");
LOOP_OVER(lpn, literal_pattern_name) {
if (Wordings__nonempty(lpn->notation_name)) {
k = 0;
for (lp = lp_list; lp; lp = lp->next_for_this_kind)
lp->marked_for_printing = FALSE;
literal_pattern_name *lpn2;
for (lpn2 = lpn; lpn2; lpn2 = lpn2->next)
for (lp = lp_list; lp; lp = lp->next_for_this_kind)
if (lp == lpn2->can_use_this_lp) {
k++; lp->marked_for_printing = TRUE;
}
if (k > 0) {
WRITE("! The named notation: ");
Wordings__to_stream(OUT, lpn->notation_name);
WRITE("\n");
WRITE("if (which == %d) {\n", lpn->allocation_id + 1);
{
#line 1196 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *lpb = NULL;
for (lp = lp_list; lp; lp = lp->next_for_this_kind)
if (lp->marked_for_printing)
if (lp->benchmark)
lpb = lp;
if ((lpb) && (lpb->singular_form_only == FALSE))
WRITE("if (value == 0) jump Use_LP_%d;\n", lpb->allocation_id);
literal_pattern *last_lp = NULL, *last_primary = NULL, *last_singular = NULL, *last_plural = NULL;
for (lp = lp_list; lp; lp = lp->next_for_this_kind) {
if (lp->marked_for_printing) {
char *op = ">="; last_lp = lp;
if (lp->primary_alternative) { last_primary = lp; }
if (lp->singular_form_only) { last_singular = lp; op = "=="; }
if (lp->plural_form_only) { last_plural = lp; op = ">"; }
WRITE("if (");
Kinds__Scalings__compile_threshold_test(OUT, lp->scaling, "value", op);
WRITE(") jump Use_LP_%d;\n", lp->allocation_id);
}
}
if (last_primary) last_lp = last_primary;
if (last_lp) {
if ((last_lp->singular_form_only) &&
(last_plural) &&
(Kinds__Scalings__compare(last_plural->scaling, last_lp->scaling) == 0))
WRITE("jump Use_LP_%d;\n", last_plural->allocation_id);
WRITE("jump Use_LP_%d;\n", last_lp->allocation_id);
}
}
#line 1165 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("}\n\n");
}
}
}
{
#line 1186 "inform7/Chapter 10/Literal Patterns.w"
for (k=0, lp = lp_list; lp; lp = lp->next_for_this_kind) {
int eligible = FALSE;
if (lp->equivalent_unit == FALSE) eligible = TRUE;
if (eligible) k++;
lp->marked_for_printing = eligible;
}
}
#line 1171 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1196 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *lpb = NULL;
for (lp = lp_list; lp; lp = lp->next_for_this_kind)
if (lp->marked_for_printing)
if (lp->benchmark)
lpb = lp;
if ((lpb) && (lpb->singular_form_only == FALSE))
WRITE("if (value == 0) jump Use_LP_%d;\n", lpb->allocation_id);
literal_pattern *last_lp = NULL, *last_primary = NULL, *last_singular = NULL, *last_plural = NULL;
for (lp = lp_list; lp; lp = lp->next_for_this_kind) {
if (lp->marked_for_printing) {
char *op = ">="; last_lp = lp;
if (lp->primary_alternative) { last_primary = lp; }
if (lp->singular_form_only) { last_singular = lp; op = "=="; }
if (lp->plural_form_only) { last_plural = lp; op = ">"; }
WRITE("if (");
Kinds__Scalings__compile_threshold_test(OUT, lp->scaling, "value", op);
WRITE(") jump Use_LP_%d;\n", lp->allocation_id);
}
}
if (last_primary) last_lp = last_primary;
if (last_lp) {
if ((last_lp->singular_form_only) &&
(last_plural) &&
(Kinds__Scalings__compare(last_plural->scaling, last_lp->scaling) == 0))
WRITE("jump Use_LP_%d;\n", last_plural->allocation_id);
WRITE("jump Use_LP_%d;\n", last_lp->allocation_id);
}
}
#line 1172 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("rtrue;\n");
for (lp = lp_list; lp; lp = lp->next_for_this_kind) {
{
#line 1231 "inform7/Chapter 10/Literal Patterns.w"
int tc, ec=0, oc=0;
WRITE("\n");
LiteralPatterns__comment_use_of_lp(OUT, lp);
WRITE(".Use_LP_%d;\n", lp->allocation_id);
for (tc=0; tc<lp->no_lp_tokens; tc++) {
if (lp->lp_elements[ec].preamble_optional)
{
#line 1296 "inform7/Chapter 10/Literal Patterns.w"
if (oc == ec) {
if (ec == 0)
WRITE("if ((value/%d) == 0) rtrue;\n",
lp->lp_elements[ec].element_multiplier);
else
WRITE("if ((value/%d)%%%d == 0) rtrue;\n",
lp->lp_elements[ec].element_multiplier,
lp->lp_elements[ec].element_range);
oc = ec + 1;
}
}
#line 1237 "inform7/Chapter 10/Literal Patterns.w"
;
if ((tc>0) && (lp->lp_tokens[tc].new_word_at))
WRITE("print \" \";\n");
switch (lp->lp_tokens[tc].lpt_type) {
case WORD_LPT:
{
#line 1251 "inform7/Chapter 10/Literal Patterns.w"
WRITE("print \"");
CompiledText__from_ISO_string(OUT, Lexer__word_raw_text(lp->lp_tokens[tc].token_wn), 0);
WRITE("\";\n");
}
#line 1241 "inform7/Chapter 10/Literal Patterns.w"
; break;
case CHARACTER_LPT:
{
#line 1258 "inform7/Chapter 10/Literal Patterns.w"
char tiny_string[2];
tiny_string[0] = lp->lp_tokens[tc].token_char; tiny_string[1] = 0;
WRITE("print \"");
CompiledText__from_ISO_string(OUT, tiny_string, 0);
WRITE("\";\n");
}
#line 1242 "inform7/Chapter 10/Literal Patterns.w"
; break;
case ELEMENT_LPT:
{
#line 1267 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_element *lpe = &(lp->lp_elements[ec]);
if (lpe->element_optional)
{
#line 1296 "inform7/Chapter 10/Literal Patterns.w"
if (oc == ec) {
if (ec == 0)
WRITE("if ((value/%d) == 0) rtrue;\n",
lp->lp_elements[ec].element_multiplier);
else
WRITE("if ((value/%d)%%%d == 0) rtrue;\n",
lp->lp_elements[ec].element_multiplier,
lp->lp_elements[ec].element_range);
oc = ec + 1;
}
}
#line 1269 "inform7/Chapter 10/Literal Patterns.w"
;
oc = ec + 1;
if (lp->no_lp_elements == 1) {
Kinds__Scalings__compile_print_in_quanta(OUT, lp->scaling, "value", "rem", "S");
} else {
if (ec == 0) {
if (lp->number_signed)
WRITE("if ((value<0) && (value/%d == 0)) print \"-\";\n", lpe->element_multiplier);
WRITE("print value/%d;\n", lpe->element_multiplier);
if (lp->number_signed) WRITE("if (value<0) value=-value;\n");
} else {
if ((lp->lp_tokens[tc].new_word_at == FALSE) &&
(lpe->without_leading_zeros == FALSE)) {
int pow = 1;
for (pow = 1000000000; pow>1; pow = pow/10)
if (lpe->element_range > pow)
WRITE("if ((value/%d)%%%d < %d) print \"0\";\n",
lpe->element_multiplier, lpe->element_range, pow);
}
WRITE("print (value/%d)%%%d;\n", lpe->element_multiplier, lpe->element_range);
}
}
ec++;
}
#line 1243 "inform7/Chapter 10/Literal Patterns.w"
; break;
default: internal_error("unknown literal pattern token type");
}
}
}
#line 1177 "inform7/Chapter 10/Literal Patterns.w"
;
WRITE("rtrue;\n");
}
}
#line 1310 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__comment_use_of_lp(OUTPUT_STREAM, literal_pattern *lp) {
WRITE("! ");
Wordings__to_stream(OUT, lp->prototype_text);
WRITE(", ");
Kinds__Scalings__describe(OUT, lp->scaling);
WRITE("\n");
}
#line 1321 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__log_lp_debugging_data(OUTPUT_STREAM, literal_pattern *lp) {
WRITE("! %s %s LP%d: primary %d, s/p: %d/%d ",
(lp->benchmark)?"***":"---",
(lp->equivalent_unit)?"equiv":"new ",
lp->allocation_id, lp->primary_alternative,
lp->singular_form_only, lp->plural_form_only);
LiteralPatterns__comment_use_of_lp(OUT, lp);
}
#line 1343 "inform7/Chapter 10/Literal Patterns.w"
sentence_handler SPECIFIES_SH_handler =
{ SENTENCE_NT, SPECIFIES_VB, 1, LiteralPatterns__new_literal_specification };
void LiteralPatterns__new_literal_specification(parse_node *pn) {
LiteralPatterns__new_literal_specification_list(pn->down->next, pn->down->next->next, NULL);
}
#line 1360 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *LiteralPatterns__new_literal_specification_list(parse_node *p, parse_node *q,
literal_pattern *lp_main) {
if (ParseTree__get_type(p) == AND_NT) {
lp_main = LiteralPatterns__new_literal_specification_list(p->down, q, lp_main);
return LiteralPatterns__new_literal_specification_list(p->down->next, q, lp_main);
}
return LiteralPatterns__new_literal_specification_inner(p, q, lp_main);
}
#line 1379 "inform7/Chapter 10/Literal Patterns.w"
double LP_real_offset = 0.0, LP_real_equivalent = 0.0, LP_real_scaling_amount = 0.0;
int LP_scaling, LP_scaling_amount, LP_to_real;
int LP_equivalent; parse_node *LP_equivalent_value;
parse_node *LP_offset_value;
kind *LP_left_kind, *LP_right_kind; /* used only for dimensional rules */
kind *LP_kind_specified; /* what kind this sentence specifies */
#line 1389 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *LiteralPatterns__new_literal_specification_inner(parse_node *p, parse_node *q,
literal_pattern *owner) {
int scaled = 1, scaled_dir = LP_SCALED_UP, offset = 0, integer_scaling = TRUE;
parse_node *part_np_list = NULL;
kind *K = NULL;
literal_pattern *lp = NULL; /* what we will create, if all goes well */
int notation_options = 0; literal_pattern_name *notation_groups = NULL;
wording SPW = ParseTree__get_text(p);
{
#line 1453 "inform7/Chapter 10/Literal Patterns.w"
LP_scaling = LP_SCALED_UP; LP_scaling_amount = 1; LP_real_scaling_amount = 1.0;
LP_real_equivalent = 0.0; LP_equivalent_value = NULL;
LP_real_offset = 0.0; LP_offset_value = NULL;
LP_to_real = FALSE;
Preform__parse_nt_against_word_range(specifies_sentence_subject_NTM, SPW, NULL, NULL);
SPW = GET_RW(specifies_sentence_subject_NTM, 1);
notation_options = most_recent_result;
if (notation_options & ABANDON_LPN) return owner;
notation_groups = NULL;
if (notation_options) notation_groups = most_recent_result_p;
}
#line 1398 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1550 "inform7/Chapter 10/Literal Patterns.w"
LP_offset_value = NULL;
Preform__parse_nt_against_word_range(specifies_sentence_object_NTM, ParseTree__get_text(q), NULL, NULL);
switch (most_recent_result) {
case PARTS_LPC: part_np_list = most_recent_result_p; break;
case SCALING_LPC: scaled = LP_scaling_amount; scaled_dir = LP_scaling; break;
}
K = LP_kind_specified;
if (K == NULL) return owner;
}
#line 1399 "inform7/Chapter 10/Literal Patterns.w"
;
if (Kinds__FloatingPoint__uses_floating_point(K)) integer_scaling = FALSE;
if ((LP_to_real) && (integer_scaling))
{
#line 1706 "inform7/Chapter 10/Literal Patterns.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(PM_LPNeedsReal));
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend to give a real "
"number as a scale factor for values of %2. However, as you've "
"defined it here, %2 uses only whole numbers, so this wouldn't "
"work. %PYou can probably fix this by making the example "
"amount a real number too - say, writing '1.0 rel specifies...' "
"instead of '1 rel specifies...'.");
Problems__issue_problem_end();
return owner;
}
#line 1403 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1722 "inform7/Chapter 10/Literal Patterns.w"
if (notation_options == TIMES_LPN) {
Kinds__Dimensions__dim_set_multiplication(LP_left_kind, LP_right_kind, K);
return owner;
}
}
#line 1405 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1686 "inform7/Chapter 10/Literal Patterns.w"
waive_lp_overflows = TRUE;
kind *K = NULL; if (Preform__parse_nt_against_word_range(s_literal_NTM, SPW, NULL, NULL)) K = Rvalues__to_kind(most_recent_result_p);
waive_lp_overflows = FALSE;
if (K) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__quote_wording(3, SPW);
Problems__Issue__handmade_problem(_p_(PM_DuplicateUnitSpec));
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend to give a new meaning "
"to expressions like '%3', but this is already something I "
"recognise - specifying %2 - so a more distinctive specification "
"must be chosen.");
Problems__issue_problem_end();
return owner;
}
}
#line 1406 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1731 "inform7/Chapter 10/Literal Patterns.w"
if (Kinds__Behaviour__is_built_in(K)) {
if (Kinds__Behaviour__get_index_priority(K) == 0)
Problems__Issue__sentence_problem(_p_(PM_LPBuiltInKOVHidden),
"you can only specify ways to write new kinds of value",
"as created with sentences like 'A weight is a kind of value.', "
"and not the built-in ones like 'number' or 'time'. (This one is "
"a kind used behind the scenes by Inform, so it's reserved "
"for Inform's own use, and you can't do much else with it.)");
else
Problems__Issue__sentence_problem(_p_(PM_LPBuiltInKOV),
"you can only specify ways to write new kinds of value",
"as created with sentences like 'A weight is a kind of value.', "
"and not the built-in ones like 'number' or 'time'.");
return owner;
}
if (Kinds__Behaviour__convert_to_unit(K) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_LPEnumeration),
"this is a kind of value which already has named values",
"so it can't have a basically numerical form as well.");
return owner;
}
}
#line 1407 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1647 "inform7/Chapter 10/Literal Patterns.w"
if (LP_equivalent_value) {
if (Rvalues__is_CONSTANT_of_kind(LP_equivalent_value, K)) {
scaled_dir = LP_SCALED_UP; scaled = Rvalues__to_encoded_notation(LP_equivalent_value);
} else {
Problems__Issue__sentence_problem_with_note(_p_(PM_BadLPEquivalent),
"the equivalent value needs to be a constant of the same kind "
"of value as you are specifying",
"and this seems not to be.",
"Note that you can only use notations specified in sentences "
"before the current one.");
}
}
if (LP_offset_value) {
if (Rvalues__is_CONSTANT_of_kind(LP_offset_value, K)) {
offset = Rvalues__to_encoded_notation(LP_offset_value);
} else {
Problems__Issue__sentence_problem_with_note(_p_(PM_BadLPOffset),
"the offset value needs to be a constant of the same kind "
"of value as you are specifying",
"and this seems not to be.",
"Note that you can only use notations specified in sentences "
"before the current one.");
}
}
}
#line 1408 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1756 "inform7/Chapter 10/Literal Patterns.w"
lp = LiteralPatterns__lp_new(K, SPW);
if (LP_equivalent_value) LP_real_scaling_amount = LP_real_equivalent;
if (scaled <= 0) {
Problems__Issue__sentence_problem(_p_(PM_LPNonpositiveScaling),
"you can only scale by a positive multiple",
"so something like 'scaled up by -1' is not allowed.");
scaled = 1;
}
lp->scaling = Kinds__Scalings__new(integer_scaling, scaled_dir,
scaled, LP_real_scaling_amount, offset, LP_real_offset);
if ((scaled_dir == LP_SCALED_DOWN) && (scaled == 0)) internal_error("Oooops");
if (owner == NULL) lp->primary_alternative = TRUE;
if (LP_equivalent_value) lp->equivalent_unit = TRUE;
if (notation_options & SINGULAR_LPN) lp->singular_form_only = TRUE;
if (notation_options & PLURAL_LPN) lp->plural_form_only = TRUE;
if (notation_options & IN_LPN) {
literal_pattern_name *lpn;
for (lpn = notation_groups; lpn; lpn = lpn->next_with_rp)
lpn->can_use_this_lp = lp;
}
}
#line 1409 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1781 "inform7/Chapter 10/Literal Patterns.w"
int i, j, tc, ec;
for (i=0, tc=0, ec=0; i<Wordings__length(SPW); i++) {
literal_pattern_token new_token;
int digit_found = FALSE;
char *text_of_word = Lexer__word_raw_text(Wordings__first_wn(SPW)+i);
for (j=0; text_of_word[j]; j++) if (isdigit(text_of_word[j])) digit_found = TRUE;
if (digit_found)
{
#line 1810 "inform7/Chapter 10/Literal Patterns.w"
int j, sgn = 1, next_token_begins_word = TRUE;
for (j=0; text_of_word[j]; j++) {
int tot = 0, digit_found = FALSE, point_found = FALSE;
if ((text_of_word[j] == '-') && (isdigit(text_of_word[j+1])) && (ec == 0)) {
sgn = -1; continue;
}
while (isdigit(text_of_word[j++])) {
digit_found = TRUE;
if (tot > 999999999) {
Problems__Issue__sentence_problem(_p_(PM_LPElementTooLarge),
"that specification contains numbers that are too large",
"and would construct values which could not sensibly "
"be stored at run-time.");
return owner;
}
tot = 10*tot + (text_of_word[j-1]-'0');
}
j--;
if ((text_of_word[j] == '.') && (text_of_word[j+1] == '0') && (ec == 0)) {
j += 2; point_found = TRUE;
}
if (digit_found) {
literal_pattern_element new_element = LiteralPatterns__lpe_new(ec, tot+1, sgn);
if (ec >= MAX_ELEMENTS_PER_LITERAL) {
Problems__Issue__sentence_problem(_p_(PM_LPTooManyElements),
"that specification contains too many numerical elements",
"and is too complicated for Inform to handle.");
return owner;
}
new_element.is_real = point_found;
if (point_found) integer_scaling = FALSE;
lp->lp_elements[ec++] = new_element;
if (sgn == -1) lp->number_signed = TRUE;
new_token = LiteralPatterns__lpt_new(ELEMENT_LPT, next_token_begins_word);
{
#line 1861 "inform7/Chapter 10/Literal Patterns.w"
if (tc >= MAX_TOKENS_PER_LITERAL) {
Problems__Issue__sentence_problem(_p_(PM_LPTooComplicated),
"that specification is too complicated",
"and will have to be shortened.");
return owner;
}
lp->lp_tokens[tc++] = new_token;
}
#line 1844 "inform7/Chapter 10/Literal Patterns.w"
;
j--;
} else {
new_token = LiteralPatterns__lpt_new(CHARACTER_LPT, next_token_begins_word);
new_token.token_char = text_of_word[j];
{
#line 1861 "inform7/Chapter 10/Literal Patterns.w"
if (tc >= MAX_TOKENS_PER_LITERAL) {
Problems__Issue__sentence_problem(_p_(PM_LPTooComplicated),
"that specification is too complicated",
"and will have to be shortened.");
return owner;
}
lp->lp_tokens[tc++] = new_token;
}
#line 1849 "inform7/Chapter 10/Literal Patterns.w"
;
}
sgn = 1; next_token_begins_word = FALSE;
}
}
#line 1788 "inform7/Chapter 10/Literal Patterns.w"
else {
new_token = LiteralPatterns__lpt_new(WORD_LPT, TRUE);
new_token.token_wn = Wordings__first_wn(SPW)+i;
{
#line 1861 "inform7/Chapter 10/Literal Patterns.w"
if (tc >= MAX_TOKENS_PER_LITERAL) {
Problems__Issue__sentence_problem(_p_(PM_LPTooComplicated),
"that specification is too complicated",
"and will have to be shortened.");
return owner;
}
lp->lp_tokens[tc++] = new_token;
}
#line 1792 "inform7/Chapter 10/Literal Patterns.w"
;
}
}
lp->no_lp_tokens = tc;
lp->no_lp_elements = ec;
if (lp->no_lp_elements == 0) {
Problems__Issue__sentence_problem(_p_(PM_LPWithoutElement),
"a way to specify a kind of value must involve numbers",
"so '10kg specifies a weight' is allowed, but not 'tonne "
"specifies a weight'.");
return owner;
}
}
#line 1410 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1872 "inform7/Chapter 10/Literal Patterns.w"
if (integer_scaling == FALSE) {
Kinds__Behaviour__convert_to_real(K);
Kinds__Scalings__convert_to_real(&(lp->scaling));
}
}
#line 1411 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1882 "inform7/Chapter 10/Literal Patterns.w"
int i, m = 1;
for (i=lp->no_lp_elements-1; i>=0; i--) {
literal_pattern_element *lpe = &(lp->lp_elements[i]);
lpe->element_multiplier = m;
m = m*(lpe->element_range);
}
}
#line 1412 "inform7/Chapter 10/Literal Patterns.w"
;
if (Kinds__Behaviour__list_of_literal_forms(K) == NULL) lp->benchmark = TRUE;
Kinds__Behaviour__add_literal_pattern(K, lp);
if (part_np_list) {
{
#line 1892 "inform7/Chapter 10/Literal Patterns.w"
int i;
parse_node *p;
for (i=0, p=part_np_list; (i<lp->no_lp_elements) && (p); i++, p = p->next) {
literal_pattern_element *lpe = &(lp->lp_elements[i]);
lpe->element_name = ParseTree__get_text(p);
int O = ParseTree__int_annotation(p, lpe_options_ANNOT);
if (O & OPTIONAL_LSO) lpe->element_optional = TRUE;
if (O & PREAMBLE_OPTIONAL_LSO) {
lpe->element_optional = TRUE; lpe->preamble_optional = TRUE;
}
if (O & WITHOUT_LEADING_ZEROS_LSO) lpe->without_leading_zeros = TRUE;
if ((i == lp->no_lp_elements - 1) && (p->next)) {
Problems__Issue__sentence_problem(_p_(PM_LPTooManyPartNames),
"this gives names for too many parts",
"that is, for more parts than there are in the pattern.");
return owner;
}
for (int j = 0; j<i; j++)
if (Wordings__match(lp->lp_elements[i].element_name, lp->lp_elements[j].element_name))
Problems__Issue__sentence_problem(_p_(PM_LPRepeatedPartNames),
"this repeats a part name",
"that is, it uses the same name for two different parts "
"of the pattern.");
}
if ((i > 0) && (i != lp->no_lp_elements)) {
Problems__Issue__sentence_problem(_p_(PM_LPNotAllNamed),
"you must supply names for all the parts",
"if for any");
return owner;
}
}
#line 1418 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 1927 "inform7/Chapter 10/Literal Patterns.w"
int i, opt_count = 0;
for (i=0; i<lp->no_lp_elements; i++) if (lp->lp_elements[i].element_optional) {
opt_count++;
if (i == 0) {
Problems__Issue__sentence_problem(_p_(PM_LPFirstOptional),
"the first part is not allowed to be optional",
"since it is needed to identify the value.");
return owner;
}
}
if (opt_count >= 2) {
Problems__Issue__sentence_problem(_p_(PM_LPMultipleOptional),
"only one part can be called optional",
"since if any part is omitted then so are all subsequent parts.");
return owner;
}
}
#line 1419 "inform7/Chapter 10/Literal Patterns.w"
;
LiteralPatterns__define_packing_phrases(lp, K);
}
if (owner == NULL) owner = lp;
else
{
#line 1431 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern *alt = owner;
while ((alt) && (alt->next_alternative_lp)) alt = alt->next_alternative_lp;
alt->next_alternative_lp = lp;
}
#line 1424 "inform7/Chapter 10/Literal Patterns.w"
;
return owner;
}
#line 1494 "inform7/Chapter 10/Literal Patterns.w"
int specifies_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TIMES_LPN; LP_left_kind = RP[1]; LP_right_kind = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 1525 "inform7/Chapter 10/Literal Patterns.w"
*X = ABANDON_LPN; *XP = NULL;
if (preform_lookahead_mode == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_MultiplyingNonKOVs),
"only kinds of value can be multiplied here",
"and only in a sentence like 'A length times a length specifies an area.'");
}
}
#line 1497 "inform7/Chapter 10/Literal Patterns.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; *XP = NULL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1499 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_group_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1] | R[2];
{
#line 1518 "inform7/Chapter 10/Literal Patterns.w"
*XP = RP[1];
if (RP[1] == NULL) *XP = RP[2];
else if (RP[2]) ((literal_pattern_name *) RP[1])->next_with_rp = RP[2];
}
#line 1501 "inform7/Chapter 10/Literal Patterns.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1503 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_group_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1507 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_group_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = SINGULAR_LPN; *XP = NULL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = PLURAL_LPN; *XP = NULL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = IN_LPN; *XP = LiteralPatterns__new_lpn(EMPTY_WORDING, RP[1]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = IN_LPN; *XP = LiteralPatterns__new_lpn(W, NULL);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 1535 "inform7/Chapter 10/Literal Patterns.w"
*X = ABANDON_LPN; *XP = NULL;
if (preform_lookahead_mode == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_BadLPNameOption));
Problems__issue_problem_segment(
"In the specification %1, I was expecting that '%2' would be an optional "
"note about one of the notations: it should have been one of 'singular', "
"'plural' or 'in ...'.");
Problems__issue_problem_end();
}
}
#line 1513 "inform7/Chapter 10/Literal Patterns.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1514 "inform7/Chapter 10/Literal Patterns.w"
#line 1564 "inform7/Chapter 10/Literal Patterns.w"
int specifies_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[2]; *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = NULL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1567 "inform7/Chapter 10/Literal Patterns.w"
int kind_specified_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; LP_kind_specified = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 1590 "inform7/Chapter 10/Literal Patterns.w"
if (preform_lookahead_mode == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_LPNotKOV),
"you can only specify ways to write kinds of value",
"as created with sentences like 'A weight is a kind of value.'");
}
}
#line 1570 "inform7/Chapter 10/Literal Patterns.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1571 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_specification_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = PARTS_LPC; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = SCALING_LPC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = SCALING_LPC; LP_real_offset = latest_constructed_real; LP_offset_value = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = OFFSET_LPC; LP_real_offset = latest_constructed_real; LP_offset_value = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = EQUIVALENT_LPC; LP_real_equivalent = latest_constructed_real; LP_equivalent_value = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1578 "inform7/Chapter 10/Literal Patterns.w"
int scaling_instruction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = SCALING_LPC; LP_scaling = LP_SCALED_UP; LP_scaling_amount = R[1]; LP_real_scaling_amount = (double) LP_scaling_amount;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = SCALING_LPC; LP_scaling = LP_SCALED_UP; LP_scaling_amount = 1; LP_real_scaling_amount = latest_constructed_real; LP_to_real = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = SCALING_LPC; LP_scaling = LP_SCALED_DOWN; LP_scaling_amount = R[1]; LP_real_scaling_amount = (double) LP_scaling_amount;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = SCALING_LPC; LP_scaling = LP_SCALED_DOWN; LP_scaling_amount = 1; LP_real_scaling_amount = latest_constructed_real; LP_to_real = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = SCALING_LPC; LP_scaling = LP_SCALED_AT; LP_scaling_amount = R[1]; LP_real_scaling_amount = (double) LP_scaling_amount;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = SCALING_LPC; LP_scaling = LP_SCALED_AT; LP_scaling_amount = 1; LP_real_scaling_amount = latest_constructed_real; LP_to_real = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1586 "inform7/Chapter 10/Literal Patterns.w"
#line 1605 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1]; if (RP[1]) ((parse_node *) RP[1])->next = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1]; if (RP[1]) ((parse_node *) RP[1])->next = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1]; if (RP[1]) ((parse_node *) RP[1])->next = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1610 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1]; if (RP[1]) ParseTree__annotate_int(*XP, lpe_options_ANNOT, R[2]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1614 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_option_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1] | R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1618 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_option_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1622 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_part_option_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = OPTIONAL_LSO;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = PREAMBLE_OPTIONAL_LSO;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = WITHOUT_LEADING_ZEROS_LSO;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 1632 "inform7/Chapter 10/Literal Patterns.w"
*X = 0;
if (preform_lookahead_mode == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_BadLPPartOption));
Problems__issue_problem_segment(
"In the specification %1, I was expecting that '%2' would be an optional "
"note about one of the parts: it should have been one of 'optional', "
"'preamble optional' or 'without leading zeros'.");
Problems__issue_problem_end();
}
}
#line 1627 "inform7/Chapter 10/Literal Patterns.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1628 "inform7/Chapter 10/Literal Patterns.w"
#line 1949 "inform7/Chapter 10/Literal Patterns.w"
int literal_pattern_group_name_NTMR(wording W, int *X, void **XP) {
#line 1950 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_name *lpn;
LOOP_OVER(lpn, literal_pattern_name) {
if (Wordings__match(lpn->notation_name, W)) {
*XP = lpn; return TRUE;
}
}
return FALSE;
}
#line 1966 "inform7/Chapter 10/Literal Patterns.w"
literal_pattern_name *LiteralPatterns__new_lpn(wording W, literal_pattern_name *existing) {
if (preform_lookahead_mode) return NULL;
literal_pattern_name *new = CREATE(literal_pattern_name);
new->notation_name = W;
new->can_use_this_lp = NULL;
new->next = NULL;
new->next_with_rp = NULL;
if (existing) {
while ((existing) && (existing->next)) existing = existing->next;
existing->next = new;
}
return new;
}
#line 1986 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__define_named_phrases(void) {
literal_pattern_name *lpn;
LOOP_OVER(lpn, literal_pattern_name)
lpn->lpn_compiled_already = FALSE;
LOOP_OVER(lpn, literal_pattern_name) {
if (Wordings__nonempty(lpn->notation_name)) {
literal_pattern_name *lpn2;
for (lpn2 = lpn; lpn2; lpn2 = lpn2->next)
if (lpn2->lpn_compiled_already == FALSE)
{
#line 2015 "inform7/Chapter 10/Literal Patterns.w"
kind *K = lpn2->can_use_this_lp->kind_specified;
TEMPORARY_STREAM;
Kinds__Textual__write(TEMP, K);
feed_t id = Feeds__begin();
Feeds__feed_text("To say ( val - ");
Feeds__feed_text(STREAM_TEXT(TEMP));
Feeds__feed_text(" ) ");
Feeds__feed_wording(lpn->notation_name);
wording XW = Feeds__end(id);
Sentences__make_node(XW, ':');
id = Feeds__begin();
char print_rule_buff[1024];
sprintf(print_rule_buff, " (- %s({val}, %d); -) ",
Kinds__Behaviour__get_name_of_printing_rule(K), lpn->allocation_id + 1);
Feeds__feed_text(print_rule_buff);
XW = Feeds__end(id);
Sentences__make_node(XW, '.');
CLOSE_TEMPORARY_STREAM;
literal_pattern_name *lpn3;
for (lpn3 = lpn2; lpn3; lpn3 = lpn3->next)
if (Kinds__Compare__eq(K, lpn3->can_use_this_lp->kind_specified))
lpn3->lpn_compiled_already = TRUE;
}
#line 1995 "inform7/Chapter 10/Literal Patterns.w"
;
}
}
Sentences__RuleSubtrees__register_recently_lexed_phrases();
}
#line 2046 "inform7/Chapter 10/Literal Patterns.w"
void LiteralPatterns__define_packing_phrases(literal_pattern *lp, kind *K) {
TEMPORARY_STREAM;
Kinds__Textual__write(TEMP, K);
{
#line 2069 "inform7/Chapter 10/Literal Patterns.w"
int i;
for (i=0; i<lp->no_lp_elements; i++) {
literal_pattern_element *lpe = &(lp->lp_elements[i]);
feed_t id = Feeds__begin();
Feeds__feed_text("To decide which number is ");
Feeds__feed_wording(lpe->element_name);
Feeds__feed_text(" part of ( full - ");
Feeds__feed_text(STREAM_TEXT(TEMP));
Feeds__feed_text(" ) ");
wording XW = Feeds__end(id);
Sentences__make_node(XW, ':');
id = Feeds__begin();
char print_rule_buff[1024];
if (i==0)
sprintf(print_rule_buff, " (- ({full}/%d) -) ", lpe->element_multiplier);
else if (lpe->element_multiplier > 1)
sprintf(print_rule_buff, " (- (({full}/%d)%%%d) -) ",
lpe->element_multiplier, lpe->element_range);
else
sprintf(print_rule_buff, " (- ({full}%%%d) -) ", lpe->element_range);
Feeds__feed_text(print_rule_buff);
XW = Feeds__end(id);
if (Wordings__phrasual_length(XW) >= MAX_WORDS_PER_PHRASE + 5)
{
#line 2147 "inform7/Chapter 10/Literal Patterns.w"
Problems__Issue__sentence_problem(_p_(PM_LPPartNamesTooLong),
"the names for these parts are too long",
"and will have to be cut down.");
}
#line 2094 "inform7/Chapter 10/Literal Patterns.w"
else
Sentences__make_node(XW, '.');
}
}
#line 2049 "inform7/Chapter 10/Literal Patterns.w"
;
{
#line 2106 "inform7/Chapter 10/Literal Patterns.w"
if (lp->no_lp_elements > 0) {
feed_t id = Feeds__begin();
char print_rule_buff[1024];
Feeds__feed_text("To decide which ");
Feeds__feed_text(STREAM_TEXT(TEMP));
Feeds__feed_text(" is ");
Feeds__feed_text(STREAM_TEXT(TEMP));
Feeds__feed_text(" with ");
for (int i=0; i<lp->no_lp_elements; i++) {
literal_pattern_element *lpe = &(lp->lp_elements[i]);
sprintf(print_rule_buff, " part%d ", i);
Feeds__feed_wording(lpe->element_name);
Feeds__feed_text(" part ( ");
Feeds__feed_text(print_rule_buff);
Feeds__feed_text(" - a number ) ");
}
wording XW = Feeds__end(id);
if (Wordings__phrasual_length(XW) >= MAX_WORDS_PER_PHRASE + 5)
{
#line 2147 "inform7/Chapter 10/Literal Patterns.w"
Problems__Issue__sentence_problem(_p_(PM_LPPartNamesTooLong),
"the names for these parts are too long",
"and will have to be cut down.");
}
#line 2124 "inform7/Chapter 10/Literal Patterns.w"
else {
Sentences__make_node(XW, ':');
id = Feeds__begin();
sprintf(print_rule_buff, " (- (");
for (int i=0; i<lp->no_lp_elements; i++) {
literal_pattern_element *lpe = &(lp->lp_elements[i]);
if (i>0) sprintf(print_rule_buff+Platform__strlen(print_rule_buff), "+");
if (lpe->element_multiplier != 1)
sprintf(print_rule_buff+Platform__strlen(print_rule_buff), "%d*",
lpe->element_multiplier);
sprintf(print_rule_buff+Platform__strlen(print_rule_buff), "{part%d}", i);
}
sprintf(print_rule_buff+Platform__strlen(print_rule_buff), ") -) ");
Feeds__feed_text(print_rule_buff);
XW = Feeds__end(id);
Sentences__make_node(XW, '.');
}
}
}
#line 2050 "inform7/Chapter 10/Literal Patterns.w"
;
Sentences__RuleSubtrees__register_recently_lexed_phrases();
CLOSE_TEMPORARY_STREAM;
}
#line 44 "inform7/Chapter 10/Times of Day.w"
void PL__TimesOfDay__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL__TimesOfDay__times_new_base_kind_notify);
}
#line 51 "inform7/Chapter 10/Times of Day.w"
int PL__TimesOfDay__times_new_base_kind_notify(kind *new_base, char *name, wording W) {
if ((name) && (strcmp(name, "TIME_TY") == 0)) {
K_time = new_base; return TRUE;
}
return FALSE;
}
#line 61 "inform7/Chapter 10/Times of Day.w"
kind *PL__TimesOfDay__kind(void) {
return K_time;
}
#line 71 "inform7/Chapter 10/Times of Day.w"
int s_literal_time_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Rvalues__from_time(-R[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Rvalues__from_time(R[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = Rvalues__from_time(R[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 75 "inform7/Chapter 10/Times of Day.w"
int elapsed_time_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 60*R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 60*R[1]+R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 80 "inform7/Chapter 10/Times of Day.w"
int clock_time_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 96 "inform7/Chapter 10/Times of Day.w"
int time_cycles = 12*60*R[2];
int t = R[1], time_hours, time_minutes;
if (R[0] == 0) { time_hours = t; time_minutes = 0; }
else { time_hours = t/60; time_minutes = t%60; }
if ((time_hours == 0) && (time_cycles > 0)) return FALSE; /* reject for example "0:01 PM" */
if (time_hours == 12) time_hours = 0; /* allow for example "12:01 AM" */
*X = time_minutes + 60*time_hours + time_cycles;
}
#line 82 "inform7/Chapter 10/Times of Day.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 96 "inform7/Chapter 10/Times of Day.w"
int time_cycles = 12*60*R[2];
int t = R[1], time_hours, time_minutes;
if (R[0] == 0) { time_hours = t; time_minutes = 0; }
else { time_hours = t/60; time_minutes = t%60; }
if ((time_hours == 0) && (time_cycles > 0)) return FALSE; /* reject for example "0:01 PM" */
if (time_hours == 12) time_hours = 0; /* allow for example "12:01 AM" */
*X = time_minutes + 60*time_hours + time_cycles;
}
#line 83 "inform7/Chapter 10/Times of Day.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 84 "inform7/Chapter 10/Times of Day.w"
int am_pm_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 88 "inform7/Chapter 10/Times of Day.w"
#line 111 "inform7/Chapter 10/Times of Day.w"
int digital_clock_time_NTMR(wording W, int *X, void **XP) {
#line 112 "inform7/Chapter 10/Times of Day.w"
int time_minutes = 0, time_hours = 0;
int ratchet = 0, t, colons = 0, digits = 0;
char *wd = Lexer__word_text(Wordings__first_wn(W));
for (t=0; wd[t]; t++) {
if (((t==1) || (t==2)) && (wd[t] == ':') && (wd[t+1])) {
if (ratchet >= 24) return FALSE;
time_hours = ratchet;
ratchet = 0; digits = 0;
colons++;
} else if (isdigit(wd[t])) {
ratchet = 10*ratchet + (wd[t]-'0'); digits++;
if ((ratchet >= 60) || (digits > 2)) return FALSE;
} else return FALSE;
}
if (colons != 1) return FALSE;
time_minutes = ratchet;
if ((time_hours < 0) || (time_hours > 12)) return FALSE;
if ((time_minutes < 0) || (time_minutes >= 60)) return FALSE;
*X = time_minutes + time_hours*60;
return TRUE;
}
#line 139 "inform7/Chapter 10/Times of Day.w"
int continental_clock_time_NTMR(wording W, int *X, void **XP) {
#line 140 "inform7/Chapter 10/Times of Day.w"
int time_minutes = 0, time_hours = 0;
int ratchet = 0, t, colons = 0, digits = 0;
char *wd = Lexer__word_text(Wordings__first_wn(W));
for (t=0; wd[t]; t++) {
if (((t==1) || (t==2)) && (wd[t] == 'h') && (wd[t+1])) {
if (ratchet >= 24) return FALSE;
time_hours = ratchet;
ratchet = 0; digits = 0;
colons++;
} else if (isdigit(wd[t])) {
ratchet = 10*ratchet + (wd[t]-'0'); digits++;
if ((ratchet >= 60) || (digits > 2)) return FALSE;
} else return FALSE;
}
if (colons != 1) return FALSE;
time_minutes = ratchet;
if ((time_hours < 0) || (time_hours > 12)) return FALSE;
if ((time_minutes < 0) || (time_minutes >= 60)) return FALSE;
*X = time_minutes + time_hours*60;
return TRUE;
}
#line 167 "inform7/Chapter 10/Times of Day.w"
int event_rule_preamble_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = NO_FIXED_TIME;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 176 "inform7/Chapter 10/Times of Day.w"
Problems__Issue__sentence_problem(_p_(PM_AtTimeThat),
"this seems to use 'that' where it should use 'when'",
"assuming it's trying to apply a rule to an event. (The convention is "
"that any rule beginning 'At' is a timed one. The time can either be a "
"fixed time, as in 'At 11:10 AM: ...', or the time when some named "
"event takes place, as in 'At the time when the clock chimes: ...'.)");
}
#line 170 "inform7/Chapter 10/Times of Day.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 186 "inform7/Chapter 10/Times of Day.w"
Problems__Issue__sentence_problem(_p_(PM_AtWithoutTime),
"'at' what time? No description of a time is given",
"which means that this rule can never have effect. (The convention is "
"that any rule beginning 'At' is a timed one. The time can either be a "
"fixed time, as in 'At 11:10 AM: ...', or the time when some named "
"event takes place, as in 'At the time when the clock chimes: ...'.)");
}
#line 171 "inform7/Chapter 10/Times of Day.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 172 "inform7/Chapter 10/Times of Day.w"
#line 138 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning *Semantics__Nouns__ExcerptMeanings__new(unsigned int mc, general_pointer data) {
excerpt_meaning *em = CREATE(excerpt_meaning);
em->meaning_code = mc;
em->data = data;
em->no_em_tokens = 0;
em->excerpt_hash = 0;
em->registered_as_noun = FALSE;
return em;
}
#line 151 "inform7/Chapter 10/Excerpt Meanings.w"
general_pointer Semantics__Nouns__ExcerptMeanings__data(excerpt_meaning *em) {
return em->data;
}
#line 159 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__log_meaning_code(unsigned int mc) {
int i, f = FALSE;
unsigned int j;
for (i=0, j=1; i<31; i++, j*=2)
if (mc & j) {
if (f) LOG(" + "); f = TRUE;
switch (j) {
case ACTION_PARTICIPLE_MC: LOG("ACTION_PARTICIPLE_MC"); break;
case ACTIVITY_MC: LOG("ACTIVITY_MC"); break;
case ADJECTIVE_MC: LOG("ADJECTIVE_MC"); break;
case COND_PHRASE_MC: LOG("COND_PHRASE_MC"); break;
case EQUATION_MC: LOG("EQUATION_MC"); break;
case I6_MC: LOG("I6_MC"); break;
case ING_MC: LOG("ING_MC"); break;
case KIND_FAST_MC: LOG("KIND_FAST_MC"); break;
case KIND_SLOW_MC: LOG("KIND_SLOW_MC"); break;
case MISCELLANEOUS_MC: LOG("MISCELLANEOUS_MC"); break;
case NAMED_AP_MC: LOG("NAMED_AP_MC"); break;
case NAMED_CONSTANT_MC: LOG("NAMED_CONSTANT_MC"); break;
case NAMETAG_MC: LOG("NAMETAG_MC"); break;
case NUMBER_MC: LOG("NUMBER_MC"); break;
case ORDINAL_MC: LOG("ORDINAL_MC"); break;
case PHRASE_CONSTANT_MC: LOG("PHRASE_CONSTANT_MC"); break;
case PREPOSITION_MC: LOG("PREPOSITION_MC"); break;
case PROPERTY_MC: LOG("PROPERTY_MC"); break;
case RULE_MC: LOG("RULE_MC"); break;
case RULEBOOK_MC: LOG("RULEBOOK_MC"); break;
case SAY_PHRASE_MC: LOG("SAY_PHRASE_MC"); break;
case TABLE_COLUMN_MC: LOG("TABLE_COLUMN_MC"); break;
case TABLE_MC: LOG("TABLE_MC"); break;
case TEXT_MC: LOG("TEXT_MC"); break;
case TEXTWITHSUBS_MC: LOG("TEXTWITHSUBS_MC"); break;
case VALUE_PHRASE_MC: LOG("VALUE_PHRASE_MC"); break;
case VARIABLE_MC: LOG("VARIABLE_MC"); break;
case VOID_PHRASE_MC: LOG("VOID_PHRASE_MC"); break;
default: LOG("<unknown-mc>"); break;
}
}
}
#line 202 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__log(excerpt_meaning *em) {
int i;
if (em == NULL) { LOG("<null-em>"); return; }
LOG("{");
for (i=0; i<em->no_em_tokens; i++) {
if (i>0) LOG(" ");
if (em->em_tokens[i] == NULL) { LOG("#"); continue; }
if (Vocabulary__get_exemplar(em->em_tokens[i], FALSE) == NULL)
internal_error("Null token in EM");
LOG("%s", Vocabulary__get_exemplar(em->em_tokens[i], FALSE));
}
LOG(" = $N", em->meaning_code);
LOG("}");
}
void Semantics__Nouns__ExcerptMeanings__log_all(void) {
int i = 0;
excerpt_meaning *em;
LOOP_OVER(em, excerpt_meaning)
LOG("%02d: %08x $M\n", i++, (pointer_sized_int) em, em);
}
#line 246 "inform7/Chapter 10/Excerpt Meanings.w"
int cached_hash_w1 = -2, cached_hash_w2 = -2, cached_value;
int Semantics__Nouns__ExcerptMeanings__hash_code(int w1, int w2) {
int i, h = 0; vocabulary_entry *v;
if ((w1 == cached_hash_w1) && (w2 == cached_hash_w2)) return cached_value;
for (i=w1; i<=w2; i++) {
v = Lexer__word(i);
if (v)
{
#line 300 "inform7/Chapter 10/Excerpt Meanings.w"
if ((v->flags) & NUMBER_MC) h = h | 1;
else if ((v->flags) & TEXT_MC) h = h | 2;
else if ((v->flags) & I6_MC) h = h | 4;
else h = h | (8 << ((v->hash) % 27));
}
#line 253 "inform7/Chapter 10/Excerpt Meanings.w"
;
}
return h;
}
#line 275 "inform7/Chapter 10/Excerpt Meanings.w"
void Semantics__Nouns__ExcerptMeanings__hash_code_from_token_list(excerpt_meaning *em) {
int i, h = 0;
if (em->no_em_tokens == 0) internal_error("Empty text when registering");
if ((em->no_em_tokens >= 1) && (em->em_tokens[0])) {
vocabulary_entry *lcf = Vocabulary__get_lower_case_form(em->em_tokens[0]);
if (lcf) {
h = h | CAPITALISED_VARIANT_FORM;
em->em_tokens[0] = lcf;
}
}
for (i=0; i<em->no_em_tokens; i++) {
vocabulary_entry *v = em->em_tokens[i];
if (v)
{
#line 300 "inform7/Chapter 10/Excerpt Meanings.w"
if ((v->flags) & NUMBER_MC) h = h | 1;
else if ((v->flags) & TEXT_MC) h = h | 2;
else if ((v->flags) & I6_MC) h = h | 4;
else h = h | (8 << ((v->hash) % 27));
}
#line 287 "inform7/Chapter 10/Excerpt Meanings.w"
;
}
em->excerpt_hash = h;
}
#line 368 "inform7/Chapter 10/Excerpt Meanings.w"
parse_node *blank_says_p = NULL;
void Semantics__Nouns__ExcerptMeanings__register_em(unsigned int meaning_code, excerpt_meaning *em) {
SParser__warn_expression_cache(); /* the existence of new meanings jeopardises any cached parsing results */
{
#line 399 "inform7/Chapter 10/Excerpt Meanings.w"
Semantics__Nouns__ExcerptMeanings__hash_code_from_token_list(em);
}
#line 372 "inform7/Chapter 10/Excerpt Meanings.w"
;
{
#line 415 "inform7/Chapter 10/Excerpt Meanings.w"
int i;
for (i=0; i<em->no_em_tokens; i++)
if (em->em_tokens[i])
((em->em_tokens[i])->flags) |= meaning_code;
}
#line 373 "inform7/Chapter 10/Excerpt Meanings.w"
;
LOGIF(EXCERPT_MEANINGS,
"Logging meaning: $M with hash %08x, mc=%d, %d tokens\n",
em, em->excerpt_hash, meaning_code, em->no_em_tokens);
if (meaning_code & SUBSET_PARSING_BITMAP) {
{
#line 425 "inform7/Chapter 10/Excerpt Meanings.w"
int i;
for (i=0; i<em->no_em_tokens; i++) {
vocabulary_entry *v = em->em_tokens[i];
if (v == NULL) {
LOG("Logging meaning: $M with hash %08x\n", em, em->excerpt_hash);
internal_error("# in registration of subset meaning");
}
if (Preform__test_vocabulary(v, article_NTM)) continue;
parse_node *p = ParseTree__new_from_em(em);
p->next_alternative = v->subset_list;
v->subset_list = p;
v->subset_list_length++;
}
}
#line 380 "inform7/Chapter 10/Excerpt Meanings.w"
;
} else if ((em->no_em_tokens == 1) && (em->em_tokens[0] == NULL) &&
(meaning_code == SAY_PHRASE_MC)) {
{
#line 443 "inform7/Chapter 10/Excerpt Meanings.w"
parse_node *p = ParseTree__new_from_em(em);
if (blank_says_p) {
parse_node *p2 = blank_says_p;
while (p2->next_alternative) p2 = p2->next_alternative;
p2->next_alternative = p;
}
else blank_says_p = p;
LOGIF(EXCERPT_MEANINGS,
"The blank list with $M is now:\n$T", em, blank_says_p);
}
#line 383 "inform7/Chapter 10/Excerpt Meanings.w"
;
} else if (em->em_tokens[0]) {
{
#line 456 "inform7/Chapter 10/Excerpt Meanings.w"
parse_node *p = ParseTree__new_from_em(em);
p->next_alternative = em->em_tokens[0]->start_list;
em->em_tokens[0]->start_list = p;
}
#line 385 "inform7/Chapter 10/Excerpt Meanings.w"
;
} else if (em->em_tokens[em->no_em_tokens-1]) {
{
#line 463 "inform7/Chapter 10/Excerpt Meanings.w"
parse_node *p = ParseTree__new_from_em(em);
p->next_alternative = em->em_tokens[em->no_em_tokens-1]->end_list;
em->em_tokens[em->no_em_tokens-1]->end_list = p;
}
#line 387 "inform7/Chapter 10/Excerpt Meanings.w"
;
} else {
int i;
for (i=1; i<em->no_em_tokens-1; i++)
if (em->em_tokens[i]) {
{
#line 470 "inform7/Chapter 10/Excerpt Meanings.w"
parse_node *p = ParseTree__new_from_em(em);
p->next_alternative = em->em_tokens[i]->middle_list;
em->em_tokens[i]->middle_list = p;
}
#line 391 "inform7/Chapter 10/Excerpt Meanings.w"
; break; }
if (i >= em->no_em_tokens-1) internal_error("registered meaning of two or more #s");
}
}
#line 479 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning *Semantics__Nouns__ExcerptMeanings__register(
unsigned int meaning_code, wording W, general_pointer data) {
if (Wordings__empty(W)) internal_error("tried to register empty excerpt meaning");
if (meaning_code == NAMETAG_MC)
LOOP_THROUGH_WORDING(i, W)
Preform__mark_word(i, s_instance_name_NTM);
if (meaning_code == KIND_SLOW_MC)
LOOP_THROUGH_WORDING(i, W)
Preform__mark_word(i, k_kind_NTM);
excerpt_meaning *em = Semantics__Nouns__ExcerptMeanings__new(meaning_code, data);
{
#line 510 "inform7/Chapter 10/Excerpt Meanings.w"
if ((meaning_code & PARAMETRISED_PARSING_BITMAP) == 0)
if (Preform__test_word(Wordings__first_wn(W), article_NTM)) {
W = Wordings__trim_first_word(W);
if (Wordings__empty(W))
internal_error("registered a meaning which was only an article");
}
}
#line 491 "inform7/Chapter 10/Excerpt Meanings.w"
;
if (meaning_code == SAY_PHRASE_MC)
{
#line 534 "inform7/Chapter 10/Excerpt Meanings.w"
char *tx = Lexer__word_raw_text(Wordings__first_wn(W));
if ((tx[0]) && ((isupper(tx[0])) || (tx[1] == 0))) {
vocabulary_entry *ucf = Vocabulary__make_case_sensitive(Lexer__word(Wordings__first_wn(W)));
if (!isupper(tx[0])) ucf = Vocabulary__get_lower_case_form(ucf);
Lexer__set_word(Wordings__first_wn(W), ucf);
LOGIF(EXCERPT_MEANINGS,
"Allowing initial capitalised word %s: meaning_code = %08x\n",
tx, meaning_code);
}
}
#line 494 "inform7/Chapter 10/Excerpt Meanings.w"
;
{
#line 556 "inform7/Chapter 10/Excerpt Meanings.w"
int tc = 0;
for (int i=0; i < Wordings__length(W); i++) {
if (tc >= MAX_TOKENS_PER_EXCERPT_MEANING) {
{
#line 625 "inform7/Chapter 10/Excerpt Meanings.w"
Problems__Issue__sentence_problem(_p_(PM_TooLongName),
"that seems to involve far too long a name",
"since in general names are limited to a maximum of 32 words.");
}
#line 559 "inform7/Chapter 10/Excerpt Meanings.w"
;
break;
}
if (compare_word(Wordings__first_wn(W) + i, OPENBRACKET_V)) {
em->em_tokens[tc++] = NULL;
{
#line 573 "inform7/Chapter 10/Excerpt Meanings.w"
int bl = 1; i++;
while (bl > 0) {
if (i >= Wordings__length(W)) {
LOG("Bad meaning: <$w>\n", W);
internal_error("Bracket mismatch when registering");
}
if (compare_word(Wordings__first_wn(W) + i, OPENBRACKET_V)) bl++;
if (compare_word(Wordings__first_wn(W) + i, CLOSEBRACKET_V)) bl--;
i++;
}
if ((i < Wordings__length(W)) && (compare_word(Wordings__first_wn(W) + i, OPENBRACKET_V))) {
LOG("Bad meaning: <$w>\n", W);
internal_error("Two consecutive bracketed tokens when registering");
}
i--;
}
#line 564 "inform7/Chapter 10/Excerpt Meanings.w"
;
} else em->em_tokens[tc++] = Lexer__word(Wordings__first_wn(W) + i);
}
em->no_em_tokens = tc;
}
#line 496 "inform7/Chapter 10/Excerpt Meanings.w"
;
Semantics__Nouns__ExcerptMeanings__register_em(meaning_code, em);
if ((Preform__parse_nt_against_word_range(notable_player_variables_NTM, W, NULL, NULL)) && (most_recent_result == 0)
&& (meaning_code & VARIABLE_MC)) meaning_of_player = RETRIEVE_POINTER_parse_node(data);
return em;
}
#line 598 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning *Semantics__Nouns__ExcerptMeanings__register_assemblage(
unsigned int meaning_code, word_assemblage wa, general_pointer data) {
excerpt_meaning *em = Semantics__Nouns__ExcerptMeanings__new(meaning_code, data);
vocabulary_entry **array; int len;
WordAssemblages__as_array(&wa, &array, &len);
int i, tc = 0;
for (i=0; i<len; i++) {
if (tc >= MAX_TOKENS_PER_EXCERPT_MEANING) {
{
#line 625 "inform7/Chapter 10/Excerpt Meanings.w"
Problems__Issue__sentence_problem(_p_(PM_TooLongName),
"that seems to involve far too long a name",
"since in general names are limited to a maximum of 32 words.");
}
#line 608 "inform7/Chapter 10/Excerpt Meanings.w"
;
break;
}
em->em_tokens[tc++] = array[i];
}
em->no_em_tokens = tc;
Semantics__Nouns__ExcerptMeanings__register_em(meaning_code, em);
return em;
}
#line 634 "inform7/Chapter 10/Excerpt Meanings.w"
excerpt_meaning *Semantics__Nouns__ExcerptMeanings__register_noun(
unsigned int meaning_code, wording W, parse_node *value) {
excerpt_meaning *em = Semantics__Nouns__ExcerptMeanings__register(
meaning_code, W, STORE_POINTER_parse_node(value));
em->registered_as_noun = TRUE;
return em;
}
excerpt_meaning *Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(
unsigned int meaning_code, word_assemblage wa, parse_node *value) {
excerpt_meaning *em = Semantics__Nouns__ExcerptMeanings__register_assemblage(
meaning_code, wa, STORE_POINTER_parse_node(value));
em->registered_as_noun = TRUE;
return em;
}
#line 12 "inform7/Chapter 10/Unicode Translations.w"
sentence_handler TRANSLATESU_SH_handler =
{ SENTENCE_NT, TRANSLATESU_VB, 2, UnicodeTranslations__unicode_translates };
void UnicodeTranslations__unicode_translates(parse_node *pn) {
if (Preform__parse_nt_against_word_range(translates_into_unicode_sentence_object_NTM, ParseTree__get_text(pn->down->next->next), NULL, NULL) == FALSE) return;
int cc = most_recent_result;
if (UnicodeTranslations__char_in_range(cc) == FALSE) return;
Preform__parse_nt_against_word_range(translates_into_unicode_sentence_subject_NTM, ParseTree__get_text(pn->down->next), NULL, NULL);
if ((most_recent_result != -1) && (most_recent_result != cc)) {
Problems__Issue__sentence_problem(_p_(PM_UnicodeAlready),
"this Unicode character name has already been translated",
"so there must be some duplication somewhere.");
return;
}
Semantics__Nouns__ExcerptMeanings__register_noun(
MISCELLANEOUS_MC,
ParseTree__get_text(pn->down->next),
Sentences__NPs__new_raw(ParseTree__get_text(pn->down->next->next)));
}
#line 44 "inform7/Chapter 10/Unicode Translations.w"
int translates_into_unicode_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = -1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 47 "inform7/Chapter 10/Unicode Translations.w"
#line 54 "inform7/Chapter 10/Unicode Translations.w"
int translates_into_unicode_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 61 "inform7/Chapter 10/Unicode Translations.w"
Problems__Issue__sentence_problem(_p_(PM_UnicodeNonLiteral),
"a Unicode character name must be translated into a literal decimal "
"number written out in digits",
"which this seems not to be.");
return FALSE;
}
#line 56 "inform7/Chapter 10/Unicode Translations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 57 "inform7/Chapter 10/Unicode Translations.w"
#line 77 "inform7/Chapter 10/Unicode Translations.w"
int s_unicode_character_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Rvalues__from_Unicode_point(R[1], W); if (!(UnicodeTranslations__char_in_range(R[1]))) return FALSE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Rvalues__from_Unicode_point(R[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 80 "inform7/Chapter 10/Unicode Translations.w"
int unicode_character_name_NTMR(wording W, int *X, void **XP) {
#line 82 "inform7/Chapter 10/Unicode Translations.w"
parse_node *p = SParser__parse_excerpt(MISCELLANEOUS_MC, W);
if ((p) && (ParseTree__get_type(p) == PROPER_NOUN_NT)) {
*X = Vocabulary__get_literal_number_value(Lexer__word(Wordings__first_wn(ParseTree__get_text(p))));
return TRUE;
}
return FALSE;
}
#line 93 "inform7/Chapter 10/Unicode Translations.w"
int UnicodeTranslations__char_in_range(int cc) {
if ((cc < 0) || (cc >= 0x10000)) {
Problems__Issue__sentence_problem(_p_(PM_UnicodeOutOfRange),
"Inform can only handle Unicode characters in the 16-bit range",
"from 0 to 65535.");
return FALSE;
}
return TRUE;
}
#line 61 "inform7/Chapter 10/Nametags.w"
individual_name *Nametags__add_to_nametag_and_reg(nametag *t,
wording W, natural_language *foreign_language, int gender, int number, int options) {
individual_name *in = Clusters__add(t->names, W, foreign_language, gender, number,
(options & REGISTER_PLURAL_NTOPT)?TRUE:FALSE);
for (; in; in = in->next)
if ((options & REGISTER_SINGULAR_NTOPT) && (t->registration_category != NAMETAG_HAS_NO_MC)) {
excerpt_meaning *em = Nametags__register_nametag(in->name, t, foreign_language);
Clusters__set_principal_meaning(in, em);
}
return in;
}
#line 91 "inform7/Chapter 10/Nametags.w"
nametag *Nametags__new(wording W, general_pointer owner, int p, int options,
unsigned int mc, natural_language *foreign_language, int gender) {
nametag *t = CREATE(nametag);
t->tagged_to = owner;
t->registration_to = owner;
if (mc == NAMETAG_MC) t->registration_to = STORE_POINTER_nametag(t);
t->registration_category = mc;
t->nt_I6_identifier[0] = 0;
t->range_number = t->allocation_id + 1;
t->search_priority = p;
t->match_exactly = FALSE;
t->names = Clusters__new();
if (options & PARSE_EXACTLY_NTOPT) t->match_exactly = TRUE;
if (Wordings__nonempty(W)) {
Nametags__add_to_nametag_and_reg(t, W, foreign_language, gender, 1, options);
}
if (options & ATTACH_TO_SEARCH_LIST_NTOPT)
{
#line 116 "inform7/Chapter 10/Nametags.w"
Sentences__Headings__disturb();
Sentences__Headings__attach_nametag(t);
Sentences__Headings__verify_divisions();
}
#line 108 "inform7/Chapter 10/Nametags.w"
;
return t;
}
#line 123 "inform7/Chapter 10/Nametags.w"
excerpt_meaning *Nametags__register_nametag(wording W, nametag *t, natural_language *foreign_language) {
if (VALID_POINTER_parse_node(t->registration_to))
return Semantics__Nouns__ExcerptMeanings__register_noun(
t->registration_category, W, RETRIEVE_POINTER_parse_node(t->registration_to));
else
return Semantics__Nouns__ExcerptMeanings__register(
t->registration_category, W, t->registration_to);
}
#line 135 "inform7/Chapter 10/Nametags.w"
void Nametags__log(nametag *t) {
if (t == NULL) { LOG("<untagged>"); return; }
wording W = Nametags__get_name(t, FALSE);
if (Wordings__nonempty(W)) {
LOG("'");
LOOP_THROUGH_WORDING(i, W) {
LOG("%s", Lexer__word_text(i));
if (i < Wordings__last_wn(W)) LOG(" ");
}
LOG("'");
}
}
#line 151 "inform7/Chapter 10/Nametags.w"
wording Nametags__get_name(nametag *t, int plural_flag) {
return Clusters__get_name(t->names, plural_flag);
}
wording Nametags__get_name_in_play(nametag *t, int plural_flag) {
return Clusters__get_name_in_play(t->names, plural_flag);
}
void Nametags__set_plural_name(nametag *t, wording W) {
Clusters__set_plural_name(t->names, W);
}
int Nametags__full_name_includes(nametag *t, vocabulary_entry *wd) {
if (t == NULL) return FALSE;
wording W = Nametags__get_name(t, FALSE);
LOOP_THROUGH_WORDING(i, W)
if (wd == Lexer__word(i))
return TRUE;
return FALSE;
}
#line 175 "inform7/Chapter 10/Nametags.w"
general_pointer Nametags__tag_holder(nametag *t) {
if (t == NULL) return NULL_GENERAL_POINTER;
return t->tagged_to;
}
int Nametags__priority(nametag *t) {
if (t == NULL) return 0;
return t->search_priority;
}
int Nametags__range_number(nametag *t) {
if (t == NULL) return 0;
return t->range_number;
}
void Nametags__set_range_number(nametag *t, int r) {
if (t == NULL) return;
t->range_number = r;
}
int Nametags__exactitude(nametag *t) {
if (t == NULL) return FALSE;
if (use_exact_parsing_option) return TRUE;
return t->match_exactly;
}
excerpt_meaning *Nametags__get_principal_meaning(nametag *t) {
return Clusters__get_principal_meaning(t->names);
}
name_resolution_data *Nametags__name_resolution_data(nametag *t) {
if (t == NULL) internal_error("tried to fetch resolution data for null tag");
return &(t->name_resolution);
}
#line 216 "inform7/Chapter 10/Nametags.w"
char *Nametags__identifier(nametag *t) {
if (t == NULL) return "nothing";
return t->nt_I6_identifier;
}
void Nametags__nametag_compose_identifier(nametag *t, char C, int N) {
wording W = Nametags__get_name(t, FALSE);
char id[32];
if (Wordings__nonempty(W))
Identifiers__compose(id, C, N, W);
else
sprintf(id, "X%d", N);
Nametags__nametag_set_I6_representation(t, id);
}
void Nametags__nametag_set_I6_representation(nametag *t, char *new) {
int i, trim = FALSE;
char *p = t->nt_I6_identifier;
if (*new == '"') { new++; trim = TRUE; }
for (i=0; (i<31) && (new[i]); i++) p[i] = new[i]; p[i] = 0;
if ((trim) && (p[0])) p[Platform__strlen(p)-1] = 0;
}
#line 245 "inform7/Chapter 10/Nametags.w"
void Nametags__name_all(void) {
nametag *nt;
LOOP_OVER(nt, nametag)
Nametags__nametag_compose_identifier(nt,
(nt->search_priority == KIND_PRIORITY)?'K':'I', nt->range_number);
ParseTree__traverse(Nametags__visit_to_name);
}
void Nametags__visit_to_name(parse_node *p) {
if ((ParseTree__get_type(p) == SENTENCE_NT) &&
(ParseTree__int_annotation(p, category_of_I6_translation_ANNOT) == NAMETAG_I6TR))
{
#line 262 "inform7/Chapter 10/Nametags.w"
wording W = Wordings__trim_last_word(ParseTree__get_text(p->down->next));
parse_node *res = SParser__parse_excerpt(NAMETAG_MC, W);
if (res) {
nametag *nt = Nametags__disambiguate(res, MAX_NAMETAG_PRIORITY);
if (nt) Nametags__nametag_set_I6_representation(nt,
Lexer__word_text(Wordings__first_wn(ParseTree__get_text(p->down->next->next))));
} else {
Problems__Issue__sentence_problem(_p_(PM_BadObjectTranslation),
"there is no such object or kind of object",
"so its name will never be translated into an I6 Object or Class identifier "
"in any event.");
}
}
#line 256 "inform7/Chapter 10/Nametags.w"
;
}
#line 290 "inform7/Chapter 10/Nametags.w"
nametag *Nametags__disambiguate(parse_node *p, int priority) {
int candidates = 0; nametag *first_nt = NULL;
for (parse_node *p2 = p; p2; p2 = p2->next_alternative) {
nametag *nt = RETRIEVE_POINTER_nametag(
Semantics__Nouns__ExcerptMeanings__data(ParseTree__get_meaning(p2)));
if ((nt->search_priority >= 1) && (nt->search_priority <= priority)) {
first_nt = nt; candidates++;
}
}
if (candidates <= 1) return first_nt;
Sentences__Headings__construct_nametag_search_list();
nametag *nt;
LOOP_OVER(nt, nametag)
Sentences__Headings__set_nametag_search_score(nt, 0);
for (parse_node *p2 = p; p2; p2 = p2->next_alternative) {
nametag *nt = RETRIEVE_POINTER_nametag(
Semantics__Nouns__ExcerptMeanings__data(ParseTree__get_meaning(p2)));
if ((nt->search_priority >= 1) && (nt->search_priority <= priority))
Sentences__Headings__set_nametag_search_score(nt,
ParseTree__get_score(p2));
}
nametag *best_nt = Sentences__Headings__highest_scoring_nametag_searched();
if (best_nt) return best_nt;
return first_nt;
}
#line 326 "inform7/Chapter 10/Nametags.w"
sentence_handler TRANSLATESL_SH_handler =
{ SENTENCE_NT, TRANSLATESL_VB, 1, Nametags__nl_translates };
#line 335 "inform7/Chapter 10/Nametags.w"
int translates_into_nl_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRANS_KIND; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRANS_INSTANCE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 338 "inform7/Chapter 10/Nametags.w"
#line 342 "inform7/Chapter 10/Nametags.w"
void Nametags__nl_translates(parse_node *pn) {
/* the object */
natural_language *nl = ParseTree__get_defn_language(pn->down->next->next);
int g = ParseTree__int_annotation(pn->down->next->next, gender_reference_ANNOT);
if (nl == NULL) internal_error("No such NL");
if (nl == English_language) {
Problems__Issue__sentence_problem(_p_(PM_CantTranslateIntoEnglish),
"you can't translate into English",
"only out of it.");
return;
}
if ((Preform__parse_nt_against_word_range(translates_into_nl_sentence_subject_NTM, ParseTree__get_text(pn->down->next), NULL, NULL)) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_CantTranslateValue),
"this isn't something which can be translated",
"that is, it isn't a kind.");
return;
}
switch (most_recent_result) {
case TRANS_INSTANCE: {
instance *I = most_recent_result_p;
nametag *t = Instances__get_nametag(I);
if (t == NULL) internal_error("stuck on instance name");
Nametags__add_to_nametag_and_reg(t, ParseTree__get_text(pn->down->next->next), nl, g,
1, REGISTER_SINGULAR_NTOPT);
break;
}
case TRANS_KIND: {
kind *K = most_recent_result_p;
kind_constructor *KC = Kinds__get_construct(K);
if (KC == NULL) internal_error("stuck on kind name");
nametag *t = Kinds__Constructors__get_nametag(KC);
if (t == NULL) internal_error("further stuck on kind name");
Nametags__add_to_nametag_and_reg(t, ParseTree__get_text(pn->down->next->next), nl, g,
1, REGISTER_SINGULAR_NTOPT + REGISTER_PLURAL_NTOPT);
break;
}
default:
internal_error("bad translation category");
}
}
#line 85 "inform7/Chapter 10/Instances.w"
instance *Instances__new(wording W, kind *K) {
PROTECTED_MODEL_PROCEDURE;
{
#line 109 "inform7/Chapter 10/Instances.w"
if (K == NULL) K = K_object;
K = Kinds__weaken(K);
}
#line 87 "inform7/Chapter 10/Instances.w"
;
property *cp = Kinds__Behaviour__get_coinciding_property(K);
instance *I = CREATE(instance);
{
#line 115 "inform7/Chapter 10/Instances.w"
I->creating_sentence = current_sentence;
I->instance_of_set_at = current_sentence;
I->usage_as_aph = NULL;
I->enumeration_index = 0;
I->connection = NULL_GENERAL_POINTER;
I->index_appearances = 0;
I->first_noted_usage = NULL;
I->last_noted_usage = NULL;
I->as_subject = InferenceSubjects__new(Kinds__Behaviour__as_subject(K),
INST_SUB, STORE_POINTER_instance(I), CERTAIN_CE);
}
#line 90 "inform7/Chapter 10/Instances.w"
;
{
#line 141 "inform7/Chapter 10/Instances.w"
int exact_parsing = TRUE, any_parsing = TRUE;
if ((cp) && (Properties__Conditions__of_what(cp))) any_parsing = FALSE;
if (Kinds__Compare__le(K, K_object)) exact_parsing = FALSE;
if (any_parsing) {
if (exact_parsing)
I->tag = Nametags__new(W,
STORE_POINTER_parse_node(Rvalues__from_instance(I)), INSTANCE_PRIORITY,
REGISTER_SINGULAR_NTOPT + PARSE_EXACTLY_NTOPT + ATTACH_TO_SEARCH_LIST_NTOPT,
NAMED_CONSTANT_MC, NULL, NEUTER_GENDER);
else
I->tag = Nametags__new(W,
STORE_POINTER_parse_node(Rvalues__from_instance(I)), INSTANCE_PRIORITY,
REGISTER_SINGULAR_NTOPT + ATTACH_TO_SEARCH_LIST_NTOPT,
NAMETAG_MC, NULL, NEUTER_GENDER);
} else {
I->tag = Nametags__new(W,
NULL_GENERAL_POINTER, INSTANCE_PRIORITY,
REGISTER_SINGULAR_NTOPT + PARSE_EXACTLY_NTOPT + ATTACH_TO_SEARCH_LIST_NTOPT,
NAMETAG_HAS_NO_MC, NULL, NEUTER_GENDER);
}
}
#line 91 "inform7/Chapter 10/Instances.w"
;
Instances__set_kind(I, K);
{
#line 177 "inform7/Chapter 10/Instances.w"
if (!(Kinds__Compare__le(K, K_object))) {
if (Kinds__Behaviour__has_named_constant_values(K) == FALSE)
internal_error("tried to make an instance value for impossible kind");
I->enumeration_index = Kinds__Behaviour__new_enumerated_value(K);
if (cp) Instances__register_as_adjectival_constant(I, cp);
}
}
#line 93 "inform7/Chapter 10/Instances.w"
;
latest_instance = I;
LOGIF(OBJECT_CREATIONS, "Created instance: $O (kind $u)\n", I, K);
Plugins__Call__new_named_instance_notify(I);
if ((Kinds__Compare__eq(K, K_grammatical_gender)) &&
(no_ggs_recorded < NO_GRAMMATICAL_GENDERS))
grammatical_genders[no_ggs_recorded++] = I;
Assertions__Assemblies__satisfies_generalisations(I->as_subject);
return I;
}
#line 187 "inform7/Chapter 10/Instances.w"
parse_node *Instances__get_creating_sentence(instance *I) {
if (I == NULL) return NULL;
return I->creating_sentence;
}
#line 195 "inform7/Chapter 10/Instances.w"
source_file *Instances__get_creating_file(instance *I) {
if (I == NULL) return NULL;
return Lexer__file_of_origin(Wordings__first_wn(ParseTree__get_text(I->creating_sentence)));
}
#line 209 "inform7/Chapter 10/Instances.w"
void Instances__make_kind_coincident(kind *K, property *P) {
Kinds__Behaviour__set_coinciding_property(K, P);
Instances__update_adjectival_forms(P);
}
#line 223 "inform7/Chapter 10/Instances.w"
void Instances__update_adjectival_forms(property *P) {
if (Properties__is_either_or(P) == TRUE) return;
kind *K = Properties__Valued__kind(P);
if (P == Kinds__Behaviour__get_coinciding_property(K)) {
instance *I;
LOOP_OVER_INSTANCES(I, K)
Instances__register_as_adjectival_constant(I, P);
}
}
#line 240 "inform7/Chapter 10/Instances.w"
void Instances__register_as_adjectival_constant(instance *I, property *P) {
property_permission *pp;
LOOP_OVER_PERMISSIONS_FOR_PROPERTY(pp, P) {
inference_subject *infs = World__Permissions__get_subject(pp);
InferenceSubjects__make_adj_const_domain(infs, I, P);
}
}
#line 251 "inform7/Chapter 10/Instances.w"
void Instances__log(instance *I) {
if (I== NULL) { LOG("<null instance>"); return; }
if (logging_to_I6_text == FALSE) LOG("I%d", I->allocation_id);
Nametags__log(I->tag);
if (!(Kinds__Compare__le(Instances__to_kind(I), K_object)))
LOG("[$u]", Instances__to_kind(I));
}
#line 263 "inform7/Chapter 10/Instances.w"
int Instances__get_numerical_value(instance *I) {
return I->enumeration_index;
}
inference_subject *Instances__as_subject(instance *I) {
if (I == NULL) return NULL;
return I->as_subject;
}
#line 275 "inform7/Chapter 10/Instances.w"
wording Instances__get_name(instance *I, int plural) {
if ((I == NULL) || (I->tag == NULL)) return EMPTY_WORDING;
return Nametags__get_name(I->tag, plural);
}
wording Instances__get_name_in_play(instance *I, int plural) {
if ((I == NULL) || (I->tag == NULL)) return EMPTY_WORDING;
return Nametags__get_name_in_play(I->tag, plural);
}
int Instances__full_name_includes(instance *I, vocabulary_entry *wd) {
if (I == NULL) return FALSE;
return Nametags__full_name_includes(I->tag, wd);
}
nametag *Instances__get_nametag(instance *I) {
return I->tag;
}
char *Instances__identifier(instance *I) {
if (I == NULL) return "nothing";
return Nametags__identifier(I->tag);
}
#line 302 "inform7/Chapter 10/Instances.w"
void Instances__write_name_for_index(OUTPUT_STREAM, instance *I) {
wording W = Instances__get_name(I, FALSE);
if (Wordings__nonempty(W)) Wordings__to_stream_raw(OUT, W);
else {
WRITE("nameless ");
kind *K = Instances__to_kind(I);
W = Kinds__Behaviour__get_name(K, FALSE);
if (Wordings__nonempty(W)) Wordings__to_stream_raw(OUT, W);
}
}
#line 321 "inform7/Chapter 10/Instances.w"
instance *Instances__parse_object(wording W) {
parse_node *p;
if (Wordings__empty(W)) return NULL;
if (Preform__parse_nt_against_word_range(s_literal_NTM, W, NULL, NULL)) return NULL;
p = SParser__parse_excerpt(NAMETAG_MC, W);
if (p == NULL) return NULL;
nametag *nt = Nametags__disambiguate(p, MAX_NAMETAG_PRIORITY);
if (nt == NULL) return NULL;
if (Nametags__priority(nt) != INSTANCE_PRIORITY) return NULL;
parse_node *pn = RETRIEVE_POINTER_parse_node(Nametags__tag_holder(nt));
if (ParseTree__is(pn, CONSTANT_VNT)) {
kind *K = ParseTree__get_kind_of_value(pn);
if (Kinds__Compare__le(K, K_object))
return ParseTree__get_constant_instance(pn);
}
return NULL;
}
#line 343 "inform7/Chapter 10/Instances.w"
int instance_of_object_NTMR(wording W, int *X, void **XP) {
#line 344 "inform7/Chapter 10/Instances.w"
instance *I = Instances__parse_object(W);
if (I) { *XP = I; return TRUE; }
return FALSE;
}
int instance_of_non_object_NTMR(wording W, int *X, void **XP) {
#line 350 "inform7/Chapter 10/Instances.w"
parse_node *p = SParser__parse_excerpt(NAMED_CONSTANT_MC, W);
instance *I = Rvalues__to_instance(p);
if (I) { *XP = I; return TRUE; }
return FALSE;
}
int instance_NTMR(wording W, int *X, void **XP) {
#line 357 "inform7/Chapter 10/Instances.w"
if (Preform__parse_nt_against_word_range(s_literal_NTM, W, NULL, NULL)) return FALSE;
W = Articles__remove_the(W);
instance *I = Instances__parse_object(W);
if (I) { *XP = I; return TRUE; }
parse_node *p = SParser__parse_excerpt(NAMED_CONSTANT_MC, W);
I = Rvalues__to_instance(p);
if (I) { *XP = I; return TRUE; }
return FALSE;
}
#line 381 "inform7/Chapter 10/Instances.w"
kind *Instances__to_kind(instance *I) {
if (I == NULL) return NULL;
inference_subject *inherits_from = InferenceSubjects__narrowest_broader_subject(I->as_subject);
return InferenceSubjects__as_kind(inherits_from);
}
int Instances__of_kind(instance *I, kind *match) {
if ((I == NULL) || (match == NULL)) return FALSE;
return Kinds__Compare__le(Instances__to_kind(I), match);
}
#line 398 "inform7/Chapter 10/Instances.w"
void Instances__set_kind(instance *I, kind *new) {
PROTECTED_MODEL_PROCEDURE;
if (I == NULL) {
LOG("Tried to set kind to $u\n", new);
internal_error("Tried to set the kind of a null object");
}
kind *existing = Instances__to_kind(I);
int m = Kinds__Compare__compatible(existing, new);
if (m == ALWAYS_MATCH) return;
if (m == NEVER_MATCH) {
LOG("Tried to set kind of $O (existing $u) to $u\n", I, existing, new);
{
#line 422 "inform7/Chapter 10/Instances.w"
if (current_sentence != I->instance_of_set_at) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, I->instance_of_set_at);
Problems__quote_kind(3, new);
Problems__quote_kind(4, existing);
Problems__Issue__handmade_problem(_p_(PM_KindsIncompatible));
Problems__issue_problem_segment(
"You wrote %1, but that seems to contradict %2, as %3 and %4 "
"are incompatible. (If %3 were a kind of %4 or vice versa "
"there'd be no problem, but they aren't.)");
Problems__issue_problem_end();
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_object(2, I);
Problems__quote_kind(3, new);
Problems__quote_kind(4, existing);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"You wrote %1, which made me think the kind of %2 was %4, "
"but for other reasons I now think it ought to be %3, and those "
"are incompatible. (If %3 were a kind of %4 or vice versa "
"there'd be no problem, but they aren't.)");
Problems__issue_problem_end();
}
}
#line 409 "inform7/Chapter 10/Instances.w"
;
return;
}
Plugins__Call__set_kind_notify(I, new);
InferenceSubjects__falls_within(I->as_subject, Kinds__Behaviour__as_subject(new));
Assertions__Assemblies__satisfies_generalisations(I->as_subject);
I->instance_of_set_at = current_sentence;
LOGIF(KIND_CHANGES, "Setting kind of $O to $u\n", I, new);
}
#line 450 "inform7/Chapter 10/Instances.w"
parse_node *Instances__get_kind_set_sentence(instance *I) {
return I->instance_of_set_at;
}
#line 470 "inform7/Chapter 10/Instances.w"
int Instances__count(kind *K) {
int c = 0;
instance *I;
LOOP_OVER_INSTANCES(I, K) c++;
return c;
}
#line 489 "inform7/Chapter 10/Instances.w"
void Instances__set_connection(instance *I, general_pointer gp) {
I->connection = gp;
}
general_pointer Instances__get_connection(instance *I) {
return I->connection;
}
#line 501 "inform7/Chapter 10/Instances.w"
void Instances__increment_indexing_count(instance *I) {
I->index_appearances++;
}
int Instances__indexed_yet(instance *I) {
if (I->index_appearances > 0) return TRUE;
return FALSE;
}
#line 513 "inform7/Chapter 10/Instances.w"
void Instances__index_name(instance *I) {
wording W = Instances__get_name_in_play(I, FALSE);
if (Wordings__nonempty(W)) {
Wordings__index_raw(W);
return;
}
kind *K = Instances__to_kind(I);
W = Kinds__Behaviour__get_name_in_play(K, FALSE);
if (Wordings__nonempty(W)) {
Wordings__index_raw(W);
return;
}
INDEX("nameless");
}
#line 531 "inform7/Chapter 10/Instances.w"
void Instances__note_usage(instance *I, parse_node *NB) {
if (I->last_noted_usage) {
if (NB == I->last_noted_usage->where_instance_used) return;
}
instance_usage *IU = CREATE(instance_usage);
IU->where_instance_used = NB;
IU->next = NULL;
if (I->last_noted_usage == NULL) {
I->first_noted_usage = IU;
I->last_noted_usage = IU;
} else {
I->last_noted_usage->next = IU;
I->last_noted_usage = IU;
}
}
void Instances__index_usages(instance *I) {
int k = 0;
instance_usage *IU = I->first_noted_usage;
for (; IU; IU = IU->next) {
parse_node *at = IU->where_instance_used;
if (at) {
source_file *sf = Lexer__file_of_origin(Wordings__first_wn(ParseTree__get_text(at)));
if (sf == primary_source_file) {
k++;
if (k == 1) {
HTML__open_para(ifl, 1, "tight");
INDEX("<i>mentioned in rules:</i> ");
} else INDEX("; ");
Index__link(Wordings__first_wn(ParseTree__get_text(at)));
}
}
}
if (k > 0) INDEX("</p>");
}
#line 571 "inform7/Chapter 10/Instances.w"
wording Instances__SUBJ_get_name_text(inference_subject *from) {
instance *I = InferenceSubjects__as_nc(from);
return Instances__get_name(I, FALSE);
}
general_pointer Instances__SUBJ_new_permission_granted(inference_subject *from) {
return STORE_POINTER_property_of_value_storage(
Properties__ValueImplementation__get_storage());
}
void Instances__SUBJ_complete_model(inference_subject *infs) {
}
void Instances__SUBJ_check_model(inference_subject *infs) {
}
#line 590 "inform7/Chapter 10/Instances.w"
void Instances__SUBJ_make_adj_const_domain(inference_subject *S,
instance *I, property *P) {
Instances__make_adj_const_domain(I, P, NULL, InferenceSubjects__as_instance(S));
}
#line 599 "inform7/Chapter 10/Instances.w"
void Instances__SUBJ_write_element_of_condition(inference_subject *infs, char *cond) {
instance *I = InferenceSubjects__as_nc(infs);
sprintf(cond, "t_0 == %s", Instances__identifier(I));
}
#line 612 "inform7/Chapter 10/Instances.w"
int Instances__SUBJ_compile_all(OUTPUT_STREAM) {
Properties__ObjectImplementation__compile_all(OUT);
instance *I;
LOOP_OVER(I, instance)
if (Kinds__Compare__le(Instances__to_kind(I), K_object) == FALSE)
Instances__SUBJ_compile(OUT, Instances__as_subject(I));
return TRUE;
}
#line 624 "inform7/Chapter 10/Instances.w"
void Instances__SUBJ_compile(OUTPUT_STREAM, inference_subject *infs) {
instance *I = InferenceSubjects__as_nc(infs);
if (Kinds__Compare__le(Instances__to_kind(I), K_object))
Properties__ObjectImplementation__compile_subject(OUT, infs);
else
WRITE("Constant %s = %d;\n", Instances__identifier(I),
I->enumeration_index);
}
#line 647 "inform7/Chapter 10/Instances.w"
adjectival_phrase *Instances__get_adjectival_phrase(instance *I) {
return I->usage_as_aph;
}
adjective_meaning *Instances__ADJ_parse(parse_node *pn,
int sense, wording AW, wording DNW, wording CONW, wording CALLW) {
return NULL;
}
void Instances__ADJ_compiling_soon(adjective_meaning *am, instance *I, int T) {
}
int Instances__ADJ_compile(instance *I, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
#line 669 "inform7/Chapter 10/Instances.w"
int Instances__ADJ_assert(instance *I,
inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) {
if (parity == FALSE) return FALSE;
property *P = Kinds__Behaviour__get_coinciding_property(Instances__to_kind(I));
if (P == NULL) internal_error("enumerative adjective on non-property");
World__Inferences__draw_property(infs_to_assert_on, P, Rvalues__from_instance(I));
return TRUE;
}
#line 681 "inform7/Chapter 10/Instances.w"
int Instances__ADJ_index(instance *I) {
property *P = Kinds__Behaviour__get_coinciding_property(Instances__to_kind(I));
if (Properties__Conditions__of_what(P) == NULL) {
if (Properties__permission_list(P)) {
INDEX("(of "); World__Permissions__index(P); INDEX(") ");
}
INDEX("having this ");
Wordings__index_raw(P->name);
} else {
INDEX("a condition which is otherwise ");
kind *K = Instances__to_kind(I);
int no_alts = Instances__count(K) - 1, i = 0;
instance *alt;
LOOP_OVER_INSTANCES(alt, K)
if (alt != I) {
INDEX("</i>");
wording NW = Instances__get_name(alt, FALSE);
Wordings__index_raw(NW);
INDEX("<i>");
i++;
if (i == no_alts-1) INDEX(" or ");
else if (i < no_alts) INDEX(", ");
}
}
return TRUE;
}
#line 721 "inform7/Chapter 10/Instances.w"
void Instances__make_adj_const_domain(instance *I, property *P,
kind *set, instance *singleton) {
kind *D = NULL;
{
#line 733 "inform7/Chapter 10/Instances.w"
if (singleton) D = Instances__to_kind(singleton);
else if (set) D = set;
if (D == NULL) internal_error("No adjectival constant domain");
}
#line 724 "inform7/Chapter 10/Instances.w"
;
adjective_meaning *am = NULL;
{
#line 740 "inform7/Chapter 10/Instances.w"
wording NW = Instances__get_name(I, FALSE);
am = Adjectives__Meanings__new(ENUMERATIVE_KADJ,
STORE_POINTER_instance(I), NW);
I->usage_as_aph = Adjectives__Phrases__declare(am, NW);
if (singleton) Adjectives__Meanings__set_domain_from_instance(am, singleton);
else if (set) Adjectives__Meanings__set_domain_from_kind(am, set);
}
#line 726 "inform7/Chapter 10/Instances.w"
;
{
#line 750 "inform7/Chapter 10/Instances.w"
i6_schema *sch = Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Calculus__Schemas__modify(sch,
"GProperty(%k, *1, %s) == %d",
D, Properties__get_translation(P), I->enumeration_index);
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, FALSE);
Calculus__Schemas__modify(sch,
"WriteGProperty(%k, *1, %s, %d)",
D, Properties__get_translation(P), I->enumeration_index);
}
#line 727 "inform7/Chapter 10/Instances.w"
;
}
#line 64 "inform7/Chapter 10/Nonlocal Variables.w"
int notable_variables_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 67 "inform7/Chapter 10/Nonlocal Variables.w"
#line 73 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable *NonlocalVariables__new_global(wording W, kind *K) {
PROTECTED_MODEL_PROCEDURE;
return NonlocalVariables__new(W, K, NULL);
}
nonlocal_variable *NonlocalVariables__new_stacked(wording W, kind *K,
stacked_variable *scope) {
if (scope == NULL) internal_error("not a stacked nonlocal_variable at all");
return NonlocalVariables__new(W, K, scope);
}
#line 87 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable *NonlocalVariables__new(wording W, kind *K, stacked_variable *scope) {
if (K == NULL) internal_error("created variable without kind");
if (Kinds__Behaviour__definite(K) == FALSE)
{
#line 105 "inform7/Chapter 10/Nonlocal Variables.w"
Problems__quote_wording(1, W);
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(PM_IndefiniteVariable));
Problems__issue_problem_segment(
"I am unable to create the variable '%1', because its kind (%2) is too "
"vague. I need to know exactly what kind of value goes into each "
"variable: for instance, it's not enough to say 'L is a list of values "
"that varies', because I don't know what the entries have to be - 'L "
"is a list of numbers that varies' would be better.");
Problems__issue_problem_end();
}
#line 89 "inform7/Chapter 10/Nonlocal Variables.w"
;
nonlocal_variable *nlv = CREATE(nonlocal_variable);
{
#line 134 "inform7/Chapter 10/Nonlocal Variables.w"
nlv->var_documentation_symbol = Index__DocReferences__position_of_symbol(&W);
nlv->name = W;
nlv->nlv_created_at = current_sentence;
nlv->nlv_kind = K;
nlv->nlv_as_rvalue[0] = 0; /* we won't decide their run-time storage until later */
nlv->nlv_as_lvalue[0] = 0;
nlv->position_in_variables_array = -1;
nlv->nlv_name_translated = FALSE;
nlv->alias_to_infs = NULL;
nlv->nlv_write_schema = NULL;
nlv->constant_at_run_time = FALSE;
nlv->var_is_initialisable_anyway = FALSE;
nlv->scope = scope;
nlv->substitution_marker = 0;
if ((Wordings__nonempty(W)) && (scope == NULL)) /* that is, if it's a global */
Semantics__Nouns__ExcerptMeanings__register_noun(VARIABLE_MC, W,
Lvalues__new_actual_NONLOCAL_VARIABLE(nlv));
nlv->nlv_knowledge =
InferenceSubjects__new(nonlocal_variables,
VARI_SUB, STORE_POINTER_nonlocal_variable(nlv), CERTAIN_CE);
}
#line 92 "inform7/Chapter 10/Nonlocal Variables.w"
;
latest_nonlocal_variable = nlv;
{
#line 119 "inform7/Chapter 10/Nonlocal Variables.w"
if (Preform__parse_nt_against_word_range(notable_variables_NTM, W, NULL, NULL)) {
switch (most_recent_result) {
case 0: i6_glob_VAR = nlv; break;
case 1: i6_nothing_VAR = nlv; break;
}
}
}
#line 95 "inform7/Chapter 10/Nonlocal Variables.w"
;
Plugins__Call__new_variable_notify(nlv);
LOGIF(VARIABLE_CREATIONS, "Created non-library variable: $Z\n", nlv);
return nlv;
}
#line 158 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__log(nonlocal_variable *nlv) {
if (nlv== NULL) { LOG("<null variable>"); return; }
LOG("'$w'(%s)[$u]", nlv->name,
(nlv->constant_at_run_time)?"const":"var",
nlv->nlv_kind);
}
#line 169 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable *NonlocalVariables__parse(wording W) {
W = Articles__remove_the(W);
if (Preform__parse_nt_against_word_range(s_global_variable_NTM, W, NULL, NULL)) {
parse_node *val = most_recent_result_p;
return ParseTree__get_constant_nonlocal_variable(val);
}
return NULL;
}
#line 184 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__translates(wording W, parse_node *p2) {
nonlocal_variable *nlv = NonlocalVariables__parse(W);
if ((nlv == NULL) || (nlv->scope)) {
LOG("Tried $w\n", W);
Problems__Issue__sentence_problem(_p_(PM_NonQuantityTranslated),
"this is not the name of a variable",
"or at any rate not one global in scope.");
return;
}
if (nlv->nlv_name_translated) {
Problems__Issue__sentence_problem(_p_(PM_QuantityTranslatedAlready),
"this variable has already been translated",
"so there must be some duplication somewhere.");
return;
}
nlv->nlv_name_translated = TRUE;
char *name = Lexer__word_text(Wordings__first_wn(ParseTree__get_text(p2)));
NonlocalVariables__set_I6_identifier(nlv, name, name);
LOGIF(VARIABLE_CREATIONS,
"Translated variable: $Z as %s\n", nlv, Lexer__word_text(Wordings__first_wn(ParseTree__get_text(p2))));
}
#line 213 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__set_I6_identifier(nonlocal_variable *nlv, char *rvalue, char *lvalue) {
if (Platform__strlen(lvalue) > 30) internal_error("L-value name too long");
if (Platform__strlen(rvalue) > 30) internal_error("R-value name too long");
strcpy(nlv->nlv_as_rvalue, rvalue);
strcpy(nlv->nlv_as_lvalue, lvalue);
nlv->position_in_variables_array = -1;
}
#line 225 "inform7/Chapter 10/Nonlocal Variables.w"
char *NonlocalVariables__identifier(nonlocal_variable *nlv) {
if (nlv->nlv_as_rvalue[0] == 0) NonlocalVariables__allocate_storage();
if (nlv->nlv_as_rvalue[0] == 0)
{
#line 240 "inform7/Chapter 10/Nonlocal Variables.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, nlv->name);
Problems__Issue__handmade_problem(_p_(PM_MeaningMissing));
Problems__issue_problem_segment(
"The sentence %1 seems to need the value '%2', but that currently "
"has no definition.");
Problems__issue_problem_end();
return "self";
}
#line 227 "inform7/Chapter 10/Nonlocal Variables.w"
;
return nlv->nlv_as_rvalue;
}
char *NonlocalVariables__lvalue_identifier(nonlocal_variable *nlv) {
if (nlv->nlv_as_lvalue[0] == 0) NonlocalVariables__allocate_storage();
if (nlv->nlv_as_lvalue[0] == 0)
{
#line 240 "inform7/Chapter 10/Nonlocal Variables.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, nlv->name);
Problems__Issue__handmade_problem(_p_(PM_MeaningMissing));
Problems__issue_problem_segment(
"The sentence %1 seems to need the value '%2', but that currently "
"has no definition.");
Problems__issue_problem_end();
return "self";
}
#line 233 "inform7/Chapter 10/Nonlocal Variables.w"
;
return nlv->nlv_as_lvalue;
}
#line 253 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__allocate_storage(void) {
int k = 0;
nonlocal_variable *var;
LOOP_OVER(var, nonlocal_variable)
if (((var->nlv_as_lvalue[0] == 0) || (var->nlv_as_rvalue[0] == 0)) &&
((var->constant_at_run_time == FALSE) || (var->var_is_bibliographic))) {
char name[32];
sprintf(name, "(Global_Vars-->%d)", k);
NonlocalVariables__set_I6_identifier(var, name, name);
var->position_in_variables_array = k++;
}
}
#line 273 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__set_write_schema(nonlocal_variable *nlv, char *sch) {
nlv->nlv_write_schema = sch;
}
char *NonlocalVariables__get_write_schema(nonlocal_variable *nlv) {
NonlocalVariables__warn_about_change(nlv);
if (nlv == NULL) return NULL;
return nlv->nlv_write_schema;
}
void NonlocalVariables__warn_about_change(nonlocal_variable *nlv) {
if (nlv == score_VAR) {
if ((scoring_option_set == FALSE) ||
((scoring_option_set == NOT_APPLICABLE) &&
(default_scoring_setting == FALSE))) {
Problems__Issue__sentence_problem(_p_(PM_CantChangeScore),
"this is a story with no scoring",
"so it makes no sense to change the 'score' value. You can add "
"scoring to the story by including the sentence 'Use scoring.', "
"in which case this problem message will go away; or you can "
"remove it with 'Use no scoring.' (Until 2011, the default was "
"to have scoring, but now it's not to have scoring.)");
}
}
}
#line 303 "inform7/Chapter 10/Nonlocal Variables.w"
wording NonlocalVariables__SUBJ_get_name_text(inference_subject *from) {
nonlocal_variable *nlv = InferenceSubjects__as_nlv(from);
return nlv->name;
}
general_pointer NonlocalVariables__SUBJ_new_permission_granted(inference_subject *from) {
return NULL_GENERAL_POINTER;
}
void NonlocalVariables__SUBJ_make_adj_const_domain(inference_subject *infs,
instance *nc, property *prn) {
}
void NonlocalVariables__SUBJ_complete_model(inference_subject *infs) {
}
void NonlocalVariables__SUBJ_check_model(inference_subject *infs) {
}
void NonlocalVariables__SUBJ_write_element_of_condition(inference_subject *infs, char *cond) {
internal_error("NLV in runtime match condition");
}
void NonlocalVariables__SUBJ_compile(OUTPUT_STREAM, inference_subject *infs) {
}
inference_subject *NonlocalVariables__get_knowledge(nonlocal_variable *nlv) {
return nlv->nlv_knowledge;
}
#line 337 "inform7/Chapter 10/Nonlocal Variables.w"
int NonlocalVariables__SUBJ_compile_all(OUTPUT_STREAM) {
NonlocalVariables__allocate_storage(); /* in case this hasn't happened already */
{
#line 371 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable *nlv;
LOOP_OVER(nlv, nonlocal_variable)
if ((nlv->position_in_variables_array < 0) &&
(nlv->var_is_initialisable_anyway == FALSE) &&
(nlv->alias_to_infs == NULL) &&
(NonlocalVariables__has_initial_value_set(nlv)))
{
#line 382 "inform7/Chapter 10/Nonlocal Variables.w"
current_sentence = NonlocalVariables__origin_of_initial_value(nlv);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, nlv->name);
Problems__quote_text(3, nlv->nlv_as_lvalue);
Problems__Issue__handmade_problem(_p_(PM_InaccessibleVariable));
Problems__issue_problem_segment(
"The sentence %1 tells me that '%2' has a specific initial value, "
"but this is a variable which has been translated into an I6 'Global' "
"called '%3' at the lowest level of Inform. Any initial value must be "
"given in its I6 definition, not here.");
Problems__issue_problem_end();
}
#line 377 "inform7/Chapter 10/Nonlocal Variables.w"
;
}
#line 339 "inform7/Chapter 10/Nonlocal Variables.w"
;
nonlocal_variable *nlv;
LOOP_OVER(nlv, nonlocal_variable) {
current_sentence = NonlocalVariables__origin_of_initial_value(nlv);
if (NonlocalVariables__has_initial_value_set(nlv))
Assertions__PropertyKnowledge__verify_global_variable(nlv);
}
int k = 0;
WRITE("Array Global_Vars -->\n");
LOOP_OVER(nlv, nonlocal_variable)
if (nlv->position_in_variables_array == k) {
WRITE(" (");
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
NonlocalVariables__compile_initial_value(OUT, nlv);
END_COMPILATION_MODE;
WRITE(") ! %d ", nlv->allocation_id);
CompiledText__comment(OUT, nlv->name);
WRITE("\n");
k++;
}
if (k < 2) WRITE(" NULL NULL");
WRITE(";\n");
return TRUE;
}
#line 399 "inform7/Chapter 10/Nonlocal Variables.w"
parse_node *NonlocalVariables__get_initial_value(nonlocal_variable *nlv) {
inference *inf;
inference_subject *infs = NonlocalVariables__get_knowledge(nlv);
POSITIVE_KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_variable_initial_value)
return World__Inferences__get_property_value(inf);
return Specifications__new_UNKNOWN(EMPTY_WORDING);
}
parse_node *NonlocalVariables__origin_of_initial_value(nonlocal_variable *nlv) {
inference *inf;
inference_subject *infs = NonlocalVariables__get_knowledge(nlv);
POSITIVE_KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_variable_initial_value)
return World__Inferences__where_inferred(inf);
return NULL;
}
int NonlocalVariables__has_initial_value_set(nonlocal_variable *nlv) {
if ((nlv) && (NonlocalVariables__origin_of_initial_value(nlv))) return TRUE;
return FALSE;
}
#line 425 "inform7/Chapter 10/Nonlocal Variables.w"
int NonlocalVariables__is_global(nonlocal_variable *nlv) {
if (nlv->scope) return FALSE;
return TRUE;
}
#line 435 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__set_kind(nonlocal_variable *nlv, kind *K) {
if (nlv == NULL) internal_error("set kind for null variable");
nlv->nlv_kind = K;
}
kind *NonlocalVariables__kind(nonlocal_variable *nlv) {
if (nlv == NULL) return NULL;
return nlv->nlv_kind;
}
#line 448 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable *NonlocalVariables__temporary(char *I6_form, kind *K) {
NonlocalVariables__set_I6_identifier(i6_glob_VAR, I6_form, I6_form);
NonlocalVariables__set_kind(i6_glob_VAR, K);
return i6_glob_VAR;
}
int formal_par_vars_made = FALSE;
nonlocal_variable *formal_par_VAR[8];
nonlocal_variable *NonlocalVariables__temporary_formal(int i) {
if (formal_par_vars_made == FALSE) {
int i;
for (i=0; i<8; i++) {
char lvalue[32];
sprintf(lvalue, "formal_par%d", i);
formal_par_VAR[i] = NonlocalVariables__new(EMPTY_WORDING, K_object, NULL);
NonlocalVariables__set_I6_identifier(formal_par_VAR[i], lvalue, lvalue);
}
formal_par_vars_made = TRUE;
}
nonlocal_variable *nlv = formal_par_VAR[i];
return nlv;
}
#line 475 "inform7/Chapter 10/Nonlocal Variables.w"
wording NonlocalVariables__treat_as_plain_text_word(nonlocal_variable *nlv) {
inference *inf;
inference_subject *infs = NonlocalVariables__get_knowledge(nlv);
POSITIVE_KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_variable_initial_value)
return ParseTree__get_text(
World__Inferences__set_property_value_kind(inf, K_text));
return EMPTY_WORDING;
}
#line 489 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__make_constant(nonlocal_variable *nlv, int bib) {
if (nlv == NULL) internal_error("no such var");
nlv->constant_at_run_time = TRUE;
nlv->var_is_initialisable_anyway = TRUE;
nlv->var_is_bibliographic = bib;
}
void NonlocalVariables__make_initalisable(nonlocal_variable *nlv) {
nlv->var_is_initialisable_anyway = TRUE;
}
int NonlocalVariables__is_constant(nonlocal_variable *nlv) {
if (nlv == NULL) internal_error("no such var");
return nlv->constant_at_run_time;
}
int NonlocalVariables__must_be_constant(nonlocal_variable *nlv) {
if (nlv->constant_at_run_time) {
Problems__Issue__sentence_problem(_p_(PM_CantChangeConstants),
"this is a name for a value which never changes during the story",
"so it can't be altered with 'now'.");
return TRUE;
}
return FALSE;
}
#line 519 "inform7/Chapter 10/Nonlocal Variables.w"
int substitution_session_id = 0;
parse_node *NonlocalVariables__substitute_constants(parse_node *spec) {
int depth = 0;
substitution_session_id++;
while (TRUE) {
if (depth++ > 20) internal_error("ill-founded constants");
nonlocal_variable *nlv = Lvalues__get_nonlocal_variable_if_any(spec);
if ((nlv) && (nlv->constant_at_run_time)) {
if (nlv->substitution_marker == substitution_session_id) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, nlv->name);
Problems__quote_kind(3, nlv->nlv_kind);
Problems__Issue__handmade_problem(_p_(PM_MeaningRecursive));
Problems__issue_problem_segment(
"The sentence %1 tells me that '%2', which should be %3 "
"that varies, is to have an initial value which can't "
"be worked out without going round in circles.");
Problems__issue_problem_end();
break;
}
nlv->substitution_marker = substitution_session_id;
parse_node *sspec = NonlocalVariables__get_initial_value(nlv);
if (ParseTree__is(sspec, UNKNOWN_VNT) == FALSE) { spec = sspec; continue; }
}
break;
}
return spec;
}
#line 554 "inform7/Chapter 10/Nonlocal Variables.w"
inference_subject *NonlocalVariables__get_alias(nonlocal_variable *nlv) {
if (nlv) {
parse_node *val = NonlocalVariables__get_initial_value(nlv);
inference_subject *vals = InferenceSubjects__from_specification(val);
if (vals) return vals;
return nlv->alias_to_infs;
}
return NULL;
}
void NonlocalVariables__set_alias(nonlocal_variable *nlv, inference_subject *infs) {
nlv->alias_to_infs = infs;
}
#line 580 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__compile_initial_value(OUTPUT_STREAM, nonlocal_variable *nlv) {
TEMPORARY_STREAM;
NonlocalVariables__compile_initial_value_inner(TEMP, nlv);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
void NonlocalVariables__compile_initial_value_inner(OUTPUT_STREAM, nonlocal_variable *nlv) {
parse_node *val =
NonlocalVariables__substitute_constants(
NonlocalVariables__get_initial_value(
nlv));
if (ParseTree__is(val, UNKNOWN_VNT)) {
current_sentence = nlv->nlv_created_at;
{
#line 606 "inform7/Chapter 10/Nonlocal Variables.w"
if (Kinds__Behaviour__compile_default_value(OUT, nlv->nlv_kind, nlv->name, "variable") == FALSE) {
wording W = Kinds__Behaviour__get_name(nlv->nlv_kind, FALSE);
Problems__quote_wording(1, nlv->name);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_EmptyDataType));
Problems__issue_problem_segment(
"I am unable to put any value into the variable '%1', because "
"%2 is a kind of value with no actual values.");
Problems__issue_problem_end();
}
}
#line 594 "inform7/Chapter 10/Nonlocal Variables.w"
} else {
current_sentence = NonlocalVariables__origin_of_initial_value(nlv);
if (Lvalues__get_storage_form(val) == NONLOCAL_VARIABLE_VNT)
{
#line 620 "inform7/Chapter 10/Nonlocal Variables.w"
nonlocal_variable *the_other = ParseTree__get_constant_nonlocal_variable(val);
if (the_other == NULL) internal_error(
"Tried to compile initial value of variable as null variable");
if (the_other == nlv) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, nlv->name);
Problems__quote_kind(3, nlv->nlv_kind);
Problems__Issue__handmade_problem(_p_(PM_InitialiseQ2));
Problems__issue_problem_segment(
"The sentence %1 tells me that '%2', which should be %3 "
"that varies, is to have an initial value equal to itself - "
"this is such an odd thing to say that I think I must have "
"misunderstood.");
Problems__issue_problem_end();
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, nlv->name);
Problems__quote_kind(3, nlv->nlv_kind);
Problems__quote_wording(4, the_other->name);
Problems__quote_kind(5, the_other->nlv_kind);
Problems__Issue__handmade_problem(_p_(PM_InitialiseQ1));
Problems__issue_problem_segment(
"The sentence %1 tells me that '%2', which should be %3 "
"that varies, is to have an initial value equal to '%4', "
"which in turn is %5 that varies. At the start of play, "
"variable values have to be set equal to definite constants, "
"so this is not allowed.");
Problems__issue_problem_end();
}
}
#line 598 "inform7/Chapter 10/Nonlocal Variables.w"
else Specifications__Compiler__compile_constant_to_kind(OUT, val, nlv->nlv_kind);
}
}
#line 658 "inform7/Chapter 10/Nonlocal Variables.w"
int value_understood_variable_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 660 "inform7/Chapter 10/Nonlocal Variables.w"
#line 664 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__index_all(void) {
nonlocal_variable *nlv;
heading *definition_area, *current_area = NULL;
INDEX("<p>");
Index__anchor("NAMES");
int understood_note_given = FALSE;
LOOP_OVER(nlv, nonlocal_variable)
if ((Wordings__first_wn(nlv->name) >= 0) && (NonlocalVariables__is_global(nlv))) {
if (Preform__parse_nt_against_word_range(value_understood_variable_name_NTM, nlv->name, NULL, NULL))
{
#line 682 "inform7/Chapter 10/Nonlocal Variables.w"
if (understood_note_given == FALSE) {
understood_note_given = TRUE;
INDEX("<i>kind</i> understood - <i>value</i><br>\n");
}
}
#line 673 "inform7/Chapter 10/Nonlocal Variables.w"
else
{
#line 690 "inform7/Chapter 10/Nonlocal Variables.w"
definition_area = Wordings__heading_of(nlv->name);
if (Sentences__Headings__indexed(definition_area) == FALSE) continue;
if (definition_area != current_area) {
wording W = Sentences__Headings__get_text(definition_area);
INDEX("<p>");
if (Wordings__nonempty(W)) Phrases__Index__index_definition_area(W, FALSE);
}
current_area = definition_area;
NonlocalVariables__index_single(nlv);
INDEX("<br>\n");
}
#line 675 "inform7/Chapter 10/Nonlocal Variables.w"
;
}
}
#line 704 "inform7/Chapter 10/Nonlocal Variables.w"
void NonlocalVariables__index_single(nonlocal_variable *nlv) {
Wordings__index_raw(nlv->name);
Index__link(Wordings__first_wn(nlv->name));
if (Wordings__nonempty(nlv->var_documentation_symbol))
Index__DocReferences__link(
Lexer__word_raw_text(Wordings__first_wn(nlv->var_documentation_symbol)));
INDEX(" - <i>");
Kinds__Textual__write(ifl, nlv->nlv_kind);
INDEX("</i>");
}
#line 18 "inform7/Chapter 10/Index Physical World.w"
void Data__Objects__page_Kinds(void) {
{
#line 29 "inform7/Chapter 10/Index Physical World.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__lt(K, K_object)) {
wording W = Kinds__Behaviour__get_name(K, FALSE);
if (Wordings__nonempty(W)) {
char temp[MAX_WORD_LENGTH + 10];
sprintf(temp, "kind_%s", Lexer__word_text(Wordings__first_wn(W)));
char *ref = Index__DocReferences__validate_if_possible(temp);
if (ref) Kinds__Behaviour__set_documentation_reference(K, ref);
}
}
}
#line 19 "inform7/Chapter 10/Index Physical World.w"
;
Kinds__Index__index_kinds(1);
}
#line 47 "inform7/Chapter 10/Index Physical World.w"
int suppress_panel_changes = FALSE;
void Data__Objects__page_World(void) {
if (existing_story_file) return; /* in this case there is no model world */
PL__SpatialMap__establish_benchmark_room();
PL__EPSMap__traverse_for_map_parameters(1);
PL__SpatialMap__establish_spatial_coordinates();
PL__HTMLMap__render_map_as_HTML();
PL__HTMLMap__add_region_key();
PL__EPSMap__render_map_as_EPS();
PL__Backdrops__index_object_further(NULL, 0, FALSE,
"<p><b>Present everywhere:</b><br>", "<p><hr><p>");
Index__anchor("MDETAILS");
int unruly = FALSE;
{
#line 72 "inform7/Chapter 10/Index Physical World.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((PL__Spatial__no_detail_index(I))
|| (PL__Map__object_is_a_direction(I)))
Instances__increment_indexing_count(I);
}
#line 63 "inform7/Chapter 10/Index Physical World.w"
;
{
#line 81 "inform7/Chapter 10/Index Physical World.w"
instance *reg;
LOOP_OVER_OBJECT_INSTANCES(reg)
if (PL__Regions__object_is_a_region(reg)) {
int subheaded = FALSE;
Instances__increment_indexing_count(reg);
instance *rm;
LOOP_OVER_OBJECT_INSTANCES(rm)
if ((PL__Spatial__object_is_a_room(rm)) &&
(PL__Regions__enclosing(rm) == reg)) {
if (subheaded == FALSE) {
{
#line 152 "inform7/Chapter 10/Index Physical World.w"
if ((unruly) && (suppress_panel_changes == FALSE)) INDEX("<p><hr><p>");
unruly = TRUE;
}
#line 91 "inform7/Chapter 10/Index Physical World.w"
;
{
#line 105 "inform7/Chapter 10/Index Physical World.w"
INDEX("<b>The <i>");
wording W = Instances__get_name(reg, FALSE);
Wordings__index_raw(W);
INDEX("</i> region");
instance *within = PL__Regions__enclosing(reg);
if (within) {
INDEX(" within the <i>");
W = Instances__get_name(within, FALSE);
Wordings__index_raw(W);
INDEX("</i> region");
}
INDEX("</b>");
}
#line 92 "inform7/Chapter 10/Index Physical World.w"
;
PL__Backdrops__index_object_further(reg, 0, FALSE, "<br>", "");
INDEX("<p>");
subheaded = TRUE;
}
PL__HTMLMap__render_single_room_as_HTML(rm);
Instances__increment_indexing_count(rm);
}
}
}
#line 64 "inform7/Chapter 10/Index Physical World.w"
;
{
#line 121 "inform7/Chapter 10/Index Physical World.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((PL__Spatial__object_is_a_room(I)) &&
(Instances__indexed_yet(I) == FALSE)) {
{
#line 152 "inform7/Chapter 10/Index Physical World.w"
if ((unruly) && (suppress_panel_changes == FALSE)) INDEX("<p><hr><p>");
unruly = TRUE;
}
#line 125 "inform7/Chapter 10/Index Physical World.w"
;
PL__HTMLMap__render_single_room_as_HTML(I);
}
}
#line 65 "inform7/Chapter 10/Index Physical World.w"
;
{
#line 135 "inform7/Chapter 10/Index Physical World.w"
int out_of_play_count = 0;
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Instances__indexed_yet(I) == FALSE) &&
(PL__Spatial__progenitor(I) == NULL)) {
{
#line 152 "inform7/Chapter 10/Index Physical World.w"
if ((unruly) && (suppress_panel_changes == FALSE)) INDEX("<p><hr><p>");
unruly = TRUE;
}
#line 140 "inform7/Chapter 10/Index Physical World.w"
;
if (++out_of_play_count == 1) {
suppress_panel_changes = TRUE;
INDEX("<b>Nowhere (that is, initially not in any room):</b><br>");
}
Data__Objects__index(I, NULL, 2, FALSE);
}
suppress_panel_changes = FALSE;
}
#line 66 "inform7/Chapter 10/Index Physical World.w"
;
}
#line 166 "inform7/Chapter 10/Index Physical World.w"
int tabulating_kinds_index = FALSE;
instance *indexing_room = NULL;
int xtras_count = 0;
void Data__Objects__index(instance *I, kind *K, int depth, int details) {
if (depth == MAX_OBJECT_INDEX_DEPTH) internal_error("MAX_OBJECT_INDEX_DEPTH exceeded");
nametag *nt = NULL;
if (I) {
if (depth > NUMBER_CREATED(instance) + 1) return; /* to recover from errors */
Instances__increment_indexing_count(I);
if (Instances__of_kind(I, K_room)) indexing_room = I;
nt = Instances__get_nametag(I);
}
if (K) nt = Kinds__Behaviour__get_nametag(K);
if (nt == NULL) internal_error("no nametag to index");
int shaded = FALSE;
{
#line 205 "inform7/Chapter 10/Index Physical World.w"
if (tabulating_kinds_index) Kinds__Index__begin_chart_row();
if (details) {
HTML__open_para(ifl, depth, "halftight");
if ((K) || (I != indexing_room)) Index__anchor(Nametags__identifier(nt));
} else {
HTML__open_para(ifl, depth, "tight");
if (I) PL__Spatial__index_spatial_relationship(I);
}
}
#line 182 "inform7/Chapter 10/Index Physical World.w"
;
int xtra = -1;
if (I) xtra = xtras_count++;
if (xtra >= 0) Index__extra_link(xtra);
{
#line 226 "inform7/Chapter 10/Index Physical World.w"
if (tabulating_kinds_index) {
int c = Instances__count(K);
if ((c == 0) && (details == FALSE)) shaded = TRUE;
if (shaded) INDEX("<font color=\"%s\">", KINDS_INDEX_SHADE);
{
#line 240 "inform7/Chapter 10/Index Physical World.w"
wording W = Nametags__get_name_in_play(nt, FALSE);
if ((Wordings__empty(W)) && (I)) {
kind *IK = Instances__to_kind(I);
W = Kinds__Behaviour__get_name_in_play(IK, FALSE);
}
if (Wordings__empty(W)) {
INDEX("nameless");
} else {
if ((details) || (PL__Spatial__object_is_a_room(I))) INDEX("<b>");
Wordings__index_raw(W);
if ((details) || (PL__Spatial__object_is_a_room(I))) INDEX("</b>");
if (details)
{
#line 257 "inform7/Chapter 10/Index Physical World.w"
if (I) {
kind *k = Instances__to_kind(I);
if (Kinds__Compare__lt(k, K_object)) {
wording W = Kinds__Behaviour__get_name_in_play(k, FALSE);
if (Wordings__nonempty(W)) {
INDEX(", a kind of ");
Wordings__index_raw(W);
}
}
}
wording PW = Nametags__get_name_in_play(nt, TRUE);
if (Wordings__nonempty(PW)) {
INDEX(" (<i>plural</i> ");
Wordings__index_raw(PW);
INDEX(")");
}
}
#line 251 "inform7/Chapter 10/Index Physical World.w"
;
}
}
#line 230 "inform7/Chapter 10/Index Physical World.w"
;
if (shaded) INDEX("</font>");
if ((details == FALSE) && (c > 0)) INDEX(" [%d]", c);
} else {
{
#line 240 "inform7/Chapter 10/Index Physical World.w"
wording W = Nametags__get_name_in_play(nt, FALSE);
if ((Wordings__empty(W)) && (I)) {
kind *IK = Instances__to_kind(I);
W = Kinds__Behaviour__get_name_in_play(IK, FALSE);
}
if (Wordings__empty(W)) {
INDEX("nameless");
} else {
if ((details) || (PL__Spatial__object_is_a_room(I))) INDEX("<b>");
Wordings__index_raw(W);
if ((details) || (PL__Spatial__object_is_a_room(I))) INDEX("</b>");
if (details)
{
#line 257 "inform7/Chapter 10/Index Physical World.w"
if (I) {
kind *k = Instances__to_kind(I);
if (Kinds__Compare__lt(k, K_object)) {
wording W = Kinds__Behaviour__get_name_in_play(k, FALSE);
if (Wordings__nonempty(W)) {
INDEX(", a kind of ");
Wordings__index_raw(W);
}
}
}
wording PW = Nametags__get_name_in_play(nt, TRUE);
if (Wordings__nonempty(PW)) {
INDEX(" (<i>plural</i> ");
Wordings__index_raw(PW);
INDEX(")");
}
}
#line 251 "inform7/Chapter 10/Index Physical World.w"
;
}
}
#line 234 "inform7/Chapter 10/Index Physical World.w"
;
}
}
#line 186 "inform7/Chapter 10/Index Physical World.w"
;
if (I)
{
#line 277 "inform7/Chapter 10/Index Physical World.w"
if (Plugins__Call__annotate_in_World_index(I) == FALSE) {
kind *k = Instances__to_kind(I);
if (k) {
wording W = Kinds__Behaviour__get_name(k, FALSE);
if ((Wordings__nonempty(W)) &&
(Kinds__Compare__eq(k, K_object) == FALSE) &&
(Kinds__Compare__eq(k, K_thing) == FALSE) &&
(Kinds__Compare__eq(k, K_room) == FALSE)) {
INDEX(" - <i>");
Wordings__index_raw(W);
INDEX("</i>");
}
}
}
}
#line 187 "inform7/Chapter 10/Index Physical World.w"
;
{
#line 295 "inform7/Chapter 10/Index Physical World.w"
parse_node *C = NULL;
if (K) C = Kinds__Behaviour__get_creating_sentence(K);
if (I) C = Instances__get_creating_sentence(I);
if (C) Index__link(Wordings__first_wn(ParseTree__get_text(C)));
if ((K) && (Kinds__Behaviour__get_documentation_reference(K)))
Index__DocReferences__link(Kinds__Behaviour__get_documentation_reference(K));
if ((details == FALSE) && (K))
Index__below_link(Nametags__identifier(nt));
}
#line 188 "inform7/Chapter 10/Index Physical World.w"
;
{
#line 217 "inform7/Chapter 10/Index Physical World.w"
if (tabulating_kinds_index)
Kinds__Index__end_chart_row(shaded, K, "tick", "tick", "tick");
else {
INDEX("</p>\n");
}
}
#line 189 "inform7/Chapter 10/Index Physical World.w"
;
if (details)
{
#line 319 "inform7/Chapter 10/Index Physical World.w"
HTML__open_para(ifl, depth, "tight");
if (I) World__Inferences__index(Instances__as_subject(I), TRUE);
else World__Inferences__index(Kinds__Behaviour__as_subject(K), TRUE);
if (K) {
INDEX("</p>");
Data__Objects__index_instances(K, depth);
}
}
#line 190 "inform7/Chapter 10/Index Physical World.w"
;
if (xtra >= 0) {
Index__extra_div_open(xtra, depth+1, "e0e0e0");
{
#line 330 "inform7/Chapter 10/Index Physical World.w"
HTML__open_para(ifl, 1, "tight");
kind *IK = Instances__to_kind(I);
int i = 0;
while ((IK != K_object) && (IK)) {
i++;
IK = Kinds__Compare__super(IK);
}
int j;
for (j=i-1; j>=0; j--) {
int k; IK = Instances__to_kind(I);
for (k=0; k<j; k++) IK = Kinds__Compare__super(IK);
if (j != i-1) INDEX(" &gt; ");
wording W = Kinds__Behaviour__get_name(IK, FALSE);
Wordings__index_raw(W);
}
parse_node *P = Instances__get_kind_set_sentence(I);
if (P) Index__link(Wordings__first_wn(ParseTree__get_text(P)));
INDEX(" &gt; <b>");
Instances__index_name(I);
INDEX("</b></p>");
}
#line 193 "inform7/Chapter 10/Index Physical World.w"
;
{
#line 354 "inform7/Chapter 10/Index Physical World.w"
World__Inferences__index_specific(Instances__as_subject(I));
}
#line 194 "inform7/Chapter 10/Index Physical World.w"
;
Plugins__Call__add_to_World_index(I);
Instances__index_usages(I);
Index__extra_div_close("e0e0e0");
}
{
#line 307 "inform7/Chapter 10/Index Physical World.w"
if (K) {
kind *K2;
LOOP_OVER_BASE_KINDS(K2)
if (Kinds__Compare__eq(Kinds__Compare__super(K2), K))
Data__Objects__index(NULL, K2, depth+1, details);
} else {
PL__Spatial__index_object_further(I, depth, details);
}
}
#line 199 "inform7/Chapter 10/Index Physical World.w"
;
}
#line 359 "inform7/Chapter 10/Index Physical World.w"
void Data__Objects__index_instances(kind *K, int depth) {
HTML__open_para(ifl, depth, "tight");
int c = 0;
instance *I;
LOOP_OVER_INSTANCES(I, K) c++;
if (c >= 10) {
int xtra = xtras_count++;
Index__extra_link(xtra);
INDEX("<font color=\"#808080\">%d ", c);
wording PW = Kinds__Behaviour__get_name(K, TRUE);
if (Wordings__nonempty(PW)) Wordings__index_raw(PW);
else INDEX("instances");
INDEX("</font></p>");
Index__extra_div_open(xtra, depth+1, "e0e0e0");
c = 0;
LOOP_OVER_INSTANCES(I, K) {
if (c > 0) INDEX(", "); c++;
INDEX("<font color=\"#808080\">");
Instances__index_name(I);
INDEX("</font>");
parse_node *at = Instances__get_creating_sentence(I);
if (at) Index__link(Wordings__first_wn(ParseTree__get_text(at)));
}
Index__extra_div_close("e0e0e0");
} else {
c = 0;
LOOP_OVER_INSTANCES(I, K) {
if (c > 0) INDEX(", "); c++;
INDEX("<font color=\"#808080\">");
Instances__index_name(I);
INDEX("</font>");
parse_node *at = Instances__get_creating_sentence(I);
if (at) Index__link(Wordings__first_wn(ParseTree__get_text(at)));
}
INDEX("</p>");
}
}
#line 333 "inform7/Chapter 11/Binary Predicates.w"
bp_term_details BinaryPredicates__new_term(inference_subject *infs) {
bp_term_details bptd;
bptd.called_name = EMPTY_WORDING;
bptd.function_of_other = NULL;
bptd.implies_infs = infs;
bptd.implies_kind = NULL;
bptd.index_term_as = NULL;
return bptd;
}
#line 346 "inform7/Chapter 11/Binary Predicates.w"
bp_term_details BinaryPredicates__full_new_term(inference_subject *infs, kind *K,
wording CW, i6_schema *f) {
bp_term_details bptd = BinaryPredicates__new_term(infs);
bptd.implies_kind = K;
bptd.called_name = CW;
bptd.function_of_other = f;
return bptd;
}
#line 359 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__set_term_domain(bp_term_details *bptd, kind *K) {
if (bptd == NULL) internal_error("no BPTD");
bptd->implies_kind = K;
bptd->implies_infs = Kinds__Behaviour__as_subject(K);
}
#line 368 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__set_term_function(bp_term_details *bptd, i6_schema *f) {
if (bptd == NULL) internal_error("no BPTD");
bptd->function_of_other = f;
}
i6_schema *BinaryPredicates__get_term_function(bp_term_details *bptd) {
if (bptd == NULL) internal_error("no BPTD");
return bptd->function_of_other;
}
#line 381 "inform7/Chapter 11/Binary Predicates.w"
kind *BinaryPredicates__kind(binary_predicate *bp) {
if (bp == R_equality) return Kinds__binary_construction(CON_relation, K_value, K_value);
kind *K0 = BinaryPredicates__kind_of_term(&(bp->term_details[0]));
kind *K1 = BinaryPredicates__kind_of_term(&(bp->term_details[1]));
if (K0 == NULL) K0 = K_object;
if (K1 == NULL) K1 = K_object;
return Kinds__binary_construction(CON_relation, K0, K1);
}
#line 393 "inform7/Chapter 11/Binary Predicates.w"
kind *BinaryPredicates__kind_of_term(bp_term_details *bptd) {
if (bptd == NULL) return NULL;
if (bptd->implies_kind) return bptd->implies_kind;
return InferenceSubjects__domain(bptd->implies_infs);
}
#line 402 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__index_term_details(bp_term_details *bptd) {
if (bptd->index_term_as) { INDEX("%s", bptd->index_term_as); return; }
wording W = EMPTY_WORDING;
if (bptd->implies_infs) W = InferenceSubjects__get_name_text(bptd->implies_infs);
if (Wordings__nonempty(W)) Wordings__index(W); else INDEX("--");
}
#line 415 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__add_term_as_call_parameter(OUTPUT_STREAM, ph_stack_frame *phsf, bp_term_details bptd) {
kind *K = BinaryPredicates__kind_of_term(&bptd);
kind *PK = K;
if ((PK == NULL) || (Kinds__Compare__lt(PK, K_object))) PK = K_object;
local_variable *lvar = LocalVariables__add_call_parameter(phsf,
bptd.called_name, PK);
if (Kinds__Compare__lt(K, K_object))
WRITE(" if (~~(%s ofclass %s)) rfalse;\n",
LocalVariables__lvalue(lvar), Kinds__Behaviour__I6_classname(K));
}
#line 429 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__set_index_details(binary_predicate *bp, char *left, char *right) {
if (left) {
bp->term_details[0].index_term_as = left;
bp->reversal->term_details[1].index_term_as = left;
}
if (right) {
bp->term_details[1].index_term_as = right;
bp->reversal->term_details[0].index_term_as = right;
}
}
#line 457 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate *BinaryPredicates__make_equality(void) {
binary_predicate *bp = BinaryPredicates__make_single(EQUALITY_KBP,
BinaryPredicates__new_term(NULL), BinaryPredicates__new_term(NULL),
"is", NULL, NULL, NULL,
Preform__Nonparsing__wording(relation_names_NTM, EQUALITY_RELATION_NAME));
bp->reversal = bp; bp->right_way_round = TRUE;
return bp;
}
#line 478 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate *BinaryPredicates__make_pair(int family,
bp_term_details left_term, bp_term_details right_term,
char *name, char *namer, property *pn,
i6_schema *mtf, i6_schema *tf, word_assemblage source_name) {
binary_predicate *bp, *bpr;
char namer_constructed[MAX_WORD_LENGTH+10];
if (name == NULL) name = "nameless";
if (namer == NULL) { sprintf(namer_constructed, "%s-r", name); namer = namer_constructed; }
bp = BinaryPredicates__make_single(family, left_term, right_term, name,
pn, mtf, tf, source_name);
bpr = BinaryPredicates__make_single(family, right_term, left_term, namer,
NULL, NULL, NULL, WordAssemblages__lit_0());
bp->reversal = bpr; bpr->reversal = bp;
bp->right_way_round = TRUE; bpr->right_way_round = FALSE;
if (WordAssemblages__nonempty(source_name))
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(
MISCELLANEOUS_MC,
Preform__Nonparsing__merge(relation_name_formal_NTM, 0, source_name),
Rvalues__from_binary_predicate(bp));
return bp;
}
#line 511 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate *BinaryPredicates__make_pair_sketchily(word_assemblage wa, int f) {
char *name = Vocabulary__get_exemplar(WordAssemblages__first_word(&wa), FALSE);
binary_predicate *bp =
BinaryPredicates__make_pair(EXPLICIT_KBP,
BinaryPredicates__new_term(NULL), BinaryPredicates__new_term(NULL),
name, NULL, NULL, NULL, NULL, wa);
bp->form_of_relation = f;
bp->reversal->form_of_relation = f;
return bp;
}
#line 534 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate *BinaryPredicates__make_single(int family,
bp_term_details left_term, bp_term_details right_term,
char *name, property *pn,
i6_schema *mtf, i6_schema *tf, word_assemblage rn) {
binary_predicate *bp = CREATE(binary_predicate);
bp->relation_family = family;
bp->form_of_relation = Relation_Implicit;
bp->relation_name = rn;
bp->bp_created_at = current_sentence;
Extensions__IDs__truncated_strcpy(bp->debugging_log_name, name, MAX_WORD_LENGTH+10);
bp->term_details[0] = left_term; bp->term_details[1] = right_term;
/* the |reversal| and the |right_way_round| field must be set by the caller */
/* for use in code compilation */
bp->test_function = tf;
bp->condition_defn_text = EMPTY_WORDING;
bp->make_true_function = mtf;
bp->make_false_function = NULL;
/* for use by the A-parser */
bp->arbitrary = FALSE;
bp->set_property = NULL;
bp->property_pending_text = EMPTY_WORDING;
bp->relates_values_not_objects = FALSE;
bp->knowledge_about_bp =
InferenceSubjects__new(relations,
RELN_SUB, STORE_POINTER_binary_predicate(bp), CERTAIN_CE);
/* for optimisation of run-time code */
bp->dynamic_memory = FALSE;
bp->i6_storage_property = pn;
bp->storage_kind = NULL;
bp->allow_function_simplification = TRUE;
bp->fast_route_finding = FALSE;
bp->loop_parent_optimisation_proviso = NULL;
bp->loop_parent_optimisation_ranger = NULL;
bp->record_needed = FALSE;
/* details for particular kinds of relation */
bp->a_listed_in_predicate = FALSE;
bp->same_property = NULL;
bp->comparative_property = NULL;
bp->comparison_sign = 0;
bp->equivalence_partition = NULL;
return bp;
}
#line 588 "inform7/Chapter 11/Binary Predicates.w"
wording BinaryPredicates__SUBJ_get_name_text(inference_subject *from) {
return EMPTY_WORDING; /* nameless */
}
general_pointer BinaryPredicates__SUBJ_new_permission_granted(inference_subject *from) {
return NULL_GENERAL_POINTER;
}
void BinaryPredicates__SUBJ_make_adj_const_domain(inference_subject *infs,
instance *nc, property *prn) {
}
void BinaryPredicates__SUBJ_complete_model(inference_subject *infs) {
int domain_size = NUMBER_CREATED(inference_subject);
binary_predicate *bp = InferenceSubjects__as_bp(infs);
if (BinaryPredicates__store_dynamically(bp)) return; /* handled at run-time instead */
if ((BinaryPredicates__get_form_of_relation(bp) == Relation_Equiv) && (bp->right_way_round)) {
Relations__equivalence_relation_make_singleton_partitions(bp, domain_size);
inference *i;
POSITIVE_KNOWLEDGE_LOOP(i, BinaryPredicates__as_subject(bp), ARBITRARY_RELATION_INF) {
inference_subject *infs0, *infs1;
World__Inferences__get_references(i, &infs0, &infs1);
Relations__equivalence_relation_merge_classes(bp, domain_size,
infs0->allocation_id, infs1->allocation_id);
}
Relations__equivalence_relation_add_properties(bp);
}
}
void BinaryPredicates__SUBJ_check_model(inference_subject *infs) {
binary_predicate *bp = InferenceSubjects__as_bp(infs);
if ((bp->right_way_round) &&
((bp->form_of_relation == Relation_OtoO) ||
(bp->form_of_relation == Relation_Sym_OtoO)))
Relations__check_OtoO_relation(bp);
if ((bp->right_way_round) &&
((bp->form_of_relation == Relation_OtoV) ||
(bp->form_of_relation == Relation_VtoO)))
Relations__check_OtoV_relation(bp);
}
void BinaryPredicates__SUBJ_write_element_of_condition(inference_subject *infs, char *cond) {
internal_error("BP in runtime match condition");
}
int BinaryPredicates__SUBJ_compile_all(OUTPUT_STREAM) {
return FALSE;
}
void BinaryPredicates__SUBJ_compile(OUTPUT_STREAM, inference_subject *infs) {
binary_predicate *bp = InferenceSubjects__as_bp(infs);
if (bp->right_way_round) {
if (BinaryPredicates__store_dynamically(bp)) {
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "InitialiseRelation_%d", bp->allocation_id);
OUT = Routines__begin(OUT, i6_routine_identifier);
inference *i;
POSITIVE_KNOWLEDGE_LOOP(i, BinaryPredicates__as_subject(bp), ARBITRARY_RELATION_INF) {
parse_node *spec0, *spec1;
World__Inferences__get_references_spec(i, &spec0, &spec1);
WRITE("RelationTest(Rel_Record_%d,RELS_ASSERT_TRUE,", bp->allocation_id);
bp->record_needed = TRUE;
Specifications__Compiler__compile(OUT, spec0);
WRITE(",");
Specifications__Compiler__compile(OUT, spec1);
WRITE(");\n");
}
OUT = Routines__end(OUT);
} else {
if ((bp->form_of_relation == Relation_VtoV) ||
(bp->form_of_relation == Relation_Sym_VtoV))
Relations__compile_vtov_storage(OUT, bp);
}
}
}
#line 668 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__log_term_details(bp_term_details *bptd, int i) {
LOG(" function(%d): $i\n", i, bptd->function_of_other);
if (Wordings__nonempty(bptd->called_name)) LOG(" term %d is '$w'\n", i, bptd->called_name);
if (bptd->implies_infs) {
wording W = InferenceSubjects__get_name_text(bptd->implies_infs);
if (Wordings__nonempty(W)) LOG(" term %d has domain $w\n", i, W);
}
}
void BinaryPredicates__log(binary_predicate *bp) {
int i;
if (bp == NULL) { LOG("<null-BP>\n"); return; }
LOG("BP%d <%s> - %s way round - %s\n",
bp->allocation_id, bp->debugging_log_name, bp->right_way_round?"right":"wrong",
BinaryPredicates__form_to_text(bp));
for (i=0; i<2; i++) BinaryPredicates__log_term_details(&bp->term_details[i], i);
LOG(" test: $i\n", bp->test_function);
LOG(" make true: $i\n", bp->make_true_function);
LOG(" make false: $i\n", bp->make_false_function);
LOG(" storage property: $Y\n", bp->i6_storage_property);
}
#line 697 "inform7/Chapter 11/Binary Predicates.w"
int relation_name_NTMR(wording W, int *X, void **XP) {
#line 698 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate *bp;
LOOP_OVER(bp, binary_predicate)
if (WordAssemblages__compare_with_wording(&(bp->relation_name), W)) {
*XP = bp; return TRUE;
}
return FALSE;
}
#line 709 "inform7/Chapter 11/Binary Predicates.w"
char *BinaryPredicates__get_log_name(binary_predicate *bp) {
return bp->debugging_log_name;
}
#line 716 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__get_form_of_relation(binary_predicate *bp) {
return bp->form_of_relation;
}
int BinaryPredicates__is_explicit_with_runtime_storage(binary_predicate *bp) {
if (bp->right_way_round == FALSE) bp = bp->reversal;
if (bp->form_of_relation == Relation_Implicit) return FALSE;
if (bp->form_of_relation == Relation_ByRoutine) return FALSE;
return TRUE;
}
char *BinaryPredicates__form_to_text(binary_predicate *bp) {
switch(bp->form_of_relation) {
case Relation_Implicit: return "Relation_Implicit";
case Relation_OtoO: return "Relation_OtoO";
case Relation_OtoV: return "Relation_OtoV";
case Relation_VtoO: return "Relation_VtoO";
case Relation_VtoV: return "Relation_VtoV";
case Relation_Sym_OtoO: return "Relation_Sym_OtoO";
case Relation_Sym_VtoV: return "Relation_Sym_VtoV";
case Relation_Equiv: return "Relation_Equiv";
case Relation_ByRoutine: return "Relation_ByRoutine";
default: return "formless-BP";
}
}
parse_node *BinaryPredicates__get_bp_created_at(binary_predicate *bp) {
return bp->bp_created_at;
}
#line 747 "inform7/Chapter 11/Binary Predicates.w"
kind *BinaryPredicates__term_kind(binary_predicate *bp, int t) {
return BinaryPredicates__kind_of_term(&(bp->term_details[t]));
}
i6_schema *BinaryPredicates__get_term_as_function_of_other(binary_predicate *bp, int t) {
return bp->term_details[t].function_of_other;
}
#line 757 "inform7/Chapter 11/Binary Predicates.w"
binary_predicate *BinaryPredicates__get_reversal(binary_predicate *bp) {
return bp->reversal;
}
int BinaryPredicates__is_the_wrong_way_round(binary_predicate *bp) {
if (bp->right_way_round == FALSE) return TRUE;
return FALSE;
}
#line 768 "inform7/Chapter 11/Binary Predicates.w"
i6_schema *BinaryPredicates__get_test_function(binary_predicate *bp) {
return bp->test_function;
}
int BinaryPredicates__can_be_made_true_at_runtime(binary_predicate *bp) {
if ((bp->make_true_function) ||
(bp->reversal->make_true_function)) return TRUE;
return FALSE;
}
#line 785 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__allow_arbitrary_assertions(binary_predicate *bp) {
return bp->arbitrary;
}
int BinaryPredicates__store_dynamically(binary_predicate *bp) {
return bp->dynamic_memory;
}
int BinaryPredicates__relates_values_not_objects(binary_predicate *bp) {
return bp->relates_values_not_objects;
}
inference_subject *BinaryPredicates__as_subject(binary_predicate *bp) {
return bp->knowledge_about_bp;
}
#line 801 "inform7/Chapter 11/Binary Predicates.w"
property *BinaryPredicates__get_i6_storage_property(binary_predicate *bp) {
return bp->i6_storage_property;
}
int BinaryPredicates__allows_function_simplification(binary_predicate *bp) {
return bp->allow_function_simplification;
}
void BinaryPredicates__mark_as_needed(binary_predicate *bp) {
bp->record_needed = TRUE;
}
#line 814 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__set_comparison_details(binary_predicate *bp,
int sign, property *prn) {
bp->comparison_sign = sign; bp->comparative_property = prn;
}
#line 831 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__write_optimised_loop_schema(i6_schema *sch, binary_predicate *bp) {
if (bp == NULL) return FALSE;
{
#line 844 "inform7/Chapter 11/Binary Predicates.w"
if (bp->loop_parent_optimisation_ranger) {
Calculus__Schemas__modify(sch,
"for (*1=%s(*2): *1: *1=%s(*2,*1))",
bp->loop_parent_optimisation_ranger,
bp->loop_parent_optimisation_ranger);
return TRUE;
}
}
#line 833 "inform7/Chapter 11/Binary Predicates.w"
;
{
#line 861 "inform7/Chapter 11/Binary Predicates.w"
if (bp->loop_parent_optimisation_proviso) {
Calculus__Schemas__modify(sch,
"objectloop (*1 in *2) if (%s(*1)==parent(*1))",
bp->loop_parent_optimisation_proviso);
return TRUE;
}
}
#line 834 "inform7/Chapter 11/Binary Predicates.w"
;
return FALSE;
}
#line 874 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__make_built_in(void) {
Calculus__Equality__REL_create_initial_stock();
Properties__ProvisionRelation__REL_create_initial_stock();
Relations__Universal__REL_create_initial_stock();
Calculus__QuasinumericRelations__REL_create_initial_stock();
PL__SpatialRelations__REL_create_initial_stock();
PL__MapDirections__REL_create_initial_stock();
Properties__SettingRelations__REL_create_initial_stock();
Properties__SameRelations__REL_create_initial_stock();
Properties__ComparativeRelations__REL_create_initial_stock();
Tables__Relations__REL_create_initial_stock();
Relations__Explicit__REL_create_initial_stock();
}
#line 891 "inform7/Chapter 11/Binary Predicates.w"
void BinaryPredicates__make_built_in_further(void) {
Calculus__Equality__REL_create_second_stock();
Properties__ProvisionRelation__REL_create_second_stock();
Relations__Universal__REL_create_second_stock();
Calculus__QuasinumericRelations__REL_create_second_stock();
PL__SpatialRelations__REL_create_second_stock();
PL__MapDirections__REL_create_second_stock();
Properties__SettingRelations__REL_create_second_stock();
Properties__SameRelations__REL_create_second_stock();
Properties__ComparativeRelations__REL_create_second_stock();
Tables__Relations__REL_create_second_stock();
Relations__Explicit__REL_create_second_stock();
}
#line 911 "inform7/Chapter 11/Binary Predicates.w"
int BinaryPredicates__typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
int result = DECLINE_TO_MATCH;
switch (bp->relation_family) {
case EQUALITY_KBP: result = Calculus__Equality__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case PROVISION_KBP: result = Properties__ProvisionRelation__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case UNIVERSAL_KBP: result = Relations__Universal__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case QUASINUMERIC_KBP: result = Calculus__QuasinumericRelations__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case SPATIAL_KBP: result = PL__SpatialRelations__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case MAP_CONNECTING_KBP: result = PL__MapDirections__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case PROPERTY_SETTING_KBP: result = Properties__SettingRelations__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case PROPERTY_SAME_KBP: result = Properties__SameRelations__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case PROPERTY_COMPARISON_KBP: result = Properties__ComparativeRelations__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case LISTED_IN_KBP: result = Tables__Relations__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
case EXPLICIT_KBP: result = Relations__Explicit__REL_typecheck(bp, kinds_of_terms, kinds_required, tck); break;
default: internal_error("typechecked unknown KBP");
}
return result;
}
int BinaryPredicates__assert(binary_predicate *bp,
inference_subject *subj0, parse_node *spec0, inference_subject *subj1, parse_node *spec1) {
int success = FALSE;
switch (bp->relation_family) {
case EQUALITY_KBP: success = Calculus__Equality__REL_assert(bp, subj0, spec0, subj1, spec1); break;
case PROVISION_KBP: success = Properties__ProvisionRelation__REL_assert(bp, subj0, spec0, subj1, spec1); break;
case UNIVERSAL_KBP: success = Relations__Universal__REL_assert(bp, subj0, spec0, subj1, spec1); break;
case QUASINUMERIC_KBP: success = Calculus__QuasinumericRelations__REL_assert(bp, subj0, spec0, subj1, spec1); break;
case SPATIAL_KBP: success = PL__SpatialRelations__REL_assert(bp, subj0, spec0, subj1, spec1); break;
case MAP_CONNECTING_KBP: success = PL__MapDirections__REL_assert(bp, subj0, spec0, subj1, spec1); break;
case PROPERTY_SETTING_KBP: success = Properties__SettingRelations__REL_assert(bp, subj0, spec0, subj1, spec1); break;
case PROPERTY_SAME_KBP: success = Properties__SameRelations__REL_assert(bp, subj0, spec0, subj1, spec1); break;
case PROPERTY_COMPARISON_KBP: success = Properties__ComparativeRelations__REL_assert(bp, subj0, spec0, subj1, spec1); break;
case LISTED_IN_KBP: success = Tables__Relations__REL_assert(bp, subj0, spec0, subj1, spec1); break;
case EXPLICIT_KBP: success = Relations__Explicit__REL_assert(bp, subj0, spec0, subj1, spec1); break;
default: internal_error("asserted unknown KBP");
}
return success;
}
i6_schema *BinaryPredicates__get_i6_schema(int task, binary_predicate *bp, annotated_i6_schema *asch) {
int success = FALSE;
switch (bp->relation_family) {
case EQUALITY_KBP: success = Calculus__Equality__REL_compile(task, bp, asch); break;
case PROVISION_KBP: success = Properties__ProvisionRelation__REL_compile(task, bp, asch); break;
case UNIVERSAL_KBP: success = Relations__Universal__REL_compile(task, bp, asch); break;
case QUASINUMERIC_KBP: success = Calculus__QuasinumericRelations__REL_compile(task, bp, asch); break;
case SPATIAL_KBP: success = PL__SpatialRelations__REL_compile(task, bp, asch); break;
case MAP_CONNECTING_KBP: success = PL__MapDirections__REL_compile(task, bp, asch); break;
case PROPERTY_SETTING_KBP: success = Properties__SettingRelations__REL_compile(task, bp, asch); break;
case PROPERTY_SAME_KBP: success = Properties__SameRelations__REL_compile(task, bp, asch); break;
case PROPERTY_COMPARISON_KBP: success = Properties__ComparativeRelations__REL_compile(task, bp, asch); break;
case LISTED_IN_KBP: success = Tables__Relations__REL_compile(task, bp, asch); break;
case EXPLICIT_KBP: success = Relations__Explicit__REL_compile(task, bp, asch); break;
default: internal_error("compiled unknown KBP");
}
if (success == FALSE) {
switch(task) {
case TEST_ATOM_TASK: asch->schema = bp->test_function; break;
case NOW_ATOM_TRUE_TASK: asch->schema = bp->make_true_function; break;
case NOW_ATOM_FALSE_TASK: asch->schema = bp->make_false_function; break;
}
}
return asch->schema;
}
void BinaryPredicates__describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
int success = FALSE;
switch (bp->relation_family) {
case EQUALITY_KBP: success = Calculus__Equality__REL_describe_for_problems(OUT, bp); break;
case PROVISION_KBP: success = Properties__ProvisionRelation__REL_describe_for_problems(OUT, bp); break;
case UNIVERSAL_KBP: success = Relations__Universal__REL_describe_for_problems(OUT, bp); break;
case QUASINUMERIC_KBP: success = Calculus__QuasinumericRelations__REL_describe_for_problems(OUT, bp); break;
case SPATIAL_KBP: success = PL__SpatialRelations__REL_describe_for_problems(OUT, bp); break;
case MAP_CONNECTING_KBP: success = PL__MapDirections__REL_describe_for_problems(OUT, bp); break;
case PROPERTY_SETTING_KBP: success = Properties__SettingRelations__REL_describe_for_problems(OUT, bp); break;
case PROPERTY_SAME_KBP: success = Properties__SameRelations__REL_describe_for_problems(OUT, bp); break;
case PROPERTY_COMPARISON_KBP: success = Properties__ComparativeRelations__REL_describe_for_problems(OUT, bp); break;
case LISTED_IN_KBP: success = Tables__Relations__REL_describe_for_problems(OUT, bp); break;
case EXPLICIT_KBP: success = Relations__Explicit__REL_describe_for_problems(OUT, bp); break;
default: internal_error("found unknown KBP");
}
if (success == NOT_APPLICABLE) return;
if (success == FALSE) {
if (WordAssemblages__nonempty(bp->relation_name)) {
WRITE("the ");
WordAssemblages__copy_to_stream(OUT, &(bp->relation_name));
} else WRITE("a");
WRITE(" relation");
}
kind *K0 = BinaryPredicates__term_kind(bp, 0); if (K0 == NULL) K0 = K_object;
kind *K1 = BinaryPredicates__term_kind(bp, 1); if (K1 == NULL) K1 = K_object;
WRITE(" (between ");
if (Kinds__Compare__eq(K0, K1)) {
Kinds__Textual__write_plural(OUT, K0);
} else {
Kinds__Textual__write_articled(OUT, K0);
WRITE(" and ");
Kinds__Textual__write_articled(OUT, K1);
}
WRITE(")");
}
#line 66 "inform7/Chapter 11/Relations.w"
int relation_names_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 89 "inform7/Chapter 11/Relations.w"
#line 109 "inform7/Chapter 11/Relations.w"
int relates_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 116 "inform7/Chapter 11/Relations.w"
*X = FALSE;
Problems__Issue__sentence_problem(_p_(PM_RelationExists),
"that relation already exists",
"and cannot have its definition amended now.");
}
#line 110 "inform7/Chapter 11/Relations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 112 "inform7/Chapter 11/Relations.w"
#line 124 "inform7/Chapter 11/Relations.w"
void Relations__parse_new(parse_node *PN) {
Preform__parse_nt_against_word_range(relates_sentence_subject_NTM, ParseTree__get_text(PN->down->next), NULL, NULL);
if (most_recent_result) {
wording W = ParseTree__get_text(PN->down->next);
W = Wordings__truncate(W, 31);
binary_predicate *bp = BinaryPredicates__make_pair_sketchily(
WordAssemblages__from_wording(W), Relation_OtoO);
ParseTree__set_new_relation_here(PN->down->next, bp);
}
}
#line 147 "inform7/Chapter 11/Relations.w"
sentence_handler NEW_RELATION_SH_handler =
{ SENTENCE_NT, NEW_RELATION_VB, 1, Relations__parse_new_relation_further };
void Relations__parse_new_relation_further(parse_node *PN) {
wording RW = ParseTree__get_text(PN->down->next); /* relation name */
wording FW = ParseTree__get_text(PN->down->next->next); /* left term declaration, before "to" */
wording SW = ParseTree__get_text(PN->down->next->next->next); /* right term declaration, after "to" */
binary_predicate *bp = ParseTree__get_new_relation_here(PN->down->next);
if (bp == NULL) return; /* to recover from problem */
binary_predicate *bpr = bp->reversal;
property *prn = NULL; /* used for run-time storage of this relation */
char *i6_prn_name = NULL; /* the I6 identifier for this property */
kind *storage_kind = NULL; /* what kind, if any, might be stored in it */
inference_subject *storage_infs = NULL; /* summing these up */
kind *left_kind = NULL, *right_kind = NULL; /* kind requirement */
wording CONW = EMPTY_WORDING; /* text of test condition if any */
int left_unique = NOT_APPLICABLE, /* |TRUE| for one, |FALSE| for various, */
right_unique = NOT_APPLICABLE, /* ...or |NOT_APPLICABLE| for unspecified */
symmetric = FALSE, /* a symmetric relation? */
equivalence = FALSE, /* an equivalence ("in groups") relation? */
rvno = FALSE, /* relate values not objects? */
frf = FALSE, /* use fast route-finding? */
dynamic = FALSE, /* use dynamic memory allocation for storage? */
provide_prn = FALSE, /* allocate the storage property to the kind? */
calling_made = FALSE; /* one of the terms has been given a name */
if (bp == NULL) internal_error("BP in relation not initially parsed");
if (Wordings__length(RW) > MAX_WORDS_IN_ASSEMBLAGE-4) {
Problems__Issue__sentence_problem(_p_(PM_RelationNameTooLong),
"this is too long a name for a single relation to have",
"and would become unwieldy.");
RW = Wordings__truncate(RW, MAX_WORDS_IN_ASSEMBLAGE-4);
}
{
#line 307 "inform7/Chapter 11/Relations.w"
LOGIF(RELATION_DEFINITIONS,
"Relation definition of $w: left term: '$w', right term: '$w'\n",
RW, FW, SW);
wording LCALLW = EMPTY_WORDING; /* left term "calling" name */
wording RCALLW = EMPTY_WORDING; /* right term "calling" name */
Preform__parse_nt_against_word_range(relates_sentence_left_object_NTM, FW, NULL, NULL);
int left_bitmap = most_recent_result;
if (left_bitmap & CALLED_RBIT) LCALLW = GET_RW(relates_sentence_left_object_NTM, 1);
FW = GET_RW(relation_term_basic_NTM, 1);
Preform__parse_nt_against_word_range(relates_sentence_right_object_NTM, SW, NULL, NULL);
int right_bitmap = most_recent_result;
if (right_bitmap & CALLED_RBIT) RCALLW = GET_RW(relation_term_right_named_NTM, 1);
SW = GET_RW(relation_term_basic_NTM, 1);
if (right_bitmap & WHEN_RBIT)
CONW = GET_RW(relates_sentence_right_object_NTM, 1);
{
#line 366 "inform7/Chapter 11/Relations.w"
if (left_bitmap & ONE_RBIT) left_unique = TRUE;
if (left_bitmap & VAR_RBIT) left_unique = FALSE;
if (right_bitmap & ONE_RBIT) right_unique = TRUE;
if (right_bitmap & VAR_RBIT) right_unique = FALSE;
if (right_bitmap & FRF_RBIT) frf = TRUE;
if (frf && (left_unique != FALSE) && (right_unique != FALSE)) {
Problems__Issue__sentence_problem(_p_(PM_FRFUnavailable),
"fast route-finding is only possible with various-to-various "
"relations",
"though this doesn't matter because with other relations the "
"standard route-finding algorithm is efficient already.");
return;
}
}
#line 326 "inform7/Chapter 11/Relations.w"
;
{
#line 389 "inform7/Chapter 11/Relations.w"
if (right_bitmap & WHEN_RBIT) {
if ((left_unique != NOT_APPLICABLE) || (right_unique != NOT_APPLICABLE)) {
Problems__Issue__sentence_problem(_p_(PM_OneOrVariousWithWhen),
"this relation is a mixture of different syntaxes",
"and must be simplified. If it is going to specify 'one' or "
"'various' then it cannot also say 'when' the relation holds.");
return;
}
}
}
#line 327 "inform7/Chapter 11/Relations.w"
;
{
#line 405 "inform7/Chapter 11/Relations.w"
if ((left_bitmap & CALLED_RBIT) || (right_bitmap & CALLED_RBIT))
calling_made = TRUE;
}
#line 328 "inform7/Chapter 11/Relations.w"
;
{
#line 414 "inform7/Chapter 11/Relations.w"
int specified_one = left_unique;
if (right_bitmap & ANOTHER_RBIT) {
symmetric = TRUE; left_unique = TRUE; right_unique = TRUE;
}
if (right_bitmap & EACHOTHER_RBIT) {
symmetric = TRUE; left_unique = FALSE; right_unique = FALSE;
}
if (right_bitmap & GROUPS_RBIT) {
symmetric = TRUE; left_unique = FALSE; right_unique = FALSE; equivalence = TRUE;
}
if ((specified_one == TRUE) && (left_unique == FALSE)) {
Problems__Issue__sentence_problem(_p_(PM_BothOneAndMany),
"the left-hand term in this relation seems to be both 'one' thing "
"and also many things",
"given the mention of 'each other'. Try removing the 'one'.");
return;
}
}
#line 329 "inform7/Chapter 11/Relations.w"
;
{
#line 449 "inform7/Chapter 11/Relations.w"
if (Wordings__empty(CONW)) {
if ((left_unique == FALSE) && (Wordings__nonempty(LCALLW))) {
Problems__Issue__sentence_problem(_p_(PM_CantCallLeft),
"the left-hand term of this relation is not unique",
"so you cannot assign a name to it using 'called'.");
return;
}
if ((right_unique == FALSE) && (Wordings__nonempty(RCALLW))) {
Problems__Issue__sentence_problem(_p_(PM_CantCallRight),
"the right-hand term of this relation is not unique",
"so you cannot assign a name to it using 'called'.");
return;
}
if ((Wordings__nonempty(LCALLW)) && (Wordings__nonempty(RCALLW))) {
Problems__Issue__sentence_problem(_p_(PM_CantCallBoth),
"the terms of the relation can't be named on both sides at once",
"and because of that it's best to use a single even-handed name: "
"for instance, 'Marriage relates one person to another (called "
"the spouse).' rather than 'Employment relates one person (called "
"the boss) to one person (called the underling).'");
return;
}
if ((symmetric == FALSE) && (left_unique) && (right_unique) && (Wordings__nonempty(RCALLW))) {
Problems__Issue__sentence_problem(_p_(PM_OneToOneMiscalled),
"with a one-to-one relation which is not symmetrical "
"only the left-hand item can be given a name using 'called'",
"so this needs rephrasing to name the left in terms of the right "
"rather than vice versa. For instance, 'Transmission relates "
"one remote to one gadget (called the target).' should be "
"rephrased as 'Transmission relates one gadget (called the "
"target) to one remote.' It will then be possible to talk about "
"'the gadget of' any given remote.");
return;
}
}
}
#line 330 "inform7/Chapter 11/Relations.w"
;
{
#line 492 "inform7/Chapter 11/Relations.w"
if (Relations__parse_relation_term_type(FW, &left_kind, "left") == FALSE) return;
if (symmetric) {
right_kind = left_kind;
} else {
if (Relations__parse_relation_term_type(SW, &right_kind, "right") == FALSE) return;
}
rvno = TRUE;
if ((Kinds__Compare__le(left_kind, K_object)) &&
(Kinds__Compare__le(right_kind, K_object))) rvno = FALSE;
if (Wordings__empty(CONW)) {
if ((Kinds__Compare__lt(left_kind, K_object) == FALSE) &&
(Relations__check_finite_range(left_kind) == FALSE)) dynamic = TRUE;
if ((Kinds__Compare__lt(right_kind, K_object) == FALSE) &&
(symmetric == FALSE) &&
(Relations__check_finite_range(right_kind) == FALSE)) dynamic = TRUE;
}
}
#line 331 "inform7/Chapter 11/Relations.w"
;
if (left_unique == NOT_APPLICABLE) {
left_unique = FALSE;
if ((Wordings__nonempty(LCALLW)) || (right_unique == FALSE)) left_unique = TRUE;
}
if (right_unique == NOT_APPLICABLE) {
right_unique = FALSE;
if ((Wordings__nonempty(RCALLW)) || (left_unique == FALSE)) right_unique = TRUE;
}
if (Wordings__empty(CONW))
{
#line 518 "inform7/Chapter 11/Relations.w"
if (Wordings__nonempty(LCALLW)) {
prn = Properties__Valued__obtain_within_kind(LCALLW, left_kind);
if (prn == NULL) return;
} else if (Wordings__nonempty(RCALLW)) {
prn = Properties__Valued__obtain_within_kind(RCALLW, right_kind);
if (prn == NULL) return;
} else {
word_assemblage pw_wa =
Preform__Nonparsing__merge(relation_storage_construction_NTM, 0,
WordAssemblages__from_wording(RW));
wording PW = WordAssemblages__to_wording(&pw_wa);
prn = Properties__Valued__obtain_within_kind(PW, K_object);
if (prn == NULL) return;
Properties__exclude_from_index(prn);
}
i6_prn_name = Properties__get_translation(prn);
storage_kind = left_kind;
kind *PK = NULL;
if (left_unique) {
storage_kind = right_kind;
if (left_kind) PK = left_kind;
} else if (right_unique) {
storage_kind = left_kind;
if (right_kind) PK = right_kind;
}
if (Kinds__Compare__le(PK, K_object) == FALSE) Properties__Valued__set_kind(prn, PK);
if (storage_kind) storage_infs = Kinds__Behaviour__as_subject(storage_kind);
else storage_infs = NULL;
if (Kinds__Compare__le(storage_kind, K_object) == FALSE) bp->storage_kind = storage_kind;
if (((left_unique) || (right_unique)) && (PK) &&
(Kinds__Compare__le(PK, K_object) == FALSE))
Properties__Valued__now_used_for_non_typesafe_relation(prn);
}
#line 342 "inform7/Chapter 11/Relations.w"
;
{
#line 349 "inform7/Chapter 11/Relations.w"
bp_term_details left_bptd, right_bptd;
inference_subject *left_infs = NULL, *right_infs = NULL;
if (left_kind) left_infs = Kinds__Behaviour__as_subject(left_kind);
if (right_kind) right_infs = Kinds__Behaviour__as_subject(right_kind);
left_bptd = BinaryPredicates__full_new_term(left_infs, left_kind, LCALLW, NULL);
right_bptd = BinaryPredicates__full_new_term(right_infs, right_kind, RCALLW, NULL);
bp->term_details[0] = left_bptd; bp->term_details[1] = right_bptd;
bpr->term_details[0] = right_bptd; bpr->term_details[1] = left_bptd;
}
#line 344 "inform7/Chapter 11/Relations.w"
;
}
#line 185 "inform7/Chapter 11/Relations.w"
;
if (rvno) { bp->relates_values_not_objects = TRUE; bpr->relates_values_not_objects = TRUE; }
if (frf) { bp->fast_route_finding = TRUE; bpr->fast_route_finding = TRUE; }
if (prn) {
bp->i6_storage_property = prn; bpr->i6_storage_property = prn;
Properties__Valued__set_stored_relation(prn, bp);
}
if (dynamic) { bp->dynamic_memory = TRUE; bpr->dynamic_memory = TRUE; }
bp->record_needed = TRUE;
if (Wordings__nonempty(CONW))
{
#line 686 "inform7/Chapter 11/Relations.w"
bp->form_of_relation = Relation_ByRoutine;
bp->test_function = Calculus__Schemas__new("(Relation_%d(*1,*2))", bp->allocation_id);
bp->condition_defn_text = CONW;
}
#line 196 "inform7/Chapter 11/Relations.w"
else if (equivalence)
{
#line 664 "inform7/Chapter 11/Relations.w"
bp->form_of_relation = Relation_Equiv;
bp->arbitrary = TRUE;
provide_prn = TRUE;
if (Kinds__Compare__le(storage_kind, K_object)) {
bp->test_function = Calculus__Schemas__new("(*1.%s == *2.%s)", i6_prn_name, i6_prn_name);
bp->make_true_function = Calculus__Schemas__new("Relation_NowEquiv(*1,%s,*2)", i6_prn_name);
bp->make_false_function = Calculus__Schemas__new("Relation_NowNEquiv(*1,%s,*2)", i6_prn_name);
} else {
bp->test_function =
Calculus__Schemas__new("(GProperty(%k, *1, %s) == GProperty(%k, *2, %s))",
storage_kind, i6_prn_name, storage_kind, i6_prn_name);
bp->make_true_function =
Calculus__Schemas__new("Relation_NowEquivV(*1,*2,%k,%s)", storage_kind, i6_prn_name);
bp->make_false_function =
Calculus__Schemas__new("Relation_NowNEquivV(*1,*2,%k,%s)", storage_kind, i6_prn_name);
}
Properties__Valued__set_kind(prn, K_number);
}
#line 197 "inform7/Chapter 11/Relations.w"
else if (left_unique) {
if (right_unique) {
if (symmetric)
{
#line 634 "inform7/Chapter 11/Relations.w"
bp->form_of_relation = Relation_Sym_OtoO;
provide_prn = TRUE;
if (Kinds__Compare__le(storage_kind, K_object)) {
bp->make_true_function = Calculus__Schemas__new("Relation_NowS1to1(*2,%s,*1)", i6_prn_name);
bp->make_false_function = Calculus__Schemas__new("Relation_NowSN1to1(*2,%s,*1)", i6_prn_name);
} else {
bp->make_true_function = Calculus__Schemas__new("Relation_NowS1to1V(*2,*1,%k,%s)",
storage_kind, i6_prn_name);
bp->make_false_function = Calculus__Schemas__new("Relation_NowSN1to1V(*2,*1,%k,%s)",
storage_kind, i6_prn_name);
}
}
#line 200 "inform7/Chapter 11/Relations.w"
else
{
#line 574 "inform7/Chapter 11/Relations.w"
bp->form_of_relation = Relation_OtoO;
provide_prn = TRUE;
if (Kinds__Compare__le(storage_kind, K_object)) {
bp->make_true_function = Calculus__Schemas__new("Relation_Now1to1(*2,%s,*1)", i6_prn_name);
bp->make_false_function = Calculus__Schemas__new("Relation_NowN1toV(*2,%s,*1)", i6_prn_name);
} else {
bp->make_true_function = Calculus__Schemas__new("Relation_Now1to1V(*2,*1,%k,%s)",
storage_kind, i6_prn_name);
bp->make_false_function = Calculus__Schemas__new("Relation_NowN1toVV(*2,*1,%k,%s)",
storage_kind, i6_prn_name);
}
}
#line 201 "inform7/Chapter 11/Relations.w"
;
} else
{
#line 589 "inform7/Chapter 11/Relations.w"
bp->form_of_relation = Relation_OtoV;
provide_prn = TRUE;
if (Kinds__Compare__le(storage_kind, K_object)) {
bp->make_true_function = Calculus__Schemas__new("*2.%s = *1", i6_prn_name);
bp->make_false_function = Calculus__Schemas__new("Relation_NowN1toV(*2,%s,*1)", i6_prn_name);
} else {
bp->make_true_function = Calculus__Schemas__new("WriteGProperty(%k, *2, %s, *1)",
storage_kind, i6_prn_name);
bp->make_false_function = Calculus__Schemas__new("Relation_NowN1toVV(*2,*1,%k,%s)",
storage_kind, i6_prn_name);
}
}
#line 202 "inform7/Chapter 11/Relations.w"
;
} else {
if (right_unique)
{
#line 604 "inform7/Chapter 11/Relations.w"
bp->form_of_relation = Relation_VtoO;
provide_prn = TRUE;
if (Kinds__Compare__le(storage_kind, K_object)) {
bp->make_true_function = Calculus__Schemas__new("*1.%s = *2", i6_prn_name);
bp->make_false_function = Calculus__Schemas__new("Relation_NowN1toV(*1,%s,*2)", i6_prn_name);
} else {
bp->make_true_function = Calculus__Schemas__new("WriteGProperty(%k, *1, %s, *2)",
storage_kind, i6_prn_name);
bp->make_false_function = Calculus__Schemas__new("Relation_NowN1toVV(*1,*2,%k,%s)",
storage_kind, i6_prn_name);
}
}
#line 204 "inform7/Chapter 11/Relations.w"
else if (symmetric)
{
#line 650 "inform7/Chapter 11/Relations.w"
bp->form_of_relation = Relation_Sym_VtoV;
bp->arbitrary = TRUE;
bp->test_function = Calculus__Schemas__new("(Relation_TestVtoV(*1,Rel_Record_%d,*2,true))",
bp->allocation_id);
bp->make_true_function = Calculus__Schemas__new("(Relation_NowVtoV(*1,Rel_Record_%d,*2,true))",
bp->allocation_id);
bp->make_false_function = Calculus__Schemas__new("(Relation_NowNVtoV(*1,Rel_Record_%d,*2,true))",
bp->allocation_id);
bp->record_needed = TRUE;
}
#line 205 "inform7/Chapter 11/Relations.w"
else
{
#line 620 "inform7/Chapter 11/Relations.w"
bp->form_of_relation = Relation_VtoV;
bp->arbitrary = TRUE;
bp->test_function = Calculus__Schemas__new("(Relation_TestVtoV(*1,Rel_Record_%d,*2,false))",
bp->allocation_id);
bp->make_true_function = Calculus__Schemas__new("(Relation_NowVtoV(*1,Rel_Record_%d,*2,false))",
bp->allocation_id);
bp->make_false_function = Calculus__Schemas__new("(Relation_NowNVtoV(*1,Rel_Record_%d,*2,false))",
bp->allocation_id);
bp->record_needed = TRUE;
}
#line 206 "inform7/Chapter 11/Relations.w"
;
}
if (dynamic) {
if (calling_made)
{
#line 554 "inform7/Chapter 11/Relations.w"
Problems__Issue__sentence_problem(_p_(PM_RelNotStoredInProperty),
"a '(called ...)' name can't be used for this relation",
"because of the kinds involved in it. (Names for terms in a relation "
"only work if it's possible to store the relation using properties, "
"but that's impossible here, so Inform uses a different scheme.)");
return;
}
#line 210 "inform7/Chapter 11/Relations.w"
;
{
#line 730 "inform7/Chapter 11/Relations.w"
bp->test_function = Calculus__Schemas__new("(RelationTest(Rel_Record_%d,RELS_TEST,*1,*2))",
bp->allocation_id);
bp->make_true_function = Calculus__Schemas__new("(RelationTest(Rel_Record_%d,RELS_ASSERT_TRUE,*1,*2))",
bp->allocation_id);
bp->make_false_function = Calculus__Schemas__new("(RelationTest(Rel_Record_%d,RELS_ASSERT_FALSE,*1,*2))",
bp->allocation_id);
}
#line 211 "inform7/Chapter 11/Relations.w"
;
Kinds__RunTime__ensure_basic_heap_present();
} else {
if (provide_prn)
Calculus__Propositions__Assert__assert_true_about(
Calculus__Propositions__Abstract__to_provide_property(prn), storage_infs, prevailing_mood);
{
#line 704 "inform7/Chapter 11/Relations.w"
if (i6_prn_name) {
i6_schema *f0 = NULL, *f1 = NULL;
if (left_unique) {
if (right_kind) {
if (Kinds__Compare__le(right_kind, K_object))
f0 = Calculus__Schemas__new("(*1.%s)", i6_prn_name);
else
f0 = Calculus__Schemas__new("(GProperty(%k, *1, %s))",
right_kind, i6_prn_name);
}
} else if (right_unique) {
if (left_kind) {
if (Kinds__Compare__le(left_kind, K_object))
f1 = Calculus__Schemas__new("(*1.%s)", i6_prn_name);
else
f1 = Calculus__Schemas__new("(GProperty(%k, *1, %s))",
left_kind, i6_prn_name);
}
}
if (f0) BinaryPredicates__set_term_function(&(bp->term_details[0]), f0);
if (f1) BinaryPredicates__set_term_function(&(bp->term_details[1]), f1);
}
}
#line 217 "inform7/Chapter 11/Relations.w"
;
}
if ((Kinds__Compare__lt(left_kind, K_object)) || (Kinds__Compare__lt(right_kind, K_object))) {
relation_guard *rg = CREATE(relation_guard);
rg->check_L = NULL; if (Kinds__Compare__lt(left_kind, K_object)) rg->check_L = left_kind;
rg->check_R = NULL; if (Kinds__Compare__lt(right_kind, K_object)) rg->check_R = right_kind;
rg->inner_test = bp->test_function;
rg->inner_make_true = bp->make_true_function;
rg->inner_make_false = bp->make_false_function;
rg->guarding = bp;
rg->f0 = BinaryPredicates__get_term_function(&(bp->term_details[0]));
rg->f1 = BinaryPredicates__get_term_function(&(bp->term_details[1]));
if (rg->f0) BinaryPredicates__set_term_function(&(bp->term_details[0]),
Calculus__Schemas__new("(RGuard_f0_%d(*1))", rg->allocation_id));
if (rg->f1) BinaryPredicates__set_term_function(&(bp->term_details[1]),
Calculus__Schemas__new("(RGuard_f1_%d(*1))", rg->allocation_id));
if (bp->test_function)
bp->test_function = Calculus__Schemas__new("(RGuard_T_%d(*1,*2))", rg->allocation_id);
if (bp->make_true_function)
bp->make_true_function = Calculus__Schemas__new("(RGuard_MT_%d(*1,*2))", rg->allocation_id);
if (bp->make_false_function)
bp->make_false_function = Calculus__Schemas__new("(RGuard_MF_%d(*1,*2))", rg->allocation_id);
}
bpr->form_of_relation = bp->form_of_relation;
LOGIF(RELATION_DEFINITIONS, "Defined the binary predicate:\n$2\n", bp);
}
#line 259 "inform7/Chapter 11/Relations.w"
int relates_sentence_left_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1] | CALLED_RBIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 262 "inform7/Chapter 11/Relations.w"
int relates_sentence_right_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1] | FRF_RBIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1] | WHEN_RBIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 267 "inform7/Chapter 11/Relations.w"
int relation_term_right_named_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1] | CALLED_RBIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 271 "inform7/Chapter 11/Relations.w"
int relation_term_right_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = ANOTHER_RBIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = EACHOTHER_RBIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = GROUPS_RBIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 277 "inform7/Chapter 11/Relations.w"
int relation_term_basic_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = ONE_RBIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = VAR_RBIT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 282 "inform7/Chapter 11/Relations.w"
#line 742 "inform7/Chapter 11/Relations.w"
int relation_storage_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 744 "inform7/Chapter 11/Relations.w"
#line 749 "inform7/Chapter 11/Relations.w"
int Relations__parse_relation_term_type(wording W, kind **set_K, char *side) {
if (Preform__parse_nt_against_word_range(k_kind_articled_NTM, W, NULL, NULL)) { *set_K = most_recent_result_p; return TRUE; }
*set_K = NULL;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_text(3, side);
Problems__Issue__handmade_problem(_p_(PM_RelatedKindsUnknown));
Problems__issue_problem_segment(
"In the relation definition %1, I am unable to understand the %3-hand "
"side -- I was expecting that %2 would be either the name of a kind, "
"or the name of a kind of value, but it wasn't either of those.");
Problems__issue_problem_end();
return FALSE;
}
#line 768 "inform7/Chapter 11/Relations.w"
int Relations__check_finite_range(kind *K) {
if (Kinds__Behaviour__is_an_enumeration(K)) return TRUE;
if (K == NULL) return TRUE; /* to recover from earlier problems */
if ((Kinds__Compare__le(K, K_object)) || (Kinds__Behaviour__definite(K) == FALSE))
Problems__Issue__sentence_problem(_p_(PM_RangeOverlyBroad),
"relations aren't allowed to range over all 'objects' or all 'values'",
"as these are too broad. A relation has to be between two kinds of "
"object, or kinds of value. So 'Taming relates various people to "
"various animals' is fine, because 'people' and 'animals' both mean "
"kinds of object, but 'Wanting relates various objects to various "
"values' is not allowed.");
return FALSE;
}
#line 792 "inform7/Chapter 11/Relations.w"
void Relations__compile_defined_relation_constants(OUTPUT_STREAM) {
WRITE("Constant RELS_SYMMETRIC $8000;\n");
WRITE("Constant RELS_EQUIVALENCE $4000;\n");
WRITE("Constant RELS_X_UNIQUE $2000;\n");
WRITE("Constant RELS_Y_UNIQUE $1000;\n");
WRITE("Constant RELS_TEST $0800;\n");
WRITE("Constant RELS_ASSERT_TRUE $0400;\n");
WRITE("Constant RELS_ASSERT_FALSE $0200;\n");
WRITE("Constant RELS_SHOW $0100;\n");
WRITE("Constant RELS_ROUTE_FIND $0080;\n");
WRITE("Constant RELS_ROUTE_FIND_COUNT $0040;\n");
WRITE("Constant RELS_LOOKUP_ANY $0008;\n");
WRITE("Constant RELS_LOOKUP_ALL_X $0004;\n");
WRITE("Constant RELS_LOOKUP_ALL_Y $0002;\n");
WRITE("Constant RELS_LIST $0001;\n");
WRITE("#Iftrue (WORDSIZE == 2);\n");
WRITE("Constant REL_BLOCK_HEADER ($100*5 + $$1101);\n"); /* $2^5 = 32$ bytes block */
WRITE("#Ifnot;\n");
WRITE("Constant REL_BLOCK_HEADER ($100*6 + $$1101)*$10000;\n");
WRITE("#Endif;\n");
}
#line 817 "inform7/Chapter 11/Relations.w"
void Relations__compile_relation_records(OUTPUT_STREAM) {
binary_predicate *bp;
LOOP_OVER(bp, binary_predicate) {
binary_predicate *dbp = bp;
if (bp->right_way_round == FALSE) dbp = bp->reversal;
int minimal = FALSE;
if ((dbp == R_equality) || (dbp == R_meaning) ||
(dbp == R_provision) || (dbp == R_universal))
minimal = TRUE;
if (bp->record_needed) {
{
#line 883 "inform7/Chapter 11/Relations.w"
WRITE("Array Rel_Record_%d -->\n", bp->allocation_id); INDENT;
if (bp->dynamic_memory) {
WRITE("1;\n"); /* meaning one entry, which is 0; to be filled in later */
} else {
Kinds__RunTime__compile_block_value_header(OUT, BinaryPredicates__kind(bp),
FALSE, 8);
WRITE("NULL NULL\n");
{
#line 903 "inform7/Chapter 11/Relations.w"
WRITE("\""); WordAssemblages__copy_to_stream(OUT, &(bp->relation_name)); WRITE(" relation\"\n");
}
#line 890 "inform7/Chapter 11/Relations.w"
; WRITE(" ");
{
#line 908 "inform7/Chapter 11/Relations.w"
char *full_suite = "RELS_ASSERT_TRUE+RELS_ASSERT_FALSE+RELS_SHOW+RELS_ROUTE_FIND";
binary_predicate *dbp = bp;
if (bp->right_way_round == FALSE) dbp = bp->reversal;
WRITE("RELS_TEST");
if (minimal == FALSE) WRITE("+RELS_LOOKUP_ANY+RELS_LOOKUP_ALL_X+RELS_LOOKUP_ALL_Y+RELS_LIST");
switch(dbp->form_of_relation) {
case Relation_Implicit:
if ((minimal == FALSE) && (BinaryPredicates__can_be_made_true_at_runtime(dbp)))
WRITE("+RELS_ASSERT_TRUE+RELS_ASSERT_FALSE+RELS_LOOKUP_ANY");
break;
case Relation_OtoO: WRITE("+RELS_X_UNIQUE+RELS_Y_UNIQUE+%s", full_suite); break;
case Relation_OtoV: WRITE("+RELS_X_UNIQUE+%s", full_suite); break;
case Relation_VtoO: WRITE("+RELS_Y_UNIQUE+%s", full_suite); break;
case Relation_Sym_OtoO: WRITE("+RELS_SYMMETRIC+RELS_X_UNIQUE+RELS_Y_UNIQUE+%s", full_suite); break;
case Relation_Equiv: WRITE("+RELS_EQUIVALENCE+%s", full_suite); break;
case Relation_VtoV: WRITE("+%s", full_suite); break;
case Relation_Sym_VtoV: WRITE("+RELS_SYMMETRIC+%s", full_suite); break;
case Relation_ByRoutine: break;
default:
internal_error("Binary predicate with unknown structural type");
}
WRITE("\n");
}
#line 891 "inform7/Chapter 11/Relations.w"
; WRITE(" ");
{
#line 934 "inform7/Chapter 11/Relations.w"
binary_predicate *dbp = bp;
if (bp->right_way_round == FALSE) dbp = bp->reversal;
switch(dbp->form_of_relation) {
case Relation_Implicit: /* Field 0 is not used */
WRITE("0"); /* which is not the same as |NULL|, unlike in C */
break;
case Relation_OtoO:
case Relation_OtoV:
case Relation_VtoO:
case Relation_Sym_OtoO:
case Relation_Equiv: /* Field 0 is the property used for run-time storage */
WRITE("%s", Properties__get_translation(dbp->i6_storage_property));
break;
case Relation_VtoV:
case Relation_Sym_VtoV: /* Field 0 is the bitmap array used for run-time storage */
WRITE("V2V_Bitmap_%d", dbp->allocation_id);
break;
case Relation_ByRoutine: /* Field 0 is the routine used to test the relation */
WRITE("Relation_%d", dbp->allocation_id);
break;
default:
internal_error("Binary predicate with unknown structural type");
}
}
#line 892 "inform7/Chapter 11/Relations.w"
; WRITE(" ");
{
#line 961 "inform7/Chapter 11/Relations.w"
Kinds__RunTime__compile_strong_id(OUT, BinaryPredicates__kind(bp));
}
#line 893 "inform7/Chapter 11/Relations.w"
; WRITE(" ");
{
#line 975 "inform7/Chapter 11/Relations.w"
WRITE("Rel_Handler_%d", bp->allocation_id);
}
#line 894 "inform7/Chapter 11/Relations.w"
; WRITE(" ");
{
#line 966 "inform7/Chapter 11/Relations.w"
WRITE("\"");
if (bp->form_of_relation == Relation_Implicit)
WRITE("%s", BinaryPredicates__get_log_name(bp));
else CompiledText__from_text(OUT, ParseTree__get_text(bp->bp_created_at));
WRITE("\"");
}
#line 895 "inform7/Chapter 11/Relations.w"
;
WRITE(";\n");
}
OUTDENT;
}
#line 827 "inform7/Chapter 11/Relations.w"
;
if (bp->dynamic_memory == FALSE)
{
#line 980 "inform7/Chapter 11/Relations.w"
char *X = "X", *Y = "Y";
binary_predicate *dbp = bp;
if (bp->right_way_round == FALSE) { X = "Y"; Y = "X"; dbp = bp->reversal; }
OUT = Routines__begin_numbered(OUT, "Rel_Handler_%d", bp->allocation_id);
LocalVariables__add_named_call("rr");
LocalVariables__add_named_call("task");
LocalVariables__add_named_call("X");
LocalVariables__add_named_call("Y");
LocalVariables__add_internal_local_c("Z1", "loop counter");
LocalVariables__add_internal_local_c("Z2", "loop counter");
LocalVariables__add_internal_local_c("Z3", "loop counter");
LocalVariables__add_internal_local_c("Z4", "loop counter");
WRITE("switch (task) {\n"); INDENT;
annotated_i6_schema asch; i6_schema *i6s = NULL;
asch = Calculus__Atoms__Compile__blank_asch();
WRITE("RELS_TEST: if (");
i6s = BinaryPredicates__get_i6_schema(TEST_ATOM_TASK, dbp, &asch);
int j, adapted = FALSE;
for (j=0; j<2; j++) {
i6_schema *fnsc = BinaryPredicates__get_term_as_function_of_other(bp, j);
if (fnsc) {
if (j == 0) {
WRITE("X == ");
Calculus__Schemas__expand_textual(fnsc, OUT, Y, Y);
adapted = TRUE;
} else {
WRITE("Y == ");
Calculus__Schemas__expand_textual(fnsc, OUT, X, X);
adapted = TRUE;
}
}
}
if (adapted == FALSE) {
if (i6s == NULL) WRITE("false");
else Calculus__Schemas__expand_textual(i6s, OUT, X, Y);
}
WRITE(") rtrue; rfalse;\n");
if (minimal)
{
#line 1129 "inform7/Chapter 11/Relations.w"
WRITE("default: RunTimeProblem(RTP_RELMINIMAL, task, 0, Rel_Record_%d);\n",
bp->allocation_id);
}
#line 1019 "inform7/Chapter 11/Relations.w"
else {
{
#line 1103 "inform7/Chapter 11/Relations.w"
WRITE("RELS_LOOKUP_ANY: ");
WRITE("if (Y == RLANY_GET_X or RLANY_CAN_GET_X) {\n"); INDENT;
Relations__write_rels_lookup(OUT, dbp, 0);
OUTDENT; WRITE("} else {\n"); INDENT;
Relations__write_rels_lookup(OUT, dbp, 1);
OUTDENT; WRITE("}\n");
WRITE("RELS_LOOKUP_ALL_X, RELS_LOOKUP_ALL_Y: ");
WRITE("LIST_OF_TY_SetLength(Y, 0);\n");
WRITE("if (task == RELS_LOOKUP_ALL_X) {\n"); INDENT;
Relations__write_rels_lookup_list(OUT, dbp, 0);
OUTDENT; WRITE("} else {\n"); INDENT;
Relations__write_rels_lookup_list(OUT, dbp, 1);
OUTDENT; WRITE("}\n");
WRITE("return Y;\n");
WRITE("RELS_LIST: ");
WRITE("LIST_OF_TY_SetLength(X, 0);\n");
WRITE("if (Y == RLIST_ALL_X) {\n"); INDENT;
Relations__write_rels_lookup_list_all(OUT, dbp, 0);
OUTDENT; WRITE("} else if (Y == RLIST_ALL_Y) {\n"); INDENT;
Relations__write_rels_lookup_list_all(OUT, dbp, 1);
OUTDENT; WRITE("}\n");
WRITE("return X;\n");
}
#line 1021 "inform7/Chapter 11/Relations.w"
;
if (BinaryPredicates__can_be_made_true_at_runtime(bp)) {
asch = Calculus__Atoms__Compile__blank_asch();
WRITE("RELS_ASSERT_TRUE: ");
i6s = BinaryPredicates__get_i6_schema(NOW_ATOM_TRUE_TASK, dbp, &asch);
if (i6s == NULL) WRITE("rfalse");
else Calculus__Schemas__expand_textual(i6s, OUT, X, Y);
WRITE("; rtrue;\n");
asch = Calculus__Atoms__Compile__blank_asch();
WRITE("RELS_ASSERT_FALSE: ");
i6s = BinaryPredicates__get_i6_schema(NOW_ATOM_FALSE_TASK, dbp, &asch);
if (i6s == NULL) WRITE("rfalse");
else Calculus__Schemas__expand_textual(i6s, OUT, X, Y);
WRITE("; rtrue;\n");
}
{
#line 1069 "inform7/Chapter 11/Relations.w"
char *shower = NULL, *par = "false";
switch(dbp->form_of_relation) {
case Relation_OtoO: shower = "Relation_RShowOtoO"; break;
case Relation_OtoV: shower = "Relation_RShowOtoO"; break;
case Relation_VtoO: shower = "Relation_ShowOtoO"; break;
case Relation_Sym_OtoO: shower = "Relation_ShowOtoO"; par = "true"; break;
case Relation_Equiv: shower = "Relation_ShowEquiv"; break;
case Relation_VtoV: shower = "Relation_ShowVtoV"; break;
case Relation_Sym_VtoV: shower = "Relation_ShowVtoV"; par = "true"; break;
}
if (shower) {
WRITE("RELS_SHOW: %s(rr, %s); rtrue;\n", shower, par);
}
}
#line 1036 "inform7/Chapter 11/Relations.w"
;
{
#line 1086 "inform7/Chapter 11/Relations.w"
char *emptier = NULL, *par = "false";
switch(dbp->form_of_relation) {
case Relation_OtoO: emptier = "Relation_EmptyOtoO"; break;
case Relation_OtoV: emptier = "Relation_EmptyOtoO"; break;
case Relation_VtoO: emptier = "Relation_EmptyOtoO"; break;
case Relation_Sym_OtoO: emptier = "Relation_EmptyOtoO"; par = "true"; break;
case Relation_Equiv: emptier = "Relation_EmptyEquiv"; break;
case Relation_VtoV: emptier = "Relation_EmptyVtoV"; break;
case Relation_Sym_VtoV: emptier = "Relation_EmptyVtoV"; par = "true"; break;
}
if (emptier) {
WRITE("RELS_EMPTY: return %s(rr, %s, (X == 1));\n", emptier, par);
}
}
#line 1037 "inform7/Chapter 11/Relations.w"
;
{
#line 1048 "inform7/Chapter 11/Relations.w"
char *router = NULL, *id = "RlnGetF(rr, RR_STORAGE)"; int follow = FALSE;
switch(dbp->form_of_relation) {
case Relation_OtoO: router = "OtoVRelRouteTo"; follow = TRUE; break;
case Relation_OtoV: router = "OtoVRelRouteTo"; follow = TRUE; break;
case Relation_VtoO: router = "VtoORelRouteTo"; follow = TRUE; break;
case Relation_VtoV:
case Relation_Sym_VtoV:
id = "rr"; router = "VtoVRelRouteTo"; break;
}
if (router) {
WRITE("RELS_ROUTE_FIND: return %s(%s, X, Y);\n", router, id);
WRITE("RELS_ROUTE_FIND_COUNT: ");
if (follow)
WRITE("return RelFollowVector(%s(%s, X, Y), X, Y);\n", router, id);
else
WRITE("return %s(%s, X, Y, true);\n", router, id);
}
}
#line 1038 "inform7/Chapter 11/Relations.w"
;
}
OUTDENT; WRITE("}\n");
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
}
#line 829 "inform7/Chapter 11/Relations.w"
;
}
}
OUT = Routines__begin(OUT, "CreateDynamicRelations");
LocalVariables__add_internal_local_c("i", "loop counter");
LocalVariables__add_internal_local_c("rel", "new relation");
LOOP_OVER(bp, binary_predicate) {
if ((bp->dynamic_memory) && (bp->right_way_round)) {
WRITE("BlkValueCreate(");
Kinds__RunTime__compile_strong_id(OUT, BinaryPredicates__kind(bp));
WRITE(", Rel_Record_%d);\n", bp->allocation_id);
WRITE("RELATION_TY_Name(Rel_Record_%d, \"", bp->allocation_id);
WordAssemblages__copy_to_stream(OUT, &(bp->relation_name));
WRITE("\");\n");
switch(bp->form_of_relation) {
case Relation_OtoO:
WRITE("RELATION_TY_OToOAdjective(Rel_Record_%d, true);\n",
bp->allocation_id);
break;
case Relation_OtoV:
WRITE("RELATION_TY_OToVAdjective(Rel_Record_%d, true);\n",
bp->allocation_id);
break;
case Relation_VtoO:
WRITE("RELATION_TY_VToOAdjective(Rel_Record_%d, true);\n",
bp->allocation_id);
break;
case Relation_Sym_OtoO:
WRITE("RELATION_TY_OToOAdjective(Rel_Record_%d, true);\n",
bp->allocation_id);
WRITE("RELATION_TY_SymmetricAdjective(Rel_Record_%d, true);\n",
bp->allocation_id);
break;
case Relation_Equiv:
WRITE("RELATION_TY_EquivalenceAdjective(Rel_Record_%d, true);\n",
bp->allocation_id);
break;
case Relation_VtoV: break;
case Relation_Sym_VtoV:
WRITE("RELATION_TY_SymmetricAdjective(Rel_Record_%d, true);\n",
bp->allocation_id);
break;
}
WRITE("InitialiseRelation_%d();\n", bp->allocation_id);
}
}
OUT = Routines__end(OUT);
}
#line 1135 "inform7/Chapter 11/Relations.w"
void Relations__write_rels_lookup(OUTPUT_STREAM, binary_predicate *bp, int t) {
kind *K = BinaryPredicates__term_kind(bp, t);
if ((bp == R_containment) && (K == NULL)) K = K_object;
if (Kinds__Behaviour__compile_domain_possible(K)) {
i6_schema loop_schema;
if (Kinds__Behaviour__write_loop_schema(&loop_schema, K, FALSE)) {
Calculus__Schemas__expand_textual(&loop_schema, OUT, "Z1", "Z2");
char *pair = "X, Z1";
if (t == 0) pair = "Z1, X";
WRITE(" {\n"); INDENT;
WRITE("if (Rel_Handler_%d(rr, RELS_TEST, %s)) {\n",
bp->allocation_id, pair); INDENT;
WRITE("if (Y == RLANY_CAN_GET_X or RLANY_CAN_GET_Y) rtrue;\n");
WRITE("return Z1;\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
}
}
WRITE("if (Y == RLANY_CAN_GET_X or RLANY_CAN_GET_Y) rfalse;\n");
if (K == NULL) WRITE("rfalse;\n");
else {
WRITE("return DefaultValueOfKOV(");
Kinds__RunTime__compile_strong_id(OUT, K);
WRITE(");\n");
}
}
#line 1165 "inform7/Chapter 11/Relations.w"
void Relations__write_rels_lookup_list(OUTPUT_STREAM, binary_predicate *bp, int t) {
kind *K = BinaryPredicates__term_kind(bp, t);
if ((bp == R_containment) && (K == NULL)) K = K_object;
if (Kinds__Behaviour__compile_domain_possible(K)) {
i6_schema loop_schema;
if (Kinds__Behaviour__write_loop_schema(&loop_schema, K, FALSE)) {
Calculus__Schemas__expand_textual(&loop_schema, OUT, "Z1", "Z2");
char *pair = "X, Z1";
if (t == 0) pair = "Z1, X";
WRITE(" {\n"); INDENT;
WRITE("if (Rel_Handler_%d(rr, RELS_TEST, %s)) {\n",
bp->allocation_id, pair); INDENT;
WRITE("LIST_OF_TY_InsertItem(Y, Z1);\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
}
}
}
#line 1187 "inform7/Chapter 11/Relations.w"
void Relations__write_rels_lookup_list_all(OUTPUT_STREAM, binary_predicate *bp, int t) {
kind *KL = BinaryPredicates__term_kind(bp, 0);
kind *KR = BinaryPredicates__term_kind(bp, 1);
if ((bp == R_containment) && (KL == NULL)) KL = K_object;
if ((bp == R_containment) && (KR == NULL)) KR = K_object;
if ((Kinds__Behaviour__compile_domain_possible(KL)) && (Kinds__Behaviour__compile_domain_possible(KL))) {
i6_schema loop_schema_L, loop_schema_R;
if ((Kinds__Behaviour__write_loop_schema(&loop_schema_L, KL, FALSE)) &&
(Kinds__Behaviour__write_loop_schema(&loop_schema_R, KR, FALSE))) {
Calculus__Schemas__expand_textual(&loop_schema_L, OUT, "Z1", "Z2");
WRITE(" {\n"); INDENT;
Calculus__Schemas__expand_textual(&loop_schema_R, OUT, "Z3", "Z4");
WRITE(" {\n"); INDENT;
WRITE("if (Rel_Handler_%d(rr, RELS_TEST, Z1, Z3)) {\n",
bp->allocation_id); INDENT;
if (t == 0) WRITE("LIST_OF_TY_InsertItem(X, Z1, false, 0, true);\n");
else WRITE("LIST_OF_TY_InsertItem(X, Z3, false, 0, true);\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
}
}
}
#line 1215 "inform7/Chapter 11/Relations.w"
void Relations__compile_default_relation(OUTPUT_STREAM, char *identifier,
kind *K) {
WRITE("Array %s -->\n", identifier); INDENT;
Kinds__RunTime__compile_block_value_header(OUT, K, FALSE, 8);
WRITE(" NULL NULL\n");
WRITE("\"default value of ");
Kinds__Textual__write(OUT, K); WRITE("\" ");
WRITE("(RELS_TEST+RELS_ASSERT_TRUE+RELS_ASSERT_FALSE) ");
WRITE("0 ");
Kinds__RunTime__compile_strong_id(OUT, K);
WRITE(" EmptyRelationHandler ");
WRITE("\"default value of "); Kinds__Textual__write(OUT, K); WRITE("\"");
WRITE(";\n"); OUTDENT;
}
void Relations__compile_blank_relation(OUTPUT_STREAM, kind *K) {
Kinds__RunTime__compile_block_value_header(OUT, K, FALSE, 34);
WRITE(" NULL NULL\n");
WRITE("\"anonymous "); Kinds__Textual__write(OUT, K); WRITE("\" ");
WRITE("(RELS_TEST+RELS_ASSERT_TRUE+RELS_ASSERT_FALSE) ");
WRITE("7 ");
Kinds__RunTime__compile_strong_id(OUT, K);
char *handler = "DoubleHashSetRelationHandler";
kind *EK = Kinds__unary_construction_material(K);
if (Kinds__Behaviour__uses_pointer_values(EK)) handler = "HashListRelationHandler";
WRITE(" %s ", handler);
WRITE("\"an anonymous relation\"");
WRITE(" 0 0");
WRITE(" 0 0 0 0 0 0 0 0");
WRITE(" 0 0 0 0 0 0 0 0");
WRITE(" 0 0 0 0 0 0 0 0");
}
#line 1251 "inform7/Chapter 11/Relations.w"
void Relations__relations_command(OUTPUT_STREAM) {
INDENT;
binary_predicate *bp;
LOOP_OVER(bp, binary_predicate)
if (bp->record_needed) {
WRITE("callback(Rel_Record_%d);\n", bp->allocation_id);
}
OUTDENT;
}
#line 1277 "inform7/Chapter 11/Relations.w"
int word_compiled = 0, bit_counter = 0, words_compiled;
void Relations__begin_bit_stream(OUTPUT_STREAM) {
word_compiled = 0; bit_counter = 0; words_compiled = 0;
}
void Relations__compile_bit(OUTPUT_STREAM, int b) {
word_compiled += (b << bit_counter);
bit_counter++;
if (bit_counter == 16) {
WRITE("$%04x ", word_compiled);
words_compiled++;
word_compiled = 0; bit_counter = 0;
}
}
void Relations__end_bit_stream(OUTPUT_STREAM) {
while (bit_counter != 0) Relations__compile_bit(OUT, 0);
}
#line 1302 "inform7/Chapter 11/Relations.w"
void Relations__compile_vtov_storage(OUTPUT_STREAM, binary_predicate *bp) {
int left_count = 0, right_count = 0, words_used = 0, bytes_used = 0;
Relations__allocate_index_storage();
{
#line 1342 "inform7/Chapter 11/Relations.w"
left_count = Relations__relation_range(bp, 0);
right_count = Relations__relation_range(bp, 1);
}
#line 1305 "inform7/Chapter 11/Relations.w"
;
WRITE("Array V2V_Bitmap_%d --> ", bp->allocation_id);
{
#line 1348 "inform7/Chapter 11/Relations.w"
kind *left_kind = BinaryPredicates__term_kind(bp, 0);
kind *right_kind = BinaryPredicates__term_kind(bp, 1);
if ((Kinds__Compare__lt(left_kind, K_object)) && (left_count > 0))
WRITE("IK%d_Count ", Kinds__Behaviour__I6_classnumber(left_kind));
else WRITE("0 ");
if ((Kinds__Compare__lt(right_kind, K_object)) && (right_count > 0))
WRITE("IK%d_Count ", Kinds__Behaviour__I6_classnumber(right_kind));
else WRITE("0 ");
WRITE("\n %d ! Number of left instances\n", left_count);
WRITE(" %d ! Number of right instances\n ", right_count);
WRITE(" %s ! To print left instances\n",
Kinds__Behaviour__get_name_of_printing_rule(left_kind));
WRITE(" %s ! To print right instances\n",
Kinds__Behaviour__get_name_of_printing_rule(right_kind));
WRITE(" true ! Cache broken flag\n");
if ((left_count > 0) && (right_count > 0))
WRITE(" V2V_Route_Cache_%d ! Cache array (if any)\n", bp->allocation_id);
else
WRITE(" 0 ! No cache array needed\n");
words_used += 8;
}
#line 1307 "inform7/Chapter 11/Relations.w"
;
if ((left_count > 0) && (right_count > 0))
{
#line 1429 "inform7/Chapter 11/Relations.w"
char *row_flags = Memory__I7_malloc(right_count, RELATION_CONSTRUCTION_MREASON);
if (row_flags) {
Relations__begin_bit_stream(OUT);
inference_subject *infs;
LOOP_OVER(infs, inference_subject)
if (Relations__infs_in_domain(infs, bp, 0)) {
int j;
for (j=0; j<right_count; j++) row_flags[j] = 0;
{
#line 1450 "inform7/Chapter 11/Relations.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, BinaryPredicates__as_subject(bp), ARBITRARY_RELATION_INF) {
inference_subject *left_infs, *right_infs;
World__Inferences__get_references(inf, &left_infs, &right_infs);
if (infs == left_infs) row_flags[Relations__get_relation_index(right_infs, 1)] = 1;
}
}
#line 1438 "inform7/Chapter 11/Relations.w"
;
for (j=0; j<right_count; j++) Relations__compile_bit(OUT, row_flags[j]);
}
Relations__end_bit_stream(OUT);
words_used += words_compiled;
Memory__I7_free(row_flags, RELATION_CONSTRUCTION_MREASON);
}
}
#line 1310 "inform7/Chapter 11/Relations.w"
;
WRITE(";\n");
if ((left_count > 0) && (right_count > 0))
{
#line 1381 "inform7/Chapter 11/Relations.w"
kind *left_kind = BinaryPredicates__term_kind(bp, 0);
kind *right_kind = BinaryPredicates__term_kind(bp, 1);
if ((bp->fast_route_finding) &&
(Kinds__Compare__eq(left_kind, right_kind)) &&
(Kinds__Compare__lt(left_kind, K_object)) &&
(left_count == right_count)) {
if (left_count < 256) {
WRITE("Array V2V_Route_Cache_%d -> %d;\n",
bp->allocation_id, 2*left_count*left_count);
bytes_used += 2*left_count*left_count;
} else {
WRITE("Array V2V_Route_Cache_%d --> %d;\n",
bp->allocation_id, 2*left_count*left_count);
words_used += 2*left_count*left_count;
}
} else {
WRITE("Constant V2V_Route_Cache_%d = 0;\n", bp->allocation_id);
}
}
#line 1315 "inform7/Chapter 11/Relations.w"
;
char rname[MAX_WORDS_IN_ASSEMBLAGE*MAX_WORD_LENGTH];
WordAssemblages__copy_to_string(&(bp->relation_name), rname);
VirtualMachines__note_usage("relation",
ParseTree__get_text(bp->bp_created_at), rname, words_used, bytes_used, FALSE);
Relations__free_index_storage();
}
#line 1407 "inform7/Chapter 11/Relations.w"
int Relations__infs_in_domain(inference_subject *infs, binary_predicate *bp, int index) {
if (InferenceSubjects__domain(infs) != NULL) return FALSE;
kind *K = BinaryPredicates__term_kind(bp, index);
if (K == NULL) return FALSE;
inference_subject *domain_infs = Kinds__Behaviour__as_subject(K);
if (InferenceSubjects__is_strictly_within(infs, domain_infs)) return TRUE;
return FALSE;
}
#line 1461 "inform7/Chapter 11/Relations.w"
int Relations__relation_range(binary_predicate *bp, int index) {
int t = 0;
inference_subject *infs;
LOOP_OVER(infs, inference_subject) {
if (Relations__infs_in_domain(infs, bp, index)) Relations__set_relation_index(infs, index, t++);
else Relations__set_relation_index(infs, index, -1);
}
return t;
}
#line 1474 "inform7/Chapter 11/Relations.w"
int *relation_indices = NULL;
void Relations__allocate_index_storage(void) {
int nc = NUMBER_CREATED(inference_subject);
relation_indices = (int *) (Memory__I7_calloc(nc, 2*sizeof(int), OBJECT_COMPILATION_MREASON));
}
void Relations__set_relation_index(inference_subject *infs, int i, int v) {
if (relation_indices == NULL) internal_error("relation index unallocated");
relation_indices[2*(infs->allocation_id) + i] = v;
}
int Relations__get_relation_index(inference_subject *infs, int i) {
if (relation_indices == NULL) internal_error("relation index unallocated");
return relation_indices[2*(infs->allocation_id) + i];
}
void Relations__free_index_storage(void) {
if (relation_indices == NULL) internal_error("relation index unallocated");
Memory__I7_free(relation_indices, OBJECT_COMPILATION_MREASON);
relation_indices = NULL;
}
#line 1559 "inform7/Chapter 11/Relations.w"
void Relations__equivalence_relation_make_singleton_partitions(binary_predicate *bp,
int domain_size) {
int i;
int *partition_array = Memory__I7_calloc(domain_size, sizeof(int), PARTITION_MREASON);
for (i=0; i<domain_size; i++) partition_array[i] = i+1;
bp->equivalence_partition = partition_array;
}
#line 1598 "inform7/Chapter 11/Relations.w"
void Relations__equivalence_relation_merge_classes(binary_predicate *bp,
int domain_size, int ix1, int ix2) {
if (bp->form_of_relation != Relation_Equiv)
internal_error("attempt to merge classes for a non-equivalence relation");
if (bp->right_way_round == FALSE) bp = bp->reversal;
int *partition_array = bp->equivalence_partition;
if (partition_array == NULL)
internal_error("attempt to use null equivalence partition array");
int little, big; /* or, The Fairies' Parliament */
big = partition_array[ix1]; little = partition_array[ix2];
if (big == little) return;
if (big < little) { int swap = little; little = big; big = swap; }
int i;
for (i=0; i<domain_size; i++)
if (partition_array[i] == big)
partition_array[i] = little;
}
#line 1622 "inform7/Chapter 11/Relations.w"
void Relations__equivalence_relation_add_properties(binary_predicate *bp) {
kind *k = BinaryPredicates__term_kind(bp, 1);
if (Kinds__Compare__le(k, K_object)) {
instance *I;
LOOP_OVER_INSTANCES(I, k) {
inference_subject *infs = Instances__as_subject(I);
{
#line 1642 "inform7/Chapter 11/Relations.w"
parse_node *val = Rvalues__from_int(
Relations__equivalence_relation_get_class(bp, infs->allocation_id), EMPTY_WORDING);
Properties__Valued__assert(bp->i6_storage_property, infs, val, CERTAIN_CE);
}
#line 1628 "inform7/Chapter 11/Relations.w"
;
}
} else {
instance *nc;
LOOP_OVER_INSTANCES(nc, k) {
inference_subject *infs = Instances__as_subject(nc);
{
#line 1642 "inform7/Chapter 11/Relations.w"
parse_node *val = Rvalues__from_int(
Relations__equivalence_relation_get_class(bp, infs->allocation_id), EMPTY_WORDING);
Properties__Valued__assert(bp->i6_storage_property, infs, val, CERTAIN_CE);
}
#line 1634 "inform7/Chapter 11/Relations.w"
;
}
}
}
#line 1649 "inform7/Chapter 11/Relations.w"
int Relations__equivalence_relation_get_class(binary_predicate *bp, int ix) {
if (bp->form_of_relation != Relation_Equiv)
internal_error("attempt to merge classes for a non-equivalence relation");
if (bp->right_way_round == FALSE) bp = bp->reversal;
int *partition_array = bp->equivalence_partition;
if (partition_array == NULL)
internal_error("attempt to use null equivalence partition array");
return partition_array[ix];
}
#line 1668 "inform7/Chapter 11/Relations.w"
void Relations__check_OtoO_relation(binary_predicate *bp) {
int nc = NUMBER_CREATED(inference_subject);
int *right_counts = (int *)
(Memory__I7_calloc(nc, sizeof(int), OBJECT_COMPILATION_MREASON));
inference **right_first = (inference **)
(Memory__I7_calloc(nc, sizeof(inference *), OBJECT_COMPILATION_MREASON));
inference **right_second = (inference **)
(Memory__I7_calloc(nc, sizeof(inference *), OBJECT_COMPILATION_MREASON));
property *prn = BinaryPredicates__get_i6_storage_property(bp);
inference_subject *infs;
LOOP_OVER(infs, inference_subject) right_counts[infs->allocation_id] = 0;
LOOP_OVER(infs, inference_subject) {
inference *inf1 = NULL;
int leftc = 0;
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
if ((World__Inferences__get_property(inf) == prn) &&
(World__Inferences__get_certainty(inf) == CERTAIN_CE)) {
parse_node *val = World__Inferences__get_property_value(inf);
inference_subject *infs2 = InferenceSubjects__from_specification(val);
leftc++;
if (infs2) {
int m = right_counts[infs2->allocation_id]++;
if (m == 0) right_first[infs2->allocation_id] = inf;
if (m == 1) right_second[infs2->allocation_id] = inf;
}
if (leftc == 1) inf1 = inf;
if (leftc == 2) {
Problems__Issue__infs_contradiction_problem(_p_(BelievedImpossible),
World__Inferences__where_inferred(inf1), World__Inferences__where_inferred(inf),
infs, "can only relate to one other thing in this way",
"since the relation in question is one-to-one.");
}
}
}
}
LOOP_OVER(infs, inference_subject) {
if (right_counts[infs->allocation_id] >= 2) {
Problems__Issue__infs_contradiction_problem(_p_(PM_Relation1to1Right),
World__Inferences__where_inferred(right_first[infs->allocation_id]),
World__Inferences__where_inferred(right_second[infs->allocation_id]),
infs, "can only relate to one other thing in this way",
"since the relation in question is one-to-one.");
}
}
Memory__I7_free(right_second, OBJECT_COMPILATION_MREASON);
Memory__I7_free(right_first, OBJECT_COMPILATION_MREASON);
Memory__I7_free(right_counts, OBJECT_COMPILATION_MREASON);
}
void Relations__check_OtoV_relation(binary_predicate *bp) {
int nc = NUMBER_CREATED(inference_subject);
int *right_counts = (int *)
(Memory__I7_calloc(nc, sizeof(int), OBJECT_COMPILATION_MREASON));
inference **right_first = (inference **)
(Memory__I7_calloc(nc, sizeof(inference *), OBJECT_COMPILATION_MREASON));
inference **right_second = (inference **)
(Memory__I7_calloc(nc, sizeof(inference *), OBJECT_COMPILATION_MREASON));
int *left_counts = (int *)
(Memory__I7_calloc(nc, sizeof(int), OBJECT_COMPILATION_MREASON));
inference **left_first = (inference **)
(Memory__I7_calloc(nc, sizeof(inference *), OBJECT_COMPILATION_MREASON));
inference **left_second = (inference **)
(Memory__I7_calloc(nc, sizeof(inference *), OBJECT_COMPILATION_MREASON));
inference_subject *infs;
LOOP_OVER(infs, inference_subject) right_counts[infs->allocation_id] = 0;
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, BinaryPredicates__as_subject(bp), ARBITRARY_RELATION_INF) {
parse_node *left_val = NULL;
parse_node *right_val = NULL;
World__Inferences__get_references_spec(inf, &left_val, &right_val);
inference_subject *left_infs = InferenceSubjects__from_specification(left_val);
inference_subject *right_infs = InferenceSubjects__from_specification(right_val);
int left_id = (left_infs)?(left_infs->allocation_id):(-1);
int right_id = (right_infs)?(right_infs->allocation_id):(-1);
if (left_id >= 0) {
int m = left_counts[left_id]++;
if (m == 0) left_first[left_id] = inf;
if (m == 1) left_second[left_id] = inf;
}
if (right_id >= 0) {
int m = right_counts[right_id]++;
if (m == 0) right_first[right_id] = inf;
if (m == 1) right_second[right_id] = inf;
}
}
if (bp->form_of_relation == Relation_VtoO) {
LOOP_OVER(infs, inference_subject) {
if (left_counts[infs->allocation_id] >= 2) {
Problems__Issue__infs_contradiction_problem(_p_(PM_RelationVtoOContradiction),
World__Inferences__where_inferred(left_first[infs->allocation_id]),
World__Inferences__where_inferred(left_second[infs->allocation_id]),
infs, "can only relate to one other thing in this way",
"since the relation in question is various-to-one.");
}
}
} else {
LOOP_OVER(infs, inference_subject) {
if (right_counts[infs->allocation_id] >= 2) {
Problems__Issue__infs_contradiction_problem(_p_(PM_RelationOtoVContradiction),
World__Inferences__where_inferred(right_first[infs->allocation_id]),
World__Inferences__where_inferred(right_second[infs->allocation_id]),
infs, "can only be related to by one other thing in this way",
"since the relation in question is one-to-various.");
}
}
}
Memory__I7_free(right_second, OBJECT_COMPILATION_MREASON);
Memory__I7_free(right_first, OBJECT_COMPILATION_MREASON);
Memory__I7_free(right_counts, OBJECT_COMPILATION_MREASON);
Memory__I7_free(left_second, OBJECT_COMPILATION_MREASON);
Memory__I7_free(left_first, OBJECT_COMPILATION_MREASON);
Memory__I7_free(left_counts, OBJECT_COMPILATION_MREASON);
}
#line 1804 "inform7/Chapter 11/Relations.w"
void Relations__compile_defined_relations(OUTPUT_STREAM) {
Relations__compile_relation_records(OUT);
binary_predicate *bp;
LOOP_OVER(bp, binary_predicate)
if ((bp->form_of_relation == Relation_ByRoutine) && (bp->right_way_round)) {
char rname[32];
sprintf(rname, "Relation_%d", bp->allocation_id);
current_sentence = bp->bp_created_at;
WRITE("! Routine to decide if %s(t_0, t_1)\n", BinaryPredicates__get_log_name(bp));
Relations__compile_routine_to_decide(OUT, rname,
bp->condition_defn_text, bp->term_details[0], bp->term_details[1]);
}
WRITE("[ RProperty obj cl pr; if (obj ofclass cl) return obj.pr; return nothing; ];\n");
relation_guard *rg;
LOOP_OVER(rg, relation_guard) {
WRITE("! Routines guarding %s(L, R)\n", BinaryPredicates__get_log_name(rg->guarding));
OUT = Routines__begin_numbered(OUT, "RGuard_f0_%d", rg->allocation_id);
LocalVariables__add_internal_local_c("X", "which is related to at most one object");
if (rg->f0) {
if (rg->check_R) WRITE("if (X ofclass %s) ", Kinds__Behaviour__I6_classname(rg->check_R));
WRITE("return ");
Calculus__Schemas__expand_textual(rg->f0, OUT, "X", "");
WRITE(";\n");
if (rg->check_R) WRITE("return nothing;\n");
} else {
WRITE("return nothing;\n");
}
OUT = Routines__end(OUT);
OUT = Routines__begin_numbered(OUT, "RGuard_f1_%d", rg->allocation_id);
LocalVariables__add_internal_local_c("X", "which is related to at most one object");
if (rg->f1) {
if (rg->check_L) WRITE("if (X ofclass %s) ", Kinds__Behaviour__I6_classname(rg->check_L));
WRITE("return ");
Calculus__Schemas__expand_textual(rg->f1, OUT, "X", "");
WRITE(";\n");
if (rg->check_L) WRITE("return nothing;\n");
} else {
WRITE("return nothing;\n");
}
OUT = Routines__end(OUT);
OUT = Routines__begin_numbered(OUT, "RGuard_T_%d", rg->allocation_id);
LocalVariables__add_internal_local_c("L", "left member of pair");
LocalVariables__add_internal_local_c("R", "right member of pair");
if (rg->inner_test) {
WRITE("if (");
if (rg->check_L) WRITE("(L ofclass %s) && ", Kinds__Behaviour__I6_classname(rg->check_L));
if (rg->check_R) WRITE("(R ofclass %s) && ", Kinds__Behaviour__I6_classname(rg->check_R));
WRITE("(");
Calculus__Schemas__expand_textual(rg->inner_test, OUT, "L", "R");
WRITE(")) rtrue;\n");
}
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
OUT = Routines__begin_numbered(OUT, "RGuard_MT_%d", rg->allocation_id);
LocalVariables__add_internal_local_c("L", "left member of pair");
LocalVariables__add_internal_local_c("R", "right member of pair");
if (rg->inner_make_true) {
WRITE("if (");
if (rg->check_L) WRITE("(L ofclass %s)", Kinds__Behaviour__I6_classname(rg->check_L));
if ((rg->check_L) && (rg->check_R)) WRITE(" && ");
if (rg->check_R) WRITE("(R ofclass %s)", Kinds__Behaviour__I6_classname(rg->check_R));
WRITE(") {\n"); INDENT;
Calculus__Schemas__expand_textual(rg->inner_make_true, OUT, "L", "R");
WRITE("; rtrue;\n");
OUTDENT; WRITE("}\n");
WRITE("RunTimeProblem(RTP_RELKINDVIOLATION, L, R, Rel_Record_%d);\n",
rg->guarding->allocation_id);
}
OUT = Routines__end(OUT);
OUT = Routines__begin_numbered(OUT, "RGuard_MF_%d", rg->allocation_id);
LocalVariables__add_internal_local_c("L", "left member of pair");
LocalVariables__add_internal_local_c("R", "right member of pair");
if (rg->inner_make_true) {
WRITE("if (");
if (rg->check_L) WRITE("(L ofclass %s)", Kinds__Behaviour__I6_classname(rg->check_L));
if ((rg->check_L) && (rg->check_R)) WRITE(" && ");
if (rg->check_R) WRITE("(R ofclass %s)", Kinds__Behaviour__I6_classname(rg->check_R));
WRITE(") {\n"); INDENT;
Calculus__Schemas__expand_textual(rg->inner_make_false, OUT, "L", "R");
WRITE("; rtrue;\n");
OUTDENT; WRITE("}\n");
WRITE("RunTimeProblem(RTP_RELKINDVIOLATION, L, R, Rel_Record_%d);\n",
rg->guarding->allocation_id);
}
OUT = Routines__end(OUT);
}
}
#line 1900 "inform7/Chapter 11/Relations.w"
void Relations__compile_routine_to_decide(OUTPUT_STREAM, char *rname,
wording W, bp_term_details par1, bp_term_details par2) {
OUT = Routines__begin(OUT, rname);
ph_stack_frame *phsf = Frames__current_stack_frame();
BinaryPredicates__add_term_as_call_parameter(OUT, phsf, par1);
BinaryPredicates__add_term_as_call_parameter(OUT, phsf, par2);
LocalVariables__enable_possessive_form_of_it();
parse_node *spec = NULL;
if (Preform__parse_nt_against_word_range(s_condition_NTM, W, NULL, NULL)) spec = most_recent_result_p;
if ((spec == NULL) || (PL__Actions__Patterns__validate_when(spec) == FALSE)) {
Problems__Issue__sentence_problem(_p_(PM_BadRelationCondition),
"the condition defining this relation makes no sense to me",
"although the definition was properly formed - it is only "
"the part after 'when' which I can't follow.");
} else {
WRITE("return "); Specifications__Compiler__compile(OUT, spec); WRITE(";\n");
}
OUT = Routines__end(OUT);
}
#line 1929 "inform7/Chapter 11/Relations.w"
void Relations__index_table(void) {
binary_predicate *bp;
INDEX("<p>");
HTML__begin_plain_html_table(ifl);
HTML__first_html_column(ifl, 0); INDEX("<i>name</i>");
HTML__next_html_column(ifl, 0); INDEX("<i>category</i>");
HTML__next_html_column(ifl, 0); INDEX("<i>relates this...</i>");
HTML__next_html_column(ifl, 0); INDEX("<i>...to this</i>");
HTML__end_html_row(ifl);
LOOP_OVER(bp, binary_predicate)
if (bp->right_way_round) {
char *type = NULL, *left = NULL, *right = NULL;
switch (bp->relation_family) {
case EQUALITY_KBP: type = "equality"; left = "<i>any</i>"; right = left; break;
case QUASINUMERIC_KBP: type = "numeric"; break;
case SPATIAL_KBP: type = "spatial"; break;
case MAP_CONNECTING_KBP: type = "map"; left = "room/door"; right = left; break;
case PROVISION_KBP: type = "provision"; left = "<i>any</i>"; right = "property"; break;
case EXPLICIT_KBP:
switch (bp->form_of_relation) {
case Relation_OtoO: type = "one-to-one"; break;
case Relation_OtoV: type = "one-to-various"; break;
case Relation_VtoO: type = "various-to-one"; break;
case Relation_VtoV: type = "various-to-various"; break;
case Relation_Sym_OtoO: type = "one-to-another"; break;
case Relation_Sym_VtoV: type = "various-to-each-other"; break;
case Relation_Equiv: type = "in groups"; break;
case Relation_ByRoutine: type = "defined"; break;
}
break;
}
if ((type == NULL) || (WordAssemblages__nonempty(bp->relation_name) == FALSE)) continue;
HTML__first_html_column(ifl, 0);
WordAssemblages__index(&(bp->relation_name));
if (bp->bp_created_at) Index__link(Wordings__first_wn(ParseTree__get_text(bp->bp_created_at)));
HTML__next_html_column(ifl, 0);
if (type) INDEX("%s", type); else INDEX("--");
HTML__next_html_column(ifl, 0);
BinaryPredicates__index_term_details(&(bp->term_details[0]));
HTML__next_html_column(ifl, 0);
BinaryPredicates__index_term_details(&(bp->term_details[1]));
HTML__end_html_row(ifl);
}
HTML__end_html_table(ifl);
INDEX("</p>");
}
#line 1979 "inform7/Chapter 11/Relations.w"
void Relations__index_for_verbs(binary_predicate *bp) {
INDEX(" ... <i>");
if (bp->right_way_round == FALSE) {
bp = bp->reversal;
INDEX("reversed ");
}
WordAssemblages__index(&(bp->relation_name));
INDEX("</i>");
}
#line 14 "inform7/Chapter 11/Explicit Relations.w"
void Relations__Explicit__REL_create_initial_stock(void) {
}
void Relations__Explicit__REL_create_second_stock(void) {
}
#line 22 "inform7/Chapter 11/Explicit Relations.w"
int Relations__Explicit__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
return DECLINE_TO_MATCH;
}
#line 32 "inform7/Chapter 11/Explicit Relations.w"
int Relations__Explicit__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
{
#line 61 "inform7/Chapter 11/Explicit Relations.w"
if (BinaryPredicates__can_be_made_true_at_runtime(bp) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_Unassertable2),
"the relationship you describe is not exact enough",
"so that I do not know how to make this assertion come true. "
"For instance, saying 'The Study is adjacent to the Hallway.' "
"is not good enough because I need to know in what direction: "
"is it east of the Hallway, perhaps, or west?");
return TRUE;
}
}
#line 36 "inform7/Chapter 11/Explicit Relations.w"
;
if (BinaryPredicates__store_dynamically(bp)) {
World__Inferences__draw_relation_spec(bp, spec0, spec1);
return TRUE;
} else {
if ((infs0 == NULL) || (infs1 == NULL))
{
#line 74 "inform7/Chapter 11/Explicit Relations.w"
Problems__Issue__sentence_problem(_p_(PM_CantRelateNothing),
"the relationship you describe seems to be with nothing",
"which does not really make sense. 'Nothing' looks like a noun, "
"but really Inform uses it to mean the absence of one, so it's "
"against the rules to say something like 'Mr Cogito disputes nothing' "
"to try to put 'Mr Cogito' and 'nothing' into a relationship.");
return TRUE;
}
#line 41 "inform7/Chapter 11/Explicit Relations.w"
;
if (BinaryPredicates__allow_arbitrary_assertions(bp)) {
World__Inferences__draw_relation(bp, infs0, infs1);
if ((BinaryPredicates__get_form_of_relation(bp) == Relation_Sym_VtoV) && (infs0 != infs1))
World__Inferences__draw_relation(bp, infs1, infs0);
return TRUE;
}
if (BinaryPredicates__is_explicit_with_runtime_storage(bp)) {
Relations__Explicit__infer_property_based_relation(bp, infs1, infs0);
if ((BinaryPredicates__get_form_of_relation(bp) == Relation_Sym_OtoO) && (infs0 != infs1))
Relations__Explicit__infer_property_based_relation(bp, infs0, infs1);
return TRUE;
}
}
return FALSE;
}
#line 91 "inform7/Chapter 11/Explicit Relations.w"
void Relations__Explicit__infer_property_based_relation(binary_predicate *relation,
inference_subject *infs0, inference_subject *infs1) {
if (BinaryPredicates__get_form_of_relation(relation) == Relation_VtoO) {
inference_subject *swap=infs0; infs0=infs1; infs1=swap;
}
property *prn = BinaryPredicates__get_i6_storage_property(relation);
World__Inferences__draw_property(infs0, prn, InferenceSubjects__as_constant(infs1));
}
#line 103 "inform7/Chapter 11/Explicit Relations.w"
int Relations__Explicit__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) {
return FALSE;
}
#line 110 "inform7/Chapter 11/Explicit Relations.w"
int Relations__Explicit__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 20 "inform7/Chapter 11/The Universal Relation.w"
void Relations__Universal__REL_create_initial_stock(void) {
R_universal =
BinaryPredicates__make_pair(UNIVERSAL_KBP,
BinaryPredicates__new_term(NULL), BinaryPredicates__new_term(NULL),
"relates", NULL, NULL, NULL, NULL,
Preform__Nonparsing__wording(relation_names_NTM, UNIVERSAL_RELATION_NAME));
R_meaning =
BinaryPredicates__make_pair(UNIVERSAL_KBP,
BinaryPredicates__new_term(NULL), BinaryPredicates__new_term(NULL),
"means", NULL, NULL, NULL, NULL,
Preform__Nonparsing__wording(relation_names_NTM, MEANING_RELATION_NAME));
}
#line 37 "inform7/Chapter 11/The Universal Relation.w"
void Relations__Universal__REL_create_second_stock(void) {
}
#line 44 "inform7/Chapter 11/The Universal Relation.w"
int Relations__Universal__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
if (bp == R_meaning) {
if (Kinds__Compare__eq(kinds_of_terms[0], K_verb) == FALSE) {
Problems__quote_kind(4, kinds_of_terms[0]);
Problems__Issue__tcp_problem(_p_(...), tck,
"that asks whether something means something, and in Inform 'to mean' "
"means that a particular relation is the meaning of a given verb. "
"Here, though, we have %4 rather than the name of a verb.");
return NEVER_MATCH;
}
if (Kinds__get_construct(kinds_of_terms[1]) != CON_relation) {
Problems__quote_kind(4, kinds_of_terms[1]);
Problems__Issue__tcp_problem(_p_(...), tck,
"that asks whether something means something, and in Inform 'to mean' "
"means that a particular relation is the meaning of a given verb. "
"Here, though, we have %4 rather than the name of a relation.");
return NEVER_MATCH;
}
} else {
if (Kinds__get_construct(kinds_of_terms[0]) != CON_relation) {
Problems__quote_kind(4, kinds_of_terms[0]);
Problems__Issue__tcp_problem(_p_(BelievedImpossible), tck,
"that asks whether something relates something, and in Inform 'to relate' "
"means that a particular relation applies between two things. Here, though, "
"we have %4 rather than the name of a relation.");
return NEVER_MATCH;
}
if (Kinds__get_construct(kinds_of_terms[1]) != CON_combination) {
Problems__quote_kind(4, kinds_of_terms[1]);
Problems__Issue__tcp_problem(_p_(BelievedImpossible), tck,
"that asks whether something relates something, and in Inform 'to relate' "
"means that a particular relation applies between two things. Here, though, "
"we have %4 rather than the combination of the two things.");
return NEVER_MATCH;
}
kind *rleft = NULL, *rright = NULL;
Kinds__binary_construction_material(kinds_of_terms[0], &rleft, &rright);
kind *cleft = NULL, *cright = NULL;
Kinds__binary_construction_material(kinds_of_terms[1], &cleft, &cright);
if (Kinds__Compare__compatible(cleft, rleft) == NEVER_MATCH) {
Problems__quote_kind(5, kinds_of_terms[0]);
Problems__quote_kind(4, cleft);
Problems__Issue__tcp_problem(_p_(BelievedImpossible), tck,
"that applies a relation to values of the wrong kinds: we have %5, but "
"the left-hand value here is %4.");
return NEVER_MATCH;
}
if (Kinds__Compare__compatible(cright, rright) == NEVER_MATCH) {
Problems__quote_kind(5, kinds_of_terms[0]);
Problems__quote_kind(4, cright);
Problems__Issue__tcp_problem(_p_(BelievedImpossible), tck,
"that applies a relation to values of the wrong kinds: we have %5, but "
"the right-hand value here is %4.");
return NEVER_MATCH;
}
}
return ALWAYS_MATCH;
}
#line 109 "inform7/Chapter 11/The Universal Relation.w"
int Relations__Universal__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
return FALSE;
}
#line 120 "inform7/Chapter 11/The Universal Relation.w"
int Relations__Universal__REL_compile(int task, binary_predicate *bp,
annotated_i6_schema *asch) {
if (bp == R_meaning) {
switch(task) {
case TEST_ATOM_TASK:
Calculus__Schemas__modify(asch->schema, "*=-(BlkValueCompare(*1(CV_MEANING), *2)==0)");
return TRUE;
}
} else {
switch(task) {
case TEST_ATOM_TASK:
Calculus__Schemas__modify(asch->schema, "*=-((RlnGetF(*1, RR_HANDLER))(*1, RELS_TEST, *&))");
return TRUE;
case NOW_ATOM_TRUE_TASK:
Calculus__Schemas__modify(asch->schema, "*=-((RlnGetF(*1, RR_HANDLER))(*1, RELS_ASSERT_TRUE, *&))");
return TRUE;
case NOW_ATOM_FALSE_TASK:
Calculus__Schemas__modify(asch->schema, "*=-((RlnGetF(*1, RR_HANDLER))(*1, RELS_ASSERT_FALSE, *&))");
return TRUE;
}
}
return FALSE;
}
#line 148 "inform7/Chapter 11/The Universal Relation.w"
int Relations__Universal__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 59 "inform7/Chapter 11/Conjugation of Verbs.w"
parse_node *set_where_created = NULL;
verb_usage *Verbs__register_vu(word_assemblage wa, int negated, int tensed,
binary_predicate *root, verb_conjugation *vc, int unexpected_upper_casing_used) {
if (WordAssemblages__nonempty(wa) == FALSE) return NULL;
Preform__mark_as_verb(WordAssemblages__first_word(&wa));
verb_usage *vu = CREATE(verb_usage);
vu->vu_text = wa;
vu->negated_form_of_verb = negated; vu->tensed = tensed;
vu->vu_meaning = root;
vu->vu_lex_entry = current_main_verb;
vu->where_vu_created = set_where_created;
vu->conjugated_from = vc;
vu->vu_allow_unexpected_upper_case = unexpected_upper_casing_used;
vu->next_in_search_list = NULL;
if (vu_search_list == NULL) vu_search_list = vu;
else {
for (verb_usage *evu = vu_search_list, *prev = NULL; evu; prev = evu, evu = evu->next_in_search_list) {
if (WordAssemblages__longer(&wa, &(evu->vu_text)) > 0) {
vu->next_in_search_list = evu;
if (prev == NULL) vu_search_list = vu;
else prev->next_in_search_list = vu;
break;
}
if (evu->next_in_search_list == NULL) {
evu->next_in_search_list = vu;
break;
}
}
}
return vu;
}
#line 96 "inform7/Chapter 11/Conjugation of Verbs.w"
int Verbs__vu_foreign(verb_usage *vu) {
if ((vu->conjugated_from) &&
(vu->conjugated_from->defined_in) &&
(vu->conjugated_from->defined_in != English_language)) {
return TRUE;
}
return FALSE;
}
#line 109 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *Verbs__find_vu(word_assemblage against) {
verb_usage *vu;
LOOP_OVER(vu, verb_usage)
if (WordAssemblages__compare(&(vu->vu_text), &against))
return vu;
return NULL;
}
#line 120 "inform7/Chapter 11/Conjugation of Verbs.w"
binary_predicate *Verbs__get_meaning(verb_usage *vu) {
return vu->vu_meaning;
}
int Verbs__get_tense_used(verb_usage *vu) {
return vu->tensed;
}
int Verbs__is_used_negatively(verb_usage *vu) {
return vu->negated_form_of_verb;
}
#line 141 "inform7/Chapter 11/Conjugation of Verbs.w"
int Verbs__parse_against_verb(wording W, verb_usage *vu) {
if ((vu->vu_allow_unexpected_upper_case == FALSE) &&
(Text__unexpectedly_upper_case(Wordings__first_wn(W)))) return -1;
return WordAssemblages__parse_as_strictly_initial_text(W, &(vu->vu_text));
}
#line 170 "inform7/Chapter 11/Conjugation of Verbs.w"
int general_verb_NTMR(wording W, int *X, void **XP) {
#line 171 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *vu;
LOOP_OVER_USAGES(vu) {
int i = Verbs__parse_against_verb(W, vu);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = vu;
return i-1;
}
}
return FALSE;
}
#line 187 "inform7/Chapter 11/Conjugation of Verbs.w"
int general_verb_present_positive_NTMR(wording W, int *X, void **XP) {
#line 188 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER_USAGES(vu) {
if ((vu->tensed == IS_TENSE) &&
(vu->negated_form_of_verb == FALSE) &&
(Verbs__vu_foreign(vu) == FALSE)) {
int i = Verbs__parse_against_verb(W, vu);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 208 "inform7/Chapter 11/Conjugation of Verbs.w"
int foreign_verb_present_positive_NTMR(wording W, int *X, void **XP) {
#line 209 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER_USAGES(vu) {
if ((vu->tensed == IS_TENSE) &&
(vu->negated_form_of_verb == FALSE) &&
(Verbs__vu_foreign(vu))) {
int i = Verbs__parse_against_verb(W, vu);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 231 "inform7/Chapter 11/Conjugation of Verbs.w"
int copular_verb_NTMR(wording W, int *X, void **XP) {
#line 232 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER_USAGES(vu) {
if (vu->vu_meaning == R_equality) {
int i = Verbs__parse_against_verb(W, vu);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 251 "inform7/Chapter 11/Conjugation of Verbs.w"
int copular_verb_present_positive_NTMR(wording W, int *X, void **XP) {
#line 252 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER_USAGES(vu) {
if ((vu->tensed == IS_TENSE) &&
(vu->vu_meaning == R_equality) &&
(vu->negated_form_of_verb == FALSE) &&
(Verbs__vu_foreign(vu) == FALSE)) {
int i = Verbs__parse_against_verb(W, vu);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 275 "inform7/Chapter 11/Conjugation of Verbs.w"
int negated_noncopular_verb_present_NTMR(wording W, int *X, void **XP) {
#line 276 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER_USAGES(vu) {
if ((vu->tensed == IS_TENSE) &&
(vu->vu_meaning != R_equality) &&
(vu->negated_form_of_verb == TRUE)) {
int i = Verbs__parse_against_verb(W, vu);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 297 "inform7/Chapter 11/Conjugation of Verbs.w"
int universal_verb_NTMR(wording W, int *X, void **XP) {
#line 298 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *vu;
LOOP_OVER_USAGES(vu)
if (vu->vu_meaning == R_universal) {
int i = Verbs__parse_against_verb(W, vu);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = vu;
return i-1;
}
}
return FALSE;
}
#line 316 "inform7/Chapter 11/Conjugation of Verbs.w"
int possession_verb_present_positive_NTMR(wording W, int *X, void **XP) {
#line 317 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER_USAGES(vu) {
if ((vu->tensed == IS_TENSE) &&
(vu->vu_meaning == a_has_b_predicate) &&
(vu->negated_form_of_verb == FALSE) &&
(Verbs__vu_foreign(vu) == FALSE)) {
int i = Verbs__parse_against_verb(W, vu);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 338 "inform7/Chapter 11/Conjugation of Verbs.w"
int negated_verb_NTMR(wording W, int *X, void **XP) {
#line 339 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER_USAGES(vu) {
if (vu->negated_form_of_verb == TRUE) {
int i = Verbs__parse_against_verb(W, vu);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 357 "inform7/Chapter 11/Conjugation of Verbs.w"
int past_tense_verb_NTMR(wording W, int *X, void **XP) {
#line 358 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *vu;
if (preform_backtrack) { vu = preform_backtrack; goto BacktrackFrom; }
LOOP_OVER_USAGES(vu) {
if (vu->tensed != IS_TENSE) {
int i = Verbs__parse_against_verb(W, vu);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = vu;
return -(i-1);
}
BacktrackFrom: ;
}
}
return FALSE;
}
#line 378 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__log(verb_usage *vu) {
if (vu == NULL) { LOG("(null verb usage)"); return; }
LOG("VU: $f ", &(vu->vu_text));
if (vu->negated_form_of_verb) LOG("(negated) ");
TimePeriods__log_tense_number(vu->tensed);
LOG(" -> %s", BinaryPredicates__get_log_name(vu->vu_meaning));
}
void Verbs__log_all(void) {
verb_usage *vu;
preposition_usage *pu;
LOG("The current S-grammar has the following verb and preposition usages:\n");
LOOP_OVER(vu, verb_usage) {
Verbs__log(vu);
LOG("\n");
}
LOOP_OVER(pu, preposition_usage) {
Prepositions__log(pu);
LOG("\n");
}
}
#line 404 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__tabulate(lexicon_entry *lex, int tense, char *tensename) {
verb_usage *vu; int f = TRUE;
LOOP_OVER(vu, verb_usage)
if ((vu->vu_lex_entry == lex) && (Verbs__is_used_negatively(vu) == FALSE)
&& (Verbs__get_tense_used(vu) == tense)) {
vocabulary_entry *lastword = WordAssemblages__last_word(&(vu->vu_text));
if (f) {
HTML__open_para(ifl, 2, "tight");
INDEX("<i>%s:</i>&nbsp;", tensename);
} else INDEX("; ");
if (strcmp(Vocabulary__get_exemplar(lastword, FALSE), "by") == 0)
INDEX("B ");
else INDEX("A ");
WordAssemblages__index(&(vu->vu_text));
if (strcmp(Vocabulary__get_exemplar(lastword, FALSE), "by") == 0)
INDEX("A");
else INDEX("B");
f = FALSE;
}
if (f == FALSE) INDEX("</p>\n");
}
void Verbs__tabulate_meaning(lexicon_entry *lex) {
verb_usage *vu;
LOOP_OVER(vu, verb_usage)
if (vu->vu_lex_entry == lex) {
if (vu->where_vu_created)
Index__link(Wordings__first_wn(ParseTree__get_text(vu->where_vu_created)));
Relations__index_for_verbs(vu->vu_meaning);
return;
}
preposition_usage *pu;
LOOP_OVER(pu, preposition_usage)
if (pu->pu_lex_entry == lex) {
if (pu->where_pu_created)
Index__link(Wordings__first_wn(ParseTree__get_text(pu->where_pu_created)));
Relations__index_for_verbs(pu->pu_meaning);
return;
}
}
#line 458 "inform7/Chapter 11/Conjugation of Verbs.w"
int inequality_conjugations_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 463 "inform7/Chapter 11/Conjugation of Verbs.w"
#line 467 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__stock(void) {
set_where_created = NULL;
current_main_verb = NULL;
Verbs__register_vu(Preform__Nonparsing__wording(inequality_conjugations_NTM, 0),
FALSE, IS_TENSE, R_numerically_less_than, NULL, FALSE);
Verbs__register_vu(Preform__Nonparsing__wording(inequality_conjugations_NTM, 1),
FALSE, IS_TENSE, R_numerically_greater_than, NULL, FALSE);
Verbs__register_vu(Preform__Nonparsing__wording(inequality_conjugations_NTM, 2),
FALSE, IS_TENSE, R_numerically_less_than_or_equal_to, NULL, FALSE);
Verbs__register_vu(Preform__Nonparsing__wording(inequality_conjugations_NTM, 3),
FALSE, IS_TENSE, R_numerically_greater_than_or_equal_to, NULL, FALSE);
}
#line 496 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__register_regular_verb(verb_conjugation *vc, binary_predicate *root,
int unexpected_upper_casing_used) {
vc->vc_meaning = root;
Index__Lexicon__new_main_verb(vc->infinitive, VERB_LEXE);
Verbs__register_main_forms_of_verb(vc, &(vc->active_tabulation), root,
unexpected_upper_casing_used);
if (root != R_equality) {
binary_predicate *bpr = BinaryPredicates__get_reversal(root);
Verbs__register_main_forms_of_verb(vc, &(vc->passive_tabulation), bpr,
unexpected_upper_casing_used);
if (WordAssemblages__nonempty(vc->present_participle))
Prepositions__register(vc->present_participle,
FALSE, root, FALSE, unexpected_upper_casing_used);
}
}
void Verbs__register_main_forms_of_verb(verb_conjugation *vc, verb_tabulation *vt,
binary_predicate *root, int unexpected_upper_casing_used) {
if (WordAssemblages__nonempty(vt->to_be_auxiliary)) {
Prepositions__register(vt->to_be_auxiliary,
FALSE, root, FALSE, unexpected_upper_casing_used);
return;
}
verb_usage *vu;
vu = Verbs__register_vu(vt->vc_text[HASBEEN_TENSE][1][THIRD_PERSON_SINGULAR],
TRUE, HASBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[HASBEEN_TENSE][1][THIRD_PERSON_PLURAL],
TRUE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[HADBEEN_TENSE][1][THIRD_PERSON_SINGULAR],
TRUE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[HADBEEN_TENSE][1][THIRD_PERSON_PLURAL],
TRUE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[HASBEEN_TENSE][0][THIRD_PERSON_SINGULAR],
FALSE, HASBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[HASBEEN_TENSE][0][THIRD_PERSON_PLURAL],
FALSE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[HADBEEN_TENSE][0][THIRD_PERSON_SINGULAR],
FALSE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[HADBEEN_TENSE][0][THIRD_PERSON_PLURAL],
FALSE, HADBEEN_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[IS_TENSE][1][THIRD_PERSON_SINGULAR],
TRUE, IS_TENSE, root, vc, unexpected_upper_casing_used);
if (vc == to_be_conjugation) negated_to_be = vu;
vu = Verbs__register_vu(vt->vc_text[IS_TENSE][1][THIRD_PERSON_PLURAL],
TRUE, IS_TENSE, root, vc, unexpected_upper_casing_used);
if (vc == to_be_conjugation) negated_plural_to_be = vu;
vu = Verbs__register_vu(vt->vc_text[WAS_TENSE][1][THIRD_PERSON_SINGULAR],
TRUE, WAS_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[WAS_TENSE][1][THIRD_PERSON_PLURAL],
TRUE, WAS_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[IS_TENSE][0][THIRD_PERSON_SINGULAR],
FALSE, IS_TENSE, root, vc, unexpected_upper_casing_used);
if (vc == to_be_conjugation) regular_to_be = vu;
vu = Verbs__register_vu(vt->vc_text[IS_TENSE][0][THIRD_PERSON_PLURAL],
FALSE, IS_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[WAS_TENSE][0][THIRD_PERSON_SINGULAR],
FALSE, WAS_TENSE, root, vc, unexpected_upper_casing_used);
vu = Verbs__register_vu(vt->vc_text[WAS_TENSE][0][THIRD_PERSON_PLURAL],
FALSE, WAS_TENSE, root, vc, unexpected_upper_casing_used);
}
#line 588 "inform7/Chapter 11/Conjugation of Verbs.w"
int verb_implies_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; giving_parts_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; giving_parts_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 591 "inform7/Chapter 11/Conjugation of Verbs.w"
int infinitive_usage_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = DEFAULT_VERBU;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 595 "inform7/Chapter 11/Conjugation of Verbs.w"
int infinitive_usage_exceptional_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = REGULAR_VERBU;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = REGULAR_VERBU;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = PREP_VERBU;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 600 "inform7/Chapter 11/Conjugation of Verbs.w"
#line 605 "inform7/Chapter 11/Conjugation of Verbs.w"
int conjugation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; is_participle_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; is_participle_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 608 "inform7/Chapter 11/Conjugation of Verbs.w"
#line 618 "inform7/Chapter 11/Conjugation of Verbs.w"
int participle_like_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 621 "inform7/Chapter 11/Conjugation of Verbs.w"
#line 634 "inform7/Chapter 11/Conjugation of Verbs.w"
int verb_implies_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = REV_REL_VERBM; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = REL_VERBM; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 689 "inform7/Chapter 11/Conjugation of Verbs.w"
*X = REL_VERBM;
*XP = Prepositions__get_meaning(RP[1]);
}
#line 637 "inform7/Chapter 11/Conjugation of Verbs.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 676 "inform7/Chapter 11/Conjugation of Verbs.w"
*X = REL_VERBM;
verb_conjugation *vc = RP[1];
if (vc->vc_meaning) *XP = vc->vc_meaning;
else {
*X = NONE_VERBM;
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"that's another verb which has no meaning at present",
"so this doesn't help me.");
}
}
#line 638 "inform7/Chapter 11/Conjugation of Verbs.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = PROP_VERBM;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 647 "inform7/Chapter 11/Conjugation of Verbs.w"
*X = NONE_VERBM;
Problems__Issue__sentence_problem(_p_(PM_VerbRelationUnknown),
"new verbs can only be defined in terms of existing relations",
"all of which have names ending 'relation': thus '...implies the "
"possession relation' is an example of a valid definition, this "
"being one of the relations built into Inform.");
}
#line 640 "inform7/Chapter 11/Conjugation of Verbs.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 657 "inform7/Chapter 11/Conjugation of Verbs.w"
*X = NONE_VERBM;
Problems__Issue__sentence_problem(_p_(PM_VerbRelationVague),
"that's too vague",
"calling a relation simply 'relation'.");
}
#line 641 "inform7/Chapter 11/Conjugation of Verbs.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7:
{
#line 666 "inform7/Chapter 11/Conjugation of Verbs.w"
*X = NONE_VERBM;
Problems__Issue__sentence_problem(_p_(PM_VerbUnknownMeaning),
"I don't see what the meaning of this verb ought to be",
"because it doesn't take any of the three forms I know: a relation "
"name ('...means the wearing relation'), a property name ('...means "
"the matching key property'), or another verb ('...means to wear.').");
}
#line 642 "inform7/Chapter 11/Conjugation of Verbs.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 643 "inform7/Chapter 11/Conjugation of Verbs.w"
#line 695 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__parse_new(parse_node *PN) {
wording PW = EMPTY_WORDING; /* wording of the parts of speech */
natural_language *nl = ParseTree__get_defn_language(PN->down);
binary_predicate *bp = NULL;
int conjugate_automatically = FALSE;
set_where_created = current_sentence;
if (PN->down->next->next)
{
#line 735 "inform7/Chapter 11/Conjugation of Verbs.w"
int reversal_flag = FALSE;
Preform__parse_nt_against_word_range(verb_implies_sentence_object_NTM, ParseTree__get_text(PN->down->next->next), NULL, NULL);
switch (most_recent_result) {
case PROP_VERBM: {
wording RW = GET_RW(verb_implies_sentence_object_NTM, 1);
bp = Properties__SettingRelations__make_set_property_BP(RW); break;
}
case REV_REL_VERBM: reversal_flag = TRUE; bp = most_recent_result_p; break;
case REL_VERBM: bp = most_recent_result_p; break;
case NONE_VERBM: return;
}
if (reversal_flag) bp = BinaryPredicates__get_reversal(bp);
}
#line 704 "inform7/Chapter 11/Conjugation of Verbs.w"
;
if (Preform__parse_nt_against_word_range(verb_implies_sentence_subject_NTM, ParseTree__get_text(PN->down->next), NULL, NULL)) {
int r = most_recent_result;
wording W = EMPTY_WORDING;
if (r == DEFAULT_VERBU) {
r = REGULAR_VERBU;
W = GET_RW(infinitive_usage_NTM, 1);
} else {
W = GET_RW(infinitive_usage_exceptional_NTM, 1);
}
if (giving_parts_NTMV) PW = GET_RW(verb_implies_sentence_subject_NTM, 1);
int unexpected_upper_casing_used = FALSE;
{
#line 957 "inform7/Chapter 11/Conjugation of Verbs.w"
LOOP_THROUGH_WORDING(i, W)
if (Text__unexpectedly_upper_case(i))
unexpected_upper_casing_used = TRUE;
}
#line 718 "inform7/Chapter 11/Conjugation of Verbs.w"
;
switch (r) {
case PREP_VERBU:
{
#line 903 "inform7/Chapter 11/Conjugation of Verbs.w"
word_assemblage wa = WordAssemblages__lit_0();
{
#line 924 "inform7/Chapter 11/Conjugation of Verbs.w"
if (Wordings__nonempty(PW)) {
Problems__Issue__sentence_problem(_p_(PM_PrepositionConjugated),
"the principal parts of 'to be' are known already",
"so should not be spelled out again as part of the instructions "
"for this new preposition.");
return;
}
}
#line 904 "inform7/Chapter 11/Conjugation of Verbs.w"
;
{
#line 935 "inform7/Chapter 11/Conjugation of Verbs.w"
if (Wordings__length(W) > MAX_WORDS_IN_PREPOSITION) {
Problems__Issue__sentence_problem(_p_(PM_PrepositionLong),
"prepositions can be very long indeed in today's Inform",
"but not as long as this.");
return;
}
wa = WordAssemblages__from_wording(W);
}
#line 905 "inform7/Chapter 11/Conjugation of Verbs.w"
;
{
#line 964 "inform7/Chapter 11/Conjugation of Verbs.w"
preposition_usage *duplicate_pu = NULL;
duplicate_pu = Prepositions__find_pu(wa);
if (duplicate_pu) {
if (duplicate_pu->where_pu_created)
Problems__Issue__two_sentences_problem(_p_(PM_DuplicateVerbs3),
duplicate_pu->where_pu_created,
"this gives us two definitions of what appears to be the "
"same prepositional form",
"or at least has the same words in.");
else
Problems__Issue__sentence_problem(_p_(BelievedImpossible), /* none are built in nowadays */
"this definition appears to clash with a built-in "
"prepositional form",
"a list of which can be seen on the Phrasebook index.");
return;
}
}
#line 906 "inform7/Chapter 11/Conjugation of Verbs.w"
;
{
#line 984 "inform7/Chapter 11/Conjugation of Verbs.w"
Prepositions__register(wa, FALSE, bp, FALSE, unexpected_upper_casing_used);
}
#line 907 "inform7/Chapter 11/Conjugation of Verbs.w"
;
}
#line 721 "inform7/Chapter 11/Conjugation of Verbs.w"
;
break;
case REGULAR_VERBU:
{
#line 751 "inform7/Chapter 11/Conjugation of Verbs.w"
word_assemblage infinitive = WordAssemblages__from_wording(W);
word_assemblage present_singular = WordAssemblages__lit_0();
word_assemblage present_plural = WordAssemblages__lit_0();
word_assemblage past = WordAssemblages__lit_0();
word_assemblage past_participle = WordAssemblages__lit_0();
word_assemblage participle = WordAssemblages__lit_0();
if (Wordings__empty(PW)) conjugate_automatically = TRUE;
else
{
#line 784 "inform7/Chapter 11/Conjugation of Verbs.w"
int more_to_read = TRUE;
int participle_count = 0;
while (more_to_read) {
wording CW = EMPTY_WORDING;
if (Preform__parse_nt_against_word_range(list_comma_division_NTM, PW, NULL, NULL)) {
CW = GET_RW(list_comma_division_NTM, 1);
PW = GET_RW(list_comma_division_NTM, 2);
more_to_read = TRUE;
} else {
CW = PW;
more_to_read = FALSE;
}
{
#line 804 "inform7/Chapter 11/Conjugation of Verbs.w"
if ((Preform__parse_nt_against_word_range(conjugation_NTM, CW, NULL, NULL)) == FALSE)
{
#line 839 "inform7/Chapter 11/Conjugation of Verbs.w"
Problems__Issue__sentence_problem(_p_(PM_VerbMalformed),
"this verb's definition is malformed",
"and should have its principal parts supplied like so: 'The verb "
"to sport (he sports, they sport, he sported, it is sported, "
"he is sporting) ...'.");
return;
}
#line 805 "inform7/Chapter 11/Conjugation of Verbs.w"
;
CW = GET_RW(conjugation_NTM, 1);
int number = most_recent_result;
int is_a_participle = is_participle_NTMV;
if (Wordings__length(CW) > MAX_WORDS_IN_VERB)
{
#line 839 "inform7/Chapter 11/Conjugation of Verbs.w"
Problems__Issue__sentence_problem(_p_(PM_VerbMalformed),
"this verb's definition is malformed",
"and should have its principal parts supplied like so: 'The verb "
"to sport (he sports, they sport, he sported, it is sported, "
"he is sporting) ...'.");
return;
}
#line 810 "inform7/Chapter 11/Conjugation of Verbs.w"
;
if (is_a_participle) {
participle_count++;
if ((Preform__parse_nt_against_word_range(participle_like_NTM, CW, NULL, NULL)) ||
(WordAssemblages__nonempty(past_participle)))
participle = WordAssemblages__from_wording(CW);
else
past_participle = WordAssemblages__from_wording(CW);
} else {
if (number == 2) {
if (WordAssemblages__nonempty(present_plural)) {
Problems__Issue__sentence_problem(_p_(PM_PresentPluralTwice),
"the present plural has been given twice",
"since two of the principal parts of this verb begin "
"with 'they'.");
}
present_plural = WordAssemblages__from_wording(CW);
} else {
if (WordAssemblages__nonempty(present_singular))
past = WordAssemblages__from_wording(CW);
else
present_singular = WordAssemblages__from_wording(CW);
}
}
}
#line 796 "inform7/Chapter 11/Conjugation of Verbs.w"
;
}
if (WordAssemblages__nonempty(present_plural) == FALSE) present_plural = infinitive;
}
#line 759 "inform7/Chapter 11/Conjugation of Verbs.w"
;
{
#line 852 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_usage *duplicate_vu = Verbs__find_vu(present_singular);
if ((duplicate_vu) && (bp)) {
parse_node *where = duplicate_vu->where_vu_created;
{
#line 869 "inform7/Chapter 11/Conjugation of Verbs.w"
if (where)
Problems__Issue__two_sentences_problem(_p_(PM_DuplicateVerbs1),
where,
"this gives us two definitions of what appears to be the same verb",
"or at least has the same infinitive form.");
else
Problems__Issue__sentence_problem(_p_(PM_DuplicateVerbs2),
"this verb definition appears to clash with a built-in verb",
"a table of which can be seen on the Phrasebook index.");
}
#line 855 "inform7/Chapter 11/Conjugation of Verbs.w"
;
return;
}
verb_conjugation *duplicate_vc = Verbs__find_vc_by_infinitive(infinitive);
if ((duplicate_vc) && (duplicate_vc->vc_meaning) && (bp)) {
parse_node *where = duplicate_vc->where_vc_created;
{
#line 869 "inform7/Chapter 11/Conjugation of Verbs.w"
if (where)
Problems__Issue__two_sentences_problem(_p_(PM_DuplicateVerbs1),
where,
"this gives us two definitions of what appears to be the same verb",
"or at least has the same infinitive form.");
else
Problems__Issue__sentence_problem(_p_(PM_DuplicateVerbs2),
"this verb definition appears to clash with a built-in verb",
"a table of which can be seen on the Phrasebook index.");
}
#line 862 "inform7/Chapter 11/Conjugation of Verbs.w"
;
return;
}
}
#line 760 "inform7/Chapter 11/Conjugation of Verbs.w"
;
{
#line 882 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_conjugation *vc = Verbs__find_vc_by_infinitive(infinitive);
if (vc == NULL) {
word_assemblage overrides[7];
int no_overrides = 7;
overrides[BASE_FORM_TYPE] = WordAssemblages__lit_0();
overrides[INFINITIVE_FORM_TYPE] = present_plural;
overrides[PAST_PARTICIPLE_FORM_TYPE] = past_participle;
overrides[PRESENT_PARTICIPLE_FORM_TYPE] = participle;
overrides[ADJOINT_INFINITIVE_FORM_TYPE] = WordAssemblages__lit_0();
overrides[5] = present_singular;
overrides[6] = past;
vc = Preform__Nonparsing__conjugate_verb(infinitive, overrides, no_overrides, nl);
}
if ((vc) && (bp)) Verbs__register_regular_verb(vc, bp, unexpected_upper_casing_used);
}
#line 761 "inform7/Chapter 11/Conjugation of Verbs.w"
;
}
#line 724 "inform7/Chapter 11/Conjugation of Verbs.w"
;
break;
case NONE_VERBU:
return;
}
}
}
#line 772 "inform7/Chapter 11/Conjugation of Verbs.w"
int list_comma_division_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 774 "inform7/Chapter 11/Conjugation of Verbs.w"
#line 989 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__ConjugateVerb_invoke(OUTPUT_STREAM, verb_conjugation *vc,
verb_conjugation *modal, int negated) {
if (modal) {
if (negated) {
WRITE("ConjugateVerb_%d(CV_NEG, PNToVP(), story_tense, ConjugateVerb_%d);",
modal->allocation_id, vc->allocation_id);
} else {
WRITE("ConjugateVerb_%d(CV_POS, PNToVP(), story_tense, ConjugateVerb_%d);",
modal->allocation_id, vc->allocation_id);
}
} else {
if (negated) {
WRITE("ConjugateVerb_%d(CV_NEG, PNToVP(), story_tense);",
vc->allocation_id);
} else {
WRITE("ConjugateVerb_%d(CV_POS, PNToVP(), story_tense);",
vc->allocation_id);
}
}
WRITE(" say__p=1; ");
}
#line 1014 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__ConjugateVerb_routine(OUTPUT_STREAM) {
WRITE("Constant CV_POS = -1;\n");
WRITE("Constant CV_NEG = -2;\n");
WRITE("Constant CV_MODAL = -3;\n");
WRITE("Constant CV_MEANING = -4;\n");
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
{
#line 1032 "inform7/Chapter 11/Conjugation of Verbs.w"
char i6_routine_name[32];
sprintf(i6_routine_name, "ConjugateVerb_%d", vc->allocation_id);
OUT = Routines__begin(OUT, i6_routine_name);
LocalVariables__add_named_call("fn");
LocalVariables__add_named_call("vp");
LocalVariables__add_named_call("t");
LocalVariables__add_named_call("modal_to");
WRITE("switch (fn) {\n"); INDENT;
WRITE("1: "); Verbs__conj_from_wa(OUT, &(vc->infinitive), vc, 0);
WRITE("\n2: "); Verbs__conj_from_wa(OUT, &(vc->past_participle), vc, 0);
WRITE("\n3: "); Verbs__conj_from_wa(OUT, &(vc->present_participle), vc, 0);
WRITE("\n");
int modal_verb = FALSE;
{
#line 1069 "inform7/Chapter 11/Conjugation of Verbs.w"
for (int sense = 0; sense < 2; sense++)
for (int tense=0; tense<NO_KNOWN_TENSES; tense++)
for (int part=1; part<=6; part++)
if (vc->active_tabulation.modal_auxiliary_usage[tense][sense][part-1] != 0)
modal_verb = TRUE;
}
#line 1046 "inform7/Chapter 11/Conjugation of Verbs.w"
;
WRITE("CV_MODAL: return %s;\n", (modal_verb)?"true":"false");
WRITE("CV_MEANING: return ");
binary_predicate *meaning = vc->vc_meaning;
if (meaning) {
WRITE("Rel_Record_%d", meaning->allocation_id);
BinaryPredicates__mark_as_needed(meaning);
} else {
WRITE("Rel_Record_0");
}
WRITE(";\n");
for (int sense = 0; sense < 2; sense++) {
WRITE("%s:\n", (sense==0)?"CV_POS":"CV_NEG"); INDENT;
{
#line 1078 "inform7/Chapter 11/Conjugation of Verbs.w"
WRITE("switch (t) {\n"); INDENT;
for (int tense=0; tense<NO_KNOWN_TENSES; tense++) {
int some_exist = FALSE, some_dont_exist = FALSE,
some_differ = FALSE, some_except_3PS_differ = FALSE, some_are_modal = FALSE;
word_assemblage *common = NULL, *common_except_3PS = NULL;
for (int part=1; part<=6; part++) {
word_assemblage *wa = &(vc->active_tabulation.vc_text[tense][sense][part-1]);
if (WordAssemblages__nonempty(*wa)) {
if (some_exist) {
if (WordAssemblages__compare(wa, common) == FALSE)
some_differ = TRUE;
if (part != 3) {
if (common_except_3PS == NULL) common_except_3PS = wa;
else if (WordAssemblages__compare(wa, common_except_3PS) == FALSE)
some_except_3PS_differ = TRUE;
}
} else {
some_exist = TRUE;
common = wa;
if (part != 3) common_except_3PS = wa;
}
if (vc->active_tabulation.modal_auxiliary_usage[tense][sense][part-1] != 0)
some_are_modal = TRUE;
}
else some_dont_exist = TRUE;
}
if (some_exist) {
WRITE("%d: ", tense+1);
if ((some_differ) || (some_are_modal)) {
if ((some_except_3PS_differ) || (some_dont_exist) || (some_are_modal))
{
#line 1121 "inform7/Chapter 11/Conjugation of Verbs.w"
WRITE("switch (vp) {\n"); INDENT;
for (int part=1; part<=6; part++) {
word_assemblage *wa = &(vc->active_tabulation.vc_text[tense][sense][part-1]);
if (WordAssemblages__nonempty(*wa)) {
WRITE("%d: ", part);
int mau = vc->active_tabulation.modal_auxiliary_usage[tense][sense][part-1];
Verbs__conj_from_wa(OUT, wa, vc, mau);
WRITE("\n");
}
}
OUTDENT; WRITE("}\n");
}
#line 1108 "inform7/Chapter 11/Conjugation of Verbs.w"
else
{
#line 1136 "inform7/Chapter 11/Conjugation of Verbs.w"
word_assemblage *wa = &(vc->active_tabulation.vc_text[tense][sense][2]);
WRITE("if (vp == 3) { "); Verbs__conj_from_wa(OUT, wa, vc, 0);
wa = &(vc->active_tabulation.vc_text[tense][sense][0]);
WRITE(" } else { "); Verbs__conj_from_wa(OUT, wa, vc, 0);
WRITE(" }\n");
}
#line 1110 "inform7/Chapter 11/Conjugation of Verbs.w"
;
} else {
{
#line 1145 "inform7/Chapter 11/Conjugation of Verbs.w"
word_assemblage *wa = &(vc->active_tabulation.vc_text[tense][sense][0]);
Verbs__conj_from_wa(OUT, wa, vc, 0);
WRITE("\n");
}
#line 1112 "inform7/Chapter 11/Conjugation of Verbs.w"
;
}
}
}
OUTDENT; WRITE("}\n");
}
#line 1059 "inform7/Chapter 11/Conjugation of Verbs.w"
;
OUTDENT;
}
OUTDENT; WRITE("}\n");
OUT = Routines__end(OUT);
}
#line 1021 "inform7/Chapter 11/Conjugation of Verbs.w"
;
WRITE("Array TableOfVerbs -->");
LOOP_OVER(vc, verb_conjugation)
if ((vc->auxiliary_only == FALSE) && (vc->instance_of_verb))
WRITE(" ConjugateVerb_%d", vc->allocation_id);
WRITE(" 0;\n");
}
#line 1152 "inform7/Chapter 11/Conjugation of Verbs.w"
void Verbs__conj_from_wa(OUTPUT_STREAM, word_assemblage *wa, verb_conjugation *vc, int mau) {
WRITE("print \"");
if ((Verbs__takes_contraction_form(wa) == FALSE) && (Verbs__takes_contraction_form(&(vc->infinitive))))
WRITE(" ");
int i, n;
vocabulary_entry **words;
WordAssemblages__as_array(wa, &words, &n);
for (i=0; i<n; i++) {
if (i>0) WRITE(" ");
char *q = Vocabulary__get_exemplar(words[i], FALSE);
if ((q[0]) && (q[Platform__strlen(q)-1] == '*')) {
char unstarred[MAX_WORD_LENGTH+1];
strcpy(unstarred, q);
unstarred[Platform__strlen(q)-1] = 0;
feed_t id = Feeds__begin();
Feeds__feed_text(" ");
Feeds__feed_text(unstarred);
Feeds__feed_text(" ");
wording W = Feeds__end(id);
adjectival_phrase *aph = Adjectives__Phrases__declare_textually(W);
WRITE("\"; AgreeAdjective_%d(prior_named_noun, (prior_named_list >= 2)); print \"",
aph->allocation_id);
} else {
WRITE("%s", q);
}
}
WRITE("\";");
if (mau != 0) WRITE(" if (modal_to) { print \" \"; modal_to(%d); }", mau);
}
int Verbs__takes_contraction_form(word_assemblage *wa) {
vocabulary_entry *ve = WordAssemblages__first_word(wa);
if (ve == NULL) return FALSE;
char *p = Vocabulary__get_exemplar(ve, FALSE);
if (p[0] == '\'') return TRUE;
return FALSE;
}
verb_conjugation *Verbs__find_vc_by_infinitive(word_assemblage infinitive) {
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if (WordAssemblages__compare(&infinitive, &(vc->infinitive)))
return vc;
return NULL;
}
#line 1201 "inform7/Chapter 11/Conjugation of Verbs.w"
int adaptive_verb_NTMR(wording W, int *X, void **XP) {
#line 1202 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if (vc->auxiliary_only == FALSE) {
int p = NaturalLanguages__adaptive_person(vc->defined_in);
word_assemblage *we_form = &(vc->active_tabulation.vc_text[IS_TENSE][0][p]);
word_assemblage *we_dont_form = &(vc->active_tabulation.vc_text[IS_TENSE][1][p]);
if (WordAssemblages__compare_with_wording(we_form, W)) {
*XP = vc; *X = FALSE; return TRUE;
}
if (WordAssemblages__compare_with_wording(we_dont_form, W)) {
*XP = vc; *X = TRUE; return TRUE;
}
}
return FALSE;
}
int adaptive_verb_infinitive_NTMR(wording W, int *X, void **XP) {
#line 1219 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if (vc->auxiliary_only == FALSE) {
word_assemblage *infinitive_form = &(vc->infinitive);
if (WordAssemblages__compare_with_wording(infinitive_form, W)) {
*XP = vc; *X = FALSE; return TRUE;
}
}
return FALSE;
}
int auxiliary_verb_only_NTMR(wording W, int *X, void **XP) {
#line 1231 "inform7/Chapter 11/Conjugation of Verbs.w"
return FALSE;
}
int instance_of_verb_NTMR(wording W, int *X, void **XP) {
#line 1235 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if ((vc->auxiliary_only == FALSE) && (vc->instance_of_verb)) {
int p = NaturalLanguages__adaptive_person(vc->defined_in);
word_assemblage *we_form = &(vc->active_tabulation.vc_text[IS_TENSE][0][p]);
word_assemblage *we_dont_form = &(vc->active_tabulation.vc_text[IS_TENSE][1][p]);
if (WordAssemblages__compare_with_wording(we_form, W)) {
*XP = vc; *X = FALSE; return TRUE;
}
if (WordAssemblages__compare_with_wording(we_dont_form, W)) {
*XP = vc; *X = TRUE; return TRUE;
}
}
return FALSE;
}
int not_instance_of_verb_at_run_time_NTMR(wording W, int *X, void **XP) {
#line 1252 "inform7/Chapter 11/Conjugation of Verbs.w"
return FALSE;
}
int modal_verb_NTMR(wording W, int *X, void **XP) {
#line 1256 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if (vc->auxiliary_only == FALSE) {
int p = NaturalLanguages__adaptive_person(vc->defined_in);
if (vc->active_tabulation.modal_auxiliary_usage[IS_TENSE][0][p] != 0) {
word_assemblage *we_form = &(vc->active_tabulation.vc_text[IS_TENSE][0][p]);
word_assemblage *we_dont_form = &(vc->active_tabulation.vc_text[IS_TENSE][1][p]);
if (WordAssemblages__compare_with_wording(we_form, W)) {
*XP = vc; *X = FALSE; return TRUE;
}
if (WordAssemblages__compare_with_wording(we_dont_form, W)) {
*XP = vc; *X = TRUE; return TRUE;
}
}
}
return FALSE;
}
int verb_infinitive_NTMR(wording W, int *X, void **XP) {
#line 1275 "inform7/Chapter 11/Conjugation of Verbs.w"
verb_conjugation *vc;
LOOP_OVER(vc, verb_conjugation)
if (vc->auxiliary_only == FALSE) {
if (WordAssemblages__compare_with_wording(&(vc->infinitive), W)) {
*XP = vc; *X = FALSE; return TRUE;
}
}
return FALSE;
}
#line 49 "inform7/Chapter 11/Prepositions.w"
int same_prop_as_registered = FALSE;
preposition_usage *Prepositions__register(word_assemblage wa,
int assumes_player, binary_predicate *root, int stroked,
int unexpected_upper_casing_used) {
if (root == NULL) internal_error("meaningless preposition");
preposition_usage *pu = CREATE(preposition_usage);
pu->pu_text = wa;
pu->pu_meaning = root; pu->player_implied = assumes_player;
pu->pu_lex_entry = NULL;
pu->is_same_property_as = NULL;
pu->where_pu_created = set_where_created;
pu->negated_sense = FALSE;
pu->allow_unexpected_upper_case = unexpected_upper_casing_used;
Preform__mark_as_preposition(WordAssemblages__first_word(&wa));
vocabulary_entry **array; int length;
WordAssemblages__as_array(&wa, &array, &length);
if (stroked) {
if (same_prop_as_registered == FALSE) {
same_prop_as_registered = TRUE;
pu->pu_lex_entry = Index__Lexicon__new_main_verb(
Preform__Nonparsing__wording(same_property_as_in_lexicon_NTM, 0), PREP_LEXE);
}
} else {
pu->pu_lex_entry = Index__Lexicon__new_main_verb(wa, PREP_LEXE);
}
return pu;
}
#line 80 "inform7/Chapter 11/Prepositions.w"
preposition_usage *Prepositions__find_pu(word_assemblage against) {
preposition_usage *pu;
LOOP_OVER(pu, preposition_usage)
if (WordAssemblages__compare(&(pu->pu_text), &against))
return pu;
return NULL;
}
#line 91 "inform7/Chapter 11/Prepositions.w"
int Prepositions__implicitly_negates(preposition_usage *pu) {
if (pu == NULL) return FALSE;
return pu->negated_sense;
}
binary_predicate *Prepositions__get_meaning(preposition_usage *pu) {
if (pu == NULL) return NULL;
return pu->pu_meaning;
}
parse_node *Prepositions__get_where_pu_created(preposition_usage *pu) {
return pu->where_pu_created;
}
#line 115 "inform7/Chapter 11/Prepositions.w"
int Prepositions__parse_prep_against(wording W, preposition_usage *pu, int fill) {
wording S = EMPTY_WORDING;
if (pu->is_same_property_as) S = pu->is_same_property_as->name;
return WordAssemblages__parse_as_weakly_initial_text(W, &(pu->pu_text), S,
pu->allow_unexpected_upper_case, TRUE);
}
#line 125 "inform7/Chapter 11/Prepositions.w"
int preposition_NTMR(wording W, int *X, void **XP) {
#line 126 "inform7/Chapter 11/Prepositions.w"
if (Vocabulary__test_flags(Wordings__first_wn(W), PREPOSITION_MC) == FALSE) return FALSE;
preposition_usage *pu;
LOOP_OVER(pu, preposition_usage) {
int i = Prepositions__parse_prep_against(W, pu, TRUE);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W)+1)) {
*XP = pu;
return i-1;
}
}
return FALSE;
}
#line 146 "inform7/Chapter 11/Prepositions.w"
int preposition_implying_player_NTMR(wording W, int *X, void **XP) {
#line 147 "inform7/Chapter 11/Prepositions.w"
if (Vocabulary__test_flags(Wordings__first_wn(W), PREPOSITION_MC) == FALSE) return FALSE;
preposition_usage *pu;
LOOP_OVER(pu, preposition_usage)
if (pu->player_implied) {
int i = Prepositions__parse_prep_against(W, pu, TRUE);
if ((i>Wordings__first_wn(W)) && (i<=Wordings__last_wn(W))) {
*XP = pu;
return i-1;
}
}
return FALSE;
}
#line 164 "inform7/Chapter 11/Prepositions.w"
void Prepositions__log(preposition_usage *pu) {
LOG("PU: $f ", &(pu->pu_text));
if (pu->player_implied) LOG("(implies player) ");
if (pu->is_same_property_as) LOG("(same $Y) ", pu->is_same_property_as);
LOG("-> %s", BinaryPredicates__get_log_name(pu->pu_meaning));
}
#line 177 "inform7/Chapter 11/Prepositions.w"
void Prepositions__register_comparative(wording W, binary_predicate *root) {
set_where_created = current_sentence;
Prepositions__register(
Preform__Nonparsing__merge(comparative_property_construction_NTM, 0,
WordAssemblages__lit_1(Lexer__word(Wordings__first_wn(W)))),
FALSE, root, FALSE, FALSE);
}
void Prepositions__register_same_property_as(binary_predicate *root) {
set_where_created = current_sentence;
preposition_usage *pu =
Prepositions__register(
Preform__Nonparsing__merge(same_property_as_construction_NTM, 0,
WordAssemblages__lit_1(PARBREAK_V)),
FALSE, root, TRUE, FALSE);
pu->is_same_property_as = Properties__SameRelations__bp_get_same_as_property(root);
}
#line 202 "inform7/Chapter 11/Prepositions.w"
int comparative_property_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 204 "inform7/Chapter 11/Prepositions.w"
#line 208 "inform7/Chapter 11/Prepositions.w"
int same_property_as_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 210 "inform7/Chapter 11/Prepositions.w"
#line 216 "inform7/Chapter 11/Prepositions.w"
int same_property_as_in_lexicon_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 218 "inform7/Chapter 11/Prepositions.w"
#line 233 "inform7/Chapter 12/Lexer.w"
char *lexer_workspace; /* Large area of contiguous memory for text */
char *lexer_word; /* Start of current word in workspace */
char *lexer_hwm; /* High water mark of workspace */
char *lexer_workspace_end; /* Pointer to just past the end of the workspace: HWM must not exceed this */
void Lexer__start(void) {
lexer_wordcount = 0;
Lexer__ensure_space_up_to(50000); /* the Standard Rules are about 44,000 words */
Lexer__allocate_lexer_workspace_chunk(1);
Vocabulary__start_hash_table();
}
#line 252 "inform7/Chapter 12/Lexer.w"
int current_lw_array_size = 0, next_lw_array_size = 75000;
void Lexer__ensure_space_up_to(int n) {
if (n < current_lw_array_size) return;
int new_size = current_lw_array_size;
while (n >= new_size) {
new_size = next_lw_array_size;
next_lw_array_size = next_lw_array_size*2;
}
lexer_details_memory_allocated = new_size*((int) sizeof(lexer_details));
lexer_details *new_lw_array =
((lexer_details *) (Memory__I7_calloc(new_size, sizeof(lexer_details), LEXER_WORDS_MREASON)));
if (new_lw_array == NULL) Problems__Fatal__issue("Out of memory: unable to create lexer workspace");
int i;
for (i=0; i<new_size; i++) {
if (i < current_lw_array_size) new_lw_array[i] = lw_array[i];
else {
new_lw_array[i].lw_text = NULL;
new_lw_array[i].lw_rawtext = NULL;
new_lw_array[i].lw_break = ' ';
new_lw_array[i].lw_source.file_of_origin = NULL;
new_lw_array[i].lw_source.line_number = -1;
new_lw_array[i].lw_identity = NULL;
}
}
if (lw_array) Memory__I7_free(lw_array, LEXER_WORDS_MREASON);
lw_array = new_lw_array;
current_lw_array_size = new_size;
}
#line 290 "inform7/Chapter 12/Lexer.w"
void Lexer__ensure_lexer_hwm_can_be_raised_by(int n, int transfer_partial_word) {
if (lexer_hwm + n + 2 >= lexer_workspace_end) {
char *old_hwm = lexer_hwm;
int m = 1;
if (transfer_partial_word) {
m = ((old_hwm - lexer_word + n + 3)/TEXT_STORAGE_CHUNK_SIZE) + 1;
if (m < 1) m = 1;
}
Lexer__allocate_lexer_workspace_chunk(m);
if (transfer_partial_word) {
*(lexer_hwm++) = ' ';
char *new_lword = lexer_hwm;
while (lexer_word < old_hwm) {
*(lexer_hwm++) = *(lexer_word++);
}
lexer_word = new_lword;
}
if (lexer_hwm + n + 2 >= lexer_workspace_end)
internal_error("further allocation failed to liberate enough space");
}
}
void Lexer__allocate_lexer_workspace_chunk(int multiplier) {
int extent = multiplier * TEXT_STORAGE_CHUNK_SIZE;
lexer_workspace = ((char *) (Memory__I7_malloc(extent, LEXER_TEXT_MREASON)));
lexer_workspace_allocated += extent;
lexer_hwm = lexer_workspace;
lexer_workspace_end = lexer_workspace + extent;
}
#line 327 "inform7/Chapter 12/Lexer.w"
char *Lexer__copy_to_memory(char *p) {
Lexer__ensure_lexer_hwm_can_be_raised_by(Platform__strlen(p), FALSE);
char *q = lexer_hwm;
lexer_hwm = q + Platform__strlen(p) + 1;
strcpy(q, p);
return q;
}
#line 366 "inform7/Chapter 12/Lexer.w"
char *lexer_punctuation_marks = "";
int lexer_divide_strings_at_text_substitutions; /* Break up text substitutions in quoted text */
int lexer_allow_I6_escapes; /* Recognise |(-| and |-)| */
int lexer_wait_for_dashes; /* Ignore all text until first |----| found */
#line 376 "inform7/Chapter 12/Lexer.w"
int Lexer__is_punctuation(char c) {
int i;
for (i=0; lexer_punctuation_marks[i]; i++)
if (c == lexer_punctuation_marks[i])
return TRUE;
return FALSE;
}
#line 393 "inform7/Chapter 12/Lexer.w"
int Lexer__indentation_level(int wn) {
int q = lw_array[wn].lw_break - 'A' + 1;
if ((q >= 1) && (q <= GROSS_AMOUNT_OF_INDENTATION)) return q;
return 0;
}
char Lexer__break_char_for_indents(int t) {
if (t <= 0) internal_error("bad indentation break");
if (t >= 26) return 'Z';
return (char) ('A' + t - 1);
}
#line 408 "inform7/Chapter 12/Lexer.w"
vocabulary_entry *Lexer__word(int wn) {
return lw_array[wn].lw_identity;
}
void Lexer__set_word(int wn, vocabulary_entry *ve) {
lw_array[wn].lw_identity = ve;
}
int Lexer__break_before(int wn) {
return lw_array[wn].lw_break;
}
source_file *Lexer__file_of_origin(int wn) {
return lw_array[wn].lw_source.file_of_origin;
}
source_location Lexer__word_location(int wn) {
if (wn < 0) {
source_location nowhere;
nowhere.file_of_origin = NULL;
nowhere.line_number = 0;
return nowhere;
}
return lw_array[wn].lw_source;
}
char *Lexer__word_raw_text(int wn) {
return lw_array[wn].lw_rawtext;
}
void Lexer__set_word_raw_text(int wn, char *rt) {
lw_array[wn].lw_rawtext = rt;
}
char *Lexer__word_text(int wn) {
return lw_array[wn].lw_text;
}
void Lexer__set_word_text(int wn, char *rt) {
lw_array[wn].lw_text = rt;
}
void Lexer__word_copy(int to, int from) {
lw_array[to] = lw_array[from];
}
#line 475 "inform7/Chapter 12/Lexer.w"
int lxs_previous_char_in_raw_feed; /* Preceding character in raw file read */
#line 488 "inform7/Chapter 12/Lexer.w"
int lxs_kind_of_word; /* One of the defined values above */
#line 500 "inform7/Chapter 12/Lexer.w"
int lxs_literal_mode; /* Are we in literal or ordinary mode? */
/* significant in ordinary mode: */
char lxs_most_significant_space_char; /* Most significant whitespace character preceding */
int lxs_number_of_tab_stops; /* Number of consecutive tabs */
int lxs_this_line_is_empty_so_far; /* Current line white space so far? */
int lxs_this_word_is_empty_so_far; /* Looking for a word to start? */
int lxs_scanning_text_substitution; /* Used to break up strings at [substitutions] */
/* significant in literal mode: */
int lxs_comment_nesting; /* For square brackets within square brackets */
int lxs_string_soak_up_spaces_mode; /* Used to fold strings which break across lines */
#line 519 "inform7/Chapter 12/Lexer.w"
void Lexer__reset_lexer(void) {
lexer_word = lexer_hwm;
lxs_previous_char_in_raw_feed = EOF;
/* reset the external states */
lexer_wait_for_dashes = FALSE;
lexer_punctuation_marks = STANDARD_PUNCTUATION_MARKS;
lexer_divide_strings_at_text_substitutions = FALSE;
lexer_allow_I6_escapes = TRUE;
/* reset the internal states */
lxs_most_significant_space_char = '\n'; /* we imagine each lexer feed starting a new line */
lxs_number_of_tab_stops = 0; /* but not yet indented with tabs */
lxs_this_line_is_empty_so_far = TRUE; /* clearly */
lxs_this_word_is_empty_so_far = TRUE; /* likewise */
lxs_literal_mode = FALSE; /* begin in ordinary mode... */
lxs_kind_of_word = ORDINARY_KW; /* ...expecting an ordinary word */
lxs_string_soak_up_spaces_mode = FALSE;
lxs_scanning_text_substitution = FALSE;
lxs_comment_nesting = 0;
}
#line 558 "inform7/Chapter 12/Lexer.w"
int lexer_feed_started_at = -1;
void Lexer__feed_begins(source_location sl) {
if (lexer_feed_started_at >= 0) internal_error("one lexer feeder interrupted another");
lexer_feed_started_at = lexer_wordcount;
lexer_position = sl;
Lexer__reset_lexer();
LOGIF(LEXICAL_OUTPUT, "Lexer feed began at %d\n", lexer_feed_started_at);
}
wording Lexer__feed_ends(int extra_padding, char *problem_source_description) {
if (lexer_feed_started_at == -1) internal_error("lexer feeder ended without starting");
{
#line 599 "inform7/Chapter 12/Lexer.w"
if (extra_padding == FALSE) {
Lexer__feed_char_into_lexer(' ');
} else {
Lexer__feed_char_into_lexer(' ');
Lexer__feed_char_into_lexer('\n');
Lexer__feed_char_into_lexer('\n');
Lexer__feed_char_into_lexer('\n');
Lexer__feed_char_into_lexer('\n');
Lexer__feed_char_into_lexer(' ');
}
}
#line 571 "inform7/Chapter 12/Lexer.w"
;
wording RRW = EMPTY_WORDING;
if (lexer_feed_started_at < lexer_wordcount)
RRW = Wordings__new(lexer_feed_started_at, lexer_wordcount-1);
lexer_feed_started_at = -1;
LOGIF(LEXICAL_OUTPUT, "Lexer feed ended at %d\n", Wordings__first_wn(RRW));
{
#line 615 "inform7/Chapter 12/Lexer.w"
if (lxs_kind_of_word != ORDINARY_KW) {
if (lexer_wordcount >= 20) {
LOG("Last words: $w\n", Wordings__new(lexer_wordcount-20, lexer_wordcount-1));
} else if (lexer_wordcount >= 1) {
LOG("Last words: $w\n", Wordings__new(0, lexer_wordcount-1));
} else {
LOG("No words recorded\n");
}
}
if (lxs_kind_of_word == STRING_KW) {
Problems__Issue__lexical_problem(_p_(PM_UnendingQuote),
"Some source text ended in the middle of quoted text",
problem_source_description,
"This probably means that a quotation mark is missing "
"somewhere. If you are using Inform with syntax colouring, "
"look for where the quoted-text colour starts. (Sometimes "
"this problem turns up because a piece of quoted text contains "
"a text substitution in square brackets which in turn contains "
"another piece of quoted text - this is not allowed, and causes "
"me to lose track.)");
}
if (lxs_kind_of_word == COMMENT_KW) {
Problems__Issue__lexical_problem(_p_(PM_UnendingComment),
"Some source text ended in the middle of a comment",
problem_source_description,
"This probably means that a ']' is missing somewhere. "
"(If you are using Inform with syntax colouring, look for "
"where the comment colour starts.) Inform's convention on "
"'nested comments' is that each '[' in a comment must be "
"matched by a corresponding ']': so for instance '[This "
"[even nested like so] acts as a comment]' is a single "
"comment - the first ']' character matches the second '[' "
"and so doesn't end the comment: only the second ']' ends "
"the comment.");
}
if (lxs_kind_of_word == I6_INCLUSION_KW) {
Problems__Issue__lexical_problem(_p_(PM_UnendingI6),
"Some source text ended in the middle of a verbatim passage "
"of Inform 6 code",
problem_source_description,
"This probably means that a '-)' is missing.");
}
lxs_kind_of_word = ORDINARY_KW;
}
#line 578 "inform7/Chapter 12/Lexer.w"
;
return RRW;
}
#line 684 "inform7/Chapter 12/Lexer.w"
void Lexer__feed_triplet(int last_cr, int cr, int next_cr) {
lxs_previous_char_in_raw_feed = last_cr;
int space = FALSE;
if (Lexer__is_punctuation((char) cr)) space = TRUE;
if ((space) && (lxs_literal_mode)) space = FALSE;
if ((space) && (cr != '[') && (cr != ']')) {
if ((space) && (next_cr == '/')) space = FALSE;
if (space) {
int lc = 0, nc = 0;
if (isdigit(last_cr)) lc = 1;
if ((last_cr >= 'a') && (last_cr <= 'z')) lc = 2;
if (isdigit(next_cr)) nc = 1;
if (next_cr == '-') nc = 1;
if ((next_cr >= 'a') && (next_cr <= 'z')) nc = 2;
if ((lc == 1) && (nc == 1)) space = FALSE;
if ((cr == '.') && (lc > 0) && (nc > 0)) space = FALSE;
}
}
if (space) {
Lexer__feed_char_into_lexer(' ');
Lexer__feed_char_into_lexer((char) cr); /* which might take us into literal mode, so to be careful... */
if (lxs_literal_mode == FALSE) Lexer__feed_char_into_lexer(' ');
} else Lexer__feed_char_into_lexer((char) cr);
if ((cr == '\n') && (lexer_position.file_of_origin))
lexer_position.line_number++;
}
#line 741 "inform7/Chapter 12/Lexer.w"
void Lexer__feed_char_into_lexer(char c) {
Lexer__ensure_lexer_hwm_can_be_raised_by(MAX_WORD_LENGTH, TRUE);
if (lxs_literal_mode) {
{
#line 1020 "inform7/Chapter 12/Lexer.w"
switch(lxs_kind_of_word) {
case COMMENT_KW:
if (c == COMMENT_BEGIN) lxs_comment_nesting++;
if (c == COMMENT_END) {
lxs_comment_nesting--;
if (lxs_comment_nesting == 0) lxs_literal_mode = FALSE;
}
break;
case STRING_KW:
if (c == STRING_END) {
lxs_string_soak_up_spaces_mode = FALSE;
*(lexer_hwm++) = c; /* record the |STRING_END| character as part of the word */
lxs_literal_mode = FALSE;
}
break;
case I6_INCLUSION_KW:
if ((c == INFORM6_ESCAPE_END_2) &&
(lxs_previous_char_in_raw_feed == INFORM6_ESCAPE_END_1)) {
lexer_hwm--; /* erase the |INFORM6_ESCAPE_END_1| character recorded last time */
lxs_literal_mode = FALSE;
}
break;
default: internal_error("in unknown literal mode");
}
if (lxs_literal_mode == FALSE) c = ' '; /* trigger completion of this word */
}
#line 745 "inform7/Chapter 12/Lexer.w"
;
if (lxs_kind_of_word == STRING_KW) {
{
#line 1067 "inform7/Chapter 12/Lexer.w"
if ((lexer_divide_strings_at_text_substitutions) && (c == TEXT_SUBSTITUTION_BEGIN)) {
Lexer__feed_char_into_lexer(STRING_END); /* feed |"| to close the old string */
Lexer__feed_char_into_lexer(' ');
Lexer__feed_char_into_lexer(TEXT_SUBSTITUTION_SEPARATOR); /* feed |,| to start new word */
c = ' '; /* the lexer now goes on to record a space, which will end the |,| word */
lxs_scanning_text_substitution = TRUE; /* but remember that we must get back again */
}
}
#line 747 "inform7/Chapter 12/Lexer.w"
;
{
#line 837 "inform7/Chapter 12/Lexer.w"
if (lxs_string_soak_up_spaces_mode) {
switch(c) {
case ' ': case '\t': c = *(lexer_hwm-1); lexer_hwm--; break;
case '\n':
*(lexer_hwm-1) = NEWLINE_IN_STRING;
c = NEWLINE_IN_STRING;
break;
default: lxs_string_soak_up_spaces_mode = FALSE; break;
}
}
if (c == '\n') {
while (is_whitespace(*(lexer_hwm-1))) lexer_hwm--;
lxs_string_soak_up_spaces_mode = TRUE;
}
}
#line 748 "inform7/Chapter 12/Lexer.w"
;
}
}
/* whitespace outside literal mode ends any partly built word and need not be recorded */
if ((lxs_literal_mode == FALSE) && (is_whitespace(c))) {
{
#line 786 "inform7/Chapter 12/Lexer.w"
if (c == '\t') {
lxs_number_of_tab_stops++;
if (lxs_most_significant_space_char != '\n') lxs_most_significant_space_char = '\t';
}
if (c == '\n') {
lxs_number_of_tab_stops = 0;
lxs_most_significant_space_char = '\n';
}
}
#line 754 "inform7/Chapter 12/Lexer.w"
;
if (lexer_word != lexer_hwm)
{
#line 862 "inform7/Chapter 12/Lexer.w"
*lexer_hwm++ = 0; /* terminate the current word as a C string */
if ((lexer_wait_for_dashes) && (strcmp(lexer_word, "----") == 0))
lexer_wait_for_dashes = FALSE; /* our long wait for documentation is over */
if ((lexer_wait_for_dashes == FALSE) && (lxs_kind_of_word != COMMENT_KW)) {
{
#line 882 "inform7/Chapter 12/Lexer.w"
int len = Platform__strlen(lexer_word), max_len = MAX_WORD_LENGTH;
if (lxs_kind_of_word == STRING_KW) max_len = MAX_STRING_LENGTH;
if (lxs_kind_of_word == I6_INCLUSION_KW) max_len = MAX_VERBATIM_LENGTH;
if (len > max_len) {
lexer_word[max_len] = 0; /* truncate to its maximum length */
if (lxs_kind_of_word == STRING_KW)
Problems__Issue__lexical_problem(_p_(PM_TooMuchQuotedText),
"Too much text in quotation marks", lexer_word,
"...\" The maximum length is very high, so this is more "
"likely to be because a close quotation mark was "
"forgotten.");
else {
if (lxs_kind_of_word == I6_INCLUSION_KW) {
lexer_word[100] = 0; /* to avoid an absurdly long problem message */
Problems__Issue__lexical_problem(_p_(Untestable), /* well, not at all conveniently */
"Verbatim Inform 6 extract too long", lexer_word,
"... -). The maximum length is quite high, so this "
"may be because a '-)' was forgotten. Still, if "
"you do need to paste a huge I6 program in, try "
"using several verbatim inclusions in a row.");
} else
Problems__Issue__lexical_problem(_p_(PM_WordTooLong),
"Word too long", lexer_word,
"(Individual words of unquoted text can run up to "
"128 letters long, which ought to be plenty. The longest "
"recognised place name in the English speaking world is "
"a hill in New Zealand called Taumatawhakatang-"
"ihangakoauauot-amateaturipukaka-pikimaunga-"
"horonuku-pokaiwhenuak-itanatahu. (You say tomato, "
"I say taumatawhakatang-...) The longest word found in a "
"classic novel is "
"bababadalgharaghtakamminarronnkonnbronntonnerronntuonnthunntrovarrhounawnskawntoohoohoordenenthurnuk, "
"creation's thunderclap from Finnegan's Wake. And both of those "
"words are fine.)");
}
}
}
#line 868 "inform7/Chapter 12/Lexer.w"
;
{
#line 939 "inform7/Chapter 12/Lexer.w"
lw_array[lexer_wordcount].lw_rawtext = lexer_word;
lw_array[lexer_wordcount].lw_source = lexer_position;
if (lxs_kind_of_word == ORDINARY_KW) {
int i;
lw_array[lexer_wordcount].lw_text = lexer_hwm;
for (i=0; lexer_word[i]; i++) *(lexer_hwm++) = Platform__tolower(lexer_word[i]);
*(lexer_hwm++) = 0;
} else {
lw_array[lexer_wordcount].lw_text = lw_array[lexer_wordcount].lw_rawtext;
}
Vocabulary__identify_word(lexer_wordcount); /* which sets |lw_array[lexer_wordcount].lw_identity| */
lexer_wordcount++;
Lexer__ensure_space_up_to(lexer_wordcount);
}
#line 869 "inform7/Chapter 12/Lexer.w"
;
}
/* now get ready for what we expect by default to be an ordinary word next */
lexer_word = lexer_hwm;
lxs_this_word_is_empty_so_far = TRUE;
lxs_kind_of_word = ORDINARY_KW;
}
#line 755 "inform7/Chapter 12/Lexer.w"
;
if (c == '\n')
{
#line 818 "inform7/Chapter 12/Lexer.w"
if (lxs_this_line_is_empty_so_far) {
int i;
for (i=0; PARAGRAPH_BREAK[i]; i++)
Lexer__feed_char_into_lexer(PARAGRAPH_BREAK[i]);
Lexer__feed_char_into_lexer(' ');
}
lxs_this_line_is_empty_so_far = TRUE;
}
#line 756 "inform7/Chapter 12/Lexer.w"
;
return;
}
/* otherwise record the current character as part of the word being built */
*(lexer_hwm++) = c;
if (lxs_scanning_text_substitution) {
{
#line 1094 "inform7/Chapter 12/Lexer.w"
if ((lexer_divide_strings_at_text_substitutions) && (c == TEXT_SUBSTITUTION_END)) {
lxs_scanning_text_substitution = FALSE;
*(lexer_hwm-1) = TEXT_SUBSTITUTION_SEPARATOR; /* overwrite recorded copy of |]| with |,| */
Lexer__feed_char_into_lexer(' '); /* then feed a space to end the |,| word */
Lexer__feed_char_into_lexer(STRING_BEGIN); /* then feed |"| to open a new string */
}
}
#line 764 "inform7/Chapter 12/Lexer.w"
;
}
if (lxs_this_word_is_empty_so_far) {
{
#line 803 "inform7/Chapter 12/Lexer.w"
if ((lxs_most_significant_space_char == '\n') && (lxs_number_of_tab_stops >= 1))
lw_array[lexer_wordcount].lw_break =
Lexer__break_char_for_indents(lxs_number_of_tab_stops); /* newline followed by 1 or more tabs */
else
lw_array[lexer_wordcount].lw_break = lxs_most_significant_space_char;
lxs_most_significant_space_char = ' '; /* waiting for the next run of whitespace, after this word */
lxs_number_of_tab_stops = 0;
}
#line 768 "inform7/Chapter 12/Lexer.w"
;
{
#line 978 "inform7/Chapter 12/Lexer.w"
switch(c) {
case COMMENT_BEGIN:
lxs_literal_mode = TRUE; lxs_kind_of_word = COMMENT_KW;
lxs_comment_nesting = 1;
break;
case STRING_BEGIN:
lxs_literal_mode = TRUE; lxs_kind_of_word = STRING_KW;
break;
case INFORM6_ESCAPE_BEGIN_2:
if ((lxs_previous_char_in_raw_feed != INFORM6_ESCAPE_BEGIN_1) ||
(lexer_allow_I6_escapes == FALSE)) break;
lxs_literal_mode = TRUE; lxs_kind_of_word = I6_INCLUSION_KW;
/* because of spacing around punctuation outside literal mode, the |(| became a word */
if (lexer_wordcount > 0) { /* this should always be true: just being cautious */
lw_array[lexer_wordcount-1].lw_text = "(-"; /* change the previous word's text from |(| to |(-| */
lw_array[lexer_wordcount-1].lw_rawtext = "(-";
Vocabulary__identify_word(lexer_wordcount-1); /* and re-identify */
}
lexer_hwm--; /* erase the just-recorded |INFORM6_ESCAPE_BEGIN_2| character */
break;
}
}
#line 769 "inform7/Chapter 12/Lexer.w"
;
}
lxs_this_word_is_empty_so_far = FALSE;
lxs_this_line_is_empty_so_far = FALSE;
}
#line 1122 "inform7/Chapter 12/Lexer.w"
wording Lexer__splice_words(wording W) {
int L = Wordings__length(W);
Lexer__ensure_space_up_to(lexer_wordcount + L);
for (int i=0; i<L; i++)
Lexer__word_copy(lexer_wordcount+i, Wordings__first_wn(W)+i);
wording N = Wordings__new(lexer_wordcount, lexer_wordcount + L - 1);
lexer_wordcount += L;
return N;
}
#line 60 "inform7/Chapter 12/Read Source Text.w"
int SourceFiles__read_extension_source_text(extension_file *EF,
char *synopsis, int documentation_only) {
int rv = SourceFiles__read_file(NULL, synopsis, EF, documentation_only);
if (Log__aspect_switched_on(LEXICAL_OUTPUT_DA)) Text__log_lexer_output();
return rv;
}
void SourceFiles__read_primary_source_text(void) {
Feeds__feed_text(MANDATORY_INSERTED_TEXT);
Log__read_further_mandatory_text();
SourceFiles__read_file(filename_of_i7_source, "your source text", NULL, FALSE);
}
#line 86 "inform7/Chapter 12/Read Source Text.w"
int SourceFiles__read_file(filename *F, char *synopsis, extension_file *EF,
int documentation_only) {
source_file *sf = CREATE(source_file);
if (EF == NULL) primary_source_file = sf;
sf->words_of_source = 0;
sf->last_lexed_word = -1;
sf->words_of_quoted_text = 0;
sf->extension_provided = EF;
sf->name = F;
int origin_tried = ORIGIN_WAS_PRIMARY_SOURCE;
{
#line 121 "inform7/Chapter 12/Read Source Text.w"
sf->handle = NULL;
if (EF) {
char author_name[MAX_FILENAME_LENGTH];
Wordings__to_string(author_name, EF->author_text);
char title[MAX_FILENAME_LENGTH];
Wordings__to_string(title, EF->title_text);
for (int area=0; area<NO_FS_AREAS; area++)
if (sf->handle == NULL) {
pathname *P = pathname_of_extensions[area];
origin_tried = area + 1;
sf->name = Locations__of_extension(P, title, author_name, TRUE);
sf->handle = Platform__iso_fopen_caseless(sf->name, "r");
if (sf->handle == NULL) {
sf->name = Locations__of_extension(P, title, author_name, FALSE);
sf->handle = Platform__iso_fopen_caseless(sf->name, "r");
}
}
if (sf->handle == NULL) {
LOG("Author: $w\n", EF->author_text);
LOG("Title: $w\n", EF->title_text);
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, synopsis);
Problems__Issue__handmade_problem(_p_(PM_BogusExtension));
Problems__issue_problem_segment(
"I can't find the extension '%2', which seems not to be installed, "
"but was requested by: %1. %P"
"You can get hold of extensions which people have made public at "
"the Inform website, www.inform7.com, or by using the Public "
"Library in the Extensions panel.");
Problems__issue_problem_end();
return -1;
}
} else {
sf->handle = Platform__iso_fopen(sf->name, "r");
if (sf->handle == NULL)
Problems__Fatal__filename_related(
"Error: can't open source text file", sf->name);
}
}
#line 98 "inform7/Chapter 12/Read Source Text.w"
;
if (EF) Extensions__Files__set_corresponding_source_file(EF, sf);
SourceFiles__feed_file_into_lexer(sf, Filenames__get_leafname(F), documentation_only);
fclose(sf->handle);
if (documentation_only == FALSE)
{
#line 171 "inform7/Chapter 12/Read Source Text.w"
int wc;
char *message;
if (EF == NULL) message = "I've now read %s, which is %d words long.\n";
else message = "I've also read %s, which is %d words long.\n";
wc = SourceFiles__total_word_count(sf);
WRITE_TO(STDOUT, message, synopsis, wc);
STREAM_FLUSH(STDOUT);
LOG(message, synopsis, wc);
}
#line 105 "inform7/Chapter 12/Read Source Text.w"
;
return origin_tried;
}
#line 193 "inform7/Chapter 12/Read Source Text.w"
void SourceFiles__feed_file_into_lexer(source_file *sf, char *leaf, int documentation_only) {
source_location top_of_file;
int cr, last_cr, next_cr, read_cr, newline_char = 0;
top_of_file.file_of_origin = sf;
top_of_file.line_number = 1;
Lexer__feed_begins(top_of_file);
if (documentation_only) lexer_wait_for_dashes = TRUE;
last_cr = ' '; cr = ' '; next_cr = SourceFiles__utf8_fgetc(sf->handle, NULL, TRUE);
if (next_cr == 0xFEFF) next_cr = SourceFiles__utf8_fgetc(sf->handle, NULL, TRUE); /* Unicode BOM code */
if (next_cr != EOF)
while (((read_cr = SourceFiles__utf8_fgetc(sf->handle, NULL, TRUE)), next_cr) != EOF) {
last_cr = cr; cr = next_cr; next_cr = read_cr;
switch(cr) {
case '\x0a':
if (newline_char == '\x0d') {
newline_char = 0; continue; /* suppress |0x000A| when it follows |0x000D| */
}
newline_char = cr; cr = '\n'; /* and otherwise convert to |'\n'| */
break;
case '\x0d':
if (newline_char == '\x0a') {
newline_char = 0; continue; /* suppress |0x000D| when it follows |0x000A| */
}
newline_char = cr; cr = '\n'; /* and otherwise convert to |'\n'| */
break;
default:
newline_char = 0;
break;
}
Lexer__feed_triplet(last_cr, cr, next_cr);
}
if (primary_source_file == sf) leaf = "main source text";
wording FEDW = Lexer__feed_ends(TRUE, leaf);
{
#line 239 "inform7/Chapter 12/Read Source Text.w"
LOOP_THROUGH_WORDING(wc, FEDW)
sf->words_of_source += SourceFiles__word_count(wc);
}
#line 231 "inform7/Chapter 12/Read Source Text.w"
;
sf->last_lexed_word = Wordings__last_wn(FEDW);
}
#line 245 "inform7/Chapter 12/Read Source Text.w"
int SourceFiles__word_count(int wc) {
int N = 0;
char *p = Lexer__word_text(wc);
if (*p == '"') {
/* inside quoted text, each run of non-whitespace counts as 1 word */
p++; /* skip opening quotation mark */
while (*p != 0) {
while ((*p == ' ') || (*p == NEWLINE_IN_STRING)) p++; /* move past white space */
if ((*p == '"') || (*p == 0)) break; /* stop if this reaches the end */
N++; /* otherwise we have a word */
while ((*p != ' ') && (*p != NEWLINE_IN_STRING)
&& (*p != '"') && (*p != 0)) p++; /* move to white space or end */
}
} else {
/* outside quoted text, each lexer word not wholly composed of punctuation scores 1 */
if (Lexer__word(wc) != PARBREAK_V)
for (; *p != 0; p++)
if ((Lexer__is_punctuation(*p) == FALSE) && (*p != '|')) {
N++;
break;
}
}
return N;
}
#line 274 "inform7/Chapter 12/Read Source Text.w"
int SourceFiles__total_word_count(source_file *sf) {
return sf->words_of_source + sf->words_of_quoted_text;
}
int SourceFiles__last_lexed_word(source_file *sf) {
return sf->last_lexed_word;
}
#line 288 "inform7/Chapter 12/Read Source Text.w"
filename *SourceFiles__get_filename(source_file *sf) {
if (sf == NULL) internal_error("tried to read filename of null source file");
return sf->name;
}
extension_file *SourceFiles__get_extension_corresponding(source_file *sf) {
if (sf == NULL) return NULL;
return sf->extension_provided;
}
source_file *SourceFiles__filename_to_source_file(char *name2) {
int l2 = Platform__strlen(name2);
source_file *sf;
LOOP_OVER(sf, source_file) {
char name1[MAX_FILENAME_LENGTH];
Filenames__to_string(name1, sf->name);
int l1 = Platform__strlen(name1);
int minl = (l1<l2)?l1:l2;
if ((l1 > minl) && (name1[l1-minl-1] != FOLDER_SEPARATOR)) continue;
if ((l2 > minl) && (name2[l2-minl-1] != FOLDER_SEPARATOR)) continue;
if (strcmp(name1+l1-minl, name2+l2-minl) == 0) return sf;
}
return NULL;
}
#line 337 "inform7/Chapter 12/Read Source Text.w"
char unicode_feed_buffer[32]; /* holds a single escape such as "[unicode 3106]" */
int ufb_counter = -1; /* position in the unicode feed buffer */
int SourceFiles__utf8_fgetc(FILE *from, char **or_from, int escape_oddities) {
int c = EOF, conts;
if (ufb_counter >= 0) {
if (unicode_feed_buffer[ufb_counter] == 0) ufb_counter = -1;
else return unicode_feed_buffer[ufb_counter++];
}
if (from) c = fgetc(from); else if (or_from) c = ((unsigned char) *((*or_from)++));
if (c == EOF) return c; /* ruling out EOF leaves a genuine byte from the file */
if (c<0x80) return c; /* in all other cases, a UTF-8 continuation sequence begins */
{
#line 370 "inform7/Chapter 12/Read Source Text.w"
if (c<0xC0) return '?'; /* malformed UTF-8 */
if (c<0xE0) { c = c & 0x1f; conts = 1; }
else if (c<0xF0) { c = c & 0xf; conts = 2; }
else if (c<0xF8) { c = c & 0x7; conts = 3; }
else if (c<0xFC) { c = c & 0x3; conts = 4; }
else { c = c & 0x1; conts = 5; }
while (conts > 0) {
int d = EOF;
if (from) d = fgetc(from); else if (or_from) d = ((unsigned char) *((*or_from)++));
if (d == EOF) return '?'; /* malformed UTF-8 */
c = c << 6;
c = c + (d & 0x3F);
conts--;
}
}
#line 350 "inform7/Chapter 12/Read Source Text.w"
;
{
#line 398 "inform7/Chapter 12/Read Source Text.w"
if ((c == 0xa1) || (c == 0xa3) || (c == 0xbf)) return c; /* pound sign, inverted ! and ? */
if (c == 0xd7) return 'x'; /* convert multiplication sign to lower case "x" */
if ((c >= 0xc0) && (c <= 0xff)) { /* accented West European letters, but... */
if ((c != 0xd0) && (c != 0xf0) && /* not Icelandic eths */
(c != 0xde) && (c != 0xfe) && /* nor Icelandic thorns */
(c != 0xf7)) /* nor division signs */
return c;
}
}
#line 351 "inform7/Chapter 12/Read Source Text.w"
;
{
#line 413 "inform7/Chapter 12/Read Source Text.w"
if (c == 0x85) return '\x0d'; /* NEL, or "next line" */
if (c == 0xa0) return ' '; /* non-breaking space */
if ((c >= 0x2000) && (c <= 0x200a)) return ' '; /* space variants */
if ((c >= 0x2010) && (c <= 0x2014)) return '-'; /* rules and dashes */
if ((c >= 0x2018) && (c <= 0x2019)) return '\''; /* smart single quotes */
if ((c >= 0x201c) && (c <= 0x201d)) return '"'; /* smart double quotes */
if ((c >= 0x2028) && (c <= 0x2029)) return '\x0d'; /* fancy newlines */
}
#line 352 "inform7/Chapter 12/Read Source Text.w"
;
if (c == 0xFEFF) return c; /* the Unicode BOM non-character */
if (escape_oddities == FALSE) return c;
sprintf(unicode_feed_buffer, "[unicode %d]", c);
ufb_counter = 1;
return '[';
}
#line 27 "inform7/Chapter 12/Lexical Services.w"
int Text__compare_word_by_strcmp(int w, char *t) {
return (strcmp(Lexer__word_text(w), t) == 0);
}
int Text__compare_raw_word_by_strcmp(int w, char *t) {
return (strcmp(Lexer__word_raw_text(w), t) == 0);
}
#line 42 "inform7/Chapter 12/Lexical Services.w"
int Text__unexpectedly_upper_case(int wn) {
if (wn<1) return FALSE;
if (compare_word(wn-1, FULLSTOP_V)) return FALSE;
if (compare_word(wn-1, PARBREAK_V)) return FALSE;
if (compare_word(wn-1, COLON_V)) return FALSE;
if (isupper(*(Lexer__word_raw_text(wn)))) {
if (Text__text_ending_sentence(wn-1)) return FALSE;
return TRUE;
}
return FALSE;
}
#line 57 "inform7/Chapter 12/Lexical Services.w"
int Text__singly_quoted(int wn) {
if (wn<1) return FALSE;
char *p = Lexer__word_raw_text(wn);
int qc = 0;
if (p[0] == '\'') qc++;
if ((Platform__strlen(p) > 1) && (p[Platform__strlen(p)-1] == '\'')) qc++;
return qc;
}
#line 70 "inform7/Chapter 12/Lexical Services.w"
int Text__text_ending_sentence(int wn) {
char *p = Lexer__word_raw_text(wn);
if (p[0] != '"') return FALSE;
p += Platform__strlen(p) - 2;
if ((p[0] == '.') && (p[1] == '"')) return TRUE;
if ((p[0] == '?') && (p[1] == '"')) return TRUE;
if ((p[0] == '!') && (p[1] == '"')) return TRUE;
p--;
if ((p[0] == '.') && (p[1] == ')') && (p[2] == '"')) return TRUE;
if ((p[0] == '?') && (p[1] == ')') && (p[2] == '"')) return TRUE;
if ((p[0] == '!') && (p[1] == ')') && (p[2] == '"')) return TRUE;
if ((p[0] == '.') && (p[1] == '\'') && (p[2] == '"')) return TRUE;
if ((p[0] == '?') && (p[1] == '\'') && (p[2] == '"')) return TRUE;
if ((p[0] == '!') && (p[1] == '\'') && (p[2] == '"')) return TRUE;
return FALSE;
}
#line 90 "inform7/Chapter 12/Lexical Services.w"
int if_start_of_paragraph_NTMR(wording W, int *X, void **XP) {
#line 91 "inform7/Chapter 12/Lexical Services.w"
int w1 = Wordings__first_wn(W);
if ((w1 == 0) || (compare_word(w1-1, PARBREAK_V))) return TRUE;
return FALSE;
}
#line 107 "inform7/Chapter 12/Lexical Services.w"
int if_start_of_source_text_NTMR(wording W, int *X, void **XP) {
#line 108 "inform7/Chapter 12/Lexical Services.w"
int w1 = Wordings__first_wn(W);
if ((no_sentences_read == 2) &&
((w1 == 0) || (compare_word(w1-1, PARBREAK_V)))) return TRUE;
return FALSE;
}
#line 117 "inform7/Chapter 12/Lexical Services.w"
int if_not_deliberately_capitalised_NTMR(wording W, int *X, void **XP) {
#line 118 "inform7/Chapter 12/Lexical Services.w"
int w1 = Wordings__first_wn(W);
if (Text__unexpectedly_upper_case(w1) == FALSE) return TRUE;
return FALSE;
}
#line 128 "inform7/Chapter 12/Lexical Services.w"
void Text__dequote_word(int wn) {
char *previous_text = Lexer__word_text(wn);
char *dequoted_text;
if (previous_text[0] != '"') return;
Lexer__set_word_raw_text(wn, Lexer__copy_to_memory(Lexer__word_raw_text(wn)));
dequoted_text = previous_text + 1;
while (*(dequoted_text) == ' ') dequoted_text++;
if ((Platform__strlen(dequoted_text) > 0) &&
(*(dequoted_text+Platform__strlen(dequoted_text)-1) == '"'))
*(dequoted_text+Platform__strlen(dequoted_text)-1) = 0;
while ((Platform__strlen(dequoted_text) > 0) &&
(*(dequoted_text+Platform__strlen(dequoted_text)-1) == ' '))
*(dequoted_text+Platform__strlen(dequoted_text)-1) = 0;
Lexer__set_word_text(wn, dequoted_text);
LOGIF(VOCABULARY, "Dequoting word %d <%s> to <%s>\n",
wn, previous_text, dequoted_text);
Vocabulary__identify_word(wn);
Vocabulary__set_raw_exemplar_to_text(wn);
}
#line 158 "inform7/Chapter 12/Lexical Services.w"
int Text__well_formed_text_routine(char *fw) {
int i, escaped = NOT_APPLICABLE;
for (i=0; fw[i] != 0; i++) {
if (fw[i] == TEXT_SUBSTITUTION_BEGIN) {
if (escaped == TRUE) return FALSE;
escaped = TRUE;
}
if (fw[i] == TEXT_SUBSTITUTION_END) {
if (escaped != TRUE) return FALSE;
escaped = FALSE;
}
}
if (escaped == NOT_APPLICABLE) return escaped;
if (escaped) return FALSE;
return TRUE;
}
int Text__perhaps_ill_formed_text_routine(char *fw) {
int i;
for (i=0; fw[i] != 0; i++) {
if (fw[i] == TEXT_SUBSTITUTION_BEGIN) return TRUE;
if (fw[i] == TEXT_SUBSTITUTION_END) return TRUE;
}
return FALSE;
}
#line 189 "inform7/Chapter 12/Lexical Services.w"
void Text__to_stream(OUTPUT_STREAM, char *p) {
if (STREAM_ENCODING(OUT) == UTF8_ENC) STREAM_USE_XML_ESCAPES(OUT, TRUE);
WRITE("%s", p);
STREAM_USE_XML_ESCAPES(OUT, FALSE);
}
#line 199 "inform7/Chapter 12/Lexical Services.w"
void Text__transcode_ISO_string_to_UTF8(char *p, char *dest) {
int i, j;
for (i=0, j=0; p[i]; i++) {
int charcode = (int) (((unsigned char *)p)[i]);
if (charcode >= 128) {
dest[j++] = (char) (0xC0 + (charcode >> 6));
dest[j++] = (char) (0x80 + (charcode & 0x3f));
} else {
dest[j++] = p[i];
}
}
dest[j] = 0;
}
#line 216 "inform7/Chapter 12/Lexical Services.w"
void Text__log_lexer_output(void) {
int i;
LOG("Entire lexer output to date:\n");
for (i=0; i<lexer_wordcount; i++) {
LOG("%d: <%s> <%s> <%c>\n", i, Lexer__word_raw_text(i), Lexer__word_text(i), Lexer__break_before(i));
}
LOG("------\n");
}
#line 54 "inform7/Chapter 12/Wordings.w"
wording Wordings__new(int A, int B) {
return (wording) { A, B };
}
wording Wordings__one_word(int A) {
return (wording) { A, A };
}
#line 66 "inform7/Chapter 12/Wordings.w"
wording Wordings__up_to(wording W, int last_wn) {
if (Wordings__empty(W)) return W;
W.word_B = last_wn;
return W;
}
wording Wordings__from(wording W, int first_wn) {
if (Wordings__empty(W)) return W;
W.word_A = first_wn;
return W;
}
#line 81 "inform7/Chapter 12/Wordings.w"
int Wordings__length(wording W) {
if (Wordings__empty(W)) return 0;
return W.word_B - W.word_A + 1;
}
int Wordings__phrasual_length(wording W) {
if (Wordings__empty(W)) return 0;
int bl = 0, n = 0;
LOOP_THROUGH_WORDING(i, W) {
if ((Lexer__word(i) == OPENBRACKET_V) || (Lexer__word(i) == OPENBRACE_V)) bl++;
if ((Lexer__word(i) == CLOSEBRACKET_V) || (Lexer__word(i) == CLOSEBRACE_V)) bl--;
if (bl == 0) n++;
}
return n;
}
int Wordings__first_wn(wording W) {
return W.word_A;
}
int Wordings__last_wn(wording W) {
return W.word_B;
}
#line 110 "inform7/Chapter 12/Wordings.w"
wording Wordings__truncate(wording W, int max) {
if (Wordings__length(W) > max) W.word_B = W.word_A + max - 1;
return W;
}
wording Wordings__first_word(wording W) {
if (Wordings__empty(W)) return EMPTY_WORDING;
W.word_B = W.word_A;
return W;
}
wording Wordings__last_word(wording W) {
if (Wordings__empty(W)) return EMPTY_WORDING;
W.word_A = W.word_B;
return W;
}
wording Wordings__trim_first_word(wording W) {
if (Wordings__empty(W)) return EMPTY_WORDING;
W.word_A++;
if (W.word_A > W.word_B) return EMPTY_WORDING;
return W;
}
wording Wordings__trim_last_word(wording W) {
if (Wordings__empty(W)) return EMPTY_WORDING;
W.word_B--;
if (W.word_A > W.word_B) return EMPTY_WORDING;
return W;
}
wording Wordings__trim_both_ends(wording W) {
if (Wordings__empty(W)) return EMPTY_WORDING;
W.word_A++; W.word_B--;
if (W.word_A > W.word_B) return EMPTY_WORDING;
return W;
}
#line 151 "inform7/Chapter 12/Wordings.w"
wording Wordings__union(wording W1, wording W2) {
if (Wordings__empty(W1)) return W2;
if (Wordings__empty(W2)) return W1;
int w1 = W1.word_A; if (w1 > W2.word_A) w1 = W2.word_A; /* the min */
int w2 = W1.word_B; if (w2 < W2.word_B) w2 = W2.word_B; /* the max */
return Wordings__new(w1, w2);
}
#line 162 "inform7/Chapter 12/Wordings.w"
int Wordings__within(wording SMALL, wording BIG) {
if ((Wordings__nonempty(SMALL)) && (Wordings__nonempty(BIG)) &&
(SMALL.word_A >= BIG.word_A) && (SMALL.word_B <= BIG.word_B))
return TRUE;
return FALSE;
}
source_location Wordings__location(wording W) {
return Lexer__word_location(W.word_A);
}
heading *Wordings__heading_of(wording W) {
return Sentences__Headings__heading_of(Wordings__location(W));
}
#line 181 "inform7/Chapter 12/Wordings.w"
int Wordings__empty(wording W) {
if ((W.word_A >= 0) && (W.word_B >= W.word_A)) return FALSE;
return TRUE;
}
int Wordings__nonempty(wording W) {
if ((W.word_A >= 0) && (W.word_B >= W.word_A)) return TRUE;
return FALSE;
}
#line 196 "inform7/Chapter 12/Wordings.w"
int Wordings__eq(wording W1, wording W2) {
if ((W1.word_A == W2.word_A) && (W1.word_B == W2.word_B))
return TRUE;
return FALSE;
}
#line 209 "inform7/Chapter 12/Wordings.w"
int Wordings__match(wording W1, wording W2) {
if ((W1.word_A >= 0) && (W1.word_B >= 0) &&
(Wordings__match_inner(W1.word_A, W1.word_B, W2.word_A, W2.word_B)))
return TRUE;
return FALSE;
}
int Wordings__starts_with(wording W, wording S) {
if ((Wordings__nonempty(W)) && (Wordings__nonempty(S)) &&
(Wordings__length(W) >= Wordings__length(S)) &&
(Wordings__match_inner(W.word_A, W.word_A + S.word_B - S.word_A, S.word_A, S.word_B)))
return TRUE;
return FALSE;
}
int Wordings__match_inner(int w1, int w2, int w3, int w4) {
if (w4-w3 != w2-w1) return FALSE;
if ((w1<0) || (w3<0)) return FALSE;
for (int j=0; j<=w2-w1; j++)
if (compare_words(w1+j, w3+j) == FALSE) return FALSE;
return TRUE;
}
#line 235 "inform7/Chapter 12/Wordings.w"
int Wordings__match_cs(wording W1, wording W2) {
if ((W1.word_A >= 0) && (W1.word_B >= 0) &&
(Wordings__match_cs_inner(W1.word_A, W1.word_B, W2.word_A, W2.word_B)))
return TRUE;
return FALSE;
}
int Wordings__match_cs_inner(int w1, int w2, int w3, int w4) {
if (w4-w3 != w2-w1) return FALSE;
if ((w1<0) || (w3<0)) return FALSE;
for (int j=0; j<=w2-w1; j++)
if (compare_words_cs(w1+j, w3+j) == FALSE) return FALSE;
return TRUE;
}
#line 255 "inform7/Chapter 12/Wordings.w"
int Wordings__match_perhaps_quoted(wording W1, wording W2) {
int w1 = W1.word_A, w2 = W1.word_B, w3 = W2.word_A, w4 = W2.word_B;
if (w4-w3 != w2-w1) return FALSE;
if ((w1<0) || (w3<0)) return FALSE;
for (int j=0; j<=w2-w1; j++) {
if (compare_words(w1+j, w3+j) == FALSE) {
if ((Vocabulary__test_flags(w1+j, (TEXT_MC+TEXTWITHSUBS_MC))) &&
(Vocabulary__test_flags(w3+j, (TEXT_MC+TEXTWITHSUBS_MC))) &&
(strcmp(Lexer__word_raw_text(w1+j), Lexer__word_raw_text(w3+j)) == 0))
continue;
return FALSE;
}
}
return TRUE;
}
#line 275 "inform7/Chapter 12/Wordings.w"
int Wordings__strcmp(wording X, wording Y) {
int x1 = X.word_A, x2 = X.word_B, y1 = Y.word_A, y2 = Y.word_B;
if (x1 < 0) { if (y1 < 0) return 0; return -1; }
if (y1 < 0) return 1;
int n;
int l1 = x2 - x1 + 1;
int l2 = y2 - y1 + 1;
for (n=0; (n<l1) && (n<l2); n++) {
int delta = strcmp(Lexer__word_text(x1 + n), Lexer__word_text(y1 + n));
if (delta != 0) return delta;
}
return l1 - l2;
}
#line 293 "inform7/Chapter 12/Wordings.w"
int Wordings__hash_code(wording W) {
if (Wordings__empty(W)) return 0;
return Semantics__Nouns__ExcerptMeanings__hash_code(W.word_A, W.word_B);
}
#line 303 "inform7/Chapter 12/Wordings.w"
int Wordings__paired_brackets(wording W) {
if ((Lexer__word(Wordings__first_wn(W)) == OPENBRACKET_V) &&
(Lexer__word(Wordings__last_wn(W)) == CLOSEBRACKET_V) &&
(Wordings__mismatched_brackets(Wordings__trim_both_ends(W)) == FALSE))
return TRUE;
return FALSE;
}
#line 314 "inform7/Chapter 12/Wordings.w"
int Wordings__mismatched_brackets(wording W) {
int bl = 0;
LOOP_THROUGH_WORDING(i, W) {
if ((Lexer__word(i) == OPENBRACKET_V) || (Lexer__word(i) == OPENBRACE_V)) bl++;
if ((Lexer__word(i) == CLOSEBRACKET_V) || (Lexer__word(i) == CLOSEBRACE_V)) bl--;
if (bl < 0) return TRUE;
}
if (bl != 0) return TRUE;
return FALSE;
}
#line 328 "inform7/Chapter 12/Wordings.w"
int Wordings__top_level_comma(wording W) {
int bl = 0;
LOOP_THROUGH_WORDING(i, W) {
if ((Lexer__word(i) == OPENBRACKET_V) || (Lexer__word(i) == OPENBRACE_V)) bl++;
if ((Lexer__word(i) == CLOSEBRACKET_V) || (Lexer__word(i) == CLOSEBRACE_V)) bl--;
if ((bl == 0) && (Lexer__word(i) == COMMA_V)) return TRUE;
}
return FALSE;
}
#line 342 "inform7/Chapter 12/Wordings.w"
int balanced_text_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 344 "inform7/Chapter 12/Wordings.w"
#line 356 "inform7/Chapter 12/Wordings.w"
int Wordings__last_word_of_formatted_text(wording W, int tab_flag) {
if (Wordings__empty(W)) return -1;
if (Wordings__length(W) == 1) return Wordings__first_wn(W);
LOOP_THROUGH_WORDING(i, W)
if (i > Wordings__first_wn(W))
if (((tab_flag) && (Lexer__break_before(i) == '\t')) ||
(Lexer__indentation_level(i) > 0) ||
(Lexer__break_before(i) == '\n'))
return i-1;
return Wordings__last_wn(W);
}
#line 378 "inform7/Chapter 12/Wordings.w"
void Wordings__to_stream(OUTPUT_STREAM, wording W) {
LOOP_THROUGH_WORDING(j, W) {
Text__to_stream(OUT, Lexer__word_text(j));
if (j<Wordings__last_wn(W)) WRITE(" ");
}
}
#line 388 "inform7/Chapter 12/Wordings.w"
void Wordings__to_string(char *str, wording W) {
str[0] = 0;
LOOP_THROUGH_WORDING(j, W) {
sprintf(str+Platform__strlen(str), "%s", Lexer__word_text(j));
if (j<Wordings__last_wn(W)) sprintf(str+Platform__strlen(str), " ");
}
}
void Wordings__to_string_truncated(char *str, int max, wording W) {
str[0] = 0;
LOOP_THROUGH_WORDING(j, W) {
char *p = Lexer__word_text(j);
char *p2 = "";
int sp = FALSE;
if (j<Wordings__last_wn(W)) { sp = TRUE; p2 = Lexer__word_raw_text(j+1); }
if (Platform__strlen(str) + Platform__strlen(p) + 2 > max) break;
sprintf(str+Platform__strlen(str), "%s", p);
if (strcmp(p2, ":")==0) sp = FALSE;
if (strcmp(p2, ",")==0) sp = FALSE;
if (strcmp(p2, ")")==0) sp = FALSE;
if (strcmp(p, "(")==0) sp = FALSE;
if (sp) sprintf(str+Platform__strlen(str), " ");
}
}
#line 421 "inform7/Chapter 12/Wordings.w"
void Wordings__to_string_abbreviated(int extent, char *str, wording W) {
if (extent < 10) internal_error("too little string space");
if (Wordings__empty(W)) {
sprintf(str, "<no text>");
} else {
char *q = str;
q[0] = 0;
LOOP_THROUGH_WORDING(i, W) {
int space = TRUE;
if (i == Wordings__first_wn(W)) space = FALSE;
else {
if (compare_word(i, COMMA_V)) space = FALSE;
if (compare_word(i, COLON_V)) space = FALSE;
if (compare_word(i, SEMICOLON_V)) space = FALSE;
if (compare_word(i, CLOSEBRACE_V)) space = FALSE;
if (compare_word(i, CLOSEBRACKET_V)) space = FALSE;
if (compare_word(i-1, OPENBRACE_V)) space = FALSE;
if (compare_word(i-1, OPENBRACKET_V)) space = FALSE;
}
char *p = Lexer__word_raw_text(i);
if (space) {
if (extent < 2) return;
sprintf(q++, " "); extent--;
}
char temp[STRING_TOLERANCE_LIMIT + 10];
temp[0] = 0;
int l = Platform__strlen(p);
char *from = p;
if (l > STRING_TOLERANCE_LIMIT+5) {
for (int j=0; j<STRING_TOLERANCE_LIMIT/2; j++)
sprintf(temp+Platform__strlen(temp), "%c", p[j]);
sprintf(temp+Platform__strlen(temp), " [...] ");
for (int j=STRING_TOLERANCE_LIMIT/2; j>0; j--)
sprintf(temp+Platform__strlen(temp), "%c", p[l-j]);
from = temp;
l = Platform__strlen(temp);
}
if (l+1 >= extent) return;
strcpy(q, from);
q += l; extent -= l;
if ((i >= Wordings__first_wn(W)+1) && (compare_word(i-1, OPENI6_V))) {
if (extent < 3) return;
sprintf(q, "-)");
q += 2; extent -= 2;
}
}
}
}
#line 489 "inform7/Chapter 12/Wordings.w"
void Wordings__to_stream_raw(OUTPUT_STREAM, wording W) {
LOOP_THROUGH_WORDING(j, W) {
char *p = Lexer__word_raw_text(j);
char *p2 = "";
int sp = FALSE;
if (j<Wordings__last_wn(W)) { sp = TRUE; p2 = Lexer__word_raw_text(j+1); }
Text__to_stream(OUT, p);
if (strcmp(p2, ":")==0) sp = FALSE;
if (strcmp(p2, ",")==0) sp = FALSE;
if (strcmp(p2, ")")==0) sp = FALSE;
if (strcmp(p, "(")==0) sp = FALSE;
if (sp) WRITE(" ");
}
}
#line 511 "inform7/Chapter 12/Wordings.w"
void Wordings__to_stream_raw_within_i6_literal(OUTPUT_STREAM, wording W) {
LOOP_THROUGH_WORDING(j, W) {
char *str = Lexer__word_raw_text(j);
if (j>Wordings__first_wn(W)) WRITE(" ");
for (int k=0; str[k] != 0; k++) {
char c = str[k];
switch (c) {
case '@': WRITE("@@"); break;
case '"': WRITE("~"); break;
case '^': WRITE("[cr]"); break;
case '\\': WRITE("[backslash]"); break;
default: WRITE("%c", c);
}
}
}
}
#line 531 "inform7/Chapter 12/Wordings.w"
void Wordings__to_string_raw(char *str, wording W) {
str[0] = 0;
LOOP_THROUGH_WORDING(j, W) {
char *p = Lexer__word_raw_text(j);
char *p2 = "";
int sp = FALSE;
if (j<Wordings__last_wn(W)) { sp = TRUE; p2 = Lexer__word_raw_text(j+1); }
sprintf(str+Platform__strlen(str), "%s", p);
if (strcmp(p2, ":")==0) sp = FALSE;
if (strcmp(p2, ",")==0) sp = FALSE;
if (strcmp(p2, ")")==0) sp = FALSE;
if (strcmp(p, "(")==0) sp = FALSE;
if (sp) sprintf(str+Platform__strlen(str), " ");
}
}
void Wordings__to_string_raw_truncated(char *str, int max, wording W) {
str[0] = 0;
LOOP_THROUGH_WORDING(j, W) {
char *p = Lexer__word_raw_text(j);
char *p2 = "";
int sp = FALSE;
if (j<Wordings__last_wn(W)) { sp = TRUE; p2 = Lexer__word_raw_text(j+1); }
if (Platform__strlen(str) + Platform__strlen(p) + 2 > max) break;
sprintf(str+Platform__strlen(str), "%s", p);
if (strcmp(p2, ":")==0) sp = FALSE;
if (strcmp(p2, ",")==0) sp = FALSE;
if (strcmp(p2, ")")==0) sp = FALSE;
if (strcmp(p, "(")==0) sp = FALSE;
if (sp) sprintf(str+Platform__strlen(str), " ");
}
}
#line 568 "inform7/Chapter 12/Wordings.w"
void Wordings__index(wording W) {
Wordings__to_stream(ifl, W);
}
void Wordings__index_raw(wording W) {
Wordings__to_stream_raw(ifl, W);
}
#line 580 "inform7/Chapter 12/Wordings.w"
void Wordings__log(wording W) {
Wordings__to_stream(dl, W);
}
void Wordings__log_raw(wording W) {
Wordings__to_stream_raw(dl, W);
}
#line 592 "inform7/Chapter 12/Wordings.w"
void Wordings__log_with_whitespace(wording W) {
LOOP_THROUGH_WORDING(j, W) {
char *del = "[sp]";
if (Lexer__break_before(j) == '\n') del = "[cr]";
if (Lexer__break_before(j) == '\t') del = "[tab]";
if (Lexer__indentation_level(j) > 0) del = "[cr+tab(s)]";
LOG("%s%s", Lexer__word_text(j), del);
if (j<Wordings__last_wn(W)) LOG(" ");
}
LOG("\n");
}
#line 609 "inform7/Chapter 12/Wordings.w"
void Wordings__log_spaceless(wording W) {
LOOP_THROUGH_WORDING(i, W) {
char *p = Lexer__word_text(i);
for (int j=0; p[j]; j++) {
if ((p[j] >= 0) || (p[j] <= 31)) LOG(" ");
else LOG("%c", p[j]);
}
if (i < Wordings__last_wn(W)) LOG(" ");
}
}
#line 30 "inform7/Chapter 12/Feeds.w"
feed_t Feeds__begin(void) {
return (feed_t) lexer_wordcount;
}
wording Feeds__end(feed_t id) {
return Wordings__new((int) id, lexer_wordcount-1);
}
#line 42 "inform7/Chapter 12/Feeds.w"
wording Feeds__feed_text(char *text) {
return Feeds__feed_text_full(text, FALSE, NULL);
}
wording Feeds__feed_text_expanding_strings(char *text) {
return Feeds__feed_text_full(text, TRUE, NULL);
}
wording Feeds__feed_text_for_preform(char *text) {
return Feeds__feed_text_full(text, FALSE, PREFORM_PUNCTUATION_MARKS);
}
#line 58 "inform7/Chapter 12/Feeds.w"
wording Feeds__feed_text_full(char *text, int expand_strings, char *nonstandard) {
source_location as_if_from_nowhere;
as_if_from_nowhere.file_of_origin = NULL;
as_if_from_nowhere.line_number = 1;
Lexer__feed_begins(as_if_from_nowhere);
lexer_divide_strings_at_text_substitutions = expand_strings;
lexer_allow_I6_escapes = TRUE;
if (nonstandard) {
lexer_punctuation_marks = nonstandard;
lexer_allow_I6_escapes = FALSE;
} else
lexer_punctuation_marks = STANDARD_PUNCTUATION_MARKS;
for (int i=0; text[i] != 0; i++) {
int last_cr, cr, next_cr;
if (i > 0) last_cr = text[i-1]; else last_cr = EOF;
cr = text[i];
if (cr != 0) next_cr = text[i+1]; else next_cr = EOF;
Lexer__feed_triplet(last_cr, cr, next_cr);
}
wording LEXW = Lexer__feed_ends(FALSE, NULL);
Vocabulary__identify_word_range(LEXW);
return LEXW;
}
#line 89 "inform7/Chapter 12/Feeds.w"
wording Feeds__feed_wording(wording W) {
return Lexer__splice_words(W);
}
#line 474 "inform7/Chapter 13/Parse Tree.w"
parse_tree_node_type parse_tree_node_types[NO_ENUMERATED_NTS] = {
/* first, the structural nodes: */
{ INVALID_NT, "(INVALID_NT)", 0, INFTY, INVALID_NCAT, 0 },
{ ROOT_NT, "ROOT_NT", 0, INFTY, L1_NCAT, DONT_VISIT_NFLAG },
{ INCLUSION_NT, "INCLUSION_NT", 0, INFTY, L1_NCAT, DONT_VISIT_NFLAG },
{ HEADING_NT, "HEADING_NT", 0, INFTY, L1_NCAT, 0 },
{ BIBLIOGRAPHIC_NT, "BIBLIOGRAPHIC_NT", 0, 0, L2_NCAT, 0 },
{ INCLUDE_NT, "INCLUDE_NT", 0, 0, L2_NCAT, 0 },
{ BEGINHERE_NT, "BEGINHERE_NT", 0, 0, L2_NCAT, 0 },
{ ENDHERE_NT, "ENDHERE_NT", 0, 0, L2_NCAT, 0 },
{ SENTENCE_NT, "SENTENCE_NT", 0, INFTY, L2_NCAT, 0 },
{ ROUTINE_NT, "ROUTINE_NT", 0, INFTY, L2_NCAT, 0 },
{ INFORM6CODE_NT, "INFORM6CODE_NT", 0, 0, L2_NCAT, 0 },
{ TABLE_NT, "TABLE_NT", 0, 0, L2_NCAT, 0 },
{ EQUATION_NT, "EQUATION_NT", 0, 0, L2_NCAT, 0 },
{ TRACE_NT, "TRACE_NT", 0, 0, L2_NCAT, 0 },
{ RELATIONSHIP_NT, "RELATIONSHIP_NT", 0, 2, L3_NCAT, ASSERT_NFLAG },
{ CALLED_NT, "CALLED_NT", 2, 2, L3_NCAT, 0 },
{ WITH_NT, "WITH_NT", 2, 2, L3_NCAT, ASSERT_NFLAG },
{ AND_NT, "AND_NT", 2, 2, L3_NCAT, ASSERT_NFLAG },
{ KIND_NT, "KIND_NT", 0, 1, L3_NCAT, ASSERT_NFLAG },
{ X_OF_Y_NT, "X_OF_Y_NT", 2, 2, L3_NCAT, ASSERT_NFLAG },
{ AVERB_NT, "AVERB_NT", 0, 0, L3_NCAT, 0 },
{ CREATED_NT, "CREATED_NT", 0, 0, L3_NCAT, ASSERT_NFLAG },
{ PROPER_NOUN_NT, "PROPER_NOUN_NT", 0, 0, L3_NCAT, ASSERT_NFLAG },
{ PROPERTY_LIST_NT, "PROPERTY_LIST_NT", 0, INFTY, L3_NCAT, ASSERT_NFLAG },
{ FROM_NT, "FROM_NT", 2, 2, L3_NCAT, 0 },
{ ALLOWED_NT, "ALLOWED_NT", 1, 1, L3_NCAT, ASSERT_NFLAG },
{ EVERY_NT, "EVERY_NT", 0, INFTY, L3_NCAT, ASSERT_NFLAG },
{ COMMON_NOUN_NT, "COMMON_NOUN_NT", 0, INFTY, L3_NCAT, ASSERT_NFLAG },
{ ACTION_NT, "ACTION_NT", 0, INFTY, L3_NCAT, ASSERT_NFLAG },
{ ADJECTIVE_NT, "ADJECTIVE_NT", 0, INFTY, L3_NCAT, ASSERT_NFLAG },
{ PROPERTYCALLED_NT, "PROPERTYCALLED_NT", 2, 2, L3_NCAT, 0 },
{ TOKEN_NT, "TOKEN_NT", 0, INFTY, L3_NCAT, 0 },
{ CODE_BLOCK_NT, "CODE_BLOCK_NT", 0, INFTY, L4_NCAT, 0 },
{ INVOCATION_LIST_NT, "INVOCATION_LIST_NT", 0, INFTY, L4_NCAT, 0 },
{ INVOCATION_LIST_SAY_NT, "INVOCATION_LIST_SAY_NT", 0, INFTY, L4_NCAT, 0 },
{ AMBIGUITY_NT, "AMBIGUITY_NT", 0, INFTY, L4_NCAT, 0 },
{ INVOCATION_NT, "INVOCATION_NT", 0, INFTY, L4_NCAT, 0 },
{ VOID_CONTEXT_NT, "VOID_CONTEXT_NT", 0, INFTY, L4_NCAT, 0 },
{ RVALUE_CONTEXT_NT, "RVALUE_CONTEXT_NT", 0, INFTY, L4_NCAT, 0 },
{ LVALUE_CONTEXT_NT, "LVALUE_CONTEXT_NT", 0, INFTY, L4_NCAT, 0 },
{ LVALUE_TR_CONTEXT_NT, "LVALUE_TR_CONTEXT_NT", 0, INFTY, L4_NCAT, 0 },
{ SPECIFIC_RVALUE_CONTEXT_NT, "SPECIFIC_RVALUE_CONTEXT_NT", 0, INFTY, L4_NCAT, 0 },
{ MATCHING_RVALUE_CONTEXT_NT, "MATCHING_RVALUE_CONTEXT_NT", 0, INFTY, L4_NCAT, 0 },
{ NEW_LOCAL_CONTEXT_NT, "NEW_LOCAL_CONTEXT_NT", 0, INFTY, L4_NCAT, 0 },
{ LVALUE_LOCAL_CONTEXT_NT, "LVALUE_LOCAL_CONTEXT_NT", 0, INFTY, L4_NCAT, 0 },
{ CONDITION_CONTEXT_NT, "CONDITION_CONTEXT_NT", 0, INFTY, L4_NCAT, 0 },
/* now the specification nodes: */
{ UNKNOWN_VNT, "UNKNOWN_VNT", 0, 0, UNKNOWN_NCAT, 0 },
{ CONSTANT_VNT, "CONSTANT_VNT", 0, 0, RVALUE_NCAT, 0 },
{ PHRASE_TO_DECIDE_VALUE_VNT, "PHRASE_TO_DECIDE_VALUE_VNT", 1, 1, RVALUE_NCAT, PHRASAL_NFLAG },
{ LOCAL_VARIABLE_VNT, "LOCAL_VARIABLE_VNT", 0, 0, LVALUE_NCAT, 0 },
{ NONLOCAL_VARIABLE_VNT, "NONLOCAL_VARIABLE_VNT", 0, 0, LVALUE_NCAT, 0 },
{ PROPERTY_VALUE_VNT, "PROPERTY_VALUE_VNT", 2, 2, LVALUE_NCAT, 0 },
{ TABLE_ENTRY_VNT, "TABLE_ENTRY_VNT", 1, 4, LVALUE_NCAT, 0 },
{ LIST_ENTRY_VNT, "LIST_ENTRY_VNT", 2, 2, LVALUE_NCAT, 0 },
{ LOGICAL_NOT_VNT, "LOGICAL_NOT_VNT", 1, 1, COND_NCAT, 0 },
{ LOGICAL_TENSE_VNT, "LOGICAL_TENSE_VNT", 1, 1, COND_NCAT, 0 },
{ LOGICAL_AND_VNT, "LOGICAL_AND_VNT", 2, 2, COND_NCAT, 0 },
{ LOGICAL_OR_VNT, "LOGICAL_OR_VNT", 2, 2, COND_NCAT, 0 },
{ TEST_PROPOSITION_VNT, "TEST_PROPOSITION_VNT", 0, 0, COND_NCAT, 0 },
{ TEST_PHRASE_OPTION_VNT, "TEST_PHRASE_OPTION_VNT", 0, 0, COND_NCAT, 0 },
{ TEST_VALUE_VNT, "TEST_VALUE_VNT", 1, 1, COND_NCAT, 0 },
};
#line 553 "inform7/Chapter 13/Parse Tree.w"
parse_tree_node_type *ParseTree__node_metadata(node_type_t t) {
if ((t >= BASE_OF_ENUMERATED_NTS) && (t < BASE_OF_ENUMERATED_NTS+NO_ENUMERATED_NTS)) {
parse_tree_node_type *metadata = &(parse_tree_node_types[t - BASE_OF_ENUMERATED_NTS]);
if ((metadata == NULL) || (metadata->identity != t))
internal_error("node type metadata lookup incorrect");
return metadata;
}
return NULL;
}
#line 566 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__valid_type(node_type_t t) {
if ((t >= BASE_OF_ENUMERATED_NTS) && (t < BASE_OF_ENUMERATED_NTS+NO_ENUMERATED_NTS)) return TRUE;
return FALSE;
}
int ParseTree__cat(node_type_t t) {
parse_tree_node_type *metadata = ParseTree__node_metadata(t);
if (metadata) return metadata->category;
return INVALID_NCAT;
}
int ParseTree__top_level(node_type_t t) {
parse_tree_node_type *metadata = ParseTree__node_metadata(t);
if ((metadata) && (metadata->category == L1_NCAT)) return TRUE;
return FALSE;
}
int ParseTree__second_level(node_type_t t) {
parse_tree_node_type *metadata = ParseTree__node_metadata(t);
if ((metadata) && (metadata->category == L2_NCAT)) return TRUE;
return FALSE;
}
int ParseTree__is_specification_node_type(node_type_t t) {
if (t == UNKNOWN_VNT) return TRUE;
parse_tree_node_type *metadata = ParseTree__node_metadata(t);
if ((metadata) &&
((metadata->category == RVALUE_NCAT) ||
(metadata->category == LVALUE_NCAT) ||
(metadata->category == COND_NCAT))) return TRUE;
return FALSE;
}
int ParseTree__visitable(node_type_t t) {
if (ParseTree__test_flag(t, DONT_VISIT_NFLAG)) return FALSE;
return TRUE;
}
int ParseTree__test_flag(node_type_t t, int f) {
parse_tree_node_type *metadata = ParseTree__node_metadata(t);
if ((metadata) && ((metadata->node_flags) & f)) return TRUE;
return FALSE;
}
#line 613 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__is_lvalue(parse_node *pn) {
parse_tree_node_type *metadata = ParseTree__node_metadata(ParseTree__get_type(pn));
if ((metadata) && (metadata->category == LVALUE_NCAT)) return TRUE;
return FALSE;
}
int ParseTree__is_rvalue(parse_node *pn) {
parse_tree_node_type *metadata = ParseTree__node_metadata(ParseTree__get_type(pn));
if ((metadata) && (metadata->category == RVALUE_NCAT)) return TRUE;
return FALSE;
}
int ParseTree__is_value(parse_node *pn) {
parse_tree_node_type *metadata = ParseTree__node_metadata(ParseTree__get_type(pn));
if ((metadata) &&
((metadata->category == LVALUE_NCAT) || (metadata->category == RVALUE_NCAT)))
return TRUE;
return FALSE;
}
int ParseTree__is_condition(parse_node *pn) {
parse_tree_node_type *metadata = ParseTree__node_metadata(ParseTree__get_type(pn));
if ((metadata) && (metadata->category == COND_NCAT)) return TRUE;
return FALSE;
}
int ParseTree__is_phrasal(parse_node *pn) {
if (ParseTree__test_flag(ParseTree__get_type(pn), PHRASAL_NFLAG)) return TRUE;
return FALSE;
}
#line 650 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__log_type(node_type_t t) {
parse_tree_node_type *metadata = ParseTree__node_metadata(t);
if (metadata) LOG("%s", metadata->node_type_name);
else if (t & 0x80000000) LOG("?%08x_NT", t);
else Semantics__Nouns__ExcerptMeanings__log_meaning_code(t);
}
char *ParseTree__get_type_name(node_type_t t) {
parse_tree_node_type *metadata = ParseTree__node_metadata(t);
if (metadata == NULL) return "?";
return metadata->node_type_name;
}
#line 666 "inform7/Chapter 13/Parse Tree.w"
parse_node *ParseTree__new(node_type_t t) {
parse_node *pn = CREATE(parse_node);
pn->node_type = t;
ParseTree__set_text(pn, EMPTY_WORDING);
pn->annotations = NULL;
pn->down = NULL; pn->next = NULL; pn->next_alternative = NULL;
pn->log_time = 0;
ParseTree__set_score(pn, 0);
return pn;
}
#line 681 "inform7/Chapter 13/Parse Tree.w"
parse_node *ParseTree__new_with_words(node_type_t code_number, wording W) {
parse_node *pn = ParseTree__new(code_number);
ParseTree__set_text(pn, W);
return pn;
}
#line 691 "inform7/Chapter 13/Parse Tree.w"
parse_node *ParseTree__new_from_em(excerpt_meaning *em) {
parse_node *pn = ParseTree__new(em->meaning_code);
ParseTree__set_meaning(pn, em);
return pn;
}
#line 700 "inform7/Chapter 13/Parse Tree.w"
wording ParseTree__get_text(parse_node *pn) {
if (pn == NULL) return EMPTY_WORDING;
return pn->text_parsed;
}
void ParseTree__set_text(parse_node *pn, wording W) {
if (pn == NULL) internal_error("tried to set words for null node");
pn->text_parsed = W;
}
#line 715 "inform7/Chapter 13/Parse Tree.w"
node_type_t ParseTree__get_type(parse_node *pn) {
if (pn == NULL) return UNKNOWN_VNT;
return pn->node_type;
}
int ParseTree__is(parse_node *pn, node_type_t t) {
if ((pn) && (pn->node_type == t)) return TRUE;
return FALSE;
}
#line 728 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__set_type(parse_node *pn, node_type_t nt) {
node_type_t from = pn->node_type;
if (ParseTree__is_specification_node_type(from)) {
LOG("$P changed to $N\n", pn, nt);
internal_error("S-node type changed");
}
pn->node_type = nt;
while ((pn->annotations) &&
(!(ParseTree__annotation_allowed(nt, pn->annotations->kind_of_annotation))))
pn->annotations = pn->annotations->next_annotation;
for (parse_node_annotation *pna = pn->annotations; pna; pna = pna->next_annotation)
if ((pna->next_annotation) &&
(!(ParseTree__annotation_allowed(nt, pna->next_annotation->kind_of_annotation))))
pna->next_annotation = pna->next_annotation->next_annotation;
}
void ParseTree__set_type_and_clear_annotations(parse_node *pn, node_type_t nt) {
pn->node_type = nt; pn->annotations = NULL;
}
#line 752 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__get_score(parse_node *pn) { return pn->score; }
void ParseTree__set_score(parse_node *pn, int s) { pn->score = s; }
#line 759 "inform7/Chapter 13/Parse Tree.w"
parse_node_annotation *ParseTree__pna_new(int koa) {
parse_node_annotation *pna = CREATE(parse_node_annotation);
pna->kind_of_annotation = koa;
pna->annotation_integer = 0;
pna->annotation_pointer = NULL_GENERAL_POINTER;
pna->next_annotation = NULL;
return pna;
}
#line 775 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__has_annotation(parse_node *PN, int koa) {
parse_node_annotation *pna;
if (PN)
for (pna=PN->annotations; pna; pna=pna->next_annotation)
if (pna->kind_of_annotation == koa)
return TRUE;
return FALSE;
}
#line 789 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__int_annotation(parse_node *PN, int koa) {
parse_node_annotation *pna;
if (PN)
for (pna=PN->annotations; pna; pna=pna->next_annotation)
if (pna->kind_of_annotation == koa)
return pna->annotation_integer;
return 0;
}
general_pointer ParseTree__pn_pointer_annotation(parse_node *PN, int koa) {
parse_node_annotation *pna;
if (PN)
for (pna=PN->annotations; pna; pna=pna->next_annotation)
if (pna->kind_of_annotation == koa)
return pna->annotation_pointer;
return NULL_GENERAL_POINTER;
}
#line 812 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__annotate_int(parse_node *PN, int koa, int v) {
parse_node_annotation *newpna, *pna, *final = NULL;
if (PN == NULL) internal_error("annotated null PN");
for (pna=PN->annotations; pna; pna=pna->next_annotation) {
if (pna->kind_of_annotation == koa) {
/* an annotation with this KOA exists already: overwrite it */
pna->annotation_integer = v;
return;
}
if (pna->next_annotation == NULL) final = pna;
}
/* no annotation with this KOA exists: create a new one and add to end of node's list */
newpna = ParseTree__pna_new(koa); newpna->annotation_integer = v;
if (final) final->next_annotation = newpna; else PN->annotations = newpna;
}
#line 831 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__pn_annotate_pointer(parse_node *PN, int koa, general_pointer data) {
if (PN == NULL) internal_error("annotated null PN");
parse_node_annotation *newpna, *pna, *final = NULL;
for (pna=PN->annotations; pna; pna=pna->next_annotation) {
if (pna->kind_of_annotation == koa) {
/* an annotation with this KOA exists already: overwrite it */
pna->annotation_pointer = data;
return;
}
if (pna->next_annotation == NULL) final = pna;
}
/* no annotation with this KOA exists: create a new one and add to end of node's list */
newpna = ParseTree__pna_new(koa); newpna->annotation_pointer = data;
if (final) final->next_annotation = newpna; else PN->annotations = newpna;
}
#line 869 "inform7/Chapter 13/Parse Tree.w"
MAKE_ANNOTATION_FUNCTIONS(action_meaning, action_pattern)
MAKE_ANNOTATION_FUNCTIONS(aph, adjectival_phrase)
MAKE_ANNOTATION_FUNCTIONS(condition_tense, time_period)
MAKE_ANNOTATION_FUNCTIONS(constant_action_name, action_name)
MAKE_ANNOTATION_FUNCTIONS(constant_action_pattern, action_pattern)
MAKE_ANNOTATION_FUNCTIONS(constant_activity, activity)
MAKE_ANNOTATION_FUNCTIONS(constant_binary_predicate, binary_predicate)
MAKE_ANNOTATION_FUNCTIONS(constant_constant_phrase, constant_phrase)
MAKE_ANNOTATION_FUNCTIONS(constant_equation, equation)
MAKE_ANNOTATION_FUNCTIONS(constant_grammar_verb, grammar_verb)
MAKE_ANNOTATION_FUNCTIONS(constant_instance, instance)
MAKE_ANNOTATION_FUNCTIONS(constant_local_variable, local_variable)
MAKE_ANNOTATION_FUNCTIONS(constant_named_rulebook_outcome, named_rulebook_outcome)
MAKE_ANNOTATION_FUNCTIONS(constant_nonlocal_variable, nonlocal_variable)
MAKE_ANNOTATION_FUNCTIONS(constant_property, property)
MAKE_ANNOTATION_FUNCTIONS(constant_rule, rule)
MAKE_ANNOTATION_FUNCTIONS(constant_rulebook, rulebook)
MAKE_ANNOTATION_FUNCTIONS(constant_scene, scene)
MAKE_ANNOTATION_FUNCTIONS(constant_table_column, table_column)
MAKE_ANNOTATION_FUNCTIONS(constant_table, table)
MAKE_ANNOTATION_FUNCTIONS(constant_text, text_stream)
MAKE_ANNOTATION_FUNCTIONS(constant_use_option, use_option)
MAKE_ANNOTATION_FUNCTIONS(constant_verb_conjugation, verb_conjugation)
MAKE_ANNOTATION_FUNCTIONS(control_structure_used, control_structure_phrase)
MAKE_ANNOTATION_FUNCTIONS(creation_proposition, pcalc_prop)
MAKE_ANNOTATION_FUNCTIONS(defn_language, natural_language)
MAKE_ANNOTATION_FUNCTIONS(embodying_heading, heading)
MAKE_ANNOTATION_FUNCTIONS(end_control_structure_used, control_structure_phrase)
MAKE_ANNOTATION_FUNCTIONS(evaluation, parse_node)
MAKE_ANNOTATION_FUNCTIONS(grammar_token_relation, binary_predicate)
MAKE_ANNOTATION_FUNCTIONS(grammar_value, parse_node)
MAKE_ANNOTATION_FUNCTIONS(implicit_in_creation_of, inference_subject)
MAKE_ANNOTATION_FUNCTIONS(interpretation_of_subject, inference_subject)
MAKE_ANNOTATION_FUNCTIONS(kind_of_new_variable, kind)
MAKE_ANNOTATION_FUNCTIONS(kind_of_value, kind)
MAKE_ANNOTATION_FUNCTIONS(kind_required_by_context, kind)
MAKE_ANNOTATION_FUNCTIONS(kind_resulting, kind)
MAKE_ANNOTATION_FUNCTIONS(kind_variable_declarations, kind_variable_declaration)
MAKE_ANNOTATION_FUNCTIONS(meaning, excerpt_meaning)
MAKE_ANNOTATION_FUNCTIONS(modal_verb, verb_conjugation)
MAKE_ANNOTATION_FUNCTIONS(new_relation_here, binary_predicate)
MAKE_ANNOTATION_FUNCTIONS(phrase_invoked, phrase)
MAKE_ANNOTATION_FUNCTIONS(phrase_options_invoked, invocation_options)
MAKE_ANNOTATION_FUNCTIONS(problem_falls_under, parse_node)
MAKE_ANNOTATION_FUNCTIONS(proposition, pcalc_prop)
MAKE_ANNOTATION_FUNCTIONS(pu, preposition_usage)
MAKE_ANNOTATION_FUNCTIONS(quant, quantifier)
MAKE_ANNOTATION_FUNCTIONS(relationship, binary_predicate)
MAKE_ANNOTATION_FUNCTIONS(say_adjective, adjectival_phrase)
MAKE_ANNOTATION_FUNCTIONS(say_verb, verb_conjugation)
MAKE_ANNOTATION_FUNCTIONS(subject_term, pcalc_term)
MAKE_ANNOTATION_FUNCTIONS(subject, inference_subject)
MAKE_ANNOTATION_FUNCTIONS(token_as_parsed, parse_node)
MAKE_ANNOTATION_FUNCTIONS(token_check_to_do, parse_node)
MAKE_ANNOTATION_FUNCTIONS(token_to_be_parsed_against, parse_node)
MAKE_ANNOTATION_FUNCTIONS(vu, verb_usage)
#line 935 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__copy(parse_node *to, parse_node *from) {
COPY(to, from, parse_node);
to->annotations = NULL;
parse_node_annotation *pna, *latest = NULL;
for (pna=from->annotations; pna; pna=pna->next_annotation) {
parse_node_annotation *pna_copy = CREATE(parse_node_annotation);
*pna_copy = *pna;
if (pna->kind_of_annotation == proposition_ANNOT)
pna_copy->annotation_pointer =
STORE_POINTER_pcalc_prop(
Calculus__Propositions__copy(
RETRIEVE_POINTER_pcalc_prop(
pna->annotation_pointer)));
pna_copy->next_annotation = NULL;
if (to->annotations == NULL) to->annotations = pna_copy;
else latest->next_annotation = pna_copy;
latest = pna_copy;
}
}
parse_node *ParseTree__duplicate(parse_node *p) {
parse_node *dup = ParseTree__new(INVALID_NT);
ParseTree__copy(dup, p);
return dup;
}
#line 964 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__copy_in_place(parse_node *to, parse_node *from) {
parse_node *next_link = to->next;
parse_node *alt_link = to->next_alternative;
parse_node *down_link = to->down;
ParseTree__copy(to, from);
to->next = next_link;
to->next_alternative = alt_link;
to->down = down_link;
}
#line 977 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__copy_subtree(parse_node *from, parse_node *to, int level) {
if ((from == NULL) || (to == NULL)) internal_error("Null deep copy");
ParseTree__copy(to, from);
if (from->down) {
to->down = ParseTree__new(PROPER_NOUN_NT);
ParseTree__copy_subtree(from->down, to->down, level+1);
}
if ((level>0) && (from->next)) {
to->next = ParseTree__new(PROPER_NOUN_NT);
ParseTree__copy_subtree(from->next, to->next, level);
}
if ((level>0) && (from->next_alternative)) {
to->next_alternative = ParseTree__new(PROPER_NOUN_NT);
ParseTree__copy_subtree(from->next_alternative, to->next_alternative, level);
}
}
#line 997 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__no_children(parse_node *pn) {
int c=0;
for (parse_node *p = (pn)?(pn->down):NULL; p; p = p->next) c++;
return c;
}
#line 1012 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__contains(parse_node *PN, parse_node *to_find) {
parse_node *to_try;
if (PN == to_find) return TRUE;
for (to_try = PN->down; to_try; to_try = to_try->next)
if (ParseTree__contains(to_try, to_find))
return TRUE;
return FALSE;
}
#line 1033 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__left_edge_of(parse_node *PN) {
parse_node *child;
int l = Wordings__first_wn(ParseTree__get_text(PN)), lc;
for (child = PN->down; child; child = child->next) {
lc = ParseTree__left_edge_of(child);
if ((lc >= 0) && ((l == -1) || (lc < l))) l = lc;
}
return l;
}
#line 1047 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__right_edge_of(parse_node *PN) {
parse_node *child;
int r = Wordings__last_wn(ParseTree__get_text(PN)), rc;
if (Wordings__first_wn(ParseTree__get_text(PN)) < 0) r = -1;
for (child = PN->down; child; child = child->next) {
rc = ParseTree__right_edge_of(child);
if ((rc >= 0) && ((r == -1) || (rc > r))) r = rc;
}
return r;
}
#line 1063 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__plant_parse_tree(void) {
tree_root = ParseTree__new(ROOT_NT);
ParseTree__push_attachment_point(tree_root);
}
#line 1080 "inform7/Chapter 13/Parse Tree.w"
parse_node *youngest_child_of_root = NULL; /* youngest child of tree root */
int allow_last_sentence_cacheing = FALSE;
void ParseTree__enable_last_sentence_cacheing(void) {
youngest_child_of_root = NULL; /* because this may have changed since last enabled */
allow_last_sentence_cacheing = TRUE;
}
void ParseTree__disable_last_sentence_cacheing(void) {
allow_last_sentence_cacheing = FALSE;
}
#line 1106 "inform7/Chapter 13/Parse Tree.w"
parse_node *ParseTree__graft(parse_node *newborn, parse_node *parent) {
parse_node *elder = NULL;
if (newborn == NULL) internal_error("newborn is null in tree ParseTree__graft");
if (parent == NULL) internal_error("parent is null in tree ParseTree__graft");
/* is the new node to be the only child of the old? */
if (parent->down == NULL) { parent->down = newborn; return NULL; }
/* can last sentence cacheing save us a long search through many children of root? */
if ((parent == tree_root) && (allow_last_sentence_cacheing)) {
if (youngest_child_of_root) {
elder = youngest_child_of_root;
elder->next = newborn;
youngest_child_of_root = newborn;
return elder;
}
/* we don't know who's the youngest child now, but we know who soon will be: */
youngest_child_of_root = newborn;
}
/* find youngest child of attach node... */
for (elder = parent->down; elder->next; elder = elder->next) ;
/* ...and make the new node its younger sibling */
elder->next = newborn; return elder;
}
#line 1132 "inform7/Chapter 13/Parse Tree.w"
parse_node *ParseTree__graft_alternative(parse_node *newborn, parse_node *parent) {
if (newborn == NULL) internal_error("newborn is null in tree ParseTree__graft_alternative");
if (parent == NULL) internal_error("parent is null in tree ParseTree__graft_alternative");
/* is the new node to be the only child of the old? */
if (parent->down == NULL) { parent->down = newborn; return NULL; }
/* find youngest child of attach node... */
parse_node *elder = NULL;
for (elder = parent->down; elder->next_alternative; elder = elder->next_alternative) ;
/* ...and make the new node its younger sibling */
elder->next_alternative = newborn; return elder;
}
#line 1159 "inform7/Chapter 13/Parse Tree.w"
int attachment_sp = 0;
parse_node *attachment_stack_parent[MAX_ATTACHMENT_STACK_SIZE];
int ParseTree__push_attachment_point(parse_node *to) {
int l = attachment_sp;
if (attachment_sp >= MAX_ATTACHMENT_STACK_SIZE) internal_error("attachment stack overflow");
attachment_stack_parent[attachment_sp++] = to;
return l;
}
void ParseTree__pop_attachment_point(int l) {
attachment_sp = l;
}
#line 1176 "inform7/Chapter 13/Parse Tree.w"
parse_node *one_off_attachment_point = NULL;
void ParseTree__set_attachment_point_one_off(parse_node *to) {
one_off_attachment_point = to;
}
#line 1185 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__insert_sentence(parse_node *new) {
if (one_off_attachment_point) {
parse_node *L = one_off_attachment_point->next;
one_off_attachment_point->next = new;
new->next = L;
one_off_attachment_point = new;
} else {
if (attachment_sp == 0) internal_error("no attachment point");
if (ParseTree__get_type(new) == HEADING_NT)
{
#line 1203 "inform7/Chapter 13/Parse Tree.w"
int heading_level = ParseTree__int_annotation(new, heading_level_ANNOT);
if (heading_level > 0)
for (int i = attachment_sp-1; i>=0; i--) {
parse_node *P = attachment_stack_parent[i];
if ((ParseTree__get_type(P) == HEADING_NT) &&
(ParseTree__int_annotation(P, heading_level_ANNOT) >= heading_level))
attachment_sp = i;
}
}
#line 1193 "inform7/Chapter 13/Parse Tree.w"
;
parse_node *sentence_attachment_point = attachment_stack_parent[attachment_sp-1];
ParseTree__graft(new, sentence_attachment_point);
if (ParseTree__get_type(new) == HEADING_NT) ParseTree__push_attachment_point(new);
}
}
#line 1224 "inform7/Chapter 13/Parse Tree.w"
int pn_log_token = 0;
void ParseTree__log_tree(parse_node *pn) {
if (pn == NULL) { LOG("<null-meaning-list>\n"); return; }
ParseTree__log_subtree_recursively(pn, 0, 0, 1, ++pn_log_token);
}
void ParseTree__log_subtree(parse_node *pn) {
if (pn == NULL) { LOG("<null-parse-node>"); return; }
LOG("$P\n", pn);
if (pn->down) {
LOG_INDENT;
ParseTree__log_subtree_recursively(pn->down, 0, 0, 1, ++pn_log_token);
LOG_OUTDENT;
}
}
#line 1246 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__log_subtree_recursively(parse_node *pn, int num, int of, int gen, int ltime) {
while (pn) {
if (pn->log_time == ltime) {
LOG("*** Not a tree: $w ***\n", ParseTree__get_text(pn)); return;
}
pn->log_time = ltime;
{
#line 1278 "inform7/Chapter 13/Parse Tree.w"
if (num == 0) {
parse_node *pn2;
for (pn2 = pn, of = 0; pn2; pn2 = pn2->next_alternative, of++) ;
num = 1;
}
}
#line 1252 "inform7/Chapter 13/Parse Tree.w"
;
if (pn == NULL) { LOG("<null-parse-node>\n"); return; }
if (of > 1) {
LOG("[%d/%d] ", num, of);
if (ParseTree__get_score(pn) != 0) LOG("(score %d) ", ParseTree__get_score(pn));
}
LOG("$P\n", pn);
if (pn->down) {
LOG_INDENT;
ParseTree__log_subtree_recursively(pn->down, 0, 0, gen+1, ltime);
LOG_OUTDENT;
}
if (pn->next_alternative) ParseTree__log_subtree_recursively(pn->next_alternative, num+1, of, gen+1, ltime);
pn = pn->next; num = 0; of = 0; gen++;
}
}
#line 1289 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__log_node(parse_node *pn) {
if (pn == NULL) { LOG("<null-parse-node>\n"); return; }
if (ParseTree__get_meaning(pn)) LOG("$M", ParseTree__get_meaning(pn));
else LOG("$N", pn->node_type);
if (Wordings__nonempty(ParseTree__get_text(pn))) LOG("'$w'", ParseTree__get_text(pn));
if ((pn->node_type >= UNKNOWN_VNT) && (pn->node_type <= TEST_VALUE_VNT))
{
#line 1307 "inform7/Chapter 13/Parse Tree.w"
if (ParseTree__get_kind_of_value(pn)) LOG("-$u", ParseTree__get_kind_of_value(pn));
if (ParseTree__is_lvalue(pn)) Lvalues__log(pn);
else if (ParseTree__is_rvalue(pn)) Rvalues__log(pn);
else if (ParseTree__is_condition(pn)) Conditions__log(pn);
if (ParseTree__get_vu(pn)) { LOG("-vu:"); Verbs__log(ParseTree__get_vu(pn)); }
if (ParseTree__get_pu(pn)) { LOG("-pu:"); Prepositions__log(ParseTree__get_pu(pn)); }
}
#line 1296 "inform7/Chapter 13/Parse Tree.w"
else
{
#line 1317 "inform7/Chapter 13/Parse Tree.w"
int show_eval = FALSE, show_refers = FALSE;
if (ParseTree__int_annotation(pn, creation_site_ANNOT))
LOG(" (created here)");
switch(pn->node_type) {
case ADJECTIVE_NT: show_eval = TRUE; break;
case HEADING_NT: LOG(" (level %d)", ParseTree__int_annotation(pn, heading_level_ANNOT)); break;
/* case INVOCATION_NT: LOG(" $e", pn); break; */
case COMMON_NOUN_NT: show_refers = TRUE; break;
case KIND_NT: show_refers = TRUE; break;
case RELATIONSHIP_NT: LOG(" (type:");
switch (ParseTree__int_annotation(pn, relationship_node_type_ANNOT)) {
case STANDARD_RELN: LOG("standard"); break;
case PARENTAGE_HERE_RELN: LOG("here"); break;
case DIRECTION_RELN: LOG("direction"); break;
}
LOG(")"); break;
case PROPER_NOUN_NT:
switch (ParseTree__int_annotation(pn, nounphrase_article_ANNOT)) {
case NO_ART: LOG(" (no article)"); break;
case IT_ART: LOG(" (pronoun)"); break;
case DEF_ART: LOG(" (definite)"); break;
case INDEF_ART: LOG(" (indefinite)"); break;
}
if (ParseTree__int_annotation(pn, plural_reference_ANNOT)) LOG(" (plural)");
if (ParseTree__int_annotation(pn, multiplicity_ANNOT))
LOG(" (x%d)", ParseTree__int_annotation(pn, multiplicity_ANNOT));
show_refers = TRUE;
break;
case AVERB_NT: LOG(" ($V)", ParseTree__int_annotation(pn, verb_id_ANNOT)); break;
case TOKEN_NT: LOG(" [%d/%d]", ParseTree__int_annotation(pn, slash_class_ANNOT),
ParseTree__int_annotation(pn, slash_dash_dash_ANNOT)); break;
case INVOCATION_LIST_NT:
case CODE_BLOCK_NT: {
control_structure_phrase *csp = ParseTree__get_control_structure_used(pn);
LOG(" "); Sentences__RuleSubtrees__log_control_structure(csp); LOG(" ");
if (pn->node_type == INVOCATION_LIST_NT)
LOG("%d", ParseTree__int_annotation(pn, indentation_level_ANNOT));
else LOG(" ");
LOG(" ");
break;
}
}
if (ParseTree__get_kind_required_by_context(pn))
LOG(" requires:$u", ParseTree__get_kind_required_by_context(pn));
if (show_refers) {
if (ParseTree__get_subject(pn)) { LOG(" refers:$j", ParseTree__get_subject(pn)); }
if (ParseTree__get_evaluation(pn)) { LOG(" eval:$P", ParseTree__get_evaluation(pn)); }
if (ParseTree__int_annotation(pn, implicitly_refers_to_ANNOT)) LOG(" (implicit)");
}
if ((show_eval) && (ParseTree__get_evaluation(pn))) {
LOG(" eval:$P", ParseTree__get_evaluation(pn));
}
if (ParseTree__get_defn_language(pn))
LOG(" language:$J", ParseTree__get_defn_language(pn));
if (ParseTree__get_creation_proposition(pn))
LOG(" (creation $D)", ParseTree__get_creation_proposition(pn));
}
#line 1298 "inform7/Chapter 13/Parse Tree.w"
;
int a = 0;
while ((pn->next_alternative) && (a<9)) a++, pn = pn->next_alternative;
if (a > 0) LOG("/%d", a);
}
#line 1378 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__log_with_annotations(parse_node *pn) {
LOG("Diagnosis $P", pn);
for (parse_node_annotation *pna = pn->annotations; pna; pna = pna->next_annotation)
LOG("-%d", pna->kind_of_annotation);
LOG("\n");
}
#line 1389 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__write_to_file(void) {
text_stream parse_tree_file;
if (STREAM_OPEN_TO_FILE(&parse_tree_file, filename_of_parse_tree, ISO_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open parse tree", filename_of_parse_tree);
text_stream *save_dl = dl;
dl = &parse_tree_file;
ParseTree__log_tree(tree_root);
dl = save_dl;
STREAM_CLOSE(&parse_tree_file);
}
#line 1407 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__write_main_source_to_log(void) {
LOG("Parse tree for the main source text only\n");
LOG("----------------------------------------\n");
ParseTree__log_tree(tree_root->down->next->next->down);
LOG("----------------------------------------\n");
}
#line 1420 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__traverse(void (*visitor)(parse_node *)) {
ParseTree__traverse_from(tree_root, visitor);
}
void ParseTree__traverse_from(parse_node *pn, void (*visitor)(parse_node *)) {
parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) {
if (ParseTree__top_level(pn->node_type)) ParseTree__traverse_from(pn->down, visitor);
if (ParseTree__visitable(pn->node_type)) {
if (ParseTree__second_level(pn->node_type)) current_sentence = pn;
(*visitor)(pn);
}
}
current_sentence = SCS;
}
void ParseTree__traverse_dfirst(void (*visitor)(parse_node *)) {
ParseTree__traverse_dfirst_from(tree_root, visitor);
}
void ParseTree__traverse_dfirst_from(parse_node *pn, void (*visitor)(parse_node *)) {
parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) {
ParseTree__traverse_dfirst_from(pn->down, visitor);
if (ParseTree__second_level(pn->node_type)) current_sentence = pn;
(*visitor)(pn);
}
current_sentence = SCS;
}
void ParseTree__traverse_wfirst(void (*visitor)(parse_node *)) {
ParseTree__traverse_wfirst_from(tree_root, visitor);
}
void ParseTree__traverse_wfirst_from(parse_node *pn, void (*visitor)(parse_node *)) {
parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) {
if (ParseTree__second_level(pn->node_type)) current_sentence = pn;
ParseTree__traverse_wfirst_from(pn->down, visitor);
(*visitor)(pn);
}
current_sentence = SCS;
}
void ParseTree__traverse_with_stream(text_stream *OUT, void (*visitor)(text_stream *, parse_node *)) {
ParseTree__traverse_from_with_stream(OUT, tree_root, visitor);
}
void ParseTree__traverse_from_with_stream(text_stream *OUT, parse_node *pn, void (*visitor)(text_stream *, parse_node *)) {
parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) {
if (ParseTree__top_level(pn->node_type))
ParseTree__traverse_from_with_stream(OUT, pn->down, visitor);
if (ParseTree__visitable(pn->node_type)) {
if (ParseTree__second_level(pn->node_type)) current_sentence = pn;
(*visitor)(OUT, pn);
}
}
current_sentence = SCS;
}
void ParseTree__traverse_int(void (*visitor)(parse_node *, int *), int *X) {
ParseTree__traverse_from_int(tree_root, visitor, X);
}
void ParseTree__traverse_from_int(parse_node *pn, void (*visitor)(parse_node *, int *), int *X) {
parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) {
if (ParseTree__top_level(pn->node_type)) ParseTree__traverse_from_int(pn->down, visitor, X);
if (ParseTree__visitable(pn->node_type)) {
if (ParseTree__second_level(pn->node_type)) current_sentence = pn;
(*visitor)(pn, X);
}
}
current_sentence = SCS;
}
void ParseTree__traverse_int_int(void (*visitor)(parse_node *, int *, int *), int *X, int *Y) {
ParseTree__traverse_from_int_int(tree_root, visitor, X, Y);
}
void ParseTree__traverse_from_int_int(parse_node *pn, void (*visitor)(parse_node *, int *, int *), int *X, int *Y) {
parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) {
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__second_level(pn->node_type)) current_sentence = pn;
(*visitor)(pn, X, Y);
}
}
current_sentence = SCS;
}
void ParseTree__traverse_ppn(void (*visitor)(parse_node *, parse_node **), parse_node **X) {
ParseTree__traverse_from_ppn(tree_root, visitor, X);
}
void ParseTree__traverse_from_ppn(parse_node *pn, void (*visitor)(parse_node *, parse_node **), parse_node **X) {
parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) {
if (ParseTree__top_level(pn->node_type)) ParseTree__traverse_from_ppn(pn->down, visitor, X);
if (ParseTree__visitable(pn->node_type)) {
if (ParseTree__second_level(pn->node_type)) current_sentence = pn;
(*visitor)(pn, X);
}
}
current_sentence = SCS;
}
void ParseTree__traverse_ppni(void (*visitor)(parse_node *, parse_node **, int *), parse_node **X, int *N) {
ParseTree__traverse_from_ppni(tree_root, visitor, X, N);
}
void ParseTree__traverse_from_ppni(parse_node *pn, void (*visitor)(parse_node *, parse_node **, int *), parse_node **X, int *N) {
parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) {
if (ParseTree__top_level(pn->node_type)) ParseTree__traverse_from_ppni(pn->down, visitor, X, N);
if (ParseTree__visitable(pn->node_type)) {
if (ParseTree__second_level(pn->node_type)) current_sentence = pn;
(*visitor)(pn, X, N);
}
}
current_sentence = SCS;
}
void ParseTree__traverse_up_to_ip(parse_node *end, void (*visitor)(parse_node *, instance **), instance **X) {
ParseTree__traverse_from_up_to_ip(end, tree_root, visitor, X);
}
int ParseTree__traverse_from_up_to_ip(parse_node *end, parse_node *pn, void (*visitor)(parse_node *, instance **), instance **X) {
parse_node *SCS = current_sentence;
for (; pn; pn = pn->next) {
if (pn == end) { current_sentence = SCS; return TRUE; }
if (ParseTree__top_level(pn->node_type)) {
if (ParseTree__traverse_from_up_to_ip(end, pn->down, visitor, X)) {
current_sentence = SCS; return TRUE;
}
}
if (ParseTree__visitable(pn->node_type)) {
if (ParseTree__second_level(pn->node_type)) current_sentence = pn;
(*visitor)(pn, X);
}
}
current_sentence = SCS;
return FALSE;
}
int ParseTree__traverse_ppn_nocs(int (*visitor)(parse_node *, parse_node *, parse_node **), parse_node **X) {
return ParseTree__traverse_from_ppn_nocs(tree_root, visitor, NULL, X);
}
int ParseTree__traverse_from_ppn_nocs(parse_node *pn, int (*visitor)(parse_node *, parse_node *, parse_node **), parse_node *from, parse_node **X) {
for (; pn; pn = pn->next) {
if (ParseTree__visitable(pn->node_type)) {
if ((*visitor)(pn, from, X)) { return TRUE; }
}
if (ParseTree__top_level(pn->node_type)) {
int res = ParseTree__traverse_from_ppn_nocs(pn->down, visitor, pn, X);
if (res) {
return TRUE;
}
}
}
return FALSE;
}
#line 1574 "inform7/Chapter 13/Parse Tree.w"
int tree_stats_size = 0, tree_stats_depth = 0, tree_stats_width = 0;
void ParseTree__verify_integrity(parse_node *p, int worth_logging) {
tree_stats_size = 0; tree_stats_depth = 0; tree_stats_width = 1;
ParseTree__verify_tree_integrity_recursively(p->down, p, "down", 0, ++pn_log_token);
if (worth_logging)
LOGIF(VERIFICATIONS, "[Initial parse tree has %d nodes, width %d and depth %d.]\n",
tree_stats_size, tree_stats_width, tree_stats_depth);
}
#line 1589 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__verify_tree_integrity_recursively(parse_node *p,
parse_node *from, char *way, int depth, int ltime) {
int width;
pointer_sized_int probably_an_address = (pointer_sized_int) p;
depth++; if (depth > tree_stats_depth) tree_stats_depth = depth;
for (width = 0; p; p = p->next, width++) {
if ((probably_an_address == 0) || (probably_an_address == -1)) {
LOG("Link %s broken from:\n$P", way, from);
internal_error_tree_unsafe("Link broken in parse tree");
}
if (p->log_time == ltime) {
LOG("Cycle found in parse tree, found %s from:\n$P", way, from);
internal_error_tree_unsafe("Cycle found in parse tree");
}
p->log_time = ltime;
node_type_t t = ParseTree__get_type(p);
if (ParseTree__valid_type(t)) tree_stats_size++;
else {
LOG("Invalid node type (%08x) found %s from:\n$P", (int) t, from);
internal_error_tree_unsafe("Link broken in parse tree");
}
if (p->next_alternative)
ParseTree__verify_tree_integrity_recursively(p->next_alternative, p, "alt", depth, ltime);
if (p->down)
ParseTree__verify_tree_integrity_recursively(p->down, p, "down", depth, ltime);
}
if (width > tree_stats_width) tree_stats_width = width;
}
#line 1640 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__verify(void) {
LOGIF(VERIFICATIONS, "[Verifying initial parse tree]\n");
if (tree_root == NULL) internal_error_tree_unsafe("Root of parse tree NULL");
ParseTree__verify_structure(tree_root);
LOGIF(VERIFICATIONS, "[Initial parse tree correct.]\n");
}
int node_errors = 0;
void ParseTree__verify_structure(parse_node *p) {
ParseTree__verify_integrity(p, FALSE);
ParseTree__make_parentage_allowed_table();
ParseTree__make_annotation_allowed_table();
node_errors = 0;
ParseTree__verify_structure_recursively(p, NULL, NULL);
if (node_errors > 0) {
LOG("[Verification failed: %d node errors]\n", node_errors);
internal_error_tree_unsafe("Parse tree broken");
}
}
#line 1666 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__verify_structure_recursively(parse_node *p,
parse_node *parent, parse_node *latest_routine) {
node_type_t t = ParseTree__get_type(p);
if (t == ROUTINE_NT) latest_routine = p;
parse_tree_node_type *metadata = ParseTree__node_metadata(t);
if (metadata == NULL) internal_error("broken tree should have been reported");
{
#line 1690 "inform7/Chapter 13/Parse Tree.w"
if (t == INVALID_NT) {
LOG("N%d is $N, which is not allowed except temporarily\n", p->allocation_id, t);
{
#line 1738 "inform7/Chapter 13/Parse Tree.w"
if (parent == tree_root) LOG("Failing subtree:\n$T", p);
else LOG("Failing subtree:\n$T", parent);
if (latest_routine) LOG("Current routine:\n$T", latest_routine);
node_errors++;
}
#line 1692 "inform7/Chapter 13/Parse Tree.w"
}
}
#line 1673 "inform7/Chapter 13/Parse Tree.w"
;
{
#line 1698 "inform7/Chapter 13/Parse Tree.w"
for (parse_node_annotation *pna=p->annotations; pna; pna=pna->next_annotation)
if (!(ParseTree__annotation_allowed(t, pna->kind_of_annotation))) {
LOG("N%d is $N, which is not allowed to have annotation %d\n",
p->allocation_id, t, pna->kind_of_annotation, p);
printf("Node %08x, ann %d\n", t, pna->kind_of_annotation);
{
#line 1738 "inform7/Chapter 13/Parse Tree.w"
if (parent == tree_root) LOG("Failing subtree:\n$T", p);
else LOG("Failing subtree:\n$T", parent);
if (latest_routine) LOG("Current routine:\n$T", latest_routine);
node_errors++;
}
#line 1703 "inform7/Chapter 13/Parse Tree.w"
}
}
#line 1674 "inform7/Chapter 13/Parse Tree.w"
;
if (parent)
{
#line 1709 "inform7/Chapter 13/Parse Tree.w"
node_type_t t_parent = ParseTree__get_type(parent);
int child_category = metadata->category;
parse_tree_node_type *metadata_parent = ParseTree__node_metadata(t_parent);
if (metadata_parent == NULL) internal_error("broken tree should have been reported");
int parent_category = metadata_parent->category;
if (!(ParseTree__parentage_allowed(t_parent, parent_category, t, child_category))) {
LOG("N%d is $N (category %d): should not be a child of $N (category %d)\n",
p->allocation_id, t, child_category, t_parent, parent_category);
{
#line 1738 "inform7/Chapter 13/Parse Tree.w"
if (parent == tree_root) LOG("Failing subtree:\n$T", p);
else LOG("Failing subtree:\n$T", parent);
if (latest_routine) LOG("Current routine:\n$T", latest_routine);
node_errors++;
}
#line 1718 "inform7/Chapter 13/Parse Tree.w"
}
}
#line 1675 "inform7/Chapter 13/Parse Tree.w"
;
int children_count = 0;
for (parse_node *q=p->down; q; q=q->next, children_count++)
ParseTree__verify_structure_recursively(q, p, latest_routine);
{
#line 1724 "inform7/Chapter 13/Parse Tree.w"
if (children_count < metadata->min_children) {
LOG("N%d has %d children, but min for $N is %d:\n",
p->allocation_id, children_count, t, metadata->min_children);
{
#line 1738 "inform7/Chapter 13/Parse Tree.w"
if (parent == tree_root) LOG("Failing subtree:\n$T", p);
else LOG("Failing subtree:\n$T", parent);
if (latest_routine) LOG("Current routine:\n$T", latest_routine);
node_errors++;
}
#line 1727 "inform7/Chapter 13/Parse Tree.w"
}
if (children_count > metadata->max_children) {
LOG("N%d has %d children, but max for $N is %d:\n",
p->allocation_id, children_count, t, metadata->max_children);
{
#line 1738 "inform7/Chapter 13/Parse Tree.w"
if (parent == tree_root) LOG("Failing subtree:\n$T", p);
else LOG("Failing subtree:\n$T", parent);
if (latest_routine) LOG("Current routine:\n$T", latest_routine);
node_errors++;
}
#line 1732 "inform7/Chapter 13/Parse Tree.w"
}
}
#line 1681 "inform7/Chapter 13/Parse Tree.w"
;
if (p->next_alternative)
ParseTree__verify_structure_recursively(p->next_alternative, parent, latest_routine);
}
#line 1748 "inform7/Chapter 13/Parse Tree.w"
int parentage_allowed_set_up = FALSE;
int parentage_allowed[NO_NODE_CATEGORIES][NO_NODE_CATEGORIES];
void ParseTree__make_parentage_allowed_table(void) {
if (parentage_allowed_set_up == FALSE) {
parentage_allowed_set_up = TRUE;
for (int i = 0; i < NO_NODE_CATEGORIES; i++)
for (int j = 0; j < NO_NODE_CATEGORIES; j++)
parentage_allowed[i][j] = FALSE;
parentage_allowed[L1_NCAT][L1_NCAT] = TRUE;
parentage_allowed[L2_NCAT][L3_NCAT] = TRUE;
parentage_allowed[L3_NCAT][L3_NCAT] = TRUE;
parentage_allowed[L2_NCAT][L4_NCAT] = TRUE;
parentage_allowed[L4_NCAT][L4_NCAT] = TRUE;
parentage_allowed[L4_NCAT][UNKNOWN_NCAT] = TRUE;
parentage_allowed[L4_NCAT][LVALUE_NCAT] = TRUE;
parentage_allowed[L4_NCAT][RVALUE_NCAT] = TRUE;
parentage_allowed[L4_NCAT][COND_NCAT] = TRUE;
parentage_allowed[LVALUE_NCAT][UNKNOWN_NCAT] = TRUE;
parentage_allowed[RVALUE_NCAT][UNKNOWN_NCAT] = TRUE;
parentage_allowed[COND_NCAT][UNKNOWN_NCAT] = TRUE;
parentage_allowed[LVALUE_NCAT][LVALUE_NCAT] = TRUE;
parentage_allowed[RVALUE_NCAT][LVALUE_NCAT] = TRUE;
parentage_allowed[COND_NCAT][LVALUE_NCAT] = TRUE;
parentage_allowed[LVALUE_NCAT][RVALUE_NCAT] = TRUE;
parentage_allowed[RVALUE_NCAT][RVALUE_NCAT] = TRUE;
parentage_allowed[COND_NCAT][RVALUE_NCAT] = TRUE;
parentage_allowed[LVALUE_NCAT][COND_NCAT] = TRUE;
parentage_allowed[RVALUE_NCAT][COND_NCAT] = TRUE;
parentage_allowed[COND_NCAT][COND_NCAT] = TRUE;
}
}
#line 1789 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__parentage_allowed(node_type_t t_parent, int cat_parent,
node_type_t t_child, int cat_child) {
if (parentage_allowed[cat_parent][cat_child]) return TRUE;
if ((t_parent == HEADING_NT) && (cat_child == L2_NCAT)) return TRUE;
if ((t_parent == PHRASE_TO_DECIDE_VALUE_VNT) && (t_child == INVOCATION_LIST_NT)) return TRUE;
if ((t_parent == AMBIGUITY_NT) || (t_child == AMBIGUITY_NT)) return TRUE;
return FALSE;
}
#line 1810 "inform7/Chapter 13/Parse Tree.w"
int annotation_allowed_set_up = FALSE;
int annotation_allowed[NO_ENUMERATED_NTS][MAX_ANNOT_NUMBER+1];
void ParseTree__allow_annotation(node_type_t t, int annot) {
annotation_allowed[t - BASE_OF_ENUMERATED_NTS][annot] = TRUE;
}
void ParseTree__allow_annotation_to_category(int cat, int annot) {
LOOP_OVER_NODE_TYPES(t)
if (ParseTree__cat(t) == cat)
ParseTree__allow_annotation(t, annot);
}
void ParseTree__allow_annotation_to_specification(int annot) {
ParseTree__allow_annotation(UNKNOWN_VNT, annot);
ParseTree__allow_annotation_to_category(LVALUE_NCAT, annot);
ParseTree__allow_annotation_to_category(RVALUE_NCAT, annot);
ParseTree__allow_annotation_to_category(COND_NCAT, annot);
}
#line 1834 "inform7/Chapter 13/Parse Tree.w"
void ParseTree__make_annotation_allowed_table(void) {
if (annotation_allowed_set_up == FALSE) {
annotation_allowed_set_up = TRUE;
ParseTree__allow_annotation_to_category(L1_NCAT, clears_pronouns_ANNOT);
ParseTree__allow_annotation_to_category(L1_NCAT, sentence_is_existential_ANNOT);
ParseTree__allow_annotation_to_category(L1_NCAT, sentence_unparsed_ANNOT);
ParseTree__allow_annotation(HEADING_NT, embodying_heading_ANNOT);
ParseTree__allow_annotation(HEADING_NT, heading_level_ANNOT);
ParseTree__allow_annotation(HEADING_NT, interpretation_of_subject_ANNOT);
ParseTree__allow_annotation(HEADING_NT, suppress_heading_dependencies_ANNOT);
ParseTree__allow_annotation_to_category(L2_NCAT, clears_pronouns_ANNOT);
ParseTree__allow_annotation_to_category(L2_NCAT, interpretation_of_subject_ANNOT);
ParseTree__allow_annotation_to_category(L2_NCAT, problem_falls_under_ANNOT);
ParseTree__allow_annotation_to_category(L2_NCAT, sentence_is_existential_ANNOT);
ParseTree__allow_annotation_to_category(L2_NCAT, sentence_unparsed_ANNOT);
ParseTree__allow_annotation_to_category(L2_NCAT, verb_problem_issued_ANNOT);
ParseTree__allow_annotation(ROUTINE_NT, indentation_level_ANNOT);
ParseTree__allow_annotation(SENTENCE_NT, implicit_in_creation_of_ANNOT);
ParseTree__allow_annotation(SENTENCE_NT, implicitness_count_ANNOT);
ParseTree__allow_annotation(SENTENCE_NT, language_element_ANNOT);
ParseTree__allow_annotation(SENTENCE_NT, you_can_ignore_ANNOT);
LOOP_OVER_NODE_TYPES(t)
if (ParseTree__test_flag(t, ASSERT_NFLAG))
ParseTree__allow_annotation(t, resolved_ANNOT);
ParseTree__allow_annotation_to_category(L3_NCAT, creation_proposition_ANNOT);
ParseTree__allow_annotation_to_category(L3_NCAT, evaluation_ANNOT);
ParseTree__allow_annotation_to_category(L3_NCAT, gender_reference_ANNOT);
ParseTree__allow_annotation_to_category(L3_NCAT, nounphrase_article_ANNOT);
ParseTree__allow_annotation_to_category(L3_NCAT, plural_reference_ANNOT);
ParseTree__allow_annotation_to_category(L3_NCAT, subject_ANNOT);
ParseTree__allow_annotation(ACTION_NT, action_meaning_ANNOT);
ParseTree__allow_annotation(ADJECTIVE_NT, aph_ANNOT);
ParseTree__allow_annotation(ADJECTIVE_NT, negated_boolean_ANNOT);
ParseTree__allow_annotation(ADJECTIVE_NT, nounphrase_article_ANNOT);
ParseTree__allow_annotation(AVERB_NT, log_inclusion_sense_ANNOT);
ParseTree__allow_annotation(AVERB_NT, verb_id_ANNOT);
ParseTree__allow_annotation(AVERB_NT, verbal_certainty_ANNOT);
ParseTree__allow_annotation(COMMON_NOUN_NT, action_meaning_ANNOT);
ParseTree__allow_annotation(COMMON_NOUN_NT, creation_site_ANNOT);
ParseTree__allow_annotation(COMMON_NOUN_NT, implicitly_refers_to_ANNOT);
ParseTree__allow_annotation(COMMON_NOUN_NT, multiplicity_ANNOT);
ParseTree__allow_annotation(COMMON_NOUN_NT, quant_ANNOT);
ParseTree__allow_annotation(COMMON_NOUN_NT, quantification_parameter_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, aph_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, category_of_I6_translation_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, creation_site_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, defn_language_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, implicitly_refers_to_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, log_inclusion_sense_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, lpe_options_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, multiplicity_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, negated_boolean_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, new_relation_here_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, nowhere_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, quant_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, quantification_parameter_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, row_amendable_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, slash_dash_dash_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, table_cell_unspecified_ANNOT);
ParseTree__allow_annotation(PROPER_NOUN_NT, turned_already_ANNOT);
ParseTree__allow_annotation(PROPERTY_LIST_NT, nounphrase_article_ANNOT);
ParseTree__allow_annotation(RELATIONSHIP_NT, relationship_ANNOT);
ParseTree__allow_annotation(RELATIONSHIP_NT, relationship_node_type_ANNOT);
ParseTree__allow_annotation(TOKEN_NT, grammar_token_literal_ANNOT);
ParseTree__allow_annotation(TOKEN_NT, grammar_token_relation_ANNOT);
ParseTree__allow_annotation(TOKEN_NT, grammar_value_ANNOT);
ParseTree__allow_annotation(TOKEN_NT, slash_class_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, colon_block_command_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, control_structure_used_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, end_control_structure_used_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, evaluation_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, indentation_level_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, kind_of_new_variable_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, kind_required_by_context_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, problem_falls_under_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, results_from_splitting_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, token_as_parsed_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, token_check_to_do_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, token_to_be_parsed_against_ANNOT);
ParseTree__allow_annotation_to_category(L4_NCAT, verb_problem_issued_ANNOT);
ParseTree__allow_annotation(CODE_BLOCK_NT, sentence_unparsed_ANNOT);
ParseTree__allow_annotation(INVOCATION_LIST_NT, from_text_substitution_ANNOT);
ParseTree__allow_annotation(INVOCATION_LIST_NT, sentence_unparsed_ANNOT);
ParseTree__allow_annotation(INVOCATION_LIST_SAY_NT, sentence_unparsed_ANNOT);
ParseTree__allow_annotation(INVOCATION_LIST_SAY_NT, suppress_newlines_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, epistemological_status_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, kind_resulting_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, kind_variable_declarations_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, modal_verb_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, phrase_invoked_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, phrase_options_invoked_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, say_adjective_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, say_verb_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, say_verb_negated_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, ssp_closing_segment_wn_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, ssp_segment_count_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, suppress_newlines_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, save_self_ANNOT);
ParseTree__allow_annotation(INVOCATION_NT, unproven_ANNOT);
ParseTree__allow_annotation_to_specification(converted_SN_ANNOT);
ParseTree__allow_annotation_to_specification(subject_term_ANNOT);
ParseTree__allow_annotation_to_specification(epistemological_status_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_action_name_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_action_pattern_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_activity_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_binary_predicate_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_constant_phrase_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_enumeration_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_equation_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_grammar_verb_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_instance_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_named_rulebook_outcome_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_number_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_property_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_rule_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_rulebook_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_scene_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_table_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_table_column_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_text_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_use_option_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, constant_verb_conjugation_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, explicit_literal_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, grammar_token_code_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, kind_of_value_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, nothing_object_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, property_name_used_as_noun_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, proposition_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, response_code_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, self_object_ANNOT);
ParseTree__allow_annotation(CONSTANT_VNT, text_unescaped_ANNOT);
ParseTree__allow_annotation(LOCAL_VARIABLE_VNT, constant_local_variable_ANNOT);
ParseTree__allow_annotation(LOCAL_VARIABLE_VNT, kind_of_value_ANNOT);
ParseTree__allow_annotation(LOGICAL_TENSE_VNT, condition_tense_ANNOT);
ParseTree__allow_annotation(NONLOCAL_VARIABLE_VNT, constant_nonlocal_variable_ANNOT);
ParseTree__allow_annotation(NONLOCAL_VARIABLE_VNT, kind_of_value_ANNOT);
ParseTree__allow_annotation(PROPERTY_VALUE_VNT, record_as_self_ANNOT);
ParseTree__allow_annotation(TEST_PHRASE_OPTION_VNT, phrase_option_ANNOT);
ParseTree__allow_annotation(TEST_PROPOSITION_VNT, proposition_ANNOT);
ParseTree__allow_annotation(UNKNOWN_VNT, pu_ANNOT);
ParseTree__allow_annotation(UNKNOWN_VNT, vu_ANNOT);
}
}
int ParseTree__annotation_allowed(node_type_t t, int annot) {
if ((annot <= 0) || (annot > MAX_ANNOT_NUMBER))
internal_error("annotation number out of range");
if ((t >= BASE_OF_ENUMERATED_NTS) && (t < BASE_OF_ENUMERATED_NTS+NO_ENUMERATED_NTS))
return annotation_allowed[t - BASE_OF_ENUMERATED_NTS][annot];
return FALSE;
}
#line 1999 "inform7/Chapter 13/Parse Tree.w"
int ParseTree__allow_in_assertions(parse_node *p) {
ParseTree__verify_structure(p);
if (ParseTree__test_flag(ParseTree__get_type(p), ASSERT_NFLAG)) return TRUE;
return FALSE;
}
#line 2008 "inform7/Chapter 13/Parse Tree.w"
parse_node *ParseTree__add_possible_reading(parse_node *existing, parse_node *reading, wording W) {
if (existing == NULL) return reading;
if (ParseTree__is(reading, UNKNOWN_VNT)) return existing;
if (ParseTree__is(reading, AMBIGUITY_NT)) reading = reading->down;
if (ParseTree__is(existing, AMBIGUITY_NT)) {
if (ParseTree__is_phrasal(reading))
for (parse_node *E = existing->down; E; E = E->next_alternative)
if (ParseTree__get_type(reading) == ParseTree__get_type(E)) {
ParseTree__add_pr_inv(E, reading);
return existing;
}
parse_node *L = existing->down;
while ((L) && (L->next_alternative)) L = L->next_alternative;
L->next_alternative = reading;
return existing;
}
if ((ParseTree__is_phrasal(reading)) &&
(ParseTree__get_type(reading) == ParseTree__get_type(existing))) {
ParseTree__add_pr_inv(existing, reading);
return existing;
}
parse_node *A = ParseTree__new_with_words(AMBIGUITY_NT, W);
A->down = existing;
A->down->next_alternative = reading;
return A;
}
void ParseTree__add_pr_inv(parse_node *E, parse_node *reading) {
for (parse_node *N = reading->down->down, *next_N = (N)?(N->next_alternative):NULL; N;
N = next_N, next_N = (N)?(N->next_alternative):NULL)
ParseTree__add_single_pr_inv(E, N);
}
void ParseTree__add_single_pr_inv(parse_node *E, parse_node *N) {
E = E->down->down;
if (Invocations__eq(E, N)) return;
while ((E) && (E->next_alternative)) {
E = E->next_alternative;
if (Invocations__eq(E, N)) return;
}
E->next_alternative = N; N->next_alternative = NULL;
}
#line 34 "inform7/Chapter 13/Sentences.w"
void Sentences__declare_source_loaded(void) {
text_loaded_from_source = TRUE;
}
#line 46 "inform7/Chapter 13/Sentences.w"
void Sentences__break_source(void) {
int l = ParseTree__push_attachment_point(tree_root);
Sentences__break(Wordings__new(language_definition_top+1, lexer_wordcount-1), NULL);
ParseTree__pop_attachment_point(l);
NaturalLanguages__include_required();
parse_node *implicit_heading = ParseTree__new(HEADING_NT);
ParseTree__set_text(implicit_heading, Feeds__feed_text_expanding_strings("Invented sentences"));
ParseTree__annotate_int(implicit_heading, sentence_unparsed_ANNOT, FALSE);
ParseTree__annotate_int(implicit_heading, heading_level_ANNOT, 0);
ParseTree__insert_sentence(implicit_heading);
Sentences__Headings__declare(implicit_heading);
}
#line 81 "inform7/Chapter 13/Sentences.w"
source_file *sfsm_source_file = NULL;
int sfsm_inside_rule_mode = FALSE;
int sfsm_skipping_material_at_level = -1;
int sfsm_in_table_mode = FALSE;
extension_file *sfsm_extension = NULL;
#line 93 "inform7/Chapter 13/Sentences.w"
void Sentences__break(wording W, extension_file *from_extension) {
int sentence_start = Wordings__first_wn(W);
ParseTree__enable_last_sentence_cacheing();
{
#line 134 "inform7/Chapter 13/Sentences.w"
sfsm_source_file = NULL;
sfsm_inside_rule_mode = FALSE;
sfsm_skipping_material_at_level = -1;
sfsm_extension = from_extension;
if (from_extension) sfsm_extension_position = 1;
else sfsm_extension_position = 0;
}
#line 97 "inform7/Chapter 13/Sentences.w"
;
{
#line 148 "inform7/Chapter 13/Sentences.w"
if ((Preform__parse_nt_against_word_range(structural_sentence_NTM, Wordings__from(W, sentence_start), NULL, NULL)) && (ssnt == TABLE_NT))
sfsm_in_table_mode = TRUE;
else
sfsm_in_table_mode = FALSE;
}
#line 98 "inform7/Chapter 13/Sentences.w"
;
LOOP_THROUGH_WORDING(position, W)
if (sentence_start < position) {
int no_stop_words, back_up_one_word;
char stop_character;
{
#line 193 "inform7/Chapter 13/Sentences.w"
int at = position;
no_stop_words = 0; stop_character = '?'; back_up_one_word = FALSE;
while (at < Wordings__last_wn(W)) {
int stopped = FALSE;
if (Lexer__word(at) == PARBREAK_V) {
if (stop_character == ':')
{
#line 229 "inform7/Chapter 13/Sentences.w"
wording W = Wordings__new(sentence_start, at-1);
Problems__quote_source(1, Sentences__NPs__new_raw(W));
Problems__Issue__handmade_problem(_p_(PM_ParaEndsInColon));
Problems__issue_problem_segment(
"The text %1 seems to end a paragraph with a colon. (Rule declarations "
"can end a sentence with a colon, so maybe there's accidentally a "
"skipped line here?)");
Problems__issue_problem_end();
}
#line 199 "inform7/Chapter 13/Sentences.w"
;
stop_character = '|'; stopped = TRUE;
}
if (Lexer__word(at) == FULLSTOP_V) {
if (stop_character == ':')
{
#line 241 "inform7/Chapter 13/Sentences.w"
wording W = Wordings__new(sentence_start, at);
Problems__quote_source(1, Sentences__NPs__new_raw(W));
Problems__Issue__handmade_problem(_p_(PM_SentenceEndsInColon));
Problems__issue_problem_segment(
"The text %1 seems to have a colon followed by a full stop, which is "
"punctuation I don't understand.");
Problems__issue_problem_end();
}
#line 203 "inform7/Chapter 13/Sentences.w"
;
if (stop_character == ';')
{
#line 252 "inform7/Chapter 13/Sentences.w"
wording W = Wordings__new(sentence_start, at);
Problems__quote_source(1, Sentences__NPs__new_raw(W));
Problems__Issue__handmade_problem(_p_(PM_SentenceEndsInSemicolon));
Problems__issue_problem_segment(
"The text %1 seems to have a semicolon followed by a full stop, which is "
"punctuation I don't understand.");
Problems__issue_problem_end();
}
#line 204 "inform7/Chapter 13/Sentences.w"
;
stop_character = '.'; stopped = TRUE;
}
if (Lexer__word(at) == SEMICOLON_V) {
if (stop_character == ':')
{
#line 263 "inform7/Chapter 13/Sentences.w"
wording W = Wordings__new(sentence_start, at);
Problems__quote_source(1, Sentences__NPs__new_raw(W));
Problems__Issue__handmade_problem(_p_(PM_SemicolonAfterColon));
Problems__issue_problem_segment(
"The text %1 seems to have a semicolon following a colon, which is "
"punctuation I don't understand.");
Problems__issue_problem_end();
}
#line 208 "inform7/Chapter 13/Sentences.w"
;
if (stop_character == '.')
{
#line 274 "inform7/Chapter 13/Sentences.w"
wording W = Wordings__new(sentence_start, at);
Problems__quote_source(1, Sentences__NPs__new_raw(W));
Problems__Issue__handmade_problem(_p_(PM_SemicolonAfterStop));
Problems__issue_problem_segment(
"The text %1 seems to have a semicolon following a full stop, which is "
"punctuation I don't understand.");
Problems__issue_problem_end();
}
#line 209 "inform7/Chapter 13/Sentences.w"
;
stop_character = ';'; stopped = TRUE;
}
{
#line 299 "inform7/Chapter 13/Sentences.w"
if ((Lexer__word(at) == COLON_V) &&
(Lexer__file_of_origin(at-1) == Lexer__file_of_origin(at)) &&
(no_stop_words == 0) &&
((isdigit(*(Lexer__word_raw_text(at-1))) == FALSE) ||
(isdigit(*(Lexer__word_raw_text(at+1))) == FALSE) ||
(Lexer__indentation_level(at+1) > 0))) {
stop_character = ':'; stopped = TRUE;
}
}
#line 213 "inform7/Chapter 13/Sentences.w"
;
{
#line 325 "inform7/Chapter 13/Sentences.w"
if ((stopped == FALSE) && /* only look if we are not already at a division */
(no_stop_words == 0) && /* be sure not to elide two such texts in a row */
(sfsm_in_table_mode == FALSE) && /* check that we are not scanning the body of a table */
(isupper(*(Lexer__word_raw_text(at)))) && /* and the current word begins with a capital letter */
(Text__text_ending_sentence(at-1))) { /* and the preceding one was quoted text ending in punctuation */
stop_character = 'X'; stopped = TRUE;
}
}
#line 214 "inform7/Chapter 13/Sentences.w"
;
if (stopped == FALSE) break;
no_stop_words++; at++;
}
if (stop_character == 'X') { /* X breaks are like full stops, but there is no stop word to skip over */
stop_character = '.'; back_up_one_word = TRUE;
}
if (no_stop_words > 0)
LOGIF(LEXICAL_OUTPUT, "Stop character '%c', no_stop_words %d, sentence_break %d, position %d\n",
stop_character, no_stop_words, sentence_start, position);
}
#line 105 "inform7/Chapter 13/Sentences.w"
;
if (no_stop_words > 0) {
Sentences__make_node(Wordings__new(sentence_start, position-1), stop_character);
position = position + no_stop_words - 1;
if (back_up_one_word) sentence_start = position;
else sentence_start = position + 1;
{
#line 148 "inform7/Chapter 13/Sentences.w"
if ((Preform__parse_nt_against_word_range(structural_sentence_NTM, Wordings__from(W, sentence_start), NULL, NULL)) && (ssnt == TABLE_NT))
sfsm_in_table_mode = TRUE;
else
sfsm_in_table_mode = FALSE;
}
#line 112 "inform7/Chapter 13/Sentences.w"
;
}
}
if ((sentence_start < Wordings__last_wn(W)) ||
((sentence_start == Wordings__last_wn(W)) && (!(Lexer__word(Wordings__last_wn(W)) == PARBREAK_V)))) {
Sentences__make_node(Wordings__from(W, sentence_start), '.');
}
ParseTree__disable_last_sentence_cacheing();
if (from_extension)
{
#line 554 "inform7/Chapter 13/Sentences.w"
switch (sfsm_extension_position) {
case 1: Problems__Issue__extension_problem(_p_(PM_ExtNoBeginsHere),
sfsm_extension, "has no 'begins here' sentence"); break;
case 2: Problems__Issue__extension_problem(_p_(PM_ExtNoEndsHere),
sfsm_extension, "has no 'ends here' sentence"); break;
case 3: break;
}
}
#line 124 "inform7/Chapter 13/Sentences.w"
;
{
#line 134 "inform7/Chapter 13/Sentences.w"
sfsm_source_file = NULL;
sfsm_inside_rule_mode = FALSE;
sfsm_skipping_material_at_level = -1;
sfsm_extension = from_extension;
if (from_extension) sfsm_extension_position = 1;
else sfsm_extension_position = 0;
}
#line 125 "inform7/Chapter 13/Sentences.w"
;
}
#line 352 "inform7/Chapter 13/Sentences.w"
void Sentences__make_node(wording W, char stop_character) {
int heading_level = 0, begins_or_ends = 0;
parse_node *new;
if (Wordings__empty(W)) internal_error("empty sentence generated");
if (Wordings__within(W, options_file_wording) == FALSE) no_sentences_read++;
Vocabulary__identify_word_range(W); /* a precaution to catch any late unidentified text */
{
#line 388 "inform7/Chapter 13/Sentences.w"
if (Lexer__file_of_origin(Wordings__first_wn(W)) != sfsm_source_file) {
parse_node *implicit_heading = ParseTree__new(HEADING_NT);
ParseTree__set_text(implicit_heading, W);
ParseTree__annotate_int(implicit_heading, sentence_unparsed_ANNOT, FALSE);
ParseTree__annotate_int(implicit_heading, heading_level_ANNOT, 0);
ParseTree__insert_sentence(implicit_heading);
Sentences__Headings__declare(implicit_heading);
sfsm_skipping_material_at_level = -1;
}
sfsm_source_file = Lexer__file_of_origin(Wordings__first_wn(W));
}
#line 363 "inform7/Chapter 13/Sentences.w"
;
{
#line 447 "inform7/Chapter 13/Sentences.w"
if (Preform__parse_nt_against_word_range(dividing_sentence_NTM, W, NULL, NULL)) {
switch (most_recent_result) {
case -1:
if (sfsm_extension_position > 0) {
switch (sfsm_extension_position) {
case 1: sfsm_extension_position++; break;
case 2: Problems__Issue__extension_problem(_p_(PM_ExtMultipleBeginsHere),
sfsm_extension, "has more than one 'begins here' sentence"); break;
case 3: Problems__Issue__extension_problem(_p_(PM_ExtBeginsAfterEndsHere),
sfsm_extension, "has a further 'begins here' after an 'ends here'"); break;
}
begins_or_ends = 1;
}
break;
case -2:
if (sfsm_extension_position > 0) {
switch (sfsm_extension_position) {
case 1: Problems__Issue__extension_problem(_p_(PM_ExtEndsWithoutBegins),
sfsm_extension, "has an 'ends here' with nothing having begun"); break;
case 2: sfsm_extension_position++; break;
case 3: Problems__Issue__extension_problem(_p_(PM_ExtMultipleEndsHere),
sfsm_extension, "has more than one 'ends here' sentence"); break;
}
begins_or_ends = -1;
}
break;
default:
heading_level = most_recent_result;
break;
}
}
}
#line 364 "inform7/Chapter 13/Sentences.w"
;
if ((begins_or_ends == -1) ||
((heading_level > 0) && (heading_level <= sfsm_skipping_material_at_level)))
sfsm_skipping_material_at_level = -1;
if (sfsm_skipping_material_at_level >= 0) return;
if (heading_level > 0) {
{
#line 488 "inform7/Chapter 13/Sentences.w"
LOOP_THROUGH_WORDING(k, W)
if (k > Wordings__first_wn(W))
if ((Lexer__break_before(k) == '\n') || (Lexer__indentation_level(k) > 0)) {
Problems__quote_source(1, Sentences__NPs__new_raw(W));
Problems__quote_source(2, Sentences__NPs__new_raw(Wordings__up_to(W, k-1)));
Problems__quote_source(3, Sentences__NPs__new_raw(Wordings__from(W, k)));
Problems__Issue__handmade_problem(_p_(PM_HeadingOverLine));
Problems__issue_problem_segment(
"The text %1 seems to be a heading, but contains a "
"line break, which is not allowed: so I am reading it "
"as just %2 and ignoring the continuation %3. The rule "
"is that a heading must be a single line which is the "
"only sentence in its paragraph, so there must be a "
"skipped line above and below.");
Problems__issue_problem_end();
break;
}
}
#line 373 "inform7/Chapter 13/Sentences.w"
;
{
#line 514 "inform7/Chapter 13/Sentences.w"
if (Lexer__break_before(Wordings__last_wn(W)+1) != '\n') {
int k;
for (k = Wordings__last_wn(W)+1;
(k<=Wordings__last_wn(W)+8) && (k<lexer_wordcount) && (Lexer__break_before(k) != '\n');
k++) ;
Problems__quote_source(1, Sentences__NPs__new_raw(W));
Problems__quote_source(2, Sentences__NPs__new_raw(Wordings__new(Wordings__last_wn(W)+1, k-1)));
Problems__Issue__handmade_problem(_p_(PM_HeadingStopsBeforeEndOfLine));
Problems__issue_problem_segment(
"The text %1 seems to be a heading, but does not occupy "
"the whole of its line of source text, which continues %2. "
"The rule is that a heading must occupy a whole single line "
"which is the only sentence in its paragraph, so there "
"must be a skipped line above and below. %P"
"A heading must not contain a colon ':' or any full stop "
"characters '.', even if they occur in an ellipsis '...' or a "
"number '2.3.13'. (I mention that because sometimes this problem "
"arises when a decimal point is misread as a full stop.)");
Problems__issue_problem_end();
}
}
#line 374 "inform7/Chapter 13/Sentences.w"
;
{
#line 539 "inform7/Chapter 13/Sentences.w"
heading *h;
new = ParseTree__new(HEADING_NT);
ParseTree__set_text(new, W);
ParseTree__annotate_int(new, sentence_unparsed_ANNOT, FALSE);
ParseTree__annotate_int(new, heading_level_ANNOT, heading_level);
ParseTree__insert_sentence(new);
h = Sentences__Headings__declare(new);
ParseTree__set_embodying_heading(new, h);
if (Sentences__Headings__include_material(h) == FALSE)
sfsm_skipping_material_at_level = heading_level;
}
#line 375 "inform7/Chapter 13/Sentences.w"
;
return;
}
{
#line 402 "inform7/Chapter 13/Sentences.w"
if ((sfsm_extension_position == 3) && (begins_or_ends == 0)) {
LOG("Spurious text: $w\n", W);
Problems__Issue__extension_problem(_p_(PM_ExtSpuriouslyContinues),
sfsm_extension, "continues after the 'ends here' sentence");
sfsm_extension_position = 4; /* to avoid multiply issuing this */
}
}
#line 379 "inform7/Chapter 13/Sentences.w"
;
{
#line 623 "inform7/Chapter 13/Sentences.w"
{
#line 702 "inform7/Chapter 13/Sentences.w"
if ((sfsm_inside_rule_mode == FALSE)
&& ((stop_character == '.') || (stop_character == '|'))
&& (Preform__parse_nt_against_word_range(comma_divisible_sentence_NTM, W, NULL, NULL)))
{
#line 712 "inform7/Chapter 13/Sentences.w"
int earliest_comma_position = Wordings__first_wn(W);
{
#line 728 "inform7/Chapter 13/Sentences.w"
if (Preform__parse_nt_against_word_range(list_or_division_NTM, W, NULL, NULL)) {
wording BW = GET_RW(list_or_division_NTM, 2);
earliest_comma_position = Wordings__first_wn(BW);
}
}
#line 713 "inform7/Chapter 13/Sentences.w"
;
wording AW = EMPTY_WORDING, BW = EMPTY_WORDING;
if (Preform__parse_nt_against_word_range(list_comma_division_NTM, Wordings__from(W, earliest_comma_position), NULL, NULL)) {
AW = GET_RW(list_comma_division_NTM, 1);
BW = GET_RW(list_comma_division_NTM, 2);
}
if (Wordings__nonempty(AW)) {
Sentences__make_node(Wordings__up_to(W, Wordings__last_wn(AW)), ':'); /* rule preamble stopped with a colon */
Sentences__make_node(BW, '.'); /* rule body with one sentence, stopped with a stop */
return;
}
}
#line 705 "inform7/Chapter 13/Sentences.w"
;
}
#line 623 "inform7/Chapter 13/Sentences.w"
;
{
#line 739 "inform7/Chapter 13/Sentences.w"
new = ParseTree__new(SENTENCE_NT);
ParseTree__set_text(new, W);
ParseTree__annotate_int(new, sentence_unparsed_ANNOT, FALSE);
ParseTree__insert_sentence(new);
}
#line 624 "inform7/Chapter 13/Sentences.w"
;
{
#line 778 "inform7/Chapter 13/Sentences.w"
if (stop_character == ':') {
if ((sfsm_inside_rule_mode) && (Sentences__RuleSubtrees__detect_control_structure(W))) {
ParseTree__set_type(new, INVOCATION_LIST_NT);
ParseTree__annotate_int(new, colon_block_command_ANNOT, TRUE);
sfsm_inside_rule_mode = TRUE;
return;
} else {
ParseTree__set_type(new, ROUTINE_NT);
sfsm_inside_rule_mode = TRUE;
return;
}
}
}
#line 626 "inform7/Chapter 13/Sentences.w"
;
if (sfsm_inside_rule_mode)
{
#line 795 "inform7/Chapter 13/Sentences.w"
ParseTree__set_type(new, INVOCATION_LIST_NT);
if (stop_character != ';') sfsm_inside_rule_mode = FALSE;
return;
}
#line 628 "inform7/Chapter 13/Sentences.w"
else if (stop_character == ';') {
Problems__quote_source(1, Sentences__NPs__new_raw(W));
Problems__Issue__handmade_problem(_p_(PM_UnexpectedSemicolon));
Problems__issue_problem_segment(
"The text %1 is followed by a semicolon ';', which only makes "
"sense to me inside a rule or phrase (where there's a heading, "
"then a colon, then a list of instructions divided by semicolons). "
"Perhaps you want a full stop '.' instead?");
Problems__issue_problem_end();
stop_character = '.';
}
/* at this point we are certainly in assertion mode, not rule mode */
if (Preform__parse_nt_against_word_range(structural_sentence_NTM, W, NULL, NULL)) {
if (most_recent_result == -1)
{
#line 821 "inform7/Chapter 13/Sentences.w"
current_sentence = new;
Plugins__Manage__plug_in(GET_RW(language_modifying_sentence_NTM, 1));
ParseTree__annotate_int(new, language_element_ANNOT, TRUE);
ParseTree__annotate_int(new, sentence_unparsed_ANNOT, FALSE);
}
#line 644 "inform7/Chapter 13/Sentences.w"
else if (most_recent_result == -2) {
{
#line 829 "inform7/Chapter 13/Sentences.w"
current_sentence = new;
Preform__parse_preform(GET_RW(language_modifying_sentence_NTM, 1), TRUE);
ParseTree__annotate_int(new, sentence_unparsed_ANNOT, FALSE);
}
#line 646 "inform7/Chapter 13/Sentences.w"
ParseTree__set_type(new, INFORM6CODE_NT); return;
} else {
if (ssnt == INCLUDE_NT) {
new->down = most_recent_result_p;
if (first_extension_inclusion == NULL) first_extension_inclusion = new;
}
ParseTree__set_type(new, ssnt);
if (ssnt == BIBLIOGRAPHIC_NT)
NaturalLanguages__set_language_of_play(
PL__Bibliographic__scan_language(new));
return;
}
}
{
#line 803 "inform7/Chapter 13/Sentences.w"
if (begins_or_ends == 1) {
ParseTree__set_type(new, BEGINHERE_NT);
ParseTree__set_text(new, Wordings__trim_last_word(Wordings__trim_last_word(W)));
Extensions__Inclusion__check_begins_here(new, sfsm_extension);
return;
}
if (begins_or_ends == -1) {
ParseTree__set_type(new, ENDHERE_NT);
ParseTree__set_text(new, Wordings__trim_last_word(Wordings__trim_last_word(W)));
Extensions__Inclusion__check_ends_here(new, sfsm_extension);
return;
}
}
#line 661 "inform7/Chapter 13/Sentences.w"
;
/* none of that happened, so we have a SENTENCE node for certain */
if (text_loaded_from_source) Sentences__VPs__seek(new);
else ParseTree__annotate_int(new, sentence_unparsed_ANNOT, TRUE);
}
#line 380 "inform7/Chapter 13/Sentences.w"
;
}
#line 429 "inform7/Chapter 13/Sentences.w"
int dividing_sentence_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 432 "inform7/Chapter 13/Sentences.w"
int heading_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 3;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 4;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 5;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 439 "inform7/Chapter 13/Sentences.w"
int extension_end_marker_sentence_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = -1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = -2;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 443 "inform7/Chapter 13/Sentences.w"
#line 589 "inform7/Chapter 13/Sentences.w"
int structural_sentence_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; ssnt = BIBLIOGRAPHIC_NT;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; ssnt = BIBLIOGRAPHIC_NT;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; ssnt = TRACE_NT;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 0; ssnt = TRACE_NT;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = 0; ssnt = TABLE_NT;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = 0; ssnt = EQUATION_NT;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = 0; ssnt = INCLUDE_NT; *XP = RP[1]; ((parse_node *) RP[1])->next = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = 0; ssnt = INFORM6CODE_NT;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 599 "inform7/Chapter 13/Sentences.w"
#line 606 "inform7/Chapter 13/Sentences.w"
int language_modifying_sentence_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = -2;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = -1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 609 "inform7/Chapter 13/Sentences.w"
#line 617 "inform7/Chapter 13/Sentences.w"
int use_option_sentence_shape_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 619 "inform7/Chapter 13/Sentences.w"
#line 677 "inform7/Chapter 13/Sentences.w"
int comma_divisible_sentence_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 683 "inform7/Chapter 13/Sentences.w"
#line 695 "inform7/Chapter 13/Sentences.w"
int list_or_division_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 698 "inform7/Chapter 13/Sentences.w"
#line 195 "inform7/Chapter 13/Headings.w"
int heading_tree_made_at_least_once = FALSE;
#line 206 "inform7/Chapter 13/Headings.w"
int last_indentation_above_level[NO_HEADING_LEVELS], lial_made = FALSE;
extension_identifier *grammar_eid = NULL;
heading *Sentences__Headings__declare(parse_node *PN) {
heading *h = CREATE(heading);
h->parent_heading = NULL; h->child_heading = NULL; h->next_heading = NULL;
h->list_of_contents = NULL; h->last_in_list_of_contents = NULL;
h->for_release = NOT_APPLICABLE; h->omit_material = FALSE;
h->index_definitions_made_under_this = TRUE;
h->use_with_or_without = NOT_APPLICABLE;
h->in_place_of_text = EMPTY_WORDING;
if ((PN == NULL) || (Wordings__empty(ParseTree__get_text(PN))))
internal_error("heading at textless node");
internal_error_if_node_type_wrong(PN, HEADING_NT);
h->sentence_declaring = PN;
h->start_location = Wordings__location(ParseTree__get_text(PN));
h->level = ParseTree__int_annotation(PN, heading_level_ANNOT);
if (h->level > 0)
{
#line 262 "inform7/Chapter 13/Headings.w"
grammar_eid = &(h->for_use_with);
current_sentence = PN;
wording W = ParseTree__get_text(PN);
while (Preform__parse_nt_against_word_range(heading_qualifier_NTM, W, NULL, NULL)) {
switch (most_recent_result) {
case PLATFORM_UNMET_HQ: h->omit_material = TRUE; break;
case NOT_FOR_RELEASE_HQ: h->for_release = FALSE; break;
case FOR_RELEASE_ONLY_HQ: h->for_release = TRUE; break;
case UNINDEXED_HQ: h->index_definitions_made_under_this = FALSE; break;
case USE_WITH_HQ: h->use_with_or_without = TRUE; break;
case USE_WITHOUT_HQ: h->use_with_or_without = FALSE; break;
case IN_PLACE_OF_HQ:
h->use_with_or_without = TRUE;
h->in_place_of_text = GET_RW(extension_qualifier_NTM, 1);
break;
}
W = GET_RW(heading_qualifier_NTM, 1);
}
}
#line 227 "inform7/Chapter 13/Headings.w"
;
if ((h->level < 0) || (h->level >= NO_HEADING_LEVELS)) internal_error("impossible level");
{
#line 240 "inform7/Chapter 13/Headings.w"
int i;
if (lial_made == FALSE) {
for (i=0; i<NO_HEADING_LEVELS; i++) last_indentation_above_level[i] = -1;
lial_made = TRUE;
}
h->indentation = last_indentation_above_level[h->level] + 1;
for (i=h->level+1; i<NO_HEADING_LEVELS; i++)
last_indentation_above_level[i] = h->indentation;
}
#line 230 "inform7/Chapter 13/Headings.w"
;
LOGIF(HEADINGS, "Created heading $H\n", h);
if (heading_tree_made_at_least_once) Sentences__Headings__make_tree();
return h;
}
#line 294 "inform7/Chapter 13/Headings.w"
int heading_qualifier_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = NOT_FOR_RELEASE_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = FOR_RELEASE_ONLY_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = UNINDEXED_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 299 "inform7/Chapter 13/Headings.w"
int bracketed_heading_qualifier_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = NOT_FOR_RELEASE_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FOR_RELEASE_ONLY_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = UNINDEXED_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 306 "inform7/Chapter 13/Headings.w"
int platform_qualifier_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = (R[1])?PLATFORM_MET_HQ:PLATFORM_UNMET_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = (R[1])?PLATFORM_UNMET_HQ:PLATFORM_MET_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 310 "inform7/Chapter 13/Headings.w"
int platform_identifier_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 330 "inform7/Chapter 13/Headings.w"
Problems__Issue__sentence_problem(_p_(PM_UnknownLanguageElement),
"this heading contains a stipulation about the current "
"Inform language definition which I can't understand",
"and should be something like '(for Glulx external files "
"language element only)'.");
}
#line 313 "inform7/Chapter 13/Headings.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 339 "inform7/Chapter 13/Headings.w"
Problems__Issue__sentence_problem(_p_(PM_UnknownVirtualMachine),
"this heading contains a stipulation about the Setting "
"for story file format which I can't understand",
"and should be something like '(for Z-machine version 5 "
"or 8 only)' or '(for Glulx only)'.");
}
#line 315 "inform7/Chapter 13/Headings.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 316 "inform7/Chapter 13/Headings.w"
int extension_qualifier_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = USE_WITH_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = USE_WITHOUT_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = USE_WITHOUT_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = IN_PLACE_OF_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = IN_PLACE_OF_HQ;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 323 "inform7/Chapter 13/Headings.w"
int extension_identifier_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 348 "inform7/Chapter 13/Headings.w"
*X = R[0] + 4;
char exft[MAX_FILENAME_LENGTH], exfa[MAX_FILENAME_LENGTH];
wording TW = GET_RW(extension_identifier_NTM, 1);
wording AW = GET_RW(extension_identifier_NTM, 2);
Wordings__to_string_raw_truncated(exft, MAX_FILENAME_LENGTH, TW);
Wordings__to_string_raw_truncated(exfa, MAX_FILENAME_LENGTH, AW);
Extensions__IDs__new(grammar_eid, exfa, exft, USEWITH_EIDBC);
}
#line 325 "inform7/Chapter 13/Headings.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 326 "inform7/Chapter 13/Headings.w"
#line 364 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__make_tree(void) {
heading *h;
{
#line 382 "inform7/Chapter 13/Headings.w"
heading *h;
pseudo_heading.child_heading = NULL; pseudo_heading.parent_heading = NULL;
pseudo_heading.next_heading = NULL;
LOOP_OVER(h, heading) {
h->parent_heading = NULL; h->child_heading = NULL; h->next_heading = NULL;
}
}
#line 366 "inform7/Chapter 13/Headings.w"
;
LOOP_OVER(h, heading) {
{
#line 396 "inform7/Chapter 13/Headings.w"
if (h->parent_heading == NULL)
Sentences__Headings__make_child_heading(h, &pseudo_heading);
}
#line 369 "inform7/Chapter 13/Headings.w"
;
{
#line 417 "inform7/Chapter 13/Headings.w"
heading *subseq;
for (subseq = NEXT_OBJECT(h, heading); /* start from the next heading in source */
(subseq) && (subseq->level >= h->level); /* for a run with level below or equal h */
subseq = NEXT_OBJECT(subseq, heading)) { /* in source declaration order */
if (subseq->level == h->level) { /* a heading of equal status ends the run... */
Sentences__Headings__make_child_heading(subseq, h->parent_heading); break; /* ...and becomes h's sibling */
}
Sentences__Headings__make_child_heading(subseq, h); /* all lesser headings in the run become h's children */
}
}
#line 370 "inform7/Chapter 13/Headings.w"
;
}
heading_tree_made_at_least_once = TRUE;
Sentences__Headings__verify_heading_tree();
}
#line 431 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__make_child_heading(heading *ch, heading *pa) {
heading *former_pa = ch->parent_heading;
if (former_pa == pa) return;
{
#line 445 "inform7/Chapter 13/Headings.w"
if (former_pa) {
if (former_pa->child_heading == ch)
former_pa->child_heading = ch->next_heading;
else {
heading *sibling;
for (sibling = former_pa->child_heading; sibling; sibling = sibling->next_heading)
if (sibling->next_heading == ch) {
sibling->next_heading = ch->next_heading;
break;
}
}
}
ch->next_heading = NULL;
}
#line 434 "inform7/Chapter 13/Headings.w"
;
ch->parent_heading = pa;
{
#line 462 "inform7/Chapter 13/Headings.w"
heading *sibling;
if (pa->child_heading == NULL) pa->child_heading = ch;
else
for (sibling = pa->child_heading; sibling; sibling = sibling->next_heading)
if (sibling->next_heading == NULL) {
sibling->next_heading = ch;
break;
}
}
#line 436 "inform7/Chapter 13/Headings.w"
;
}
#line 479 "inform7/Chapter 13/Headings.w"
int heading_tree_damaged = FALSE;
void Sentences__Headings__verify_heading_tree(void) {
Sentences__Headings__verify_heading_tree_recursively(&pseudo_heading, -1);
if (heading_tree_damaged) internal_error("heading tree failed to verify");
}
void Sentences__Headings__verify_heading_tree_recursively(heading *h, int depth) {
if (h == NULL) return;
if ((h != &pseudo_heading) && (depth != h->indentation)) {
heading_tree_damaged = TRUE;
LOG("$H\n*** indentation should be %d ***\n", h, depth);
}
Sentences__Headings__verify_heading_tree_recursively(h->child_heading, depth+1);
Sentences__Headings__verify_heading_tree_recursively(h->next_heading, depth);
}
#line 503 "inform7/Chapter 13/Headings.w"
int Sentences__Headings__include_material(heading *h) {
if ((h->for_release == TRUE) && (this_is_a_release_compile == FALSE)) return FALSE;
if ((h->for_release == FALSE) && (this_is_a_release_compile == TRUE)) return FALSE;
if (h->omit_material) return FALSE;
return TRUE;
}
int Sentences__Headings__indexed(heading *h) {
if (h == NULL) return TRUE; /* definitions made nowhere are normally indexed */
return h->index_definitions_made_under_this;
}
#line 518 "inform7/Chapter 13/Headings.w"
extension_file *Sentences__Headings__get_extension_containing(heading *h) {
if ((h == NULL) || (h->start_location.file_of_origin == NULL)) return NULL;
return SourceFiles__get_extension_corresponding(h->start_location.file_of_origin);
}
#line 529 "inform7/Chapter 13/Headings.w"
wording Sentences__Headings__get_text(heading *h) {
if ((h == NULL) || (h->level == 0)) return EMPTY_WORDING;
return ParseTree__get_text(h->sentence_declaring);
}
#line 546 "inform7/Chapter 13/Headings.w"
heading *Sentences__Headings__heading_of(source_location sl) {
heading *h;
if (sl.file_of_origin == NULL) return NULL;
LOOP_BACKWARDS_OVER(h, heading)
if ((sl.file_of_origin == h->start_location.file_of_origin) &&
(sl.line_number >= h->start_location.line_number)) return h;
internal_error("unable to determine the heading level of source material");
return NULL;
}
#line 565 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__satisfy_dependencies(void) {
heading *h;
LOOP_OVER(h, heading)
if (h->use_with_or_without != NOT_APPLICABLE)
Sentences__Headings__satisfy_individual_heading_dependency(h);
}
#line 577 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__satisfy_individual_heading_dependency(heading *h) {
if (h->level < 1) return;
extension_identifier *eid = &(h->for_use_with);
int loaded = FALSE;
if (Extensions__IDs__no_times_used_in_context(eid, LOADED_EIDBC) != 0) loaded = TRUE;
LOGIF(HEADINGS, "SIHD on $H: loaded %d: annotation %d: $w: %d\n", h, loaded,
ParseTree__int_annotation(h->sentence_declaring,
suppress_heading_dependencies_ANNOT),
h->in_place_of_text, h->use_with_or_without);
if (Wordings__nonempty(h->in_place_of_text)) {
wording S = h->in_place_of_text;
if (ParseTree__int_annotation(h->sentence_declaring,
suppress_heading_dependencies_ANNOT) == FALSE) {
if (Preform__parse_nt_against_word_range(quoted_text_NTM, h->in_place_of_text, NULL, NULL)) {
Text__dequote_word(Wordings__first_wn(S));
char *text = Lexer__word_text(Wordings__first_wn(S));
S = Feeds__feed_text(text);
}
heading *h2; int found = FALSE;
if (loaded == FALSE)
{
#line 622 "inform7/Chapter 13/Headings.w"
current_sentence = h->sentence_declaring;
Problems__quote_source(1, current_sentence);
Problems__quote_extension_id(2, &(h->for_use_with));
Problems__Issue__handmade_problem(_p_(PM_HeadingInPlaceOfUnincluded));
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend to replace a section "
"of source text from the extension '%2', but no extension of that "
"name has been included - so it is not possible to replace any of its "
"headings.");
Problems__issue_problem_end();
}
#line 596 "inform7/Chapter 13/Headings.w"
else {
LOOP_OVER(h2, heading)
if ((h2->sentence_declaring) &&
(Wordings__match_perhaps_quoted(S,
ParseTree__get_text(h2->sentence_declaring))) &&
(Extensions__IDs__match(
Extensions__Files__get_eid(
Sentences__Headings__get_extension_containing(h2)), eid))) {
found = TRUE;
if (h->level != h2->level)
{
#line 719 "inform7/Chapter 13/Headings.w"
current_sentence = h->sentence_declaring;
Problems__Issue__sentence_problem(_p_(PM_UnequalHeadingInPlaceOf),
"these headings are not of the same level",
"so it is not possible to make the replacement. (Level here means "
"being a Volume, Book, Part, Chapter or Section: for instance, "
"only a Chapter heading can be used 'in place of' a Chapter.)");
}
#line 607 "inform7/Chapter 13/Headings.w"
;
Sentences__Headings__excise_material_under(h2, NULL);
Sentences__Headings__excise_material_under(h, h2->sentence_declaring);
break;
}
if (found == FALSE)
{
#line 697 "inform7/Chapter 13/Headings.w"
current_sentence = h->sentence_declaring;
Problems__quote_source(1, current_sentence);
Problems__quote_extension_id(2, &(h->for_use_with));
Problems__quote_wording(3, h->in_place_of_text);
Problems__quote_text(4,
"unspecified, that is, the extension didn't have a version number");
extension_file *ef;
LOOP_OVER(ef, extension_file)
if (Extensions__IDs__match(&(h->for_use_with), Extensions__Files__get_eid(ef)))
Problems__quote_wording(4,
Wordings__one_word(Extensions__Files__get_version_wn(ef)));
Problems__Issue__handmade_problem(_p_(PM_HeadingInPlaceOfUnknown));
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend to replace a section "
"of source text from the extension '%2', but that extension does "
"not seem to have any heading called '%3'. (The version I loaded "
"was %4.)");
Problems__issue_problem_end();
}
#line 612 "inform7/Chapter 13/Headings.w"
;
}
}
} else
if (h->use_with_or_without != loaded) Sentences__Headings__excise_material_under(h, NULL);
}
#line 644 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__excise_material_under(heading *h, parse_node *transfer_to) {
LOGIF(HEADINGS, "Excision under $H\n", h);
parse_node *hpn = h->sentence_declaring;
if (h->sentence_declaring == NULL) internal_error("stipulations on a non-sentence heading");
if (Wordings__nonempty(h->in_place_of_text)) {
heading *h2 = Sentences__Headings__find_dependent_heading(hpn->down);
if (h2)
{
#line 681 "inform7/Chapter 13/Headings.w"
current_sentence = h2->sentence_declaring;
Problems__quote_source(1, current_sentence);
Problems__quote_extension_id(2, &(h2->for_use_with));
Problems__quote_source(3, h->sentence_declaring);
Problems__quote_extension_id(4, &(h->for_use_with));
Problems__Issue__handmade_problem(_p_(PM_HeadingInPlaceOfSubordinate));
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend to replace a section "
"of source text from the extension '%2', but that doesn't really make "
"sense because this new piece of source text is part of a superior "
"heading ('%3') which is already being replaced spliced into '%4'.");
Problems__issue_problem_end();
}
#line 651 "inform7/Chapter 13/Headings.w"
;
}
Sentences__Headings__suppress_dependencies(hpn);
if (transfer_to) ParseTree__graft(hpn->down, transfer_to);
hpn->down = NULL;
}
heading *Sentences__Headings__find_dependent_heading(parse_node *pn) {
if (ParseTree__get_type(pn) == HEADING_NT) {
heading *h = ParseTree__get_embodying_heading(pn);
if ((h) && (Wordings__nonempty(h->in_place_of_text))) return h;
}
for (parse_node *p = pn->down; p; p = p->next) {
heading *h = ParseTree__get_embodying_heading(p);
if (h) return h;
}
return NULL;
}
void Sentences__Headings__suppress_dependencies(parse_node *pn) {
if (ParseTree__get_type(pn) == HEADING_NT)
ParseTree__annotate_int(pn, suppress_heading_dependencies_ANNOT, TRUE);
for (parse_node *p = pn->down; p; p = p->next)
Sentences__Headings__suppress_dependencies(p);
}
#line 736 "inform7/Chapter 13/Headings.w"
int no_tags_attached = 0;
void Sentences__Headings__attach_nametag(nametag *new_tag) {
if (current_sentence == NULL) return;
heading *h = Wordings__heading_of(ParseTree__get_text(current_sentence));
if (h == NULL) return;
no_tags_attached++;
name_resolution_data *nrd = Nametags__name_resolution_data(new_tag);
nrd->next_to_search = NULL;
if (h->last_in_list_of_contents == NULL) h->list_of_contents = new_tag;
else Nametags__name_resolution_data(h->last_in_list_of_contents)->next_under_heading = new_tag;
nrd->next_under_heading = NULL;
h->last_in_list_of_contents = new_tag;
}
#line 758 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__verify_divisions(void) {
nametag *nt; heading *h;
int total = 0, disaster = FALSE;
LOOP_OVER(nt, nametag)
Nametags__name_resolution_data(nt)->heading_count = 0;
LOOP_OVER(h, heading)
LOOP_OVER_NAMETAGS_UNDER(nt, h)
Nametags__name_resolution_data(nt)->heading_count++, total++;
LOOP_OVER(nt, nametag)
if (Nametags__name_resolution_data(nt)->heading_count > 1) {
LOG("$z occurs under %d headings\n",
nt, Nametags__name_resolution_data(nt)->heading_count);
disaster = TRUE;
}
if (total != no_tags_attached) {
LOG("%d tags != %d attached\n",
total, no_tags_attached);
disaster = TRUE;
}
if (disaster) internal_error_tree_unsafe("heading contents list failed verification");
}
#line 844 "inform7/Chapter 13/Headings.w"
nametag *nt_search_start = NULL, *nt_search_finish = NULL;
#line 853 "inform7/Chapter 13/Headings.w"
heading *nametag_search_list_valid_for_this_heading = NULL; /* initially it's unbuilt */
void Sentences__Headings__disturb(void) {
nametag_search_list_valid_for_this_heading = NULL;
}
#line 864 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__construct_nametag_search_list(void) {
heading *h = NULL;
{
#line 888 "inform7/Chapter 13/Headings.w"
if ((current_sentence == NULL) || (Wordings__empty(ParseTree__get_text(current_sentence))))
internal_error("cannot establish position P: there is no current sentence");
source_location position_P = Wordings__location(ParseTree__get_text(current_sentence));
h = Sentences__Headings__heading_of(position_P);
}
#line 867 "inform7/Chapter 13/Headings.w"
;
if ((h == NULL) || (h == nametag_search_list_valid_for_this_heading)) return; /* rely on the cache */
LOGIF(HEADINGS, "Rebuilding nametag search list from: $H\n", h);
{
#line 898 "inform7/Chapter 13/Headings.w"
nt_search_start = NULL;
nt_search_finish = NULL;
pseudo_heading.list_of_contents = NULL; /* should always be true, but just in case */
}
#line 873 "inform7/Chapter 13/Headings.w"
;
int i;
for (i=1; i<=MAX_NAMETAG_PRIORITY; i++)
Sentences__Headings__build_search_list_from(h, NULL, i);
{
#line 907 "inform7/Chapter 13/Headings.w"
int c = 0; nametag *nt;
LOOP_OVER_NT_SEARCH_LIST(nt) c++;
if (c != no_tags_attached) {
LOG("Reordering failed from $H\n", h);
LOG("%d tags created, %d in ordering\n", no_tags_attached, c);
Sentences__Headings__log_all_headings();
LOG("Making fresh tree:\n");
Sentences__Headings__make_tree();
Sentences__Headings__log_all_headings();
internal_error_tree_unsafe("reordering of nametags failed");
}
}
#line 879 "inform7/Chapter 13/Headings.w"
;
nametag_search_list_valid_for_this_heading = h;
}
#line 949 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__build_search_list_from(heading *within, heading *way_we_came, int p) {
nametag *nt; heading *subhead;
if (within == NULL) return;
LOOP_OVER_NAMETAGS_UNDER(nt, within)
if (Nametags__priority(nt) == p)
{
#line 971 "inform7/Chapter 13/Headings.w"
if (nt_search_finish == NULL) {
nt_search_start = nt;
} else {
if (Nametags__name_resolution_data(nt_search_finish)->next_to_search != NULL)
internal_error("end of tag search list has frayed somehow");
Nametags__name_resolution_data(nt_search_finish)->next_to_search = nt;
}
Nametags__name_resolution_data(nt)->next_to_search = NULL;
nt_search_finish = nt;
}
#line 956 "inform7/Chapter 13/Headings.w"
;
/* recurse downwards through subordinate headings, other than the way we came up */
for (subhead = within->child_heading; subhead; subhead = subhead->next_heading)
if (subhead != way_we_came)
Sentences__Headings__build_search_list_from(subhead, within, p);
/* recurse upwards to superior headings, unless we came here through a downward recursion */
if (within->parent_heading != way_we_came)
Sentences__Headings__build_search_list_from(within->parent_heading, within, p);
}
#line 986 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__set_nametag_search_score(nametag *nt, int v) {
Nametags__name_resolution_data(nt)->search_score = v;
}
nametag *Sentences__Headings__highest_scoring_nametag_searched(void) {
nametag *nt, *best_nt = NULL;
int best_score = 0;
LOOP_OVER_NT_SEARCH_LIST(nt) {
int x = Nametags__name_resolution_data(nt)->search_score;
if (x > best_score) { best_nt = nt; best_score = x; }
}
return best_nt;
}
#line 1007 "inform7/Chapter 13/Headings.w"
sentence_handler HEADING_SH_handler =
{ HEADING_NT, -1, 0, Sentences__Headings__handle_heading };
void Sentences__Headings__handle_heading(parse_node *PN) {
Assertions__Traverse__new_discussion();
}
#line 1019 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__log(heading *h) {
if (h==NULL) { LOG("<null heading>\n"); return; }
if (h==&pseudo_heading) { LOG("<pseudo_heading>\n"); return; }
LOG("H%d ", h->allocation_id);
if (h->start_location.file_of_origin)
LOG("<%f, line %d>",
SourceFiles__get_filename(h->start_location.file_of_origin),
h->start_location.line_number);
else LOG("<nowhere>");
LOG(" level:%d indentation:%d", h->level, h->indentation);
}
#line 1035 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__log_all_headings(void) {
heading *h;
LOOP_OVER(h, heading) LOG("$H\n", h);
LOG("\n");
Sentences__Headings__log_headings_recursively(&pseudo_heading, 0);
}
void Sentences__Headings__log_headings_recursively(heading *h, int depth) {
int i;
if (h==NULL) return;
for (i=0; i<depth; i++) LOG(" ");
LOG("$H\n", h);
if (depth-1 != h->indentation) LOG("*** indentation should be %d ***\n", depth-1);
Sentences__Headings__log_headings_recursively(h->child_heading, depth+1);
Sentences__Headings__log_headings_recursively(h->next_heading, depth);
}
#line 1055 "inform7/Chapter 13/Headings.w"
int headings_indexed = 0;
void Sentences__Headings__index(void) {
INDEX("<p><b>");
PL__Bibliographic__contents_heading();
INDEX("</b></p><p>CONTENTS</p>");
Sentences__Headings__index_heading_recursively(pseudo_heading.child_heading);
contents_entry *ce;
int min_positive_level = 10;
LOOP_OVER(ce, contents_entry)
if ((ce->heading_entered->level > 0) &&
(ce->heading_entered->level < min_positive_level))
min_positive_level = ce->heading_entered->level;
LOOP_OVER(ce, contents_entry)
{
#line 1081 "inform7/Chapter 13/Headings.w"
heading *h = ce->heading_entered;
/* indent to correct tab position */
INDEX("<ul class=\"leaders\">\n");
int ind_used = h->indentation;
if (h->level == 0) ind_used = 1;
INDEX("<li class=\"leaded indent%d\"><span>", ind_used);
if (h->level == 0) {
if (NUMBER_CREATED(contents_entry) == 1)
INDEX("Source text");
else
INDEX("Preamble");
} else {
/* write the text of the heading title */
Wordings__index_raw(ParseTree__get_text(h->sentence_declaring));
}
INDEX("</span><span>");
contents_entry *next_ce = NEXT_OBJECT(ce, contents_entry);
if (h->level != 0)
while ((next_ce) && (next_ce->heading_entered->level > ce->heading_entered->level))
next_ce = NEXT_OBJECT(next_ce, contents_entry);
int start_word = Wordings__first_wn(ParseTree__get_text(ce->heading_entered->sentence_declaring));
int end_word = (next_ce)?(Wordings__first_wn(ParseTree__get_text(next_ce->heading_entered->sentence_declaring)))
: (SourceFiles__last_lexed_word(FIRST_OBJECT(source_file)));
int i, N = 0;
for (i = start_word; i < end_word; i++)
N += SourceFiles__word_count(i);
if (h->level > min_positive_level) INDEX("<font color=\"#888\">");
INDEX("%d words", N);
if (h->level > min_positive_level) INDEX("</font>");
/* place a link to the relevant line of the primary source text */
Index__link_location(h->start_location);
INDEX("</span></li></ul>\n");
{
#line 1155 "inform7/Chapter 13/Headings.w"
nametag *nt;
int c = 0;
LOOP_OVER_NAMETAGS_UNDER(nt, h) {
wording W = Nametags__get_name(nt, FALSE);
if (Wordings__nonempty(W)) {
if (c++ == 0) {
HTML__open_para(ifl, ind_used+1, "hanging");
INDEX("<font color=\"#808080\">");
} else INDEX(", ");
INDEX("<i>");
Wordings__index_raw(W);
INDEX("</i>");
}
}
if (c > 0) INDEX("</font></p>\n");
}
#line 1115 "inform7/Chapter 13/Headings.w"
;
}
#line 1068 "inform7/Chapter 13/Headings.w"
;
if (NUMBER_CREATED(contents_entry) == 1) {
INDEX("<p>(This would look more like a contents page if the source text "
"were divided up into headings.");
Index__DocReferences__link("HEADINGS");
INDEX(")</p>\n");
}
}
#line 1122 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__index_heading_recursively(heading *h) {
if (h == NULL) return;
int show_heading = TRUE;
heading *next = h->child_heading;
if (next == NULL) next = h->next_heading;
if ((next) &&
(SourceFiles__get_extension_corresponding(next->start_location.file_of_origin)))
next = NULL;
if (h->level == 0) {
show_heading = FALSE;
if ((headings_indexed == 0) &&
((next == NULL) ||
(Wordings__first_wn(ParseTree__get_text(next->sentence_declaring)) !=
Wordings__first_wn(ParseTree__get_text(h->sentence_declaring)))))
show_heading = TRUE;
}
if (SourceFiles__get_extension_corresponding(h->start_location.file_of_origin))
show_heading = FALSE;
if (show_heading) {
contents_entry *ce = CREATE(contents_entry);
ce->heading_entered = h;
headings_indexed++;
}
Sentences__Headings__index_heading_recursively(h->child_heading);
Sentences__Headings__index_heading_recursively(h->next_heading);
}
#line 1183 "inform7/Chapter 13/Headings.w"
void Sentences__Headings__write_as_xml(void) {
text_stream xf_struct; text_stream *xf = &xf_struct;
if (STREAM_OPEN_TO_FILE(xf, filename_of_headings, UTF8_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open headings file", filename_of_headings);
Sentences__Headings__write_headings_as_xml_inner(xf);
STREAM_CLOSE(xf);
}
void Sentences__Headings__write_headings_as_xml_inner(OUTPUT_STREAM) {
heading *h;
{
#line 1211 "inform7/Chapter 13/Headings.w"
WRITE("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
}
#line 1193 "inform7/Chapter 13/Headings.w"
;
WRITE("<plist version=\"1.0\"><dict>\n");
INDENT;
WRITE("<key>Application Version</key><string>%s</string>\n", NI_BUILD);
LOOP_OVER(h, heading) {
WRITE("<key>%d</key><dict>\n", h->allocation_id);
INDENT;
{
#line 1223 "inform7/Chapter 13/Headings.w"
if (h->start_location.file_of_origin)
WRITE("<key>Filename</key><string>%f</string>\n",
SourceFiles__get_filename(h->start_location.file_of_origin));
WRITE("<key>Line</key><integer>%d</integer>\n", h->start_location.line_number);
if (h->sentence_declaring != NULL) {
WRITE("<key>Title</key><string>");
Wordings__to_stream_raw(OUT, ParseTree__get_text(h->sentence_declaring));
WRITE("</string>\n");
} else {
WRITE("<key>Title</key><string>--</string>\n");
}
WRITE("<key>Level</key><integer>%d</integer>\n", h->level);
WRITE("<key>Indentation</key><integer>%d</integer>\n", h->indentation);
}
#line 1200 "inform7/Chapter 13/Headings.w"
;
OUTDENT;
WRITE("</dict>\n");
}
OUTDENT;
WRITE("</dict></plist>\n");
}
#line 150 "inform7/Chapter 13/Verb Phrases.w"
void Sentences__VPs__traverse(void) {
ParseTree__traverse(Sentences__VPs__visit);
}
void Sentences__VPs__visit(parse_node *p) {
if ((ParseTree__get_type(p) == SENTENCE_NT) &&
(ParseTree__int_annotation(p, sentence_unparsed_ANNOT))) {
Sentences__VPs__seek(p);
{
#line 166 "inform7/Chapter 13/Verb Phrases.w"
if (Wordings__within(ParseTree__get_text(p), options_file_wording)) {
int v = ParseTree__int_annotation(p->down, verb_id_ANNOT);
if (!((v == USE_VB) || (v == TEST_VB) || (v == DEBUG_VB) || (v == RELEASE_VB)))
Problems__Issue__unlocated_problem(_p_(BelievedImpossible), /* not usefully testable, anyway */
"The options file placed in this installation of Inform's folder "
"is incorrect, making use of a sentence form which isn't allowed "
"in that situation. The options file is only allowed to contain "
"use options, Test ... with..., and Release along with... "
"instructions.");
}
}
#line 157 "inform7/Chapter 13/Verb Phrases.w"
;
Sentences__Rearrangement__check_sentence_for_direction_creation(p);
ParseTree__annotate_int(p, sentence_unparsed_ANNOT, FALSE);
}
}
#line 183 "inform7/Chapter 13/Verb Phrases.w"
int assertion_NP_is_in_VP_for_to_be = FALSE;
#line 191 "inform7/Chapter 13/Verb Phrases.w"
parse_node *nss_tree_head = NULL;
binary_predicate *bp_parsed = NULL;
int certainty_parsed = UNKNOWN_CE;
int existent = FALSE;
void Sentences__VPs__seek(parse_node *PN) {
certainty_parsed = UNKNOWN_CE;
bp_parsed = NULL;
nss_tree_head = PN;
existent = FALSE;
CLEAR_RW(nonstructural_sentence_NTM);
if (Preform__parse_nt_against_word_range(nonstructural_sentence_NTM, ParseTree__get_text(PN), NULL, NULL)) {
if (existent) ParseTree__annotate_int(PN, sentence_is_existential_ANNOT, TRUE);
{
#line 217 "inform7/Chapter 13/Verb Phrases.w"
switch (ParseTree__int_annotation(PN->down, verb_id_ANNOT)) {
case DEBUG_VB: Sentences__VPs__switch_dl_mode(PN->down->next,
ParseTree__int_annotation(PN->down, log_inclusion_sense_ANNOT)); break;
case NEW_MEANINGLESS_VERB_VB: Verbs__parse_new(PN); break;
case NEW_VERB_VB: Verbs__parse_new(PN); break;
case NEW_RELATION_VB: Relations__parse_new(PN); break;
}
}
#line 204 "inform7/Chapter 13/Verb Phrases.w"
;
return;
}
Preform__parse_nt_against_word_range(bad_nonstructural_sentence_diagnosis_NTM, ParseTree__get_text(PN), NULL, NULL);
}
#line 228 "inform7/Chapter 13/Verb Phrases.w"
void Sentences__VPs__switch_dl_mode(parse_node *PN, int sense) {
if (ParseTree__get_type(PN) == AND_NT) {
Sentences__VPs__switch_dl_mode(PN->down, sense);
Sentences__VPs__switch_dl_mode(PN->down->next, sense);
return;
}
Log__set_aspect_from_text(ParseTree__get_text(PN), sense);
}
#line 294 "inform7/Chapter 13/Verb Phrases.w"
int nonstructural_sentence_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = Sentences__VPs__nss_tree2(R[2], nonstructural_sentence_NTM->range_result[1], RP[1], RP[3]);
{
#line 406 "inform7/Chapter 13/Verb Phrases.w"
natural_language *nl = (natural_language *) (RP[2]);
ParseTree__set_defn_language(nss_tree_head->down->next->next, nl);
}
#line 295 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = Sentences__VPs__nss_tree2(SPECIFIES_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = Sentences__VPs__nss_tree2(DEFINED_BY_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = Sentences__VPs__nss_tree2(PLURAL_VB, nonstructural_sentence_NTM->range_result[2], RP[2], RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = Sentences__VPs__nss_tree2(PLURAL_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = Sentences__VPs__nss_tree2(NEW_ACTION_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]) /* actions\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 356 "inform7/Chapter 13/Verb Phrases.w"
*X = BAD_NONVERB;
Problems__Issue__assertion_problem(_p_(PM_BadActionDeclaration),
"it is not sufficient to say that something is an 'action'",
"without giving the necessary details: for example, 'Unclamping "
"is an action applying to one thing.'");
}
#line 301 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = Sentences__VPs__nss_tree2(BEGINS_WHEN_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]) /* scenes\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = Sentences__VPs__nss_tree2(ENDS_WHEN_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]) /* scenes\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *X = Sentences__VPs__nss_tree3(ENDS_WHEN_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2], RP[3]) /* scenes\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10: *X = Sentences__VPs__nss_tree2(FIGURE_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]) /* figures\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11: *X = Sentences__VPs__nss_tree2(SOUND_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]) /* sounds\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12: *X = Sentences__VPs__nss_tree2(TEST_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]) /* parsing\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13: *X = Sentences__VPs__nss_tree2(UNDERSTAND_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]) /* parsing\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14: *X = Sentences__VPs__nss_tree2(EPISODE_VB, nonstructural_sentence_NTM->range_result[2], Sentences__NPs__new_raw(nonstructural_sentence_NTM->range_result[1]), RP[1]) /* bibliographic\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15: *X = Sentences__VPs__nss_tree2(FILE_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]) /* files\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 16: *X = Sentences__VPs__nss_tree2(NEW_ACTIVITY_VB, nonstructural_sentence_NTM->range_result[1], RP[1], Sentences__NPs__new_raw(nonstructural_sentence_NTM->range_result[2]));
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 17: *X = Sentences__VPs__nss_tree2(NEW_VERB_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 18: *X = Sentences__VPs__nss_tree1(NEW_MEANINGLESS_VERB_VB, nonstructural_sentence_NTM->range_result[1], RP[2]);
{
#line 400 "inform7/Chapter 13/Verb Phrases.w"
natural_language *nl = (natural_language *) (RP[1]);
ParseTree__set_defn_language(nss_tree_head->down, nl);
}
#line 313 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 19: *X = Sentences__VPs__nss_tree1(NEW_MEANINGLESS_VERB_VB, nonstructural_sentence_NTM->range_result[1], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 20: *X = Sentences__VPs__nss_tree2(NEW_VERB_VB, nonstructural_sentence_NTM->range_result[1], RP[2], RP[3]);
{
#line 400 "inform7/Chapter 13/Verb Phrases.w"
natural_language *nl = (natural_language *) (RP[1]);
ParseTree__set_defn_language(nss_tree_head->down, nl);
}
#line 315 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 21: *X = Sentences__VPs__nss_tree2(NEW_VERB_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 22: *X = Sentences__VPs__nss_tree1(NEW_ADJ_VB, nonstructural_sentence_NTM->range_result[1], RP[2]);
{
#line 400 "inform7/Chapter 13/Verb Phrases.w"
natural_language *nl = (natural_language *) (RP[1]);
ParseTree__set_defn_language(nss_tree_head->down, nl);
}
#line 317 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 23: *X = Sentences__VPs__nss_tree2(NEW_ADJ_VB, nonstructural_sentence_NTM->range_result[1], RP[2], RP[3]);
{
#line 400 "inform7/Chapter 13/Verb Phrases.w"
natural_language *nl = (natural_language *) (RP[1]);
ParseTree__set_defn_language(nss_tree_head->down, nl);
}
#line 318 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 24: *X = Sentences__VPs__nss_tree2(CANBE_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 25: *X = Sentences__VPs__nss_tree2(CANBE_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 26: *X = Sentences__VPs__nss_tree2(IN_RULEBOOK_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 27: *X = Sentences__VPs__nss_tree2(NOT_IN_RULEBOOK_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 28: *X = Sentences__VPs__nss_tree1(NO_EFFECT_AT_ALL_VB, nonstructural_sentence_NTM->range_result[1], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 29: *X = Sentences__VPs__nss_tree2(NO_EFFECT_IF_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 30: *X = Sentences__VPs__nss_tree2(NO_EFFECT_UNLESS_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 31: *X = Sentences__VPs__nss_tree2(SUBSTITUTES_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 32: *X = Sentences__VPs__nss_tree3(SUBSTITUTES_IF_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2], RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 33: *X = Sentences__VPs__nss_tree3(SUBSTITUTES_UNLESS_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2], RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 34: *X = Sentences__VPs__nss_tree3(NEW_RELATION_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2], RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 35:
{
#line 344 "inform7/Chapter 13/Verb Phrases.w"
*X = BAD_NONVERB;
Problems__Issue__sentence_problem(_p_(PM_CanHave),
"'can have' is not a form allowed by Inform",
"though it looks as if it might be. If you want to set up a property "
"with a limited number of options, you can say 'A room can be "
"spacious, cramped or adequate.', for instance; if you want a "
"property with a value, 'A room has a number called the secret "
"code number.'. So 'can be' and 'has' are fine, but not 'can have'.");
}
#line 330 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 36: *X = 0; INHERIT_RANGES(existential_sentence_NTM, regular_sentence_NTM);
{
#line 365 "inform7/Chapter 13/Verb Phrases.w"
wording SW = GET_RW(regular_sentence_NTM, 1);
wording VW = GET_RW(regular_sentence_NTM, 2);
wording OW = GET_RW(regular_sentence_NTM, 3);
int save = assertion_NP_is_in_VP_for_to_be;
assertion_NP_is_in_VP_for_to_be = FALSE;
if (bp_parsed == R_equality) assertion_NP_is_in_VP_for_to_be = TRUE;
parse_node *VP_PN = ParseTree__new(AVERB_NT);
ParseTree__set_text(VP_PN, VW);
if (certainty_parsed != UNKNOWN_CE)
ParseTree__annotate_int(VP_PN, verbal_certainty_ANNOT, certainty_parsed);
int t = R[1], altered = FALSE;
if (t < 0) { t = -t; altered = TRUE; }
ParseTree__annotate_int(VP_PN, verb_id_ANNOT, t);
ParseTree__graft(VP_PN, nss_tree_head);
parse_node *np1 = NULL;
if (Preform__parse_nt_against_word_range(nounphrase_as_subject_NTM, SW, NULL, NULL) == FALSE) return FALSE; /* shouldn't ever happen */
np1 = most_recent_result_p;
ParseTree__graft(np1, nss_tree_head);
parse_node *np2 = NULL;
if (Preform__parse_nt_against_word_range(nounphrase_as_object_NTM, OW, NULL, NULL) == FALSE) return FALSE; /* shouldn't ever happen */
np2 = most_recent_result_p;
ParseTree__graft(np2, nss_tree_head);
assertion_NP_is_in_VP_for_to_be = save;
{
#line 424 "inform7/Chapter 13/Verb Phrases.w"
if ((t == ASSERT_VB) && ((altered == FALSE) || (bp_parsed != R_equality))) {
parse_node *REL_PN = ParseTree__new(RELATIONSHIP_NT);
ParseTree__set_text(REL_PN, VW);
ParseTree__set_relationship(REL_PN, BinaryPredicates__get_reversal(bp_parsed));
np1->next = REL_PN; REL_PN->down = np2;
}
}
#line 394 "inform7/Chapter 13/Verb Phrases.w"
;
*X = 0;
}
#line 331 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 37:
{
#line 365 "inform7/Chapter 13/Verb Phrases.w"
wording SW = GET_RW(regular_sentence_NTM, 1);
wording VW = GET_RW(regular_sentence_NTM, 2);
wording OW = GET_RW(regular_sentence_NTM, 3);
int save = assertion_NP_is_in_VP_for_to_be;
assertion_NP_is_in_VP_for_to_be = FALSE;
if (bp_parsed == R_equality) assertion_NP_is_in_VP_for_to_be = TRUE;
parse_node *VP_PN = ParseTree__new(AVERB_NT);
ParseTree__set_text(VP_PN, VW);
if (certainty_parsed != UNKNOWN_CE)
ParseTree__annotate_int(VP_PN, verbal_certainty_ANNOT, certainty_parsed);
int t = R[1], altered = FALSE;
if (t < 0) { t = -t; altered = TRUE; }
ParseTree__annotate_int(VP_PN, verb_id_ANNOT, t);
ParseTree__graft(VP_PN, nss_tree_head);
parse_node *np1 = NULL;
if (Preform__parse_nt_against_word_range(nounphrase_as_subject_NTM, SW, NULL, NULL) == FALSE) return FALSE; /* shouldn't ever happen */
np1 = most_recent_result_p;
ParseTree__graft(np1, nss_tree_head);
parse_node *np2 = NULL;
if (Preform__parse_nt_against_word_range(nounphrase_as_object_NTM, OW, NULL, NULL) == FALSE) return FALSE; /* shouldn't ever happen */
np2 = most_recent_result_p;
ParseTree__graft(np2, nss_tree_head);
assertion_NP_is_in_VP_for_to_be = save;
{
#line 424 "inform7/Chapter 13/Verb Phrases.w"
if ((t == ASSERT_VB) && ((altered == FALSE) || (bp_parsed != R_equality))) {
parse_node *REL_PN = ParseTree__new(RELATIONSHIP_NT);
ParseTree__set_text(REL_PN, VW);
ParseTree__set_relationship(REL_PN, BinaryPredicates__get_reversal(bp_parsed));
np1->next = REL_PN; REL_PN->down = np2;
}
}
#line 394 "inform7/Chapter 13/Verb Phrases.w"
;
*X = 0;
}
#line 332 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 38: *X = Sentences__VPs__nss_tree2(USEMEANS_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 39: *X = Sentences__VPs__nss_tree1(USE_VB, nonstructural_sentence_NTM->range_result[1], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 40: *X = Sentences__VPs__nss_tree1(RELEASE_VB, nonstructural_sentence_NTM->range_result[1], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 41: *X = Sentences__VPs__nss_tree1(MAP_PARAMETER_VB, nonstructural_sentence_NTM->range_result[1], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 42: *X = Sentences__VPs__nss_tree1(DEBUG_VB, nonstructural_sentence_NTM->range_result[1], RP[1]); ParseTree__annotate_int(nss_tree_head->down, log_inclusion_sense_ANNOT, TRUE);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 43: *X = Sentences__VPs__nss_tree1(DEBUG_VB, nonstructural_sentence_NTM->range_result[1], RP[1]); ParseTree__annotate_int(nss_tree_head->down, log_inclusion_sense_ANNOT, FALSE);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 44: *X = Sentences__VPs__nss_tree2(DOC_VB, nonstructural_sentence_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 340 "inform7/Chapter 13/Verb Phrases.w"
#line 443 "inform7/Chapter 13/Verb Phrases.w"
int Sentences__VPs__nss_tree1(int t, wording VW, parse_node *np1) {
parse_node *VP_PN = ParseTree__new(AVERB_NT);
ParseTree__set_text(VP_PN, VW);
ParseTree__annotate_int(VP_PN, verb_id_ANNOT, t);
ParseTree__graft(VP_PN, nss_tree_head);
ParseTree__graft(np1, nss_tree_head);
return 0;
}
int Sentences__VPs__nss_tree2(int t, wording VW, parse_node *np1, parse_node *np2) {
parse_node *VP_PN = ParseTree__new(AVERB_NT);
ParseTree__set_text(VP_PN, VW);
ParseTree__annotate_int(VP_PN, verb_id_ANNOT, t);
ParseTree__graft(VP_PN, nss_tree_head);
ParseTree__graft(np1, nss_tree_head);
ParseTree__graft(np2, nss_tree_head);
return 0;
}
int Sentences__VPs__nss_tree3(int t, wording VW, parse_node *np1, parse_node *np2, parse_node *np3) {
parse_node *VP_PN = ParseTree__new(AVERB_NT);
ParseTree__set_text(VP_PN, VW);
ParseTree__annotate_int(VP_PN, verb_id_ANNOT, t);
ParseTree__graft(VP_PN, nss_tree_head);
ParseTree__graft(np1, nss_tree_head);
ParseTree__graft(np2, nss_tree_head);
ParseTree__graft(np3, nss_tree_head);
return 0;
}
#line 492 "inform7/Chapter 13/Verb Phrases.w"
int nounphrase_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = GENERATE_RAW_NP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 494 "inform7/Chapter 13/Verb Phrases.w"
int nounphrase_definite_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 498 "inform7/Chapter 13/Verb Phrases.w"
int nounphrase_figure_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = GENERATE_RAW_NP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 501 "inform7/Chapter 13/Verb Phrases.w"
int nounphrase_sound_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = GENERATE_RAW_NP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 504 "inform7/Chapter 13/Verb Phrases.w"
int nounphrase_external_file_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = GENERATE_RAW_NP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 507 "inform7/Chapter 13/Verb Phrases.w"
int nounphrase_actionable_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = GENERATE_RAW_NP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 510 "inform7/Chapter 13/Verb Phrases.w"
int variable_creation_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 514 "inform7/Chapter 13/Verb Phrases.w"
#line 518 "inform7/Chapter 13/Verb Phrases.w"
int translation_target_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRANSLATESU_VB; *XP = NULL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRANSLATES_VB; *XP = NULL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRANSLATES_VB; *XP = NULL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = TRANSLATESL_VB; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 523 "inform7/Chapter 13/Verb Phrases.w"
#line 545 "inform7/Chapter 13/Verb Phrases.w"
int existential_sentence_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = -ASSERT_VB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE; existent = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[2]; INHERIT_RANGES(existential_sentence_inner_NTM, existential_sentence_NTM); existent = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 649 "inform7/Chapter 13/Verb Phrases.w"
*X = BAD_NONVERB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
Problems__Issue__sentence_problem(_p_(PM_TwoLikelihoods),
"this sentence seems to have a likelihood qualification on both "
"sides of the verb",
"which is not allowed. 'The black door certainly is usually open' "
"might possibly be grammatical English in some idioms, but Inform "
"doesn't like a sentence in this shape because the 'certainly' "
"on one side of the verb and the 'usually' on the other are "
"rival indications of certainty.");
}
#line 548 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = ASSERT_VB; bp_parsed = Prepositions__get_meaning(RP[3]); certainty_parsed = R[2]; existent = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = ASSERT_VB; bp_parsed = Prepositions__get_meaning(RP[2]); certainty_parsed = R[3]; existent = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = ASSERT_VB; bp_parsed = Prepositions__get_meaning(RP[2]); certainty_parsed = UNKNOWN_CE; existent = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = -ASSERT_VB; bp_parsed = R_equality; certainty_parsed = R[2]; existent = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = -ASSERT_VB; bp_parsed = R_equality; certainty_parsed = R[2]; existent = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = -ASSERT_VB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE; existent = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 555 "inform7/Chapter 13/Verb Phrases.w"
#line 569 "inform7/Chapter 13/Verb Phrases.w"
int existential_sentence_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 592 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail1_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail1_inner_NTM, 2);
PUT_RW(existential_sentence_inner_NTM, 2, BW);
PUT_RW(existential_sentence_inner_NTM, 3, CW);
}
#line 570 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 601 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail2_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail2_inner_NTM, 2);
PUT_RW(existential_sentence_inner_NTM, 2, BW);
PUT_RW(existential_sentence_inner_NTM, 3, CW);
}
#line 571 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 610 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail3_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail3_inner_NTM, 2);
PUT_RW(existential_sentence_inner_NTM, 2, BW);
PUT_RW(existential_sentence_inner_NTM, 3, CW);
}
#line 572 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 592 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail1_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail1_inner_NTM, 2);
PUT_RW(existential_sentence_inner_NTM, 2, BW);
PUT_RW(existential_sentence_inner_NTM, 3, CW);
}
#line 573 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 601 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail2_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail2_inner_NTM, 2);
PUT_RW(existential_sentence_inner_NTM, 2, BW);
PUT_RW(existential_sentence_inner_NTM, 3, CW);
}
#line 574 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 610 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail3_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail3_inner_NTM, 2);
PUT_RW(existential_sentence_inner_NTM, 2, BW);
PUT_RW(existential_sentence_inner_NTM, 3, CW);
}
#line 575 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 576 "inform7/Chapter 13/Verb Phrases.w"
int existential_sentence_inner_tail1_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(existential_sentence_inner_tail1_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 580 "inform7/Chapter 13/Verb Phrases.w"
int existential_sentence_inner_tail2_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(existential_sentence_inner_tail2_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 584 "inform7/Chapter 13/Verb Phrases.w"
int existential_sentence_inner_tail3_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(existential_sentence_inner_tail3_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 588 "inform7/Chapter 13/Verb Phrases.w"
#line 639 "inform7/Chapter 13/Verb Phrases.w"
int certainty_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = CERTAIN_CE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = LIKELY_CE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = UNLIKELY_CE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = IMPOSSIBLE_CE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = INITIALLY_CE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 645 "inform7/Chapter 13/Verb Phrases.w"
#line 697 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 804 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail1_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail1_inner_NTM, 2);
PUT_RW(regular_sentence_NTM, 2, BW);
PUT_RW(regular_sentence_NTM, 3, CW);
}
#line 698 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 813 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail2_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail2_inner_NTM, 2);
PUT_RW(regular_sentence_NTM, 2, BW);
PUT_RW(regular_sentence_NTM, 3, CW);
}
#line 699 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 822 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail3_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail3_inner_NTM, 2);
PUT_RW(regular_sentence_NTM, 2, BW);
PUT_RW(regular_sentence_NTM, 3, CW);
}
#line 700 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 831 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail4_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail4_inner_NTM, 2);
PUT_RW(regular_sentence_NTM, 2, BW);
PUT_RW(regular_sentence_NTM, 3, CW);
}
#line 701 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 804 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail1_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail1_inner_NTM, 2);
PUT_RW(regular_sentence_NTM, 2, BW);
PUT_RW(regular_sentence_NTM, 3, CW);
}
#line 702 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 813 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail2_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail2_inner_NTM, 2);
PUT_RW(regular_sentence_NTM, 2, BW);
PUT_RW(regular_sentence_NTM, 3, CW);
}
#line 703 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 822 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail3_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail3_inner_NTM, 2);
PUT_RW(regular_sentence_NTM, 2, BW);
PUT_RW(regular_sentence_NTM, 3, CW);
}
#line 704 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7:
{
#line 831 "inform7/Chapter 13/Verb Phrases.w"
*X = R[1];
wording BW = GET_RW(regular_sentence_tail4_inner_NTM, 1);
wording CW = GET_RW(regular_sentence_tail4_inner_NTM, 2);
PUT_RW(regular_sentence_NTM, 2, BW);
PUT_RW(regular_sentence_NTM, 3, CW);
}
#line 705 "inform7/Chapter 13/Verb Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 706 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail1_without_rc_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail1_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail1_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail1_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 712 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail2_without_rc_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail2_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail2_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail2_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 718 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail3_without_rc_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail3_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail3_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail3_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 724 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail4_without_rc_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail4_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail4_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail4_without_rc_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 730 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail1_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail1_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 734 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail2_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail2_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 738 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail3_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail3_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 742 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail4_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(regular_sentence_tail4_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 746 "inform7/Chapter 13/Verb Phrases.w"
#line 777 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail1_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 649 "inform7/Chapter 13/Verb Phrases.w"
*X = BAD_NONVERB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
Problems__Issue__sentence_problem(_p_(PM_TwoLikelihoods),
"this sentence seems to have a likelihood qualification on both "
"sides of the verb",
"which is not allowed. 'The black door certainly is usually open' "
"might possibly be grammatical English in some idioms, but Inform "
"doesn't like a sentence in this shape because the 'certainly' "
"on one side of the verb and the 'usually' on the other are "
"rival indications of certainty.");
}
#line 778 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = HAS_VB; bp_parsed = a_has_b_predicate; certainty_parsed = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = HAS_VB; bp_parsed = a_has_b_predicate; certainty_parsed = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = HAS_VB; bp_parsed = a_has_b_predicate; certainty_parsed = UNKNOWN_CE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 782 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail2_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 649 "inform7/Chapter 13/Verb Phrases.w"
*X = BAD_NONVERB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
Problems__Issue__sentence_problem(_p_(PM_TwoLikelihoods),
"this sentence seems to have a likelihood qualification on both "
"sides of the verb",
"which is not allowed. 'The black door certainly is usually open' "
"might possibly be grammatical English in some idioms, but Inform "
"doesn't like a sentence in this shape because the 'certainly' "
"on one side of the verb and the 'usually' on the other are "
"rival indications of certainty.");
}
#line 784 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = -ASSERT_VB; bp_parsed = R_equality; certainty_parsed = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = -ASSERT_VB; bp_parsed = R_equality; certainty_parsed = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = -ASSERT_VB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 788 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail3_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 649 "inform7/Chapter 13/Verb Phrases.w"
*X = BAD_NONVERB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
Problems__Issue__sentence_problem(_p_(PM_TwoLikelihoods),
"this sentence seems to have a likelihood qualification on both "
"sides of the verb",
"which is not allowed. 'The black door certainly is usually open' "
"might possibly be grammatical English in some idioms, but Inform "
"doesn't like a sentence in this shape because the 'certainly' "
"on one side of the verb and the 'usually' on the other are "
"rival indications of certainty.");
}
#line 790 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = -ASSERT_VB; bp_parsed = Verbs__get_meaning(RP[1]); certainty_parsed = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = -ASSERT_VB; bp_parsed = Verbs__get_meaning(RP[2]); certainty_parsed = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = -ASSERT_VB; bp_parsed = Verbs__get_meaning(RP[1]); certainty_parsed = UNKNOWN_CE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 794 "inform7/Chapter 13/Verb Phrases.w"
int regular_sentence_tail4_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 649 "inform7/Chapter 13/Verb Phrases.w"
*X = BAD_NONVERB; bp_parsed = R_equality; certainty_parsed = UNKNOWN_CE;
Problems__Issue__sentence_problem(_p_(PM_TwoLikelihoods),
"this sentence seems to have a likelihood qualification on both "
"sides of the verb",
"which is not allowed. 'The black door certainly is usually open' "
"might possibly be grammatical English in some idioms, but Inform "
"doesn't like a sentence in this shape because the 'certainly' "
"on one side of the verb and the 'usually' on the other are "
"rival indications of certainty.");
}
#line 796 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = -ASSERT_VB; bp_parsed = Verbs__get_meaning(RP[1]); certainty_parsed = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = -ASSERT_VB; bp_parsed = Verbs__get_meaning(RP[2]); certainty_parsed = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = -ASSERT_VB; bp_parsed = Verbs__get_meaning(RP[1]); certainty_parsed = UNKNOWN_CE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 800 "inform7/Chapter 13/Verb Phrases.w"
#line 842 "inform7/Chapter 13/Verb Phrases.w"
int bad_nonstructural_sentence_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 844 "inform7/Chapter 13/Verb Phrases.w"
int bad_nonstructural_sentence_diagnosis_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(bad_nonstructural_sentence_diagnosis_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(bad_nonstructural_sentence_diagnosis_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 854 "inform7/Chapter 13/Verb Phrases.w"
if (ParseTree__int_annotation(current_sentence, verb_problem_issued_ANNOT) == FALSE) {
ParseTree__annotate_int(current_sentence, verb_problem_issued_ANNOT, TRUE);
Problems__Issue__sentence_problem(_p_(PM_NonPresentTense),
"assertions about the initial state of play must be given in the "
"present tense",
"so 'The cat is in the basket' is fine but not 'The cat has been in "
"the basket'. Time is presumed to start only when the game begins, so "
"there is no anterior state which we can speak of.");
}
}
#line 848 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 867 "inform7/Chapter 13/Verb Phrases.w"
if (ParseTree__int_annotation(current_sentence, verb_problem_issued_ANNOT) == FALSE) {
ParseTree__annotate_int(current_sentence, verb_problem_issued_ANNOT, TRUE);
Problems__Issue__negative_sentence_problem(_p_(PM_NegatedVerb1));
}
}
#line 849 "inform7/Chapter 13/Verb Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 850 "inform7/Chapter 13/Verb Phrases.w"
#line 875 "inform7/Chapter 13/Verb Phrases.w"
void Sentences__VPs__log(int verb_number) {
switch(verb_number) {
case ASSERT_VB: LOG("ASSERT_VB"); break;
case BEGINS_WHEN_VB: LOG("BEGINS_WHEN_VB"); break;
case CANBE_VB: LOG("CANBE_VB"); break;
case DEBUG_VB: LOG("DEBUG_VB"); break;
case DEFINED_BY_VB: LOG("DEFINED_BY_VB"); break;
case DOC_VB: LOG("DOC_VB"); break;
case ENDS_WHEN_VB: LOG("ENDS_WHEN_VB"); break;
case EPISODE_VB: LOG("EPISODE_VB"); break;
case FIGURE_VB: LOG("FIGURE_VB"); break;
case FILE_VB: LOG("FILE_VB"); break;
case HAS_VB: LOG("HAS_VB"); break;
case IN_RULEBOOK_VB: LOG("IN_RULEBOOK_VB"); break;
case MAP_PARAMETER_VB: LOG("MAP_PARAMETER_VB"); break;
case NEW_ACTION_VB: LOG("NEW_ACTION_VB"); break;
case NEW_ACTIVITY_VB: LOG("NEW_ACTIVITY_VB"); break;
case NEW_RELATION_VB: LOG("NEW_RELATION_VB"); break;
case NEW_ADJ_VB: LOG("NEW_ADJ_VB"); break;
case NEW_MEANINGLESS_VERB_VB: LOG("NEW_MEANINGLESS_VERB_VB"); break;
case NEW_VERB_VB: LOG("NEW_VERB_VB"); break;
case NO_EFFECT_AT_ALL_VB: LOG("NO_EFFECT_AT_ALL_VB"); break;
case NO_EFFECT_IF_VB: LOG("NO_EFFECT_IF_VB"); break;
case NO_EFFECT_UNLESS_VB: LOG("NO_EFFECT_UNLESS_VB"); break;
case NOT_IN_RULEBOOK_VB: LOG("NOT_IN_RULEBOOK_VB"); break;
case PLURAL_VB: LOG("PLURAL_VB"); break;
case RELEASE_VB: LOG("RELEASE_VB"); break;
case SOUND_VB: LOG("SOUND_VB"); break;
case SPECIFIES_VB: LOG("SPECIFIES_VB"); break;
case SUBSTITUTES_IF_VB: LOG("SUBSTITUTES_IF_VB"); break;
case SUBSTITUTES_UNLESS_VB: LOG("SUBSTITUTES_UNLESS_VB"); break;
case SUBSTITUTES_VB: LOG("SUBSTITUTES_VB"); break;
case TEST_VB: LOG("TEST_VB"); break;
case TRANSLATESU_VB: LOG("TRANSLATESU_VB"); break;
case TRANSLATESL_VB: LOG("TRANSLATESL_VB"); break;
case UNDERSTAND_VB: LOG("UNDERSTAND_VB"); break;
case USE_VB: LOG("USE_VB"); break;
case USEMEANS_VB: LOG("USEMEANS_VB"); break;
default: LOG("(number %d)", verb_number); break;
}
}
#line 41 "inform7/Chapter 13/Noun Phrases.w"
parse_node *Sentences__NPs__new_raw(wording W) {
parse_node *PN = ParseTree__new(PROPER_NOUN_NT);
ParseTree__annotate_int(PN, nounphrase_article_ANNOT, NO_ART);
ParseTree__set_text(PN, W);
return PN;
}
parse_node *Sentences__NPs__new_raw_empty(void) {
parse_node *PN;
PN = ParseTree__new(PROPER_NOUN_NT);
ParseTree__annotate_int(PN, nounphrase_article_ANNOT, NO_ART);
return PN;
}
#line 74 "inform7/Chapter 13/Noun Phrases.w"
int nounphrase_articled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = NULL; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[3];
{
#line 83 "inform7/Chapter 13/Noun Phrases.w"
ParseTree__annotate_int(*XP, nounphrase_article_ANNOT, INDEF_ART);
ParseTree__annotate_int(*XP, plural_reference_ANNOT, (R[2] >= 3)?TRUE:FALSE);
ParseTree__annotate_int(*XP, gender_reference_ANNOT, (R[2] % 3) + 1);
}
#line 76 "inform7/Chapter 13/Noun Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[3];
{
#line 90 "inform7/Chapter 13/Noun Phrases.w"
ParseTree__annotate_int(*XP, nounphrase_article_ANNOT, DEF_ART);
ParseTree__annotate_int(*XP, plural_reference_ANNOT, (R[2] >= 3)?TRUE:FALSE);
ParseTree__annotate_int(*XP, gender_reference_ANNOT, (R[2] % 3) + 1);
}
#line 77 "inform7/Chapter 13/Noun Phrases.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 79 "inform7/Chapter 13/Noun Phrases.w"
#line 98 "inform7/Chapter 13/Noun Phrases.w"
int np_balanced_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 101 "inform7/Chapter 13/Noun Phrases.w"
int np_articled_balanced_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 105 "inform7/Chapter 13/Noun Phrases.w"
#line 117 "inform7/Chapter 13/Noun Phrases.w"
parse_node *Sentences__NPs__annotate_by_articles(parse_node *RAW_NP) {
Preform__parse_nt_against_word_range(nounphrase_articled_NTM, ParseTree__get_text(RAW_NP), NULL, NULL);
parse_node *MODEL = most_recent_result_p;
ParseTree__set_text(RAW_NP, ParseTree__get_text(MODEL));
ParseTree__annotate_int(RAW_NP, nounphrase_article_ANNOT,
ParseTree__int_annotation(MODEL, nounphrase_article_ANNOT));
ParseTree__annotate_int(RAW_NP, plural_reference_ANNOT,
ParseTree__int_annotation(MODEL, plural_reference_ANNOT));
return RAW_NP;
}
#line 135 "inform7/Chapter 13/Noun Phrases.w"
int nounphrase_articled_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = NULL; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = Sentences__NPs__PN_pair(AND_NT, Wordings__one_word(R[2]), RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 139 "inform7/Chapter 13/Noun Phrases.w"
int np_articled_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = Wordings__first_wn(W); *XP= RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = Wordings__first_wn(W); *XP= RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 143 "inform7/Chapter 13/Noun Phrases.w"
#line 164 "inform7/Chapter 13/Noun Phrases.w"
int nounphrase_rule_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = NULL; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = Sentences__NPs__PN_pair(AND_NT, Wordings__one_word(R[2]), RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 168 "inform7/Chapter 13/Noun Phrases.w"
int np_rule_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = Wordings__first_wn(W); *XP= RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = Wordings__first_wn(W); *XP= RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 172 "inform7/Chapter 13/Noun Phrases.w"
int nounphrase_rule_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = Sentences__NPs__new_raw(W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 175 "inform7/Chapter 13/Noun Phrases.w"
#line 183 "inform7/Chapter 13/Noun Phrases.w"
int nounphrase_alternative_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = NULL; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = Sentences__NPs__PN_pair(AND_NT, Wordings__one_word(R[2]), RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 187 "inform7/Chapter 13/Noun Phrases.w"
int np_alternative_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = Wordings__first_wn(W); *XP= RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = Wordings__first_wn(W); *XP= RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 191 "inform7/Chapter 13/Noun Phrases.w"
#line 207 "inform7/Chapter 13/Noun Phrases.w"
int nounphrase_as_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 210 "inform7/Chapter 13/Noun Phrases.w"
int nounphrase_as_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[3];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 215 "inform7/Chapter 13/Noun Phrases.w"
int np_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[3];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 219 "inform7/Chapter 13/Noun Phrases.w"
#line 224 "inform7/Chapter 13/Noun Phrases.w"
int if_copular_NTMR(wording W, int *X, void **XP) {
#line 225 "inform7/Chapter 13/Noun Phrases.w"
return assertion_NP_is_in_VP_for_to_be;
}
#line 263 "inform7/Chapter 13/Noun Phrases.w"
int np_relative_phrase_limited_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 268 "inform7/Chapter 13/Noun Phrases.w"
int np_relative_phrase_unlimited_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 273 "inform7/Chapter 13/Noun Phrases.w"
#line 283 "inform7/Chapter 13/Noun Phrases.w"
int np_relative_phrase_exception_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 285 "inform7/Chapter 13/Noun Phrases.w"
#line 302 "inform7/Chapter 13/Noun Phrases.w"
int np_relative_phrase_implicit_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = Sentences__NPs__PN_rel(W, R_wearing, -1, NULL); /* player\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = Sentences__NPs__PN_rel(W, R_carrying, -1, NULL); /* player\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = Sentences__NPs__PN_rel(W, R_carrying, -1, NULL); /* player\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; *XP = Sentences__NPs__PN_rel(W, NULL, PARENTAGE_HERE_RELN, NULL); /* spatial\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 307 "inform7/Chapter 13/Noun Phrases.w"
int np_relative_phrase_explicit_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = Sentences__NPs__PN_rel(W, BinaryPredicates__get_reversal(Prepositions__get_meaning(RP[1])), -1, RP[2]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 312 "inform7/Chapter 13/Noun Phrases.w"
#line 387 "inform7/Chapter 13/Noun Phrases.w"
int np_inner_without_rp_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = NULL; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = Sentences__NPs__PN_pair(CALLED_NT, np_inner_without_rp_NTM->range_result[1], RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = Sentences__NPs__PN_pair(WITH_NT, Wordings__one_word(R[2]), RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; *XP = Sentences__NPs__PN_pair(AND_NT, Wordings__one_word(R[2]), RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = 0; *XP = Sentences__NPs__PN_pair((R[2]==0)?X_OF_Y_NT:FROM_NT, W, RP[2], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = 0; *XP = Sentences__NPs__new_raw(W); ParseTree__annotate_int(*XP, nounphrase_article_ANNOT, IT_ART);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 396 "inform7/Chapter 13/Noun Phrases.w"
#line 413 "inform7/Chapter 13/Noun Phrases.w"
int np_with_or_having_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(np_with_or_having_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(np_with_or_having_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(np_with_or_having_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = Wordings__first_wn(np_with_or_having_tail_NTM->range_result[1]); *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 418 "inform7/Chapter 13/Noun Phrases.w"
int np_new_property_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = NULL; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = Sentences__NPs__PN_pair(AND_NT, Wordings__one_word(R[2]), RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 423 "inform7/Chapter 13/Noun Phrases.w"
int np_new_property_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = Sentences__NPs__PN_void(PROPERTY_LIST_NT, W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 426 "inform7/Chapter 13/Noun Phrases.w"
int np_new_property_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = Wordings__first_wn(W); *XP= RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = Wordings__first_wn(W); *XP= RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 430 "inform7/Chapter 13/Noun Phrases.w"
int np_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = Wordings__first_wn(W); *XP= RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = Wordings__first_wn(W); *XP= RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 434 "inform7/Chapter 13/Noun Phrases.w"
#line 443 "inform7/Chapter 13/Noun Phrases.w"
int np_kind_phrase_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 446 "inform7/Chapter 13/Noun Phrases.w"
int np_kind_phrase_unarticled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = Sentences__NPs__PN_void(KIND_NT, W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = Sentences__NPs__PN_single(KIND_NT, W, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 450 "inform7/Chapter 13/Noun Phrases.w"
#line 460 "inform7/Chapter 13/Noun Phrases.w"
int np_from_or_of_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(np_from_or_of_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(np_from_or_of_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(np_from_or_of_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; return FAIL_NONTERMINAL + Wordings__first_wn(np_from_or_of_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = 1; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 467 "inform7/Chapter 13/Noun Phrases.w"
#line 473 "inform7/Chapter 13/Noun Phrases.w"
parse_node *Sentences__NPs__PN_void(node_type_t t, wording W) {
if (preform_lookahead_mode) return NULL;
parse_node *P = ParseTree__new(t);
ParseTree__set_text(P, W);
return P;
}
parse_node *Sentences__NPs__PN_single(node_type_t t, wording W, parse_node *A) {
if (preform_lookahead_mode) return NULL;
parse_node *P = ParseTree__new(t);
ParseTree__set_text(P, W);
P->down = A;
return P;
}
parse_node *Sentences__NPs__PN_pair(node_type_t t, wording W, parse_node *A, parse_node *B) {
if (preform_lookahead_mode) return NULL;
parse_node *P = ParseTree__new(t);
ParseTree__set_text(P, W);
P->down = A; P->down->next = B;
return P;
}
#line 504 "inform7/Chapter 13/Noun Phrases.w"
parse_node *Sentences__NPs__PN_rel(wording W, binary_predicate *R, int reln_type, parse_node *referent) {
if (preform_lookahead_mode) return NULL;
parse_node *P = ParseTree__new(RELATIONSHIP_NT);
ParseTree__set_text(P, W);
if (R) ParseTree__set_relationship(P, R);
else if (reln_type >= 0)
ParseTree__annotate_int(P, relationship_node_type_ANNOT, reln_type);
else internal_error("undefined relationship node");
if (referent == NULL) {
referent = Sentences__NPs__new_raw(W);
ParseTree__annotate_int(referent, implicitly_refers_to_ANNOT, TRUE);
}
P->down = referent;
return P;
}
#line 531 "inform7/Chapter 13/Noun Phrases.w"
int Sentences__NPs__turn_player_to_yourself(parse_node *pn) {
if ((Wordings__nonempty(ParseTree__get_text(pn))) &&
(ParseTree__get_type(pn) == PROPER_NOUN_NT) &&
(ParseTree__int_annotation(pn, turned_already_ANNOT) == FALSE)) {
nonlocal_variable *q = NonlocalVariables__parse(ParseTree__get_text(pn));
inference_subject *diversion = NonlocalVariables__get_alias(q);
if (diversion) {
Assertions__Refiner__noun_from_infs(pn, diversion);
ParseTree__annotate_int(pn, turned_already_ANNOT, TRUE);
return TRUE;
}
}
return FALSE;
}
#line 62 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__expunge_X_OF_Y_subtree(parse_node *pn) {
ParseTree__set_type_and_clear_annotations(pn, PROPER_NOUN_NT);
pn->down = NULL;
Sentences__NPs__annotate_by_articles(pn);
}
void Sentences__Rearrangement__expunge_FROM_subtree(parse_node *pn) {
ParseTree__set_type_and_clear_annotations(pn, PROPER_NOUN_NT);
pn->down = NULL;
Sentences__NPs__annotate_by_articles(pn);
}
#line 85 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__convert_clause_to_RELATIONSHIP(parse_node *pn) {
ParseTree__set_type(pn, RELATIONSHIP_NT);
ParseTree__annotate_int(pn, relationship_node_type_ANNOT, DIRECTION_RELN);
}
#line 114 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__tidy_up_ofs_and_froms(void) {
ParseTree__verify_integrity(tree_root, FALSE);
ParseTree__traverse_wfirst(Sentences__Rearrangement__traverse_for_property_names);
ParseTree__traverse(Sentences__Rearrangement__traverse_for_nonbreaking_ofs);
ParseTree__traverse_dfirst(Sentences__Rearrangement__traverse_for_FROM_NT_subtrees);
}
#line 127 "inform7/Chapter 13/Of and From.w"
parse_node *directions_noticed[MAX_DIRECTIONS];
binary_predicate *direction_relations_noticed[MAX_DIRECTIONS];
int no_directions_noticed = 0;
#line 140 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__traverse_for_property_names(parse_node *pn) {
if (ParseTree__get_type(pn) == AVERB_NT)
{
#line 194 "inform7/Chapter 13/Of and From.w"
if ((ParseTree__int_annotation(pn, verb_id_ANNOT) == HAS_VB)
&& (pn->next)
&& (pn->next->next)
&& (ParseTree__get_type(pn->next->next) == CALLED_NT)
&& (pn->next->next->down)
&& (pn->next->next->down->next)) {
parse_node *apparent_subject = pn->next;
wording SW = ParseTree__get_text(apparent_subject);
if (ParseTree__get_type(apparent_subject) == WITH_NT)
if (apparent_subject->down) {
int s1 = Wordings__first_wn(ParseTree__get_text(apparent_subject->down));
if (apparent_subject->down->next)
SW = Wordings__new(s1, Wordings__last_wn(ParseTree__get_text(apparent_subject->down->next)));
else
SW = Wordings__new(s1, Wordings__last_wn(SW));
}
if (Preform__parse_nt_against_word_range(prohibited_property_owners_NTM, SW, NULL, NULL) == FALSE) {
Preform__parse_nt_against_word_range(has_properties_called_sentence_object_NTM, ParseTree__get_text(pn->next->next->down->next), NULL, NULL);
}
}
}
#line 142 "inform7/Chapter 13/Of and From.w"
;
}
#line 148 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__check_sentence_for_direction_creation(parse_node *pn) {
if (ParseTree__get_type(pn) != SENTENCE_NT) return;
if ((pn->down == NULL) || (pn->down->next == NULL) || (pn->down->next->next == NULL)) return;
if (ParseTree__get_type(pn->down) != AVERB_NT) return;
if (ParseTree__get_type(pn->down->next) != PROPER_NOUN_NT) return;
if (ParseTree__get_type(pn->down->next->next) != PROPER_NOUN_NT) return;
current_sentence = pn;
pn = pn->down->next;
if (!((Preform__parse_nt_against_word_range(notable_map_kinds_NTM, ParseTree__get_text(pn->next), NULL, NULL))
&& (most_recent_result == 0))) return;
if (no_directions_noticed >= MAX_DIRECTIONS) {
Problems__Issue__limit_problem(_p_(PM_TooManyDirections),
"different directions", MAX_DIRECTIONS);
return;
}
direction_relations_noticed[no_directions_noticed] =
PL__MapDirections__create_sketchy_mapping_direction(ParseTree__get_text(pn));
directions_noticed[no_directions_noticed++] = pn;
}
#line 171 "inform7/Chapter 13/Of and From.w"
binary_predicate *Sentences__Rearrangement__relation_noticed(int i) {
return direction_relations_noticed[i];
}
#line 225 "inform7/Chapter 13/Of and From.w"
int prohibited_property_owners_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 229 "inform7/Chapter 13/Of and From.w"
#line 235 "inform7/Chapter 13/Of and From.w"
int action_name_formal_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 237 "inform7/Chapter 13/Of and From.w"
int activity_name_formal_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 240 "inform7/Chapter 13/Of and From.w"
int relation_name_formal_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 243 "inform7/Chapter 13/Of and From.w"
int rule_name_formal_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 246 "inform7/Chapter 13/Of and From.w"
int rulebook_name_formal_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 249 "inform7/Chapter 13/Of and From.w"
#line 260 "inform7/Chapter 13/Of and From.w"
int has_properties_called_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 263 "inform7/Chapter 13/Of and From.w"
int has_property_name_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 267 "inform7/Chapter 13/Of and From.w"
int has_property_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; Properties__Valued__obtain(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 271 "inform7/Chapter 13/Of and From.w"
int bad_property_name_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 281 "inform7/Chapter 13/Of and From.w"
Problems__Issue__sentence_problem(_p_(PM_PropertyCalledArticle),
"a property name cannot consist only of an article",
"which this one seems to. It would lead to awful ambiguities. "
"More likely, the end of the sentence has been lost somehow?");
}
#line 273 "inform7/Chapter 13/Of and From.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 289 "inform7/Chapter 13/Of and From.w"
Problems__Issue__sentence_problem(_p_(PM_PropertyCalledPresence),
"a property name cannot consist only of the word 'presence'",
"because this would lead to ambiguities with the rule clause "
"'...in the presence of...' (For instance, when writing something "
"like 'Instead of eating in the presence of the Queen: ...') "
"The best way to fix this is probably to add another word or "
"two to the property name: 'stage presence', say, would be fine.");
}
#line 274 "inform7/Chapter 13/Of and From.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 300 "inform7/Chapter 13/Of and From.w"
Problems__Issue__sentence_problem(_p_(PM_PropertyNameForbidden),
"a property name cannot contain quoted text or a comma",
"which this one seems to. I think I must be misunderstanding: "
"possibly you've added a subordinate clause which I can't "
"make sense of?");
}
#line 275 "inform7/Chapter 13/Of and From.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 300 "inform7/Chapter 13/Of and From.w"
Problems__Issue__sentence_problem(_p_(PM_PropertyNameForbidden),
"a property name cannot contain quoted text or a comma",
"which this one seems to. I think I must be misunderstanding: "
"possibly you've added a subordinate clause which I can't "
"make sense of?");
}
#line 276 "inform7/Chapter 13/Of and From.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 277 "inform7/Chapter 13/Of and From.w"
#line 328 "inform7/Chapter 13/Of and From.w"
int sentence_needing_second_look_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 330 "inform7/Chapter 13/Of and From.w"
#line 334 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__traverse_for_nonbreaking_ofs(parse_node *pn) {
if ((ParseTree__get_type(pn) == SENTENCE_NT) &&
(pn->down) && (ParseTree__get_type(pn->down) == AVERB_NT)) {
int vn = ParseTree__int_annotation(pn->down, verb_id_ANNOT);
if (((vn == ASSERT_VB) || (vn == HAS_VB) || (vn == DEFINED_BY_VB)) &&
(Preform__parse_nt_against_word_range(sentence_needing_second_look_NTM, ParseTree__get_text(pn), NULL, NULL))) {
current_sentence = pn; /* (just in case any problem messages are issued) */
pn->down = NULL; /* thus cutting off and forgetting its former subtree */
Sentences__VPs__seek(pn); /* ...in order to make a new one */
}
}
}
#line 368 "inform7/Chapter 13/Of and From.w"
void Sentences__Rearrangement__traverse_for_FROM_NT_subtrees(parse_node *pn) {
switch(ParseTree__get_type(pn)) {
case SENTENCE_NT: current_sentence = pn; break;
case FROM_NT:
if ((pn->down) && (pn->down->next)) {
int direction_found = FALSE;
{
#line 396 "inform7/Chapter 13/Of and From.w"
wording W = ParseTree__get_text(pn->down->next);
if (Text__unexpectedly_upper_case(Wordings__first_wn(W)) == FALSE)
for (int i=0; i<no_directions_noticed; i++)
if (Wordings__match(W, ParseTree__get_text(directions_noticed[i])))
direction_found = TRUE;
if (direction_found) Sentences__Rearrangement__convert_clause_to_RELATIONSHIP(pn);
}
#line 374 "inform7/Chapter 13/Of and From.w"
;
if (direction_found == FALSE) Sentences__Rearrangement__expunge_FROM_subtree(pn);
} else internal_error("malformed FROM_NT subtree");
break;
case X_OF_Y_NT:
if ((pn->down) && (pn->down->next)) {
int allow_this = FALSE, direction_found = FALSE;
if (Preform__parse_nt_against_word_range(property_name_NTM, ParseTree__get_text(pn->down->next), NULL, NULL)) allow_this = TRUE;
{
#line 396 "inform7/Chapter 13/Of and From.w"
wording W = ParseTree__get_text(pn->down->next);
if (Text__unexpectedly_upper_case(Wordings__first_wn(W)) == FALSE)
for (int i=0; i<no_directions_noticed; i++)
if (Wordings__match(W, ParseTree__get_text(directions_noticed[i])))
direction_found = TRUE;
if (direction_found) Sentences__Rearrangement__convert_clause_to_RELATIONSHIP(pn);
}
#line 382 "inform7/Chapter 13/Of and From.w"
;
if ((allow_this == FALSE) && (direction_found == FALSE))
Sentences__Rearrangement__expunge_X_OF_Y_subtree(pn);
} else internal_error("malformed X_OF_Y_NT subtree");
break;
}
}
#line 65 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__register_recently_lexed_phrases(void) {
if (problem_count > 0) return; /* for then the tree is perhaps broken anyway */
ParseTree__traverse(Sentences__RuleSubtrees__demote_command_nodes);
ParseTree__traverse(Sentences__RuleSubtrees__detect_loose_command_nodes);
}
#line 74 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__demote_command_nodes(parse_node *p) {
if ((ParseTree__get_type(p) == ROUTINE_NT) && (p->down == NULL)) {
parse_node *end_def = p;
while ((end_def->next) && (ParseTree__get_type(end_def->next) == INVOCATION_LIST_NT))
end_def = end_def->next;
if (p == end_def) return; /* |ROUTINE_NT| not followed by any |INVOCATION_LIST_NT|s */
/* splice so that |p->next| to |end_def| become the children of |p|: */
p->down = p->next;
p->next = end_def->next;
end_def->next = NULL;
Sentences__RuleSubtrees__parse_routine_structure(p);
}
}
#line 91 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__detect_loose_command_nodes(parse_node *p) {
if (ParseTree__get_type(p) == INVOCATION_LIST_NT)
internal_error("loose COMMAND node outside of rule definition");
}
#line 114 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__parse_routine_structure(parse_node *routine_node) {
int initial_problem_count = problem_count;
parse_node *uses_colon_syntax = NULL;
parse_node *uses_begin_end_syntax = NULL;
parse_node *mispunctuates_begin_end_syntax = NULL;
parse_node *requires_colon_syntax = NULL;
{
#line 158 "inform7/Chapter 13/Rule Subtrees.w"
parse_node *p;
for (p = routine_node->down; p; p = p->next) {
control_structure_phrase *csp =
Sentences__RuleSubtrees__detect_control_structure(ParseTree__get_text(p));
if (csp) {
int syntax_used = ParseTree__int_annotation(p, colon_block_command_ANNOT);
if (syntax_used == FALSE) { /* i.e., doesn't end with a colon */
/* don't count "if x is 1, let y be 2" -- with no block -- as deciding it */
if ((csp->subordinate_to == NULL) &&
(!(Preform__parse_nt_against_word_range(phrase_beginning_block_NTM, ParseTree__get_text(p), NULL, NULL))))
syntax_used = NOT_APPLICABLE;
}
if (syntax_used != NOT_APPLICABLE) {
if (syntax_used) {
if (uses_colon_syntax == NULL) uses_colon_syntax = p;
} else {
{
#line 189 "inform7/Chapter 13/Rule Subtrees.w"
if ((uses_begin_end_syntax == NULL) && (mispunctuates_begin_end_syntax == NULL)) {
if (Preform__parse_nt_against_word_range(phrase_beginning_block_NTM, ParseTree__get_text(p), NULL, NULL))
uses_begin_end_syntax = p;
else
mispunctuates_begin_end_syntax = p;
}
}
#line 174 "inform7/Chapter 13/Rule Subtrees.w"
;
}
}
if ((csp->requires_new_syntax) && (requires_colon_syntax == NULL))
requires_colon_syntax = p;
}
if (Sentences__RuleSubtrees__detect_end_control_structure(ParseTree__get_text(p))) {
if (uses_begin_end_syntax == NULL)
uses_begin_end_syntax = p;
}
}
}
#line 122 "inform7/Chapter 13/Rule Subtrees.w"
;
{
#line 199 "inform7/Chapter 13/Rule Subtrees.w"
if ((uses_colon_syntax) && (mispunctuates_begin_end_syntax)) {
current_sentence = routine_node;
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, mispunctuates_begin_end_syntax);
Problems__Issue__handmade_problem(_p_(PM_BadOldSyntax));
Problems__issue_problem_segment(
"The rule or phrase definition %1 seems to use indentation and "
"colons to group phrases together into 'if', 'repeat' or 'while' "
"blocks. That's fine, but then this phrase seems to be missing "
"some punctuation - %2. Perhaps a colon is missing?");
Problems__issue_problem_end();
return;
}
if ((uses_colon_syntax) && (uses_begin_end_syntax)) {
current_sentence = routine_node;
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, uses_colon_syntax);
Problems__quote_source(3, uses_begin_end_syntax);
Problems__Issue__handmade_problem(_p_(PM_BothBlockSyntaxes));
Problems__issue_problem_segment(
"The rule or phrase definition %1 seems to use both ways of grouping "
"phrases together into 'if', 'repeat' and 'while' blocks at once. "
"Inform allows two alternative forms, but they cannot be mixed in "
"the same definition. %POne way is to end the 'if', 'repeat' or "
"'while' phrases with a 'begin', and then to match that with an "
"'end if' or similar. ('Otherwise' or 'otherwise if' clauses are "
"phrases like any other, and end with semicolons in this case.) "
"You use this begin/end form here, for instance - %3. %P"
"The other way is to end with a colon ':' and then indent the "
"subsequent phrases underneath, using tabs. (Note that any "
"'otherwise' or 'otherwise if' clauses also have to end with "
"colons in this case.) You use this indented form here - %2.");
Problems__issue_problem_end();
return;
}
if ((requires_colon_syntax) && (uses_begin_end_syntax)) {
current_sentence = routine_node;
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, requires_colon_syntax);
Problems__Issue__handmade_problem(_p_(PM_NotInOldSyntax));
Problems__issue_problem_segment(
"The construction %2, in the rule or phrase definition %1, "
"is only allowed if the rule is written in the 'new' format, "
"that is, with the phrases written one to a line with "
"indentation showing how they are grouped together, and "
"with colons indicating the start of such a group.");
Problems__issue_problem_end();
return;
}
}
#line 123 "inform7/Chapter 13/Rule Subtrees.w"
;
if (problem_count > initial_problem_count) return;
if (uses_colon_syntax)
{
#line 256 "inform7/Chapter 13/Rule Subtrees.w"
ParseTree__annotate_int(routine_node, indentation_level_ANNOT,
Lexer__indentation_level(Wordings__first_wn(ParseTree__get_text(routine_node))));
parse_node *p;
for (p = routine_node->down; p; p = p->next) {
int I = Lexer__indentation_level(Wordings__first_wn(ParseTree__get_text(p)));
ParseTree__annotate_int(p, indentation_level_ANNOT, I);
}
}
#line 126 "inform7/Chapter 13/Rule Subtrees.w"
;
{
#line 271 "inform7/Chapter 13/Rule Subtrees.w"
for (parse_node *p = routine_node->down; p; p = p->next) {
control_structure_phrase *csp;
csp = Sentences__RuleSubtrees__detect_control_structure(ParseTree__get_text(p));
if (csp) {
if ((ParseTree__int_annotation(p, colon_block_command_ANNOT)) ||
(Preform__parse_nt_against_word_range(phrase_beginning_block_NTM, ParseTree__get_text(p), NULL, NULL)) ||
(csp->subordinate_to)) {
ParseTree__set_control_structure_used(p, csp);
if (csp == case_CSP)
{
#line 290 "inform7/Chapter 13/Rule Subtrees.w"
ParseTree__set_text(p, GET_RW(control_structure_phrase_NTM, 1));
}
#line 279 "inform7/Chapter 13/Rule Subtrees.w"
;
}
}
csp = Sentences__RuleSubtrees__detect_end_control_structure(ParseTree__get_text(p));
if (csp) ParseTree__set_end_control_structure_used(p, csp);
}
}
#line 127 "inform7/Chapter 13/Rule Subtrees.w"
;
{
#line 301 "inform7/Chapter 13/Rule Subtrees.w"
for (parse_node *p = routine_node->down; p; p = p->next)
if (ParseTree__get_control_structure_used(p) == NULL) {
control_structure_phrase *csp;
csp = Sentences__RuleSubtrees__detect_control_structure(ParseTree__get_text(p));
if ((csp == if_CSP) && (Preform__parse_nt_against_word_range(phrase_with_comma_notation_NTM, ParseTree__get_text(p), NULL, NULL)))
{
#line 312 "inform7/Chapter 13/Rule Subtrees.w"
wording BCW = GET_RW(phrase_with_comma_notation_NTM, 1); /* text before the comma */
wording ACW = GET_RW(phrase_with_comma_notation_NTM, 2); /* text after the comma */
/* First trim and annotate the "if ..." part */
ParseTree__annotate_int(p, colon_block_command_ANNOT, TRUE); /* it previously had no colon... */
ParseTree__set_control_structure_used(p, csp); /* ...and therefore didn't have its CSP set */
ParseTree__set_text(p, BCW);
/* Now make a new node for the "then" part, indenting it one step inward */
parse_node *then_node = ParseTree__new(INVOCATION_LIST_NT);
ParseTree__annotate_int(then_node, results_from_splitting_ANNOT, TRUE);
ParseTree__annotate_int(then_node, indentation_level_ANNOT,
ParseTree__int_annotation(p, indentation_level_ANNOT) + 1);
ParseTree__set_text(then_node, ACW);
parse_node *last_node_of_if_construction = then_node, *rest_of_routine = p->next;
/* Attach the "then" node after the "if" node: */
p->next = then_node;
{
#line 344 "inform7/Chapter 13/Rule Subtrees.w"
if (rest_of_routine)
if ((uses_colon_syntax == FALSE) ||
(ParseTree__int_annotation(p, indentation_level_ANNOT) ==
ParseTree__int_annotation(rest_of_routine, indentation_level_ANNOT))) {
if (ParseTree__get_control_structure_used(rest_of_routine) == otherwise_CSP)
{
#line 357 "inform7/Chapter 13/Rule Subtrees.w"
then_node->next = rest_of_routine;
last_node_of_if_construction = last_node_of_if_construction->next;
rest_of_routine = rest_of_routine->next;
}
#line 349 "inform7/Chapter 13/Rule Subtrees.w"
else if (Sentences__RuleSubtrees__abbreviated_otherwise(ParseTree__get_text(rest_of_routine)))
{
#line 368 "inform7/Chapter 13/Rule Subtrees.w"
parse_node *otherwise_node = ParseTree__new(CODE_BLOCK_NT);
ParseTree__annotate_int(otherwise_node, results_from_splitting_ANNOT, TRUE);
ParseTree__annotate_int(otherwise_node, indentation_level_ANNOT,
ParseTree__int_annotation(p, indentation_level_ANNOT));
ParseTree__set_text(otherwise_node,
Wordings__one_word(Wordings__first_wn(ParseTree__get_text(rest_of_routine)))); /* extract just the word "otherwise" */
ParseTree__set_control_structure_used(otherwise_node, otherwise_CSP);
then_node->next = otherwise_node;
otherwise_node->next = rest_of_routine;
ParseTree__set_text(rest_of_routine,
Wordings__trim_first_word(ParseTree__get_text(rest_of_routine))); /* to remove the "otherwise" */
ParseTree__annotate_int(rest_of_routine, indentation_level_ANNOT,
ParseTree__int_annotation(rest_of_routine, indentation_level_ANNOT) + 1);
last_node_of_if_construction = rest_of_routine;
rest_of_routine = rest_of_routine->next;
}
#line 351 "inform7/Chapter 13/Rule Subtrees.w"
;
}
}
#line 332 "inform7/Chapter 13/Rule Subtrees.w"
;
if (uses_colon_syntax == FALSE) {
last_node_of_if_construction->next = Sentences__RuleSubtrees__end_node(p);
last_node_of_if_construction->next->next = rest_of_routine;
} else {
last_node_of_if_construction->next = rest_of_routine;
}
}
#line 306 "inform7/Chapter 13/Rule Subtrees.w"
;
}
}
#line 129 "inform7/Chapter 13/Rule Subtrees.w"
;
if (problem_count > initial_problem_count) return;
if (uses_colon_syntax)
{
#line 396 "inform7/Chapter 13/Rule Subtrees.w"
parse_node *p, *prev, *run_on_at = NULL;
parse_node *first_misaligned_phrase = NULL, *first_overindented_phrase = NULL;
int k, indent, expected_indent = 1, indent_misalign = FALSE, indent_overmuch = FALSE,
just_opened_block = FALSE;
/* the blocks open stack holds blocks currently open */
parse_node *blstack_opening_phrase[GROSS_AMOUNT_OF_INDENTATION+1];
control_structure_phrase *blstack_construct[GROSS_AMOUNT_OF_INDENTATION+1];
int blstack_stage[GROSS_AMOUNT_OF_INDENTATION+1];
int blo_sp = 0, suppress_further_problems = FALSE;
if (ParseTree__int_annotation(routine_node, indentation_level_ANNOT) != 0)
{
#line 427 "inform7/Chapter 13/Rule Subtrees.w"
current_sentence = routine_node;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_NonflushRule));
Problems__issue_problem_segment(
"The phrase or rule definition %1 is written using tab indentations "
"to show how its phrases are to be grouped together. But in that "
"case the opening line needs to be on the left margin, not indented.");
Problems__issue_problem_end();
suppress_further_problems = TRUE;
}
#line 408 "inform7/Chapter 13/Rule Subtrees.w"
;
for (prev = NULL, p = routine_node->down, k=1; p; prev = p, p = p->next, k++) {
control_structure_phrase *csp = ParseTree__get_control_structure_used(p);
{
#line 445 "inform7/Chapter 13/Rule Subtrees.w"
indent = expected_indent;
if (ParseTree__int_annotation(p, indentation_level_ANNOT) > 0)
indent = ParseTree__int_annotation(p, indentation_level_ANNOT);
else if (Wordings__nonempty(ParseTree__get_text(p))) {
switch (Lexer__break_before(Wordings__first_wn(ParseTree__get_text(p)))) {
case '\n': indent = 0; break;
case '\t': indent = 1; break;
default:
if ((prev) && (csp == NULL)) {
control_structure_phrase *pcsp = ParseTree__get_control_structure_used(prev);
if ((pcsp) && (pcsp->allow_run_on)) break;
}
if ((ParseTree__int_annotation(p, results_from_splitting_ANNOT) == FALSE) &&
(run_on_at == NULL)) run_on_at = p;
break;
}
}
if (indent >= GROSS_AMOUNT_OF_INDENTATION)
{
#line 614 "inform7/Chapter 13/Rule Subtrees.w"
indent_overmuch = TRUE;
if (first_overindented_phrase == NULL) first_overindented_phrase = p;
}
#line 462 "inform7/Chapter 13/Rule Subtrees.w"
;
}
#line 412 "inform7/Chapter 13/Rule Subtrees.w"
;
{
#line 476 "inform7/Chapter 13/Rule Subtrees.w"
if (indent == 0) {
{
#line 585 "inform7/Chapter 13/Rule Subtrees.w"
indent_misalign = TRUE;
if (first_misaligned_phrase == NULL) first_misaligned_phrase = p;
}
#line 477 "inform7/Chapter 13/Rule Subtrees.w"
;
{
#line 566 "inform7/Chapter 13/Rule Subtrees.w"
if ((blo_sp > 0) &&
(blstack_stage[blo_sp-1] == 0) &&
(blstack_construct[blo_sp-1]->body_empty_except_for_subordinates)) {
{
#line 677 "inform7/Chapter 13/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
current_sentence = routine_node;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, p);
Problems__Issue__handmade_problem(_p_(PM_NonCaseInIf));
Problems__issue_problem_segment(
"In the phrase or rule definition %1, the phrase %2 came as a "
"surprise since it was not a case in an 'if X is...' but was "
"instead some other miscellaneous instruction.");
Problems__issue_problem_end();
}
}
#line 569 "inform7/Chapter 13/Rule Subtrees.w"
;
}
just_opened_block = FALSE;
}
#line 478 "inform7/Chapter 13/Rule Subtrees.w"
;
} else {
if ((csp) && (csp->subordinate_to)) {
{
#line 502 "inform7/Chapter 13/Rule Subtrees.w"
expected_indent--;
if (expected_indent < indent) {
{
#line 692 "inform7/Chapter 13/Rule Subtrees.w"
if ((indent_misalign == FALSE) && (suppress_further_problems == FALSE)) {
current_sentence = p;
if (csp->subordinate_to == if_CSP) {
LOG("$T\n", routine_node);
Problems__Issue__sentence_problem(_p_(PM_MisalignedOtherwise),
"this doesn't match a corresponding 'if'",
"as it must. An 'otherwise' must be vertically underneath the "
"'if' to which it corresponds, at the same indentation, and "
"if the 'otherwise' uses a colon to begin a block then the "
"'if' must do the same.");
}
if (csp->subordinate_to == switch_CSP)
Problems__Issue__sentence_problem(_p_(PM_MisalignedCase),
"this seems to be misplaced since it is not a case within an "
"'if X is...'",
"as it must be. Each case must be placed one tab stop in from "
"the 'if X is...' to which it belongs, and the instructions "
"for what to do in that case should be one tab stop further in "
"still.");
}
}
#line 504 "inform7/Chapter 13/Rule Subtrees.w"
;
} else {
{
#line 541 "inform7/Chapter 13/Rule Subtrees.w"
if ((just_opened_block) &&
(blo_sp > 0) &&
(!(blstack_construct[blo_sp-1]->body_empty_except_for_subordinates)) && (p))
{
#line 655 "inform7/Chapter 13/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
LOG("$T\n", routine_node);
current_sentence = routine_node;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, prev);
Problems__quote_source_eliding_begin(3, p);
Problems__Issue__handmade_problem(_p_(PM_EmptyIndentedBlock));
Problems__issue_problem_segment(
"The phrase or rule definition %1 is written using the 'colon "
"and indentation' syntax for its 'if's, 'repeat's and 'while's, "
"where blocks of phrases grouped together are indented one "
"tab step inward from the 'if ...:' or similar phrase to which "
"they belong. But the phrase %2, which ought to begin a block, "
"is immediately followed by %3 at the same or a lower indentation, "
"so the block seems to be empty - this must mean there has been "
"a mistake in indenting the phrases.");
Problems__issue_problem_end();
}
}
#line 544 "inform7/Chapter 13/Rule Subtrees.w"
;
while (indent < expected_indent) {
parse_node *opening;
if (blo_sp == 0) {
{
#line 585 "inform7/Chapter 13/Rule Subtrees.w"
indent_misalign = TRUE;
if (first_misaligned_phrase == NULL) first_misaligned_phrase = p;
}
#line 548 "inform7/Chapter 13/Rule Subtrees.w"
;
indent = expected_indent;
break;
}
if ((blstack_construct[blo_sp-1]->body_empty_except_for_subordinates) &&
(expected_indent - indent == 1)) {
indent = expected_indent;
break;
}
expected_indent--;
if (blstack_construct[blo_sp-1]->indent_subblocks) expected_indent--;
opening = blstack_opening_phrase[--blo_sp];
{
#line 578 "inform7/Chapter 13/Rule Subtrees.w"
parse_node *implicit_end = Sentences__RuleSubtrees__end_node(opening);
implicit_end->next = prev->next; prev->next = implicit_end;
prev = implicit_end;
}
#line 560 "inform7/Chapter 13/Rule Subtrees.w"
;
}
}
#line 506 "inform7/Chapter 13/Rule Subtrees.w"
;
if ((blo_sp == 0) ||
(csp->subordinate_to != blstack_construct[blo_sp-1])) {
{
#line 692 "inform7/Chapter 13/Rule Subtrees.w"
if ((indent_misalign == FALSE) && (suppress_further_problems == FALSE)) {
current_sentence = p;
if (csp->subordinate_to == if_CSP) {
LOG("$T\n", routine_node);
Problems__Issue__sentence_problem(_p_(PM_MisalignedOtherwise),
"this doesn't match a corresponding 'if'",
"as it must. An 'otherwise' must be vertically underneath the "
"'if' to which it corresponds, at the same indentation, and "
"if the 'otherwise' uses a colon to begin a block then the "
"'if' must do the same.");
}
if (csp->subordinate_to == switch_CSP)
Problems__Issue__sentence_problem(_p_(PM_MisalignedCase),
"this seems to be misplaced since it is not a case within an "
"'if X is...'",
"as it must be. Each case must be placed one tab stop in from "
"the 'if X is...' to which it belongs, and the instructions "
"for what to do in that case should be one tab stop further in "
"still.");
}
}
#line 509 "inform7/Chapter 13/Rule Subtrees.w"
;
} else {
if (blstack_stage[blo_sp-1] > csp->used_at_stage)
{
#line 716 "inform7/Chapter 13/Rule Subtrees.w"
if ((indent_misalign == FALSE) && (suppress_further_problems == FALSE)) {
current_sentence = p;
if ((csp == default_case_CSP) || (csp == case_CSP))
Problems__Issue__sentence_problem(_p_(PM_DefaultCaseNotLast),
"'otherwise' must be the last clause if an 'if ... is:'",
"and in particular it has to come after all the '-- V:' "
"case values supplied.");
else
Problems__Issue__sentence_problem(_p_(PM_MisarrangedOtherwise),
"this seems to be misplaced since it is out of sequence within its 'if'",
"with an 'otherwise if...' coming after the more general 'otherwise' "
"rather than before. (Note that an 'otherwise' or 'otherwise if' must "
"be vertically underneath the 'if' to which it corresponds, at the "
"same indentation.");
}
}
#line 512 "inform7/Chapter 13/Rule Subtrees.w"
;
blstack_stage[blo_sp-1] = csp->used_at_stage;
}
}
expected_indent++;
}
#line 481 "inform7/Chapter 13/Rule Subtrees.w"
;
just_opened_block = TRUE;
} else {
if (expected_indent < indent)
{
#line 585 "inform7/Chapter 13/Rule Subtrees.w"
indent_misalign = TRUE;
if (first_misaligned_phrase == NULL) first_misaligned_phrase = p;
}
#line 484 "inform7/Chapter 13/Rule Subtrees.w"
;
if (expected_indent > indent)
{
#line 541 "inform7/Chapter 13/Rule Subtrees.w"
if ((just_opened_block) &&
(blo_sp > 0) &&
(!(blstack_construct[blo_sp-1]->body_empty_except_for_subordinates)) && (p))
{
#line 655 "inform7/Chapter 13/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
LOG("$T\n", routine_node);
current_sentence = routine_node;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, prev);
Problems__quote_source_eliding_begin(3, p);
Problems__Issue__handmade_problem(_p_(PM_EmptyIndentedBlock));
Problems__issue_problem_segment(
"The phrase or rule definition %1 is written using the 'colon "
"and indentation' syntax for its 'if's, 'repeat's and 'while's, "
"where blocks of phrases grouped together are indented one "
"tab step inward from the 'if ...:' or similar phrase to which "
"they belong. But the phrase %2, which ought to begin a block, "
"is immediately followed by %3 at the same or a lower indentation, "
"so the block seems to be empty - this must mean there has been "
"a mistake in indenting the phrases.");
Problems__issue_problem_end();
}
}
#line 544 "inform7/Chapter 13/Rule Subtrees.w"
;
while (indent < expected_indent) {
parse_node *opening;
if (blo_sp == 0) {
{
#line 585 "inform7/Chapter 13/Rule Subtrees.w"
indent_misalign = TRUE;
if (first_misaligned_phrase == NULL) first_misaligned_phrase = p;
}
#line 548 "inform7/Chapter 13/Rule Subtrees.w"
;
indent = expected_indent;
break;
}
if ((blstack_construct[blo_sp-1]->body_empty_except_for_subordinates) &&
(expected_indent - indent == 1)) {
indent = expected_indent;
break;
}
expected_indent--;
if (blstack_construct[blo_sp-1]->indent_subblocks) expected_indent--;
opening = blstack_opening_phrase[--blo_sp];
{
#line 578 "inform7/Chapter 13/Rule Subtrees.w"
parse_node *implicit_end = Sentences__RuleSubtrees__end_node(opening);
implicit_end->next = prev->next; prev->next = implicit_end;
prev = implicit_end;
}
#line 560 "inform7/Chapter 13/Rule Subtrees.w"
;
}
}
#line 486 "inform7/Chapter 13/Rule Subtrees.w"
;
expected_indent = indent;
{
#line 566 "inform7/Chapter 13/Rule Subtrees.w"
if ((blo_sp > 0) &&
(blstack_stage[blo_sp-1] == 0) &&
(blstack_construct[blo_sp-1]->body_empty_except_for_subordinates)) {
{
#line 677 "inform7/Chapter 13/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
current_sentence = routine_node;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, p);
Problems__Issue__handmade_problem(_p_(PM_NonCaseInIf));
Problems__issue_problem_segment(
"In the phrase or rule definition %1, the phrase %2 came as a "
"surprise since it was not a case in an 'if X is...' but was "
"instead some other miscellaneous instruction.");
Problems__issue_problem_end();
}
}
#line 569 "inform7/Chapter 13/Rule Subtrees.w"
;
}
just_opened_block = FALSE;
}
#line 488 "inform7/Chapter 13/Rule Subtrees.w"
;
}
}
if (expected_indent < 1) expected_indent = 1;
}
#line 413 "inform7/Chapter 13/Rule Subtrees.w"
;
{
#line 526 "inform7/Chapter 13/Rule Subtrees.w"
if ((csp) && (csp->subordinate_to == NULL) && (ParseTree__int_annotation(p, colon_block_command_ANNOT))) {
expected_indent++;
if (csp->indent_subblocks) expected_indent++;
blstack_construct[blo_sp] = csp;
blstack_stage[blo_sp] = 0;
blstack_opening_phrase[blo_sp++] = p;
just_opened_block = TRUE;
}
}
#line 414 "inform7/Chapter 13/Rule Subtrees.w"
;
}
indent = 1;
{
#line 541 "inform7/Chapter 13/Rule Subtrees.w"
if ((just_opened_block) &&
(blo_sp > 0) &&
(!(blstack_construct[blo_sp-1]->body_empty_except_for_subordinates)) && (p))
{
#line 655 "inform7/Chapter 13/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
LOG("$T\n", routine_node);
current_sentence = routine_node;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, prev);
Problems__quote_source_eliding_begin(3, p);
Problems__Issue__handmade_problem(_p_(PM_EmptyIndentedBlock));
Problems__issue_problem_segment(
"The phrase or rule definition %1 is written using the 'colon "
"and indentation' syntax for its 'if's, 'repeat's and 'while's, "
"where blocks of phrases grouped together are indented one "
"tab step inward from the 'if ...:' or similar phrase to which "
"they belong. But the phrase %2, which ought to begin a block, "
"is immediately followed by %3 at the same or a lower indentation, "
"so the block seems to be empty - this must mean there has been "
"a mistake in indenting the phrases.");
Problems__issue_problem_end();
}
}
#line 544 "inform7/Chapter 13/Rule Subtrees.w"
;
while (indent < expected_indent) {
parse_node *opening;
if (blo_sp == 0) {
{
#line 585 "inform7/Chapter 13/Rule Subtrees.w"
indent_misalign = TRUE;
if (first_misaligned_phrase == NULL) first_misaligned_phrase = p;
}
#line 548 "inform7/Chapter 13/Rule Subtrees.w"
;
indent = expected_indent;
break;
}
if ((blstack_construct[blo_sp-1]->body_empty_except_for_subordinates) &&
(expected_indent - indent == 1)) {
indent = expected_indent;
break;
}
expected_indent--;
if (blstack_construct[blo_sp-1]->indent_subblocks) expected_indent--;
opening = blstack_opening_phrase[--blo_sp];
{
#line 578 "inform7/Chapter 13/Rule Subtrees.w"
parse_node *implicit_end = Sentences__RuleSubtrees__end_node(opening);
implicit_end->next = prev->next; prev->next = implicit_end;
prev = implicit_end;
}
#line 560 "inform7/Chapter 13/Rule Subtrees.w"
;
}
}
#line 418 "inform7/Chapter 13/Rule Subtrees.w"
;
if (indent_overmuch)
{
#line 620 "inform7/Chapter 13/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
current_sentence = routine_node;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, first_overindented_phrase);
Problems__Issue__handmade_problem(_p_(PM_TooMuchIndentation));
Problems__issue_problem_segment(
"The phrase or rule definition %1 is written using tab indentations "
"to show how its phrases are to be grouped together. But the level "
"of indentation goes far too deep, reaching more than 25 tab stops "
"from the left margin.");
Problems__issue_problem_end();
}
}
#line 420 "inform7/Chapter 13/Rule Subtrees.w"
else if (run_on_at)
{
#line 636 "inform7/Chapter 13/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
current_sentence = routine_node;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, run_on_at);
Problems__Issue__handmade_problem(_p_(PM_RunOnsInTabbedRoutine));
Problems__issue_problem_segment(
"The phrase or rule definition %1 is written using the 'colon "
"and indentation' syntax for its 'if's, 'repeat's and 'while's, "
"but that's only allowed if each phrase in the definition "
"occurs on its own line. So phrases like %2, which follow "
"directly on from the previous phrase, aren't allowed.");
Problems__issue_problem_end();
}
}
#line 421 "inform7/Chapter 13/Rule Subtrees.w"
else if (indent_misalign)
{
#line 591 "inform7/Chapter 13/Rule Subtrees.w"
if (suppress_further_problems == FALSE) {
LOG("$T\n", routine_node);
current_sentence = routine_node;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_source_eliding_begin(2, first_misaligned_phrase);
Problems__Issue__handmade_problem(_p_(PM_MisalignedIndentation));
Problems__issue_problem_segment(
"The phrase or rule definition %1 is written using the 'colon "
"and indentation' syntax for its 'if's, 'repeat's and 'while's, "
"where blocks of phrases grouped together are indented one "
"tab step inward from the 'if ...:' or similar phrase to which "
"they belong. But the tabs here seem to be misaligned, and I can't "
"determine the structure. The first phrase going awry in the "
"definition seems to be %2, in case that helps. %PThis sometimes "
"happens even when the code looks about right, to the eye, if rows "
"of spaces have been used to indent phrases instead of tabs.");
Problems__Issue__diagnose_further();
Problems__issue_problem_end();
}
}
#line 422 "inform7/Chapter 13/Rule Subtrees.w"
;
}
#line 132 "inform7/Chapter 13/Rule Subtrees.w"
;
if (problem_count > initial_problem_count) return;
{
#line 737 "inform7/Chapter 13/Rule Subtrees.w"
parse_node *routine_list = routine_node->down;
parse_node *top_level = ParseTree__new(CODE_BLOCK_NT);
routine_node->down = top_level;
parse_node *attach_owners[MAX_BLOCK_NESTING+1];
parse_node *attach_points[MAX_BLOCK_NESTING+1];
control_structure_phrase *attach_csps[MAX_BLOCK_NESTING+1];
int attach_point_sp = 0;
/* push the top level code block onto the stack */
attach_owners[attach_point_sp] = NULL;
attach_csps[attach_point_sp] = NULL;
attach_points[attach_point_sp++] = top_level;
parse_node *overflow_point = NULL; /* if any overflow is found */
for (parse_node *pn = routine_list, *pn_prev = NULL; pn; pn_prev = pn, pn = pn->next) {
/* unstring this node from the old list */
if (pn_prev) pn_prev->next = NULL;
{
#line 768 "inform7/Chapter 13/Rule Subtrees.w"
int go_up = FALSE, go_down = FALSE;
control_structure_phrase *csp = ParseTree__get_end_control_structure_used(pn);
if (csp) go_up = TRUE;
else {
csp = ParseTree__get_control_structure_used(pn);
if (csp) {
go_down = TRUE;
if (Sentences__RuleSubtrees__opens_block(csp) == FALSE) {
go_up = TRUE;
ParseTree__set_type(pn, CODE_BLOCK_NT);
}
}
}
if (go_up)
{
#line 788 "inform7/Chapter 13/Rule Subtrees.w"
control_structure_phrase *superior_csp = attach_csps[attach_point_sp-1];
if ((superior_csp) && (superior_csp->subordinate_to))
{
#line 813 "inform7/Chapter 13/Rule Subtrees.w"
if (attach_point_sp != 1) attach_point_sp--;
}
#line 789 "inform7/Chapter 13/Rule Subtrees.w"
;
if (go_down == FALSE)
{
#line 813 "inform7/Chapter 13/Rule Subtrees.w"
if (attach_point_sp != 1) attach_point_sp--;
}
#line 790 "inform7/Chapter 13/Rule Subtrees.w"
;
}
#line 781 "inform7/Chapter 13/Rule Subtrees.w"
;
{
#line 795 "inform7/Chapter 13/Rule Subtrees.w"
parse_node *to = attach_points[attach_point_sp-1];
if ((go_up) && (go_down) && (attach_owners[attach_point_sp-1]))
to = attach_owners[attach_point_sp-1];
ParseTree__graft(pn, to);
}
#line 782 "inform7/Chapter 13/Rule Subtrees.w"
;
if (go_down)
{
#line 803 "inform7/Chapter 13/Rule Subtrees.w"
parse_node *next_attach_point = pn;
if (go_up == FALSE) {
pn->down = ParseTree__new(CODE_BLOCK_NT);
next_attach_point = pn->down;
}
{
#line 818 "inform7/Chapter 13/Rule Subtrees.w"
if (attach_point_sp <= MAX_BLOCK_NESTING) {
attach_owners[attach_point_sp] = pn;
attach_csps[attach_point_sp] = csp;
attach_points[attach_point_sp++] = next_attach_point;
} else {
if (overflow_point == NULL) overflow_point = pn;
}
}
#line 808 "inform7/Chapter 13/Rule Subtrees.w"
;
}
#line 783 "inform7/Chapter 13/Rule Subtrees.w"
;
}
#line 756 "inform7/Chapter 13/Rule Subtrees.w"
;
}
if (overflow_point) {
current_sentence = overflow_point;
Problems__Issue__sentence_problem(_p_(PM_BlockNestingTooDeep),
"compound phrases have gone too deep",
"perhaps because many have begun but not been properly ended?");
}
}
#line 135 "inform7/Chapter 13/Rule Subtrees.w"
;
if (problem_count > initial_problem_count) return;
{
#line 834 "inform7/Chapter 13/Rule Subtrees.w"
int n = problem_count;
Sentences__RuleSubtrees__police_code_block(routine_node->down, NULL);
if (problem_count > n) LOG("Local parse tree: $T\n", routine_node);
}
#line 138 "inform7/Chapter 13/Rule Subtrees.w"
;
if (problem_count > initial_problem_count) return;
{
#line 992 "inform7/Chapter 13/Rule Subtrees.w"
int n = problem_count;
Sentences__RuleSubtrees__purge_otherwise_if(routine_node->down);
if (problem_count > n) LOG("Local parse tree: $T\n", routine_node);
}
#line 141 "inform7/Chapter 13/Rule Subtrees.w"
;
if (problem_count > initial_problem_count) return;
{
#line 1039 "inform7/Chapter 13/Rule Subtrees.w"
Sentences__RuleSubtrees__purge_end_markers(routine_node->down);
}
#line 144 "inform7/Chapter 13/Rule Subtrees.w"
;
if (problem_count > initial_problem_count) return;
if (uses_colon_syntax == FALSE)
{
#line 1057 "inform7/Chapter 13/Rule Subtrees.w"
Sentences__RuleSubtrees__purge_begin_markers(routine_node->down);
}
#line 148 "inform7/Chapter 13/Rule Subtrees.w"
;
{
#line 1079 "inform7/Chapter 13/Rule Subtrees.w"
Sentences__RuleSubtrees__insert_cb_nodes(routine_node->down);
}
#line 150 "inform7/Chapter 13/Rule Subtrees.w"
;
{
#line 1105 "inform7/Chapter 13/Rule Subtrees.w"
Sentences__RuleSubtrees__read_instead_markers(routine_node->down);
}
#line 151 "inform7/Chapter 13/Rule Subtrees.w"
;
{
#line 1126 "inform7/Chapter 13/Rule Subtrees.w"
Sentences__RuleSubtrees__break_up_says(routine_node->down);
}
#line 152 "inform7/Chapter 13/Rule Subtrees.w"
;
}
#line 841 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__police_code_block(parse_node *block, control_structure_phrase *context) {
for (parse_node *p = block->down, *prev_p = NULL; p; prev_p = p, p = p->next) {
current_sentence = p;
control_structure_phrase *prior =
(prev_p)?ParseTree__get_control_structure_used(prev_p):NULL;
control_structure_phrase *csp = ParseTree__get_end_control_structure_used(p);
if ((csp) && (csp != prior)) {
if (prior == NULL)
{
#line 882 "inform7/Chapter 13/Rule Subtrees.w"
Problems__Issue__sentence_problem_with_note(_p_(PM_EndWithoutBegin),
"this is an 'end' with no matching 'begin'",
"which should not happen: every phrase like 'if ... begin;' "
"should eventually be followed by its bookend 'end if'. "
"It makes no sense to have an 'end ...' on its own.",
"Perhaps the problem is actually that you opened several "
"such begin... end 'blocks' and accidentally closed them "
"once too many? This is very easily done.");
}
#line 849 "inform7/Chapter 13/Rule Subtrees.w"
else
{
#line 894 "inform7/Chapter 13/Rule Subtrees.w"
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, prior->keyword);
Problems__quote_source(3, prev_p);
Problems__Issue__handmade_problem(_p_(PM_WrongEnd));
Problems__issue_problem_segment(
"You wrote %1, but the end I was expecting next was 'end %2', "
"finishing the block you began with %3.");
Problems__issue_problem_end();
}
#line 850 "inform7/Chapter 13/Rule Subtrees.w"
;
}
csp = ParseTree__get_control_structure_used(p);
if (csp) {
if (Sentences__RuleSubtrees__opens_block(csp)) {
if ((p->next == NULL) ||
(ParseTree__get_end_control_structure_used(p->next) == NULL))
{
#line 906 "inform7/Chapter 13/Rule Subtrees.w"
Problems__Issue__sentence_problem(_p_(PM_BeginWithoutEnd),
"the definition of the phrase ended with no matching 'end' for "
"this 'begin'",
"bearing in mind that every begin must have a matching end, and "
"that the one most recently begun must be the one first to end. For "
"instance, 'if ... begin' must have a matching 'end if'.");
}
#line 858 "inform7/Chapter 13/Rule Subtrees.w"
;
} else {
if (context == NULL)
{
#line 916 "inform7/Chapter 13/Rule Subtrees.w"
if (csp == otherwise_CSP)
Problems__Issue__sentence_problem(_p_(PM_OtherwiseWithoutIf),
"this is an 'else' or 'otherwise' with no matching 'if' (or 'unless')",
"which must be wrong.");
else if (csp == otherwise_if_CSP)
Problems__Issue__sentence_problem(_p_(PM_OtherwiseIfMisplaced),
"the 'otherwise if' clause here seems not to be occurring inside "
"a large 'if'",
"and seems to be freestanding instead. (Though 'otherwise ...' can "
"usually be used after simple one-line 'if's to provide an alternative "
"course of action, 'otherwise if...' is a different matter, and is "
"used to divide up larger-scale instructions.)");
else
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"this clause can't occur outside of a control phrase",
"which suggests that the structure of this routine is wrong.");
}
#line 861 "inform7/Chapter 13/Rule Subtrees.w"
else if (context != csp->subordinate_to)
{
#line 936 "inform7/Chapter 13/Rule Subtrees.w"
if ((csp == otherwise_CSP) || (csp == otherwise_if_CSP)) {
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, context->keyword);
Problems__Issue__handmade_problem(_p_(PM_OtherwiseInNonIf));
Problems__issue_problem_segment(
"The %1 here did not make sense inside a "
"'%2' structure: it's provided for 'if' (or 'unless').");
Problems__issue_problem_end();
} else
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"this clause is wrong for the phrase containing it",
"which suggests that the structure of this routine is wrong.");
}
#line 863 "inform7/Chapter 13/Rule Subtrees.w"
else if ((csp == otherwise_CSP) && (p->next))
{
#line 952 "inform7/Chapter 13/Rule Subtrees.w"
int doubled = FALSE, oi = FALSE;
for (parse_node *p2 = p->next; p2; p2 = p2->next) {
if (ParseTree__get_control_structure_used(p2) == otherwise_CSP) {
current_sentence = p2;
doubled = TRUE;
}
if (ParseTree__get_control_structure_used(p2) == otherwise_if_CSP)
oi = TRUE;
}
if (doubled)
Problems__Issue__sentence_problem(_p_(PM_DoubleOtherwise),
"that makes two unconditional 'otherwise' or 'else' clauses "
"for this 'if'",
"which is forbidden since 'otherwise' is meant to be a single "
"(optional) catch-all clause at the end.");
else if (oi)
Problems__Issue__sentence_problem(_p_(PM_OtherwiseIfAfterOtherwise),
"this seems to be misplaced since it is out of sequence within its 'if'",
"with an 'otherwise if...' coming after the more general 'otherwise' "
"rather than before. (If there's an 'otherwise' clause, it has to be "
"the last clause of the 'if'.)");
else
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"'otherwise' must be the last clause",
"but it seems not to be.");
}
#line 865 "inform7/Chapter 13/Rule Subtrees.w"
else if ((csp == default_case_CSP) && (p->next))
{
#line 982 "inform7/Chapter 13/Rule Subtrees.w"
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"'otherwise' must be the last clause",
"which must be wrong.");
}
#line 867 "inform7/Chapter 13/Rule Subtrees.w"
;
}
}
if (p->down) Sentences__RuleSubtrees__police_code_block(p, csp);
}
}
#line 1002 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__purge_otherwise_if(parse_node *block) {
for (parse_node *p = block->down, *prev_p = NULL; p; prev_p = p, p = p->next) {
if (ParseTree__get_control_structure_used(p) == otherwise_if_CSP) {
parse_node *former_contents = p->down;
parse_node *former_successors = p->next;
/* put an otherwise node in the position previously occupied by p */
parse_node *otherwise_node = ParseTree__new(CODE_BLOCK_NT);
ParseTree__set_control_structure_used(otherwise_node, otherwise_CSP);
/* extract just the word "otherwise" */
ParseTree__set_text(otherwise_node, Wordings__one_word(Wordings__first_wn(ParseTree__get_text(p))));
if (prev_p) prev_p->next = otherwise_node; else block->down = otherwise_node;
/* move p to below the otherwise node */
otherwise_node->down = p;
ParseTree__set_type(p, INVOCATION_LIST_NT);
ParseTree__set_control_structure_used(p, if_CSP);
p->next = NULL;
ParseTree__set_text(p, Wordings__trim_first_word(ParseTree__get_text(p)));
/* put the code previously under p under a new code block node under p */
p->down = ParseTree__new(CODE_BLOCK_NT);
p->down->down = former_contents;
/* any further "otherwise if" or "otherwise" nodes after p follow */
p->down->next = former_successors;
}
if (p->down) Sentences__RuleSubtrees__purge_otherwise_if(p);
}
}
#line 1044 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__purge_end_markers(parse_node *block) {
for (parse_node *p = block->down, *prev_p = NULL; p; prev_p = p, p = p->next) {
if (ParseTree__get_end_control_structure_used(p)) {
if (prev_p) prev_p->next = p->next; else block->down = p->next;
}
if (p->down) Sentences__RuleSubtrees__purge_end_markers(p);
}
}
#line 1062 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__purge_begin_markers(parse_node *block) {
for (parse_node *p = block->down, *prev_p = NULL; p; prev_p = p, p = p->next) {
if (ParseTree__get_control_structure_used(p))
if (Preform__parse_nt_against_word_range(phrase_beginning_block_NTM, ParseTree__get_text(p), NULL, NULL))
ParseTree__set_text(p, GET_RW(phrase_beginning_block_NTM, 1));
if (p->down) Sentences__RuleSubtrees__purge_begin_markers(p);
}
}
#line 1084 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__insert_cb_nodes(parse_node *block) {
for (parse_node *p = block->down, *prev_p = NULL; p; prev_p = p, p = p->next) {
if (Sentences__RuleSubtrees__opens_block(ParseTree__get_control_structure_used(p))) {
parse_node *blank_cb_node = ParseTree__new(CODE_BLOCK_NT);
ParseTree__set_control_structure_used(blank_cb_node,
ParseTree__get_control_structure_used(p));
ParseTree__set_control_structure_used(p, NULL);
blank_cb_node->down = p;
blank_cb_node->next = p->next;
p->next = p->down;
p->down = NULL;
if (prev_p) prev_p->next = blank_cb_node; else block->down = blank_cb_node;
p = blank_cb_node;
}
if (p->down) Sentences__RuleSubtrees__insert_cb_nodes(p);
}
}
#line 1110 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__read_instead_markers(parse_node *block) {
for (parse_node *p = block->down, *prev_p = NULL; p; prev_p = p, p = p->next) {
if (Preform__parse_nt_against_word_range(instead_keyword_NTM, ParseTree__get_text(p), NULL, NULL)) {
ParseTree__set_text(p, GET_RW(instead_keyword_NTM, 1));
parse_node *instead_node = ParseTree__new(CODE_BLOCK_NT);
ParseTree__set_control_structure_used(instead_node, instead_CSP);
instead_node->next = p->next;
p->next = instead_node;
}
if (p->down) Sentences__RuleSubtrees__read_instead_markers(p);
}
}
#line 1131 "inform7/Chapter 13/Rule Subtrees.w"
void Sentences__RuleSubtrees__break_up_says(parse_node *block) {
for (parse_node *p = block->down, *prev_p = NULL; p; prev_p = p, p = p->next) {
int sf = NO_SIGF;
wording W = ParseTree__get_text(p);
if (ParseTree__int_annotation(p, from_text_substitution_ANNOT)) sf = SAY_SIGF;
else if (Preform__parse_nt_against_word_range(other_significant_phrase_NTM, W, NULL, NULL)) {
sf = most_recent_result; W = GET_RW(other_significant_phrase_NTM, 1);
}
switch (sf) {
case SAY_SIGF: {
parse_node *blank_cb_node = ParseTree__new(CODE_BLOCK_NT);
ParseTree__set_control_structure_used(blank_cb_node, say_CSP);
blank_cb_node->next = p->next;
ParseTree__set_text(blank_cb_node, ParseTree__get_text(p));
p->next = NULL;
if (prev_p) prev_p->next = blank_cb_node; else block->down = blank_cb_node;
current_sentence = p;
Sentences__RuleSubtrees__unroll_says(blank_cb_node, W, 0);
p = blank_cb_node;
break;
}
case NOW_SIGF: {
ParseTree__set_control_structure_used(p, now_CSP);
parse_node *cond_node = ParseTree__new(CONDITION_CONTEXT_NT);
ParseTree__set_text(cond_node, W);
p->down = cond_node;
break;
}
}
if (p->down) Sentences__RuleSubtrees__break_up_says(p);
}
}
void Sentences__RuleSubtrees__unroll_says(parse_node *cb_node, wording W, int depth) {
while (Preform__parse_nt_against_word_range(phrase_with_comma_notation_NTM, W, NULL, NULL)) {
wording AW = GET_RW(phrase_with_comma_notation_NTM, 1);
wording BW = GET_RW(phrase_with_comma_notation_NTM, 2);
W = AW;
{
#line 1179 "inform7/Chapter 13/Rule Subtrees.w"
if ((Wordings__length(W) > 1) || (strcmp(Lexer__word_text(Wordings__first_wn(W)), "\"\"") != 0)) {
if ((Wordings__length(W) == 1) && (Vocabulary__test_flags(Wordings__first_wn(W), TEXTWITHSUBS_MC)) && (depth == 0)) {
char *p = Lexer__word_raw_text(Wordings__first_wn(W));
{
#line 1196 "inform7/Chapter 13/Rule Subtrees.w"
int k, sqb = 0;
for (k=0; p[k]; k++) {
switch (p[k]) {
case '[': sqb++; if (sqb > 1)
{
#line 1232 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
if ((p[k+1] == 'u') && (p[k+2] == 'n') && (p[k+3] == 'i') && (p[k+4] == 'c') &&
(p[k+5] == 'o') && (p[k+6] == 'd') && (p[k+7] == 'e') && (p[k+8] == ' ')) {
Problems__Issue__sentence_problem(_p_(PM_NestedUSubstitution),
"the text here contains one substitution '[...]' inside another",
"which is not allowed. Actually, it looks as if you might have got "
"into this by typing an exotic character as part of the name of a "
"text substitution - those get rewritten automatically as '[unicode N]' "
"for the appropriate Unicode character code number N. Either way - "
"this isn't allowed.");
} else {
Problems__Issue__sentence_problem(_p_(PM_NestedSubstitution),
"the text here contains one substitution '[...]' inside another",
"which is not allowed. (If you just wanted a literal open and closed "
"square bracket, use '[bracket]' and '[close bracket]'.)");
}
it_is_not_worth_adding = FALSE;
return;
}
#line 1199 "inform7/Chapter 13/Rule Subtrees.w"
; break;
case ']': sqb--; if (sqb < 0)
{
#line 1266 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_UnopenedSubstitution),
"the text here uses a close square bracket ']', which closes a substitution "
"in the text, but never actually opened it",
"with a matching '['. (If you just wanted a literal close square bracket, "
"use '[close bracket]'.)");
it_is_not_worth_adding = FALSE;
return;
}
#line 1200 "inform7/Chapter 13/Rule Subtrees.w"
; break;
case ':': if ((k>0) && (isdigit(p[k-1])) && (isdigit(p[k+1]))) break;
case ';':
if (sqb > 0)
{
#line 1301 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_TSWithPunctuation),
"a substitution contains a '.', ':' or ';'",
"which suggests that a close square bracket ']' may have gone astray.");
it_is_not_worth_adding = FALSE;
}
#line 1203 "inform7/Chapter 13/Rule Subtrees.w"
;
break;
case ',':
if (sqb > 0)
{
#line 1215 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_TSWithComma),
"a substitution contains a comma ','",
"which is against the rules, because 'say' is a special phrase in "
"which the comma divides items in a list of things to say, and so it "
"loses its ordinary meanings. Because of this, no text substitution "
"can contain a comma. "
"(If you're trying to use a value produced by a phrase with a phrase "
"option - say 'the best route from A to B, using even locked doors' - "
"you'll need to put this in a 'let' variable first and then say that, "
"or else define a better text substitution to do the job for you.)");
it_is_not_worth_adding = FALSE;
return;
}
#line 1206 "inform7/Chapter 13/Rule Subtrees.w"
;
break;
}
}
if (sqb != 0)
{
#line 1254 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_UnclosedSubstitution),
"the text here uses an open square bracket '[', which opens a substitution "
"in the text, but doesn't close it again",
"so that the result is malformed. (If you just wanted a literal open "
"square bracket, use '[bracket]'.)");
it_is_not_worth_adding = FALSE;
return;
}
#line 1210 "inform7/Chapter 13/Rule Subtrees.w"
;
}
#line 1182 "inform7/Chapter 13/Rule Subtrees.w"
;
wording A = Feeds__feed_text_expanding_strings(p);
if (Preform__parse_nt_against_word_range(verify_expanded_text_substitution_NTM, A, NULL, NULL))
Sentences__RuleSubtrees__unroll_says(cb_node, A, depth+1);
} else {
parse_node *say_term_node = ParseTree__new(INVOCATION_LIST_SAY_NT);
ParseTree__set_text(say_term_node, W);
ParseTree__graft(say_term_node, cb_node);
}
}
}
#line 1170 "inform7/Chapter 13/Rule Subtrees.w"
;
W = BW;
}
{
#line 1179 "inform7/Chapter 13/Rule Subtrees.w"
if ((Wordings__length(W) > 1) || (strcmp(Lexer__word_text(Wordings__first_wn(W)), "\"\"") != 0)) {
if ((Wordings__length(W) == 1) && (Vocabulary__test_flags(Wordings__first_wn(W), TEXTWITHSUBS_MC)) && (depth == 0)) {
char *p = Lexer__word_raw_text(Wordings__first_wn(W));
{
#line 1196 "inform7/Chapter 13/Rule Subtrees.w"
int k, sqb = 0;
for (k=0; p[k]; k++) {
switch (p[k]) {
case '[': sqb++; if (sqb > 1)
{
#line 1232 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
if ((p[k+1] == 'u') && (p[k+2] == 'n') && (p[k+3] == 'i') && (p[k+4] == 'c') &&
(p[k+5] == 'o') && (p[k+6] == 'd') && (p[k+7] == 'e') && (p[k+8] == ' ')) {
Problems__Issue__sentence_problem(_p_(PM_NestedUSubstitution),
"the text here contains one substitution '[...]' inside another",
"which is not allowed. Actually, it looks as if you might have got "
"into this by typing an exotic character as part of the name of a "
"text substitution - those get rewritten automatically as '[unicode N]' "
"for the appropriate Unicode character code number N. Either way - "
"this isn't allowed.");
} else {
Problems__Issue__sentence_problem(_p_(PM_NestedSubstitution),
"the text here contains one substitution '[...]' inside another",
"which is not allowed. (If you just wanted a literal open and closed "
"square bracket, use '[bracket]' and '[close bracket]'.)");
}
it_is_not_worth_adding = FALSE;
return;
}
#line 1199 "inform7/Chapter 13/Rule Subtrees.w"
; break;
case ']': sqb--; if (sqb < 0)
{
#line 1266 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_UnopenedSubstitution),
"the text here uses a close square bracket ']', which closes a substitution "
"in the text, but never actually opened it",
"with a matching '['. (If you just wanted a literal close square bracket, "
"use '[close bracket]'.)");
it_is_not_worth_adding = FALSE;
return;
}
#line 1200 "inform7/Chapter 13/Rule Subtrees.w"
; break;
case ':': if ((k>0) && (isdigit(p[k-1])) && (isdigit(p[k+1]))) break;
case ';':
if (sqb > 0)
{
#line 1301 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_TSWithPunctuation),
"a substitution contains a '.', ':' or ';'",
"which suggests that a close square bracket ']' may have gone astray.");
it_is_not_worth_adding = FALSE;
}
#line 1203 "inform7/Chapter 13/Rule Subtrees.w"
;
break;
case ',':
if (sqb > 0)
{
#line 1215 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_TSWithComma),
"a substitution contains a comma ','",
"which is against the rules, because 'say' is a special phrase in "
"which the comma divides items in a list of things to say, and so it "
"loses its ordinary meanings. Because of this, no text substitution "
"can contain a comma. "
"(If you're trying to use a value produced by a phrase with a phrase "
"option - say 'the best route from A to B, using even locked doors' - "
"you'll need to put this in a 'let' variable first and then say that, "
"or else define a better text substitution to do the job for you.)");
it_is_not_worth_adding = FALSE;
return;
}
#line 1206 "inform7/Chapter 13/Rule Subtrees.w"
;
break;
}
}
if (sqb != 0)
{
#line 1254 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_UnclosedSubstitution),
"the text here uses an open square bracket '[', which opens a substitution "
"in the text, but doesn't close it again",
"so that the result is malformed. (If you just wanted a literal open "
"square bracket, use '[bracket]'.)");
it_is_not_worth_adding = FALSE;
return;
}
#line 1210 "inform7/Chapter 13/Rule Subtrees.w"
;
}
#line 1182 "inform7/Chapter 13/Rule Subtrees.w"
;
wording A = Feeds__feed_text_expanding_strings(p);
if (Preform__parse_nt_against_word_range(verify_expanded_text_substitution_NTM, A, NULL, NULL))
Sentences__RuleSubtrees__unroll_says(cb_node, A, depth+1);
} else {
parse_node *say_term_node = ParseTree__new(INVOCATION_LIST_SAY_NT);
ParseTree__set_text(say_term_node, W);
ParseTree__graft(say_term_node, cb_node);
}
}
}
#line 1173 "inform7/Chapter 13/Rule Subtrees.w"
;
}
#line 1291 "inform7/Chapter 13/Rule Subtrees.w"
int verify_expanded_text_substitution_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 1301 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_TSWithPunctuation),
"a substitution contains a '.', ':' or ';'",
"which suggests that a close square bracket ']' may have gone astray.");
it_is_not_worth_adding = FALSE;
}
#line 1292 "inform7/Chapter 13/Rule Subtrees.w"
; return FAIL_NONTERMINAL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 1310 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_EmptySubstitution),
"the text here contains an empty substitution '[]'",
"which is not allowed. To say nothing - well, say nothing.");
it_is_not_worth_adding = FALSE;
}
#line 1293 "inform7/Chapter 13/Rule Subtrees.w"
; return FAIL_NONTERMINAL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 1310 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_EmptySubstitution),
"the text here contains an empty substitution '[]'",
"which is not allowed. To say nothing - well, say nothing.");
it_is_not_worth_adding = FALSE;
}
#line 1294 "inform7/Chapter 13/Rule Subtrees.w"
; return FAIL_NONTERMINAL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 1310 "inform7/Chapter 13/Rule Subtrees.w"
it_is_not_worth_adding = TRUE;
Problems__Issue__sentence_problem(_p_(PM_EmptySubstitution),
"the text here contains an empty substitution '[]'",
"which is not allowed. To say nothing - well, say nothing.");
it_is_not_worth_adding = FALSE;
}
#line 1295 "inform7/Chapter 13/Rule Subtrees.w"
; return FAIL_NONTERMINAL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1297 "inform7/Chapter 13/Rule Subtrees.w"
#line 1320 "inform7/Chapter 13/Rule Subtrees.w"
parse_node *Sentences__RuleSubtrees__end_node(parse_node *opening) {
parse_node *implicit_end = ParseTree__new(INVOCATION_LIST_NT);
ParseTree__set_end_control_structure_used(implicit_end,
ParseTree__get_control_structure_used(opening));
ParseTree__annotate_int(implicit_end, indentation_level_ANNOT,
ParseTree__int_annotation(opening, indentation_level_ANNOT));
return implicit_end;
}
#line 1335 "inform7/Chapter 13/Rule Subtrees.w"
control_structure_phrase *Sentences__RuleSubtrees__csp_new(void) {
control_structure_phrase *csp = CREATE(control_structure_phrase);
csp->subordinate_to = NULL;
csp->indent_subblocks = FALSE;
csp->body_empty_except_for_subordinates = FALSE;
csp->used_at_stage = -1;
csp->requires_new_syntax = FALSE;
csp->allow_run_on = FALSE;
csp->keyword = "<none>";
csp->is_a_loop = FALSE;
return csp;
}
void Sentences__RuleSubtrees__create_standard_csps(void) {
switch_CSP = Sentences__RuleSubtrees__csp_new();
switch_CSP->body_empty_except_for_subordinates = TRUE;
switch_CSP->indent_subblocks = TRUE;
switch_CSP->requires_new_syntax = TRUE;
switch_CSP->keyword = "if";
if_CSP = Sentences__RuleSubtrees__csp_new();
if_CSP->keyword = "if";
repeat_CSP = Sentences__RuleSubtrees__csp_new();
repeat_CSP->keyword = "repeat";
repeat_CSP->is_a_loop = TRUE;
while_CSP = Sentences__RuleSubtrees__csp_new();
while_CSP->keyword = "while";
while_CSP->is_a_loop = TRUE;
otherwise_CSP = Sentences__RuleSubtrees__csp_new();
otherwise_CSP->subordinate_to = if_CSP;
otherwise_CSP->used_at_stage = 1;
abbreviated_otherwise_CSP = Sentences__RuleSubtrees__csp_new();
abbreviated_otherwise_CSP->subordinate_to = if_CSP;
abbreviated_otherwise_CSP->used_at_stage = 1;
otherwise_if_CSP = Sentences__RuleSubtrees__csp_new();
otherwise_if_CSP->subordinate_to = if_CSP;
otherwise_if_CSP->used_at_stage = 0;
case_CSP = Sentences__RuleSubtrees__csp_new();
case_CSP->subordinate_to = switch_CSP;
case_CSP->used_at_stage = 1;
case_CSP->requires_new_syntax = TRUE;
case_CSP->allow_run_on = TRUE;
default_case_CSP = Sentences__RuleSubtrees__csp_new();
default_case_CSP->subordinate_to = switch_CSP;
default_case_CSP->used_at_stage = 2;
default_case_CSP->requires_new_syntax = TRUE;
default_case_CSP->allow_run_on = TRUE;
say_CSP = Sentences__RuleSubtrees__csp_new();
now_CSP = Sentences__RuleSubtrees__csp_new();
instead_CSP = Sentences__RuleSubtrees__csp_new();
}
void Sentences__RuleSubtrees__log_control_structure(control_structure_phrase *csp) {
if (csp == if_CSP) LOG("IF");
if (csp == repeat_CSP) LOG("RPT");
if (csp == while_CSP) LOG("WHI");
if (csp == switch_CSP) LOG("SWI");
if (csp == otherwise_CSP) LOG("O");
if (csp == abbreviated_otherwise_CSP) LOG("AO");
if (csp == otherwise_if_CSP) LOG("OIF");
if (csp == case_CSP) LOG("CAS");
if (csp == default_case_CSP) LOG("DEF");
if (csp == say_CSP) LOG("SAY");
if (csp == now_CSP) LOG("NOW");
if (csp == instead_CSP) LOG("INS");
if (csp == NULL) LOG("---");
}
int Sentences__RuleSubtrees__comma_possible(control_structure_phrase *csp) {
if ((csp == if_CSP) || (csp == switch_CSP) || (csp == otherwise_if_CSP))
return TRUE;
return FALSE;
}
int Sentences__RuleSubtrees__is_a_loop(control_structure_phrase *csp) {
if (csp) return csp->is_a_loop;
return FALSE;
}
int Sentences__RuleSubtrees__opens_block(control_structure_phrase *csp) {
if ((csp) && (csp->subordinate_to == NULL) && (csp != say_CSP) && (csp != now_CSP) && (csp != instead_CSP)) return TRUE;
return FALSE;
}
int Sentences__RuleSubtrees__permits_break(control_structure_phrase *csp) {
if ((csp == repeat_CSP) || (csp == while_CSP)) return TRUE;
return FALSE;
}
char *Sentences__RuleSubtrees__incipit(control_structure_phrase *csp) {
if (csp) return csp->keyword;
return "<none>";
}
control_structure_phrase *Sentences__RuleSubtrees__detect_control_structure(wording W) {
if (Preform__parse_nt_against_word_range(control_structure_phrase_NTM, W, NULL, NULL)) {
if (most_recent_result_p == abbreviated_otherwise_CSP) return NULL;
return most_recent_result_p;
}
return NULL;
}
int Sentences__RuleSubtrees__abbreviated_otherwise(wording W) {
if (Preform__parse_nt_against_word_range(control_structure_phrase_NTM, W, NULL, NULL)) {
if (most_recent_result_p == abbreviated_otherwise_CSP) return TRUE;
}
return FALSE;
}
control_structure_phrase *Sentences__RuleSubtrees__detect_end_control_structure(wording W) {
if (Preform__parse_nt_against_word_range(end_control_structure_phrase_NTM, W, NULL, NULL)) return most_recent_result_p;
return NULL;
}
#line 1474 "inform7/Chapter 13/Rule Subtrees.w"
int control_structure_phrase_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = switch_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = switch_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = if_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; *XP = repeat_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 0; *XP = while_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = 0; *XP = otherwise_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = 0; *XP = otherwise_if_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = 0; *XP = abbreviated_otherwise_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = 0; *XP = default_case_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *X = 0; *XP = case_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1485 "inform7/Chapter 13/Rule Subtrees.w"
int end_control_structure_phrase_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = if_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = while_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = repeat_CSP;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1490 "inform7/Chapter 13/Rule Subtrees.w"
int other_significant_phrase_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = SAY_SIGF;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = NOW_SIGF;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1494 "inform7/Chapter 13/Rule Subtrees.w"
#line 1498 "inform7/Chapter 13/Rule Subtrees.w"
int phrase_with_comma_notation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1500 "inform7/Chapter 13/Rule Subtrees.w"
#line 1504 "inform7/Chapter 13/Rule Subtrees.w"
int instead_keyword_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1507 "inform7/Chapter 13/Rule Subtrees.w"
#line 1511 "inform7/Chapter 13/Rule Subtrees.w"
int phrase_beginning_block_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1513 "inform7/Chapter 13/Rule Subtrees.w"
#line 187 "inform7/Chapter 14/Extension Files.w"
extension_file *Extensions__Files__new(wording AW, wording NW, wording VMW, int version_word) {
char violation[160]; /* enough for two lines of type */
violation[0] = 0;
extension_file *ef = CREATE(extension_file);
ef->author_text = AW;
ef->title_text = NW;
{
#line 215 "inform7/Chapter 14/Extension Files.w"
char exft[MAX_FILENAME_LENGTH], exfa[MAX_FILENAME_LENGTH];
Wordings__to_string_raw_truncated(exfa, MAX_FILENAME_LENGTH, ef->author_text);
Wordings__to_string_raw_truncated(exft, MAX_FILENAME_LENGTH, ef->title_text);
if (Extensions__Census__currently_recording_errors() == FALSE) {
if (Platform__strlen(exfa) >= MAX_EXTENSION_AUTHOR_LENGTH) {
sprintf(violation,
"has an author's name which is too long, exceeding the maximum "
"allowed (%d characters) by %d",
MAX_EXTENSION_AUTHOR_LENGTH-1,
(int) (1+Platform__strlen(exfa)-MAX_EXTENSION_AUTHOR_LENGTH));
exfa[MAX_EXTENSION_AUTHOR_LENGTH-1] = 0;
}
if (Platform__strlen(exft) >= MAX_EXTENSION_AUTHOR_LENGTH) {
sprintf(violation,
"has a title which is too long, exceeding the maximum allowed "
"(%d characters) by %d",
MAX_EXTENSION_TITLE_LENGTH-1,
(int) (1+Platform__strlen(exft)-MAX_EXTENSION_TITLE_LENGTH));
exft[MAX_EXTENSION_TITLE_LENGTH-1] = 0;
}
}
Extensions__IDs__new(&(ef->ef_id), exfa, exft, LOADED_EIDBC);
if (Extensions__IDs__is_standard_rules(&(ef->ef_id))) standard_rules_extension = ef;
}
#line 193 "inform7/Chapter 14/Extension Files.w"
;
ef->min_version_needed = version_word;
ef->inclusion_sentence = current_sentence;
ef->VM_restriction_text = VMW;
ef->body_text = EMPTY_WORDING;
ef->body_text_unbroken = FALSE;
ef->documentation_text = EMPTY_WORDING;
ef->version_loaded = -1;
ef->loaded_from_built_in_area = FALSE;
ef->authorial_modesty = FALSE;
ef->rubric_as_lexed[0] = 0;
ef->extra_credit_as_lexed[0] = 0;
if (violation[0]) Problems__Issue__extension_problem(_p_(PM_IncludesTooLong), ef, violation); /* see below */
return ef;
}
#line 252 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__set_rubric(extension_file *ef, char *text) {
Extensions__IDs__truncated_strcpy(ef->rubric_as_lexed, text, MAX_RUBRIC_LENGTH);
LOGIF(EXTENSIONS_CENSUS, "Extension rubric: %s\n", ef->rubric_as_lexed);
}
void Extensions__Files__set_extra_credit(extension_file *ef, char *text) {
Extensions__IDs__truncated_strcpy(ef->extra_credit_as_lexed, text, MAX_RUBRIC_LENGTH);
LOGIF(EXTENSIONS_CENSUS, "Extension extra credit: %s\n", ef->extra_credit_as_lexed);
}
#line 267 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__set_corresponding_source_file(extension_file *ef, source_file *sf) {
ef->read_into_file = sf;
}
source_file *Extensions__Files__get_corresponding_source_file(extension_file *ef) {
return ef->read_into_file;
}
#line 278 "inform7/Chapter 14/Extension Files.w"
extension_identifier *Extensions__Files__get_eid(extension_file *ef) {
return &(ef->ef_id);
}
#line 285 "inform7/Chapter 14/Extension Files.w"
int Extensions__Files__get_version_wn(extension_file *ef) {
return ef->version_loaded;
}
#line 295 "inform7/Chapter 14/Extension Files.w"
int general_authorial_modesty = FALSE;
void Extensions__Files__set_authorial_modesty(extension_file *ef) { ef->authorial_modesty = TRUE; }
void Extensions__Files__set_general_authorial_modesty(void) { general_authorial_modesty = TRUE; }
#line 305 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_name_to_file(extension_file *ef, OUTPUT_STREAM) {
Wordings__to_stream_raw(OUT, ef->title_text);
}
void Extensions__Files__write_author_to_file(extension_file *ef, OUTPUT_STREAM) {
Wordings__to_stream_raw(OUT, ef->author_text);
}
#line 316 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__log(extension_file *ef) {
if (ef == NULL) { LOG("<null-extension-file>"); return; }
LOG("$w by $w", ef->title_text, ef->author_text);
}
#line 325 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_I6_comment_describing(extension_file *ef, OUTPUT_STREAM) {
if (ef == standard_rules_extension) {
WRITE("! From the Standard Rules\n");
} else {
WRITE("! From \"");
Wordings__to_stream_raw_within_i6_literal(OUT, ef->title_text);
WRITE("\" by ");
Wordings__to_stream_raw_within_i6_literal(OUT, ef->author_text);
WRITE("\n");
}
}
#line 340 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_full_title_to_stream(OUTPUT_STREAM, extension_file *ef) {
Wordings__to_stream_raw(OUT, ef->title_text);
WRITE(" by ");
Wordings__to_stream_raw(OUT, ef->author_text);
}
#line 357 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__check_versions(void) {
extension_file *ef;
LOOP_OVER(ef, extension_file) {
int have = Extensions__Inclusion__parse_version(ef->version_loaded),
need = Extensions__Inclusion__parse_version(ef->min_version_needed);
if (need > have) {
LOG("Need %d, have %d\n", need, have);
current_sentence = ef->inclusion_sentence;
Problems__quote_source(1, current_sentence);
Problems__quote_extension(2, ef);
if (ef->version_loaded >= 0) {
Problems__quote_wording(3, Wordings__one_word(ef->version_loaded));
Problems__Issue__handmade_problem(_p_(PM_ExtVersionTooLow));
Problems__issue_problem_segment(
"You wrote %1: but my copy of %2 is only version %3.");
Problems__issue_problem_end();
} else {
Problems__Issue__handmade_problem(_p_(PM_ExtNoVersion));
Problems__issue_problem_segment(
"You wrote %1: but my copy of %2 contains no version "
"number, and is therefore considered to be earlier than "
"all numbered versions.");
Problems__issue_problem_end();
}
}
}
}
#line 405 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__ShowExtensionVersions_routine(OUTPUT_STREAM) {
OUT = Routines__begin(OUT, "ShowExtensionVersions");
extension_file *ef;
LOOP_OVER(ef, extension_file) {
char the_author_name[512];
Wordings__to_string_raw_truncated(the_author_name, 510, ef->author_text);
if ((ef->authorial_modesty == FALSE) && /* if (1) extension doesn't ask to be modest */
((general_authorial_modesty == FALSE) || /* and (2) author doesn't ask to be modest, or... */
(PL__Bibliographic__story_author_is(the_author_name) == FALSE))) /* ...didn't write this extension */
Extensions__Files__credit_ef(OUT, ef, TRUE); /* then we award a credit */
}
OUT = Routines__end(OUT);
OUT = Routines__begin(OUT, "ShowFullExtensionVersions");
LOOP_OVER(ef, extension_file) Extensions__Files__credit_ef(OUT, ef, TRUE);
OUT = Routines__end(OUT);
OUT = Routines__begin(OUT, "ShowOneExtension");
LocalVariables__add_named_call("id");
LOOP_OVER(ef, extension_file) {
WRITE("if (id == %d) ", ef->allocation_id + 1);
Extensions__Files__credit_ef(OUT, ef, FALSE);
}
OUT = Routines__end(OUT);
}
#line 435 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__credit_ef(OUTPUT_STREAM, extension_file *ef, int with_newline) {
WRITE("print \"%s", ef->ef_id.raw_title);
if (ef->version_loaded >= 0) {
WRITE(" version ");
Wordings__to_stream_raw(OUT, Wordings__one_word(ef->version_loaded));
}
WRITE(" by %s", ef->ef_id.raw_author_name);
if (ef->extra_credit_as_lexed[0]) WRITE(" (%s)", ef->extra_credit_as_lexed);
if (with_newline) WRITE("^");
WRITE("\";\n");
}
#line 452 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__index(void) {
INDEX("<p>EXTENSIONS</p>\n");
Extensions__Files__index_extensions_from(NULL);
extension_file *from;
LOOP_OVER(from, extension_file)
if (from != standard_rules_extension)
Extensions__Files__index_extensions_from(from);
Extensions__Files__index_extensions_from(standard_rules_extension);
INDEX("<p></p>");
}
void Extensions__Files__index_extensions_from(extension_file *from) {
int show_head = TRUE;
extension_file *ef;
LOOP_OVER(ef, extension_file) {
extension_file *owner = NULL;
if (ef == standard_rules_extension) owner = standard_rules_extension;
else if (Wordings__nonempty(ParseTree__get_text(ef->inclusion_sentence))) {
source_location sl = Wordings__location(ParseTree__get_text(ef->inclusion_sentence));
if (sl.file_of_origin == NULL) owner = standard_rules_extension;
else owner = SourceFiles__get_extension_corresponding(
Lexer__file_of_origin(Wordings__first_wn(ParseTree__get_text(ef->inclusion_sentence))));
}
if (owner != from) continue;
if (show_head) {
HTML__open_para(ifl, 2, "hanging");
INDEX("<font color=\"#888\">Included ");
if (from == standard_rules_extension) INDEX("automatically by Inform");
else if (from == NULL) INDEX("from the source text");
else {
INDEX("by the extension ");
Wordings__index_raw(from->title_text);
}
show_head = FALSE;
INDEX("</font></p>");
}
INDEX("<ul class=\"leaders\"><li class=\"leaded indent2\"><span>");
Wordings__index_raw(ef->title_text);
INDEX(" ");
Extensions__IDs__begin_extension_link(ifl, &(ef->ef_id), NULL);
INDEX("<img border=0 src=inform:/doc_images/help.png>");
Extensions__IDs__end_extension_link(ifl, &(ef->ef_id));
if (ef != standard_rules_extension) { /* give author and inclusion links, but not for SR */
INDEX(" by ");
Wordings__index_raw(ef->author_text);
}
if (ef->version_loaded >= 0) {
INDEX(" <small>version ");
Wordings__index_raw(Wordings__one_word(ef->version_loaded));
INDEX("</small>");
}
if (ef->extra_credit_as_lexed[0]) {
INDEX(" <small>(");
Text__to_stream(ifl, ef->extra_credit_as_lexed);
INDEX(")</small>");
}
INDEX("</span><span>");
INDEX("%d words", SourceFiles__total_word_count(ef->read_into_file));
if (from == NULL) Index__link(Wordings__first_wn(ParseTree__get_text(ef->inclusion_sentence)));
INDEX("</span></li></ul>\n");
}
}
#line 527 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__handle_census_mode(void) {
if (census_mode) {
Extensions__Dictionary__load();
Extensions__Census__perform();
Extensions__Files__write_top_level_of_extensions_documentation();
Extensions__Files__write_sketchy_documentation_for_extensions_found();
abort_I6T_interpreter = TRUE; /* our work is done: exit at the next graceful opportunity */
}
}
void Extensions__Files__update_census(void) {
extension_file *ef;
Extensions__Dictionary__load();
Extensions__Census__perform();
Extensions__Files__write_top_level_of_extensions_documentation();
LOOP_OVER(ef, extension_file) Extensions__Documentation__write_detailed(ef);
Extensions__Files__write_sketchy_documentation_for_extensions_found();
Extensions__Dictionary__write_back();
if (Log__aspect_switched_on(EXTENSIONS_CENSUS_DA)) Extensions__IDs__log_EID_hash_table();
}
#line 553 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_sketchy_documentation_for_extensions_found(void) {
extension_census_datum *ecd;
LOOP_OVER(ecd, extension_census_datum)
Extensions__Documentation__write_sketchy(ecd);
}
#line 588 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_top_level_of_extensions_documentation(void) {
Extensions__Files__write_top_level_extensions_page("Extensions.html", 1);
Extensions__Files__write_top_level_extensions_page("ExtIndex.html", 2);
}
#line 596 "inform7/Chapter 14/Extension Files.w"
void Extensions__Files__write_top_level_extensions_page(char *leaf, int content) {
text_stream HOMEPAGE_struct;
text_stream *HOMEPAGE = &HOMEPAGE_struct;
FILE *TEMPLATE;
filename *F = Filenames__in_folder(pathname_of_extension_docs, leaf);
if (STREAM_OPEN_TO_FILE(HOMEPAGE, F, UTF8_ENC) == FALSE)
Problems__Fatal__filename_related(
"Unable to open extensions documentation index for writing", F);
TEMPLATE = Platform__iso_fopen(filename_of_extensions_documentation_model, "r");
if (TEMPLATE == NULL)
Problems__Fatal__issue("Unable to open model extensions documentation for reading");
{
#line 621 "inform7/Chapter 14/Extension Files.w"
char line_of_template[LONGEST_LINE_IN_EX_TEMPLATE];
int skipping_between_markers = FALSE;
while (!(feof(TEMPLATE))) {
int n = Platform__truncated_iso_fgets(TEMPLATE, line_of_template, LONGEST_LINE_IN_EX_TEMPLATE);
if (n == -1) break; /* file I/O error, or end of file */
if (strcmp(line_of_template, LINE_MARKING_START_OF_CENSUS) == 0) {
HTML__begin_html_table(HOMEPAGE, NULL, TRUE, 0, 4, 0, 0, 0);
HTML__first_html_column(HOMEPAGE, 0);
WRITE_TO(HOMEPAGE, "<img src='inform:/doc_images/extensions@2x.png' border=0 width=150 height=150>");
HTML__next_html_column(HOMEPAGE, 0);
WRITE_TO(HOMEPAGE, "<div class='headingbox'>\n");
WRITE_TO(HOMEPAGE, "<div class='headingtext'>Installed Extensions</div>\n");
WRITE_TO(HOMEPAGE, "<div class='headingrubric'>Bundles of extra rules or phrases "
"to extend what Inform can do</div>\n");
WRITE_TO(HOMEPAGE, "</div>\n");
switch (content) {
case 1: Extensions__Census__write_results(HOMEPAGE); break;
case 2: Extensions__Dictionary__write_to_HTML(HOMEPAGE); break;
}
skipping_between_markers = TRUE;
}
if (skipping_between_markers == FALSE) WRITE_TO(HOMEPAGE, "%s", line_of_template);
if (strcmp(line_of_template, LINE_MARKING_END_OF_CENSUS) == 0)
skipping_between_markers = FALSE;
}
}
#line 607 "inform7/Chapter 14/Extension Files.w"
;
STREAM_CLOSE(HOMEPAGE);
fclose(TEMPLATE);
}
#line 31 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__traverse(void) {
int includes_cleared;
do {
includes_cleared = TRUE;
if (problem_count > 0) return;
parse_node *elder = NULL;
ParseTree__traverse_ppni(Extensions__Inclusion__visit, &elder, &includes_cleared);
} while (includes_cleared == FALSE);
}
void Extensions__Inclusion__visit(parse_node *pn, parse_node **elder, int *includes_cleared) {
if (ParseTree__get_type(pn) == INCLUDE_NT) {
{
#line 53 "inform7/Chapter 14/Including Extensions.w"
parse_node *title = pn->down, *author = pn->down->next;
ParseTree__set_type(pn, INCLUSION_NT); pn->down = NULL;
int l = ParseTree__push_attachment_point(pn);
Extensions__Inclusion__fulfill_request_to_include_extension(title, author);
ParseTree__pop_attachment_point(l);
}
#line 43 "inform7/Chapter 14/Including Extensions.w"
;
*includes_cleared = FALSE;
} else if (ParseTree__get_type(pn) != ROOT_NT) {
*elder = pn;
}
}
#line 72 "inform7/Chapter 14/Including Extensions.w"
int extension_title_and_version_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = -1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = -1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 77 "inform7/Chapter 14/Including Extensions.w"
int extension_unversioned_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; rest1_NTMV = Wordings__first_wn(extension_unversioned_NTM->range_result[1]); rest2_NTMV = Wordings__last_wn(extension_unversioned_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; rest1_NTMV = -1; rest2_NTMV = -1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 81 "inform7/Chapter 14/Including Extensions.w"
int extension_unversioned_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 89 "inform7/Chapter 14/Including Extensions.w"
t1_NTMV = -1; t2_NTMV = -1;
Problems__Issue__sentence_problem(_p_(PM_IncludeExtQuoted),
"the name of an included extension should be given without double "
"quotes in an Include sentence",
"so for instance 'Include Oh My God by Janice Bing.' rather than "
"'Include \"Oh My God\" by Janice Bing.')");
}
#line 83 "inform7/Chapter 14/Including Extensions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; t1_NTMV = Wordings__first_wn(W); t2_NTMV = Wordings__last_wn(W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 85 "inform7/Chapter 14/Including Extensions.w"
#line 99 "inform7/Chapter 14/Including Extensions.w"
int extension_version_NTMR(wording W, int *X, void **XP) {
#line 100 "inform7/Chapter 14/Including Extensions.w"
*X = Wordings__first_wn(W); /* actually, defer parsing by returning a word number here */
return TRUE;
}
#line 107 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__fulfill_request_to_include_extension(parse_node *p, parse_node *auth_p) {
if (ParseTree__get_type(p) == AND_NT) {
Extensions__Inclusion__fulfill_request_to_include_extension(p->down, auth_p);
Extensions__Inclusion__fulfill_request_to_include_extension(p->down->next, auth_p);
return;
}
rest1_NTMV = -1; rest2_NTMV = -1;
t1_NTMV = -1; t2_NTMV = -1;
Preform__parse_nt_against_word_range(extension_title_and_version_NTM, ParseTree__get_text(p), NULL, NULL);
wording W = Wordings__new(t1_NTMV, t2_NTMV);
wording AW = ParseTree__get_text(auth_p);
wording RW = Wordings__new(rest1_NTMV, rest2_NTMV);
int version_word = most_recent_result;
if (Wordings__nonempty(W))
{
#line 134 "inform7/Chapter 14/Including Extensions.w"
if (version_word >= 0)
Extensions__Inclusion__parse_version(version_word); /* this checks the formatting of the version number */
extension_file *requested_extension =
Extensions__Inclusion__load(AW, W, version_word, RW);
if (requested_extension->body_text_unbroken) {
Sentences__break(requested_extension->body_text, requested_extension);
requested_extension->body_text_unbroken = FALSE;
}
}
#line 122 "inform7/Chapter 14/Including Extensions.w"
;
}
#line 149 "inform7/Chapter 14/Including Extensions.w"
extension_file *Extensions__Inclusion__load(wording A, wording T,
int version_word, wording VMW) {
extension_file *ef;
LOOP_OVER(ef, extension_file)
if ((Wordings__match(ef->author_text, A)) && (Wordings__match(ef->title_text, T)))
{
#line 175 "inform7/Chapter 14/Including Extensions.w"
if (Extensions__Inclusion__parse_version(ef->min_version_needed) <
Extensions__Inclusion__parse_version(version_word)) {
ef->min_version_needed = version_word;
ef->inclusion_sentence = current_sentence;
}
return ef;
}
#line 154 "inform7/Chapter 14/Including Extensions.w"
;
ef = Extensions__Files__new(A, T, VMW, version_word);
if (problem_count == 0)
{
#line 186 "inform7/Chapter 14/Including Extensions.w"
char synopsis[MAX_FILENAME_LENGTH];
{
#line 212 "inform7/Chapter 14/Including Extensions.w"
Wordings__to_string_raw(synopsis, T);
sprintf(synopsis+Platform__strlen(synopsis), " by ");
Wordings__to_string_raw(synopsis+Platform__strlen(synopsis), A);
for (int i=0; synopsis[i]; i++) synopsis[i] =
(char) (HTML__iso_remove_accents((int) synopsis[i]));
}
#line 188 "inform7/Chapter 14/Including Extensions.w"
;
feed_t id = Feeds__begin();
switch (SourceFiles__read_extension_source_text(ef, synopsis, census_mode)) {
case ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA:
case ORIGIN_WAS_USER_EXTENSIONS_AREA:
ef->loaded_from_built_in_area = FALSE; break;
case ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA:
ef->loaded_from_built_in_area = TRUE; break;
default: /* which can happen if the extension file cannot be found */
ef->loaded_from_built_in_area = FALSE; break;
}
wording EXW = Feeds__end(id);
if (Wordings__nonempty(EXW))
{
#line 237 "inform7/Chapter 14/Including Extensions.w"
Preform__parse_nt_against_word_range(extension_body_NTM, EXW, NULL, NULL);
ef->body_text = GET_RW(extension_body_NTM, 1);
if (most_recent_result) ef->documentation_text = GET_RW(extension_body_NTM, 2);
ef->body_text_unbroken = TRUE; /* mark this to be sentence-broken */
}
#line 201 "inform7/Chapter 14/Including Extensions.w"
;
}
#line 158 "inform7/Chapter 14/Including Extensions.w"
;
return ef;
}
#line 230 "inform7/Chapter 14/Including Extensions.w"
int extension_body_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 233 "inform7/Chapter 14/Including Extensions.w"
#line 278 "inform7/Chapter 14/Including Extensions.w"
int Extensions__Inclusion__parse_version(int vwn) {
int i, rv, slashes = 0, digits = 0, slash_at = 0;
char *p, *q;
if (vwn == -1) return 0; /* an unspecified version equates to |0/000000| */
p = Lexer__word_text(vwn); q = p;
for (i=0; p[i] != 0; i++)
if (p[i] == '/') {
slashes++; if ((i == 0) || (slashes > 1)) goto Malformed;
slash_at = i; q = p+i+1;
} else {
if (!(isdigit(p[i]))) goto Malformed;
digits++;
}
if ((p[0] == '0') || (digits == 0)) goto Malformed;
if ((slashes == 0) && (digits <= 3)) /* so that |p| points to 1 to 3 digits, not starting with |0| */
return atoi(p)*1000000;
p[slash_at] = 0; /* temporarily replace the slash with a null, making |p| and |q| distinct C strings */
if (Platform__strlen(p) > 3) goto Malformed; /* now |p| points to 1 to 3 digits, not starting with |0| */
if (Platform__strlen(q) != 6) goto Malformed;
while (*q == '0') q++; /* now |q| points to 0 to 6 digits, not starting with |0| */
if (q[0] == 0) q--; /* if it was 0 digits, backspace to make it a single digit |0| */
rv = (atoi(p)*1000000) + atoi(q);
p[slash_at] = '/'; /* put the slash back over the null byte temporarily dividing the string */
return rv;
Malformed:
{
#line 313 "inform7/Chapter 14/Including Extensions.w"
LOG("Offending word number %d <%s>\n", vwn, Lexer__word_text(vwn));
Problems__Issue__sentence_problem(_p_(PM_ExtVersionMalformed),
"a version number must have the form N/DDDDDD",
"as in the example '2/040426' for release 2 made on 26 April 2004. "
"(The DDDDDD part is optional, so '3' is a legal version number too. "
"N must be between 1 and 999: in particular, there is no version 0.)");
Vocabulary__change_text_of_word(vwn, "1");
return 1000000; /* which equates to |1/000000| */
}
#line 304 "inform7/Chapter 14/Including Extensions.w"
;
}
#line 346 "inform7/Chapter 14/Including Extensions.w"
int begins_here_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; auth1_NTMV = Wordings__first_wn(begins_here_sentence_subject_NTM->range_result[1]); auth2_NTMV = Wordings__last_wn(begins_here_sentence_subject_NTM->range_result[1]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 353 "inform7/Chapter 14/Including Extensions.w"
auth1_NTMV = -1; auth2_NTMV = -1;
Problems__Issue__handmade_problem(_p_(PM_ExtMiswordedBeginsHere));
Problems__issue_problem_segment(
"has a misworded 'begins here' sentence ('%2'), which contains "
"no 'by'. Recall that every extension should begin with a "
"sentence such as 'Quantum Mechanics by Max Planck begins "
"here.', and end with a matching 'Quantum Mechanics ends "
"here.', perhaps with documentation to follow.");
Problems__issue_problem_end();
}
#line 348 "inform7/Chapter 14/Including Extensions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 349 "inform7/Chapter 14/Including Extensions.w"
#line 366 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__check_begins_here(parse_node *PN, extension_file *ef) {
current_sentence = PN; /* in case problem messages need to be issued */
Problems__quote_extension(1, ef);
Problems__quote_wording(2, ParseTree__get_text(PN));
Preform__parse_nt_against_word_range(begins_here_sentence_subject_NTM, ParseTree__get_text(PN), NULL, NULL);
wording W = Wordings__new(t1_NTMV, t2_NTMV);
wording AW = Wordings__new(auth1_NTMV, auth2_NTMV);
if (Wordings__empty(AW)) return;
ef->version_loaded = most_recent_result;
ef->VM_restriction_text = Wordings__new(rest1_NTMV, rest2_NTMV);
if (ef->version_loaded >= 0) Extensions__Inclusion__parse_version(ef->version_loaded);
if (Wordings__nonempty(ef->VM_restriction_text))
{
#line 393 "inform7/Chapter 14/Including Extensions.w"
if (Preform__parse_nt_against_word_range(platform_qualifier_NTM, ef->VM_restriction_text, NULL, NULL)) {
if (most_recent_result == PLATFORM_UNMET_HQ)
{
#line 437 "inform7/Chapter 14/Including Extensions.w"
current_sentence = ef->inclusion_sentence;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ef->title_text);
Problems__quote_wording(3, ef->author_text);
Problems__quote_wording(4, ef->VM_restriction_text);
Problems__Issue__handmade_problem(_p_(PM_ExtInadequateVM));
Problems__issue_problem_segment(
"You wrote %1: but my copy of %2 by %3 stipulates that it "
"is '%4'. That means it can only be used with certain of "
"the possible compiled story file formats, and at the "
"moment, we don't fit the requirements. (You can change "
"the format used for this project on the Settings panel.)");
Problems__issue_problem_end();
}
#line 395 "inform7/Chapter 14/Including Extensions.w"
;
} else {
{
#line 421 "inform7/Chapter 14/Including Extensions.w"
Problems__quote_extension(1, ef);
Problems__quote_wording(2, ef->VM_restriction_text);
Problems__Issue__handmade_problem(_p_(PM_ExtMalformedVM));
Problems__issue_problem_segment(
"Your source text makes use of the extension %1: but my copy "
"stipulates that it is '%2', which is a description of the required "
"story file format which I can't understand, and should be "
"something like '(for Z-machine version 5 or 8 only)'.");
Problems__issue_problem_end();
}
#line 397 "inform7/Chapter 14/Including Extensions.w"
;
}
}
#line 381 "inform7/Chapter 14/Including Extensions.w"
;
if ((Wordings__match(ef->title_text, W) == FALSE) ||
(Wordings__match(ef->author_text, AW) == FALSE))
{
#line 407 "inform7/Chapter 14/Including Extensions.w"
Problems__quote_extension(1, ef);
Problems__quote_wording(2, ParseTree__get_text(PN));
Problems__Issue__handmade_problem(_p_(PM_ExtMisidentified));
Problems__issue_problem_segment(
"The extension %1, which your source text makes use of, seems to be "
"misidentified: its 'begins here' sentence declares it as '%2'. "
"(Perhaps it was wrongly installed?)");
Problems__issue_problem_end();
return;
}
#line 385 "inform7/Chapter 14/Including Extensions.w"
;
}
#line 458 "inform7/Chapter 14/Including Extensions.w"
void Extensions__Inclusion__check_ends_here(parse_node *PN, extension_file *ef) {
wording W = Articles__remove_the(ParseTree__get_text(PN));
if ((problem_count == 0) && (Wordings__match(ef->title_text, W) == FALSE)) {
current_sentence = PN;
Problems__quote_extension(1, ef);
Problems__quote_wording(2, ParseTree__get_text(PN));
Problems__Issue__handmade_problem(_p_(PM_ExtMisidentifiedEnds));
Problems__issue_problem_segment(
"The extension %1, which your source text makes use of, seems to be "
"malformed: its 'begins here' sentence correctly identifies it, but "
"then the 'ends here' sentence calls it '%2' instead. (They need "
"to be a matching pair except that the end does not name the "
"author: for instance, 'Hocus Pocus by Jan Ackerman begins here.' "
"would match with 'Hocus Pocus ends here.')");
Problems__issue_problem_end();
return;
}
}
#line 490 "inform7/Chapter 14/Including Extensions.w"
sentence_handler BEGINHERE_SH_handler =
{ BEGINHERE_NT, -1, 0, Extensions__Inclusion__handle_extension_begins };
sentence_handler ENDHERE_SH_handler =
{ ENDHERE_NT, -1, 0, Extensions__Inclusion__handle_extension_ends };
void Extensions__Inclusion__handle_extension_begins(parse_node *PN) {
Assertions__Traverse__new_discussion(); near_start_of_extension = 1;
}
void Extensions__Inclusion__handle_extension_ends(parse_node *PN) {
near_start_of_extension = 0;
}
#line 76 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__new(extension_identifier *eid, char *an, char *ti, int context) {
unsigned int hc = 0, i;
Extensions__IDs__truncated_strcpy(eid->raw_author_name, an, MAX_EXTENSION_AUTHOR_LENGTH);
Extensions__IDs__truncated_strcpy(eid->author_name, an, MAX_EXTENSION_AUTHOR_LENGTH);
Extensions__IDs__normalise_casing(eid->author_name);
Extensions__IDs__truncated_strcpy(eid->raw_title, ti, MAX_EXTENSION_TITLE_LENGTH);
Extensions__IDs__truncated_strcpy(eid->title, ti, MAX_EXTENSION_TITLE_LENGTH);
Extensions__IDs__normalise_casing(eid->title);
char *norm_an = eid->author_name, *norm_ti = eid->title;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wsign-conversion"
for (i=0; norm_an[i]; i++) hc = hc*30011 + (norm_an[i]);
hc = hc*30011 + '/';
for (i=0; norm_ti[i]; i++) hc = hc*30011 + (norm_ti[i]);
#pragma clang diagnostic pop
hc = hc % EI_HASH_CODING_BASE;
eid->extension_id_hash_code = (int) hc;
Extensions__IDs__add_EID_to_database(eid, context);
}
void Extensions__IDs__set_raw(extension_identifier *eid, char *raw_an, char *raw_ti) {
strcpy(eid->raw_author_name, raw_an);
strcpy(eid->raw_title, raw_ti);
}
void Extensions__IDs__write_to_HTML_file(OUTPUT_STREAM, extension_identifier *eid, int fancy) {
Text__to_stream(OUT, eid->raw_title);
if (fancy) WRITE("<font color=\"#404040\">");
WRITE(" by ");
if (fancy) WRITE("</font>");
Text__to_stream(OUT, eid->raw_author_name);
}
void Extensions__IDs__write_to_I6_file(OUTPUT_STREAM, extension_identifier *eid) {
Text__to_stream(OUT, eid->raw_title);
if (Extensions__IDs__is_standard_rules(eid) == FALSE) {
WRITE(" by ");
Text__to_stream(OUT, eid->raw_author_name);
}
}
void Extensions__IDs__write_to_C_string(char *p, extension_identifier *eid) {
sprintf(p, "%s by %s", eid->raw_title, eid->raw_author_name);
}
void Extensions__IDs__write_link_to_HTML_file(OUTPUT_STREAM, extension_identifier *eid) {
WRITE("<a href='Extensions/");
Text__to_stream(OUT, eid->author_name);
WRITE("/");
Text__to_stream(OUT, eid->title);
WRITE(".html' STYLE=\"text-decoration: none\"><font color=\"#404040\">");
if (Extensions__IDs__is_standard_rules(eid)) Text__to_stream(OUT, eid->title);
else Extensions__IDs__write_to_HTML_file(OUT, eid, FALSE);
WRITE("</font></a>");
}
#line 145 "inform7/Chapter 14/Extension Identifiers.w"
int Extensions__IDs__match(extension_identifier *eid1, extension_identifier *eid2) {
if ((eid1 == NULL) || (eid2 == NULL)) internal_error("bad eid match");
if (eid1->extension_id_hash_code != eid2->extension_id_hash_code) return FALSE;
if (strcmp(eid1->author_name, eid2->author_name) != 0) return FALSE;
if (strcmp(eid1->title, eid2->title) != 0) return FALSE;
return TRUE;
}
#line 156 "inform7/Chapter 14/Extension Identifiers.w"
int Extensions__IDs__compare(extension_identifier *eid1, extension_identifier *eid2) {
int d;
if ((eid1 == NULL) || (eid2 == NULL)) internal_error("bad eid match");
d = strcmp(eid1->author_name, eid2->author_name);
if (d != 0) return d;
return strcmp(eid1->title, eid2->title);
}
int Extensions__IDs__compare_by_title(extension_identifier *eid1, extension_identifier *eid2) {
int d;
if ((eid1 == NULL) || (eid2 == NULL)) internal_error("bad eid match");
d = strcmp(eid1->title, eid2->title);
if (d != 0) return d;
return strcmp(eid1->author_name, eid2->author_name);
}
int Extensions__IDs__compare_by_date(extension_identifier *eid1, extension_identifier *eid2) {
int d;
if ((eid1 == NULL) || (eid2 == NULL)) internal_error("bad eid match");
d = strcmp(Extensions__IDs__get_sort_date(eid2), Extensions__IDs__get_sort_date(eid1));
if (d != 0) return d;
d = strcmp(eid1->title, eid2->title);
if (d != 0) return d;
return strcmp(eid1->author_name, eid2->author_name);
}
int Extensions__IDs__compare_by_length(extension_identifier *eid1, extension_identifier *eid2) {
int d;
if ((eid1 == NULL) || (eid2 == NULL)) internal_error("bad eid match");
d = strcmp(Extensions__IDs__get_sort_word_count(eid2), Extensions__IDs__get_sort_word_count(eid1));
if (d != 0) return d;
d = strcmp(eid1->title, eid2->title);
if (d != 0) return d;
return strcmp(eid1->author_name, eid2->author_name);
}
#line 197 "inform7/Chapter 14/Extension Identifiers.w"
int an_eid_for_standard_rules_created = FALSE;
extension_identifier an_eid_for_standard_rules;
int Extensions__IDs__is_standard_rules(extension_identifier *eid) {
if (an_eid_for_standard_rules_created == FALSE) {
an_eid_for_standard_rules_created = TRUE;
Extensions__IDs__new(&an_eid_for_standard_rules,
"Graham Nelson", "Standard Rules", HYPOTHETICAL_EIDBC);
}
return Extensions__IDs__match(eid, &an_eid_for_standard_rules);
}
#line 223 "inform7/Chapter 14/Extension Identifiers.w"
int EID_database_created = FALSE;
extension_identifier_database_entry *hash_of_EIDEs[EI_HASH_CODING_BASE];
void Extensions__IDs__add_EID_to_database(extension_identifier *eid, int context) {
extension_identifier_database_entry *eide;
int i, hc;
if (EID_database_created == FALSE) {
EID_database_created = TRUE;
for (hc=0; hc<EI_HASH_CODING_BASE; hc++) hash_of_EIDEs[hc] = NULL;
}
hc = eid->extension_id_hash_code;
for (eide = hash_of_EIDEs[hc]; eide; eide = eide->hash_next)
if (Extensions__IDs__match(eid, eide->eide_id)) {
eide->incidence_count[context]++;
return;
}
eide = CREATE(extension_identifier_database_entry);
eide->hash_next = hash_of_EIDEs[hc]; hash_of_EIDEs[hc] = eide;
eide->eide_id = eid;
for (i=0; i<NO_EIDB_CONTEXTS; i++) eide->incidence_count[i] = 0;
eide->incidence_count[context] = 1;
eide->last_usage_date[0] = 0;
eide->sort_usage_date[0] = 0;
eide->word_count_text[0] = 0;
}
#line 253 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__set_usage_date(extension_identifier *eid, char *date) {
extension_identifier_database_entry *eide;
int hc = eid->extension_id_hash_code;
for (eide = hash_of_EIDEs[hc]; eide; eide = eide->hash_next)
if (Extensions__IDs__match(eid, eide->eide_id)) {
strcpy(eide->last_usage_date, date);
return;
}
}
void Extensions__IDs__set_sort_date(extension_identifier *eid, char *date) {
extension_identifier_database_entry *eide;
int hc = eid->extension_id_hash_code;
for (eide = hash_of_EIDEs[hc]; eide; eide = eide->hash_next)
if (Extensions__IDs__match(eid, eide->eide_id)) {
strcpy(eide->sort_usage_date, date);
return;
}
}
char *Extensions__IDs__get_usage_date(extension_identifier *eid) {
extension_identifier_database_entry *eide;
int hc = eid->extension_id_hash_code;
for (eide = hash_of_EIDEs[hc]; eide; eide = eide->hash_next)
if (Extensions__IDs__match(eid, eide->eide_id)) {
char *p = eide->last_usage_date;
if (p[0]) return eide->last_usage_date;
if (eide->incidence_count[DICTIONARY_REFERRED_EIDBC] > 0)
return "Once upon a time";
return "Never";
}
return "---";
}
char *Extensions__IDs__get_sort_date(extension_identifier *eid) {
extension_identifier_database_entry *eide;
int hc = eid->extension_id_hash_code;
for (eide = hash_of_EIDEs[hc]; eide; eide = eide->hash_next)
if (Extensions__IDs__match(eid, eide->eide_id)) {
char *p = eide->sort_usage_date;
if (p[0]) return eide->sort_usage_date;
if (eide->incidence_count[DICTIONARY_REFERRED_EIDBC] > 0)
return "00000000000000Once upon a time";
return "00000000000000Never";
}
return "000000000000000";
}
void Extensions__IDs__set_word_count(extension_identifier *eid, int wc) {
extension_identifier_database_entry *eide;
int hc = eid->extension_id_hash_code;
for (eide = hash_of_EIDEs[hc]; eide; eide = eide->hash_next)
if (Extensions__IDs__match(eid, eide->eide_id)) {
sprintf(eide->word_count_text, "%08d words", wc);
return;
}
}
char *Extensions__IDs__get_sort_word_count(extension_identifier *eid) {
extension_identifier_database_entry *eide;
int hc = eid->extension_id_hash_code;
for (eide = hash_of_EIDEs[hc]; eide; eide = eide->hash_next)
if (Extensions__IDs__match(eid, eide->eide_id)) {
char *p = eide->word_count_text;
if (p[0]) return eide->word_count_text;
if (eide->incidence_count[DICTIONARY_REFERRED_EIDBC] > 0)
return "00000000I did read this, but forgot";
return "00000000I've never read this";
}
return "---";
}
char *Extensions__IDs__get_word_count(extension_identifier *eid) {
char *p = Extensions__IDs__get_sort_word_count(eid);
while (*p == '0') p++;
return p;
}
#line 335 "inform7/Chapter 14/Extension Identifiers.w"
int Extensions__IDs__no_times_used_in_context(extension_identifier *eid, int context) {
extension_identifier_database_entry *eide;
for (eide = hash_of_EIDEs[eid->extension_id_hash_code]; eide; eide = eide->hash_next)
if (Extensions__IDs__match(eid, eide->eide_id)) return eide->incidence_count[context];
return 0;
}
#line 345 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__log_EID_hash_table(void) {
int hc, total = 0;
LOG("Extension identifier hash table:\n");
for (hc=0; hc<EI_HASH_CODING_BASE; hc++) {
extension_identifier_database_entry *eide;
for (eide = hash_of_EIDEs[hc]; eide; eide = eide->hash_next) {
total++;
LOG("%03d %3d %3d %3d %3d %50s %50s\n",
hc, eide->incidence_count[0], eide->incidence_count[1],
eide->incidence_count[2], eide->incidence_count[3],
eide->eide_id->author_name, eide->eide_id->title);
}
}
LOG("%d entries in all\n", total);
}
#line 368 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__truncated_strcpy(char *to, char *from, int max) {
int i;
for (i=0; ((from[i]) && (i<max-1)); i++) to[i] = from[i];
to[i] = 0;
}
#line 380 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__normalise_casing(char *p) {
int i, uc;
for (i=0, uc = TRUE; p[i]; i++) {
if (uc) p[i] = Platform__toupper(p[i]);
else p[i] = Platform__tolower(p[i]);
uc = FALSE;
if (p[i] == ' ') uc = TRUE;
if (p[i] == '-') uc = TRUE;
if (p[i] == '(') uc = TRUE;
}
}
#line 397 "inform7/Chapter 14/Extension Identifiers.w"
void Extensions__IDs__begin_extension_link(OUTPUT_STREAM, extension_identifier *eid, char *rubric) {
char transcoded[2*MAX_FILENAME_LENGTH];
Platform__transcode_ISO_string_to_locale(eid->author_name, transcoded);
WRITE("<a href='inform://Extensions/Extensions/");
Extensions__IDs__escape_apostrophes(OUT, transcoded);
WRITE("/");
Platform__transcode_ISO_string_to_locale(eid->title, transcoded);
Extensions__IDs__escape_apostrophes(OUT, transcoded);
WRITE(".html' ");
if (rubric) WRITE("title=\"%s\" ", rubric);
else WRITE("title=\"%s by %s\" ", eid->raw_title, eid->raw_author_name);
WRITE("STYLE=\"text-decoration: none\">");
}
void Extensions__IDs__escape_apostrophes(OUTPUT_STREAM, char *p) {
int i;
for (i=0; p[i]; i++)
if ((p[i] == '\'') || (p[i] == '\"') || (p[i] == ' ') || (p[i] == '&') ||
(p[i] == '<') || (p[i] == '>') || (p[i] == '%'))
WRITE("%%%x", (int) p[i]);
else
WRITE("%c", p[i]);
}
void Extensions__IDs__end_extension_link(OUTPUT_STREAM, extension_identifier *eid) {
WRITE("</a>");
}
#line 54 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__perform(void) {
Extensions__Census__begin_recording_census_errors();
for (int area=0; area<NO_FS_AREAS; area++)
Extensions__Census__take_census_of_domain(pathname_of_extensions[area], area+1);
Extensions__Census__end_recording_census_errors();
}
#line 69 "inform7/Chapter 14/Extension Census.w"
pathname *current_extension_domain = NULL;
void Extensions__Census__take_census_of_domain(pathname *P, int origin) {
current_extension_domain = P;
Extensions__Census__census_from(P, TRUE, origin, "");
}
#line 96 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__census_from(pathname *P, int top_level, int origin, char *parent) {
char item_name[MAX_FILENAME_LENGTH+1];
FILE *TEMPF;
int linecount = 0;
filename *temporary_filename =
Filenames__in_folder(pathname_of_extension_docs,
(top_level)?"Temporary1.txt":"Temporary0.txt");
if (Pathnames__write_contents_to_file(temporary_filename, P) == FALSE) {
LOGIF(EXTENSIONS_CENSUS, "Unable to obtain contents of <%p>\n", P);
return;
}
TEMPF = Platform__iso_fopen(temporary_filename, "r");
if (TEMPF == NULL) Problems__Fatal__issue("Unable to open temporary file for reading");
while (Platform__truncated_locale_fgets(TEMPF, item_name, MAX_FILENAME_LENGTH+1) >= 1) {
int n = Platform__strlen(item_name) - 1;
if (n<0) continue;
LOGIF(EXTENSIONS_CENSUS, "%d: %s\n", linecount++, item_name);
if (top_level)
{
#line 141 "inform7/Chapter 14/Extension Census.w"
if (item_name[0] == '.') continue;
if (item_name[n] == FOLDER_SEPARATOR) {
item_name[n] = 0; /* remove the terminal slash: it has served its purpose */
if (strcmp(item_name, RESERVED_AUTHOR_NAME) == 0) continue;
if (Platform__strlen(item_name) > MAX_EXTENSION_TITLE_LENGTH-1) {
Extensions__Census__census_error("author name exceeds the maximum permitted length",
item_name, NULL, NULL, NULL); continue;
}
int i, fs = FALSE;
for (i=0; item_name[i]; i++) if (item_name[i] == '.') fs = TRUE;
if (fs) {
Extensions__Census__census_error("author name contains a full stop",
item_name, NULL, NULL, NULL); continue;
}
Extensions__Census__census_from(
Pathnames__subfolder(P, item_name),
FALSE, origin, item_name);
continue;
}
Extensions__Census__census_error("non-folder found where author folders should be",
item_name, NULL, NULL, NULL); continue;
}
#line 116 "inform7/Chapter 14/Extension Census.w"
else
{
#line 179 "inform7/Chapter 14/Extension Census.w"
int overridden_by_an_extension_already_found = FALSE;
char candidate_title[MAX_EXTENSION_TITLE_LENGTH + 1],
raw_title[MAX_EXTENSION_TITLE_LENGTH + 1];
char candidate_author_name[MAX_EXTENSION_TITLE_LENGTH + 1],
raw_author_name[MAX_EXTENSION_TITLE_LENGTH + 1];
char titling_line[MAX_TITLING_LINE_LENGTH], rubric_text[MAX_RUBRIC_LENGTH + 1];
char version_text[MAX_TITLING_LINE_LENGTH], requirement_text[MAX_TITLING_LINE_LENGTH];
char claimed_author_name[MAX_TITLING_LINE_LENGTH], claimed_title[MAX_TITLING_LINE_LENGTH];
if (item_name[0] == '.') continue;
if (item_name[n] == FOLDER_SEPARATOR) {
Extensions__Census__census_error("folder or application in author folder",
parent, item_name, NULL, NULL); continue;
}
if (Platform__strlen(item_name) > MAX_EXTENSION_TITLE_LENGTH-1) {
Extensions__Census__census_error("title exceeds the maximum permitted length",
parent, item_name, NULL, NULL); continue;
}
{
#line 230 "inform7/Chapter 14/Extension Census.w"
strcpy(candidate_author_name, parent);
strcpy(candidate_title, item_name);
{
#line 249 "inform7/Chapter 14/Extension Census.w"
if ((n>=5) &&
(candidate_title[n-3] == '.') &&
((candidate_title[n-2] == 'i') || (candidate_title[n-2] == 'I')) &&
(candidate_title[n-1] == '7') &&
((candidate_title[n] == 'x') || (candidate_title[n-2] == 'X')))
candidate_title[n-3] = 0;
}
#line 232 "inform7/Chapter 14/Extension Census.w"
;
strcpy(raw_title, candidate_title);
strcpy(raw_author_name, candidate_author_name);
Extensions__IDs__normalise_casing(candidate_author_name);
Extensions__IDs__normalise_casing(candidate_title);
int i, fs = FALSE;
for (i=0; candidate_title[i]; i++) if (candidate_title[i] == '.') fs = TRUE;
if (fs) {
Extensions__Census__census_error("title contains a full stop",
parent, candidate_title, NULL, NULL); continue;
}
}
#line 199 "inform7/Chapter 14/Extension Census.w"
;
{
#line 261 "inform7/Chapter 14/Extension Census.w"
FILE *EXTF;
{
#line 272 "inform7/Chapter 14/Extension Census.w"
filename *F =
Locations__of_extension(current_extension_domain,
item_name, parent, FALSE);
EXTF = Platform__iso_fopen_caseless(F, "r");
if (EXTF == NULL) {
Extensions__Census__census_error("file cannot be read",
parent, item_name, NULL, NULL); continue;
}
}
#line 262 "inform7/Chapter 14/Extension Census.w"
;
{
#line 287 "inform7/Chapter 14/Extension Census.w"
int titling_chars_read = 0, c;
titling_line[0] = 0;
while ((c = SourceFiles__utf8_fgetc(EXTF, NULL, FALSE)) != EOF) {
if (c == 0xFEFF) continue; /* skip the optional Unicode BOM pseudo-character */
if ((c == '\x0a') || (c == '\x0d') || (c == '\n')) break;
if (titling_chars_read < MAX_TITLING_LINE_LENGTH - 1)
titling_line[titling_chars_read++] = (char) c;
}
titling_line[titling_chars_read--] = 0;
Extensions__IDs__normalise_casing(titling_line);
}
#line 263 "inform7/Chapter 14/Extension Census.w"
;
{
#line 306 "inform7/Chapter 14/Extension Census.w"
int rubric_chars_read = 0, c, found_start = FALSE;
while ((c = SourceFiles__utf8_fgetc(EXTF, NULL, FALSE)) != EOF) {
if (rubric_chars_read >= MAX_RUBRIC_LENGTH) break;
if ((c == '\x0a') || (c == '\x0d') || (c == '\n') || (c == '\t')) c = ' ';
if ((c != ' ') && (found_start == FALSE)) {
if (c == '"') found_start = TRUE;
else break;
} else {
if (c == '"') break;
if (found_start) rubric_text[rubric_chars_read++] = (char) c;
}
}
rubric_text[rubric_chars_read] = 0;
}
#line 264 "inform7/Chapter 14/Extension Census.w"
;
fclose(EXTF);
}
#line 200 "inform7/Chapter 14/Extension Census.w"
;
{
#line 342 "inform7/Chapter 14/Extension Census.w"
int start = 0, end = Platform__strlen(titling_line) - 1;
while ((end>=0) && ((titling_line[end] == ' ') ||
(titling_line[end] == '\t') || (titling_line[end] == '.'))) {
titling_line[end] = 0; end--; /* trim white space or full stops from the end of the titling line */
}
if ((end < Platform__strlen(" Begin Here")) || (strcmp(titling_line+end-4, " Here") != 0)) {
Extensions__Census__census_error("appears not to be an extension (its first line does "
"not end 'begin(s) here', as extension titling lines must)",
parent, item_name, NULL, NULL); continue;
}
end -= 5; if (titling_line[end] == 's') end--;
titling_line[end+1] = 0; /* trim |"s Here"| or |" Here"| */
if (strcmp(titling_line+end-5, " Begin") != 0) {
Extensions__Census__census_error("appears not to be an extension (its first line does "
"not end 'begin(s) here', as extension titling lines must)",
parent, item_name, NULL, NULL); continue;
}
end -= 6; titling_line[end+1] = 0; /* trim |" Begin"| */
{
#line 378 "inform7/Chapter 14/Extension Census.w"
int l;
version_text[0] = 0;
if (strncmp(titling_line, "Version ", 8) == 0)
for (l=0, start=0; titling_line[l]; l++)
if (strncmp(titling_line + l, " Of ", 4) == 0) {
for (start=8; start<l; start++) version_text[start-8] = titling_line[start];
version_text[l-8] = 0;
start = l+4;
break;
}
}
#line 363 "inform7/Chapter 14/Extension Census.w"
;
if (strncmp(titling_line+start, "The ", 4) == 0) start += 4; /* advance past any |"The "| */
{
#line 394 "inform7/Chapter 14/Extension Census.w"
int l, j;
claimed_author_name[0] = 0;
claimed_title[0] = 0;
for (l=start; titling_line[l]; l++)
if (strncmp(titling_line+l, " By ", 4) == 0) {
for (j=start; j<l; j++) claimed_title[j-start] = titling_line[j];
claimed_title[l-start] = 0;
for (j=l+4; titling_line[j]; j++) claimed_author_name[j-l-4] = titling_line[j];
claimed_author_name[j-l-4] = 0;
break;
}
if ((claimed_author_name[0] == 0) || (claimed_title[0] == 0)) {
Extensions__Census__census_error("appears not to be an extension (the titling line does "
"not give both author and title)",
parent, item_name, NULL, NULL); continue;
}
}
#line 365 "inform7/Chapter 14/Extension Census.w"
;
{
#line 415 "inform7/Chapter 14/Extension Census.w"
int l;
requirement_text[0] = 0;
for (l=0; claimed_title[l]; l++)
if (claimed_title[l] == '(') {
strcpy(requirement_text, claimed_title + l);
claimed_title[l] = 0; /* truncate to just before open bracket */
while ((l>0) && (claimed_title[l-1] == ' ')) { /* trim spaces from the end */
l--; claimed_title[l] = 0;
}
break;
}
}
#line 366 "inform7/Chapter 14/Extension Census.w"
;
}
#line 201 "inform7/Chapter 14/Extension Census.w"
;
{
#line 436 "inform7/Chapter 14/Extension Census.w"
int right_leafname = FALSE, right_folder = FALSE;
if (strcmp(claimed_title, candidate_title) == 0) right_leafname = TRUE;
if (strcmp(claimed_author_name, candidate_author_name) == 0) right_folder = TRUE;
if ((right_leafname == TRUE) && (right_folder == FALSE)) {
Extensions__Census__census_error("an extension with the right filename but in the wrong "
"author's folder",
parent, item_name, claimed_author_name, claimed_title); continue;
}
if ((right_leafname == FALSE) && (right_folder == TRUE)) {
Extensions__Census__census_error("an extension stored in the correct author's folder, but "
"with the wrong filename",
parent, item_name, claimed_author_name, claimed_title); continue;
}
if ((right_leafname == FALSE) && (right_folder == FALSE)) {
Extensions__Census__census_error("an extension but with the wrong filename and put in the "
"wrong author's folder",
parent, item_name, claimed_author_name, claimed_title); continue;
}
}
#line 202 "inform7/Chapter 14/Extension Census.w"
;
{
#line 464 "inform7/Chapter 14/Extension Census.w"
extension_census_datum *other;
LOOP_OVER(other, extension_census_datum)
if ((strcmp(candidate_author_name, other->ecd_id.author_name) == 0)
&& (strcmp(candidate_title, other->ecd_id.title) == 0)
&& ((other->built_in) || (origin == ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA))) {
other->overriding_a_built_in_extension = TRUE;
overridden_by_an_extension_already_found = TRUE;
}
}
#line 203 "inform7/Chapter 14/Extension Census.w"
;
if (overridden_by_an_extension_already_found == FALSE) {
extension_census_datum *ecd;
{
#line 479 "inform7/Chapter 14/Extension Census.w"
ecd = CREATE(extension_census_datum);
Extensions__IDs__new(&(ecd->ecd_id), candidate_author_name, candidate_title, INSTALLED_EIDBC);
Extensions__IDs__set_raw(&(ecd->ecd_id), raw_author_name, raw_title);
strcpy(ecd->VM_requirement, requirement_text);
version_text[MAX_VERSION_NUMBER_LENGTH] = 0; /* truncate to maximum legal length */
strcpy(ecd->version_text, version_text);
ecd->domain = current_extension_domain;
ecd->built_in = FALSE;
if (origin == ORIGIN_WAS_BUILT_IN_EXTENSIONS_AREA) ecd->built_in = TRUE;
ecd->project_specific = FALSE;
if (origin == ORIGIN_WAS_MATERIALS_EXTENSIONS_AREA) ecd->project_specific = TRUE;
ecd->overriding_a_built_in_extension = FALSE;
ecd->next = NULL;
rubric_text[MAX_RUBRIC_LENGTH-1] = 0;
strcpy(ecd->rubric, rubric_text);
}
#line 206 "inform7/Chapter 14/Extension Census.w"
;
}
}
#line 117 "inform7/Chapter 14/Extension Census.w"
;
}
fclose(TEMPF);
}
#line 510 "inform7/Chapter 14/Extension Census.w"
int no_census_errors = 0;
text_stream CENERR_struct;
text_stream *CENERR = NULL;
void Extensions__Census__begin_recording_census_errors(void) {
no_census_errors = 0;
CENERR = NULL;
}
int Extensions__Census__currently_recording_errors(void) {
if (CENERR) return TRUE;
return FALSE;
}
void Extensions__Census__end_recording_census_errors(void) {
if (CENERR) STREAM_CLOSE(CENERR);
CENERR = NULL;
}
#line 534 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__census_error(char *message, char *auth, char *title,
char *claimed_author, char *claimed_title) {
no_census_errors++;
if (CENERR == NULL) {
CENERR = &CENERR_struct;
if (STREAM_OPEN_TO_FILE(CENERR, filename_of_extensions_census_errors, UTF8_ENC) == FALSE)
Problems__Fatal__filename_related("Unable to write census error log", filename_of_extensions_census_errors);
}
HTML__open_para(CENERR, 2, "hanging");
if (claimed_author)
WRITE_TO(CENERR, "<b>%s by %s</b> - %s (the extension says it is '%s by %s')",
title, auth, message, claimed_title, claimed_author);
else if ((auth) && (title)) WRITE_TO(CENERR, "<b>%s by %s</b> - %s", title, auth, message);
else WRITE_TO(CENERR, "<b>%s</b> - %s", auth, message);
WRITE_TO(CENERR, "</p>\n");
}
#line 557 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__warn_about_census_errors(OUTPUT_STREAM) {
if (no_census_errors == 0) return; /* no need for a warning */
if (NUMBER_CREATED(extension_census_datum) < 20) return; /* it's a short page anyway */
WRITE("<p><img border=0 src=inform:/doc_images/misinstalled.png>&nbsp;"
"<b>Warning</b>. One or more extensions are installed incorrectly: "
"see details below.</p>");
}
#line 572 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__transcribe_census_errors(OUTPUT_STREAM) {
FILE *RESULTS;
char error_line[LONGEST_POSSIBLE_CENSUS_ERROR];
if (no_census_errors == 0) return; /* nothing to include, then */
RESULTS = Platform__iso_fopen(filename_of_extensions_census_errors, "r");
if (RESULTS == NULL)
Problems__Fatal__filename_related(
"Unable to read census error log", filename_of_extensions_census_errors);
{
#line 594 "inform7/Chapter 14/Extension Census.w"
WRITE("<hr><p><img border=0 align=\"left\" src=inform:/doc_images/census_problem.png>"
"<b>Warning</b>. Inform checks the folder of user-installed extensions "
"each time it translates the source text, in order to keep this directory "
"page up to date. Each file must be a properly labelled extension (with "
"its titling line correctly identifying itself), and must be in the right "
"place - e.g. 'Marbles by Daphne Quilt' must have the filename 'Marbles.i7x' "
"(or just 'Marbles' with no file extension) and be stored in the folder "
"'Daphne Quilt'. The title should be at most %d characters long; the "
"author name, %d. At the last check, these rules were not being followed:</p>",
MAX_EXTENSION_TITLE_LENGTH, MAX_EXTENSION_AUTHOR_LENGTH);
}
#line 580 "inform7/Chapter 14/Extension Census.w"
;
while (Platform__truncated_iso_fgets(RESULTS, error_line, LONGEST_POSSIBLE_CENSUS_ERROR) >= 1) {
WRITE("%s", error_line);
WRITE("\n");
}
fclose(RESULTS);
}
#line 619 "inform7/Chapter 14/Extension Census.w"
void Extensions__Census__write_results(OUTPUT_STREAM) {
{
#line 651 "inform7/Chapter 14/Extension Census.w"
int nps = 0, nbi = 0, ni = 0;
extension_census_datum *ecd;
LOOP_OVER(ecd, extension_census_datum) {
if (ecd->project_specific) nps++;
else if (ecd->built_in) nbi++;
else ni++;
}
WRITE("<p><img src='inform:/doc_images/builtin_ext.png' border=0>&nbsp;You have "
"%d extensions built-in to this copy of Inform, marked with a grey folder "
"icon in the catalogue below.</p>",
nbi);
if (ni == 0)
WRITE("<p><img src='inform:/doc_images/folder4.png' border=0>&nbsp;You "
"have no other extensions installed at present.</p>");
else {
WRITE("<p>");
HTML__Javascript__open_file(OUT, pathname_of_extensions[EXTERNAL_FS_AREA], NULL,
"<img src='inform:/doc_images/folder4.png' border=0>");
WRITE("&nbsp;You have %d further extension%s installed. These are marked "
"with a blue folder icon in the catalogue below. (Click it to see "
"where the file is stored on your computer.) "
"For more extensions, visit <b>www.inform7.com</b>.</p>",
ni, (ni==1)?"":"s");
}
if (nps > 0) {
WRITE("<p>");
HTML__Javascript__open_file(OUT, pathname_of_extensions[INTERNAL_FS_AREA], NULL, PROJECT_SPECIFIC_SYMBOL);
WRITE("&nbsp;You have %d extension%s in the .materials folder for the "
"current project. (Click the purple folder icon to show the "
"location.) %s not available to other projects.</p>",
nps, (nps==1)?"":"s", (nps==1)?"This is":"These are");
}
}
#line 620 "inform7/Chapter 14/Extension Census.w"
;
Extensions__Census__warn_about_census_errors(OUT);
HTML__end_html_row(OUT);
HTML__end_html_table(OUT);
WRITE("<hr>");
{
#line 690 "inform7/Chapter 14/Extension Census.w"
extension_file *ef;
LOOP_OVER(ef, extension_file)
Extensions__Dictionary__time_stamp(ef);
}
#line 625 "inform7/Chapter 14/Extension Census.w"
;
int key_vms = FALSE, key_override = FALSE, key_builtin = FALSE,
key_pspec = FALSE, key_bullet = FALSE;
{
#line 698 "inform7/Chapter 14/Extension Census.w"
WRITE("<p>Sort catalogue: <a href=\"#\" style=\"text-decoration: none\" "
"onclick=\"openExtra('disp1', 'plus1'); closeExtra('disp2', 'plus2'); "
"closeExtra('disp3', 'plus3'); closeExtra('disp4', 'plus4'); "
"closeExtra('disp5', 'plus5'); return false;\">"
"<img border=0 id=\"plus1\" src=inform:/doc_images/extrarboff.png>&nbsp;By title</a> | ");
WRITE("<a href=\"#\" style=\"text-decoration: none\" "
"onclick=\"closeExtra('disp1', 'plus1'); openExtra('disp2', 'plus2'); "
"closeExtra('disp3', 'plus3'); closeExtra('disp4', 'plus4'); "
"closeExtra('disp5', 'plus5'); return false;\">"
"<img border=0 id=\"plus2\" src=inform:/doc_images/extrarbon.png>&nbsp;By author</a> | ");
WRITE("<a href=\"#\" style=\"text-decoration: none\" "
"onclick=\"closeExtra('disp1', 'plus1'); closeExtra('disp2', 'plus2'); "
"openExtra('disp3', 'plus3'); closeExtra('disp4', 'plus4'); "
"closeExtra('disp5', 'plus5'); return false;\">"
"<img border=0 id=\"plus3\" src=inform:/doc_images/extrarboff.png>&nbsp;By installation</a> | ");
WRITE("<a href=\"#\" style=\"text-decoration: none\" "
"onclick=\"closeExtra('disp1', 'plus1'); closeExtra('disp2', 'plus2'); "
"closeExtra('disp3', 'plus3'); openExtra('disp4', 'plus4'); "
"closeExtra('disp5', 'plus5'); return false;\">"
"<img border=0 id=\"plus4\" src=inform:/doc_images/extrarboff.png>&nbsp;By date used</a> | ");
WRITE("<a href=\"#\" style=\"text-decoration: none\" "
"onclick=\"closeExtra('disp1', 'plus1'); closeExtra('disp2', 'plus2'); "
"closeExtra('disp3', 'plus3'); closeExtra('disp4', 'plus4'); "
"openExtra('disp5', 'plus5'); return false;\">"
"<img border=0 id=\"plus5\" src=inform:/doc_images/extrarboff.png>&nbsp;By word count</a></p>");
}
#line 630 "inform7/Chapter 14/Extension Census.w"
;
int no_entries = NUMBER_CREATED(extension_census_datum);
extension_census_datum **sorted_census_results = Memory__I7_calloc(no_entries,
sizeof(extension_census_datum *), EXTENSION_DICTIONARY_MREASON);
int d;
for (d=1; d<=5; d++) {
{
#line 728 "inform7/Chapter 14/Extension Census.w"
char *display = "none";
if (d == CE_BY_AUTHOR) display = "block";
WRITE("<div id=\"disp%d\" style=\"display: %s;\">", d, display);
}
#line 638 "inform7/Chapter 14/Extension Census.w"
;
{
#line 753 "inform7/Chapter 14/Extension Census.w"
int i = 0;
extension_census_datum *ecd;
LOOP_OVER(ecd, extension_census_datum)
sorted_census_results[i++] = ecd;
int (*criterion)(const void *, const void *) = NULL;
switch (d) {
case CE_BY_TITLE: criterion = Extensions__Census__compare_ecd_by_title; break;
case CE_BY_AUTHOR: criterion = Extensions__Census__compare_ecd_by_author; break;
case CE_BY_INSTALL: criterion = Extensions__Census__compare_ecd_by_installation; break;
case CE_BY_DATE: criterion = Extensions__Census__compare_ecd_by_date; break;
case CE_BY_LENGTH: criterion = Extensions__Census__compare_ecd_by_length; break;
default: internal_error("no such sorting criterion");
}
qsort(sorted_census_results, (size_t) no_entries, sizeof(extension_census_datum *),
criterion);
}
#line 639 "inform7/Chapter 14/Extension Census.w"
;
{
#line 776 "inform7/Chapter 14/Extension Census.w"
HTML__begin_html_table(OUT, FIRST_STRIPE_COLOUR, TRUE, 0, 0, 2, 0, 0);
{
#line 798 "inform7/Chapter 14/Extension Census.w"
switch (d) {
case CE_BY_TITLE:
{
#line 848 "inform7/Chapter 14/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 800 "inform7/Chapter 14/Extension Census.w"
;
WRITE("Extensions in alphabetical order");
{
#line 856 "inform7/Chapter 14/Extension Census.w"
WRITE("</font>");
HTML__end_html_row(OUT);
}
#line 802 "inform7/Chapter 14/Extension Census.w"
;
break;
case CE_BY_DATE:
{
#line 848 "inform7/Chapter 14/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 805 "inform7/Chapter 14/Extension Census.w"
;
WRITE("Extensions in order of date used (most recent first)");
{
#line 856 "inform7/Chapter 14/Extension Census.w"
WRITE("</font>");
HTML__end_html_row(OUT);
}
#line 807 "inform7/Chapter 14/Extension Census.w"
;
break;
case CE_BY_LENGTH:
{
#line 848 "inform7/Chapter 14/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 810 "inform7/Chapter 14/Extension Census.w"
;
WRITE("Extensions in order of word count (longest first)");
{
#line 856 "inform7/Chapter 14/Extension Census.w"
WRITE("</font>");
HTML__end_html_row(OUT);
}
#line 812 "inform7/Chapter 14/Extension Census.w"
;
break;
}
}
#line 777 "inform7/Chapter 14/Extension Census.w"
;
int stripe = 0;
char *current_author_name = "";
int i, current_installation = -1;
for (i=0; i<no_entries; i++) {
extension_census_datum *ecd = sorted_census_results[i];
{
#line 819 "inform7/Chapter 14/Extension Census.w"
if ((d == CE_BY_AUTHOR) &&
(strcmp(current_author_name, ecd->ecd_id.author_name) != 0)) {
current_author_name = ecd->ecd_id.author_name;
{
#line 848 "inform7/Chapter 14/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 822 "inform7/Chapter 14/Extension Census.w"
;
{
#line 862 "inform7/Chapter 14/Extension Census.w"
WRITE("%s", ecd->ecd_id.raw_author_name);
extension_census_datum *ecd2;
int cu = 0, cn = 0, j;
for (j = i; j < no_entries; j++) {
ecd2 = sorted_census_results[j];
if (strcmp(current_author_name, ecd2->ecd_id.author_name) != 0) break;
if (Extensions__Census__ecd_used(ecd2)) cu++;
else cn++;
}
WRITE("&nbsp;&nbsp;<small>(%d extension%s", cu+cn, (cu+cn==1)?"":"s");
if ((cu == 0) && (cn == 1)) WRITE(", unused");
else if ((cu == 0) && (cn == 2)) WRITE(", both unused");
else if ((cu == 0) && (cn > 2)) WRITE(", all unused");
else if ((cn == 0) && (cu == 1)) WRITE(", used");
else if ((cn == 0) && (cu == 2)) WRITE(", both used");
else if ((cn == 0) && (cu > 2)) WRITE(", all used");
else if (cn+cu > 0) WRITE(", %d used, %d unused", cu, cn);
WRITE(")</small>");
}
#line 823 "inform7/Chapter 14/Extension Census.w"
;
{
#line 856 "inform7/Chapter 14/Extension Census.w"
WRITE("</font>");
HTML__end_html_row(OUT);
}
#line 824 "inform7/Chapter 14/Extension Census.w"
;
stripe = 0;
}
if ((d == CE_BY_INSTALL) && (Extensions__Census__installation_region(ecd) != current_installation)) {
current_installation = Extensions__Census__installation_region(ecd);
{
#line 848 "inform7/Chapter 14/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 829 "inform7/Chapter 14/Extension Census.w"
;
{
#line 886 "inform7/Chapter 14/Extension Census.w"
switch (current_installation) {
case 0:
WRITE("Supplied in the .materials folder&nbsp;&nbsp;<small>%p</small>",
pathname_of_extensions[INTERNAL_FS_AREA]); break;
case 1: WRITE("Built in to Inform"); break;
case 2: WRITE("User installed but overriding a built-in extension"); break;
case 3:
WRITE("User installed&nbsp;&nbsp;<small>%p</small>", pathname_of_extensions[EXTERNAL_FS_AREA]);
break;
}
}
#line 830 "inform7/Chapter 14/Extension Census.w"
;
{
#line 856 "inform7/Chapter 14/Extension Census.w"
WRITE("</font>");
HTML__end_html_row(OUT);
}
#line 831 "inform7/Chapter 14/Extension Census.w"
;
stripe = 0;
}
}
#line 783 "inform7/Chapter 14/Extension Census.w"
;
stripe = 1 - stripe;
if (stripe == 0)
HTML__first_html_column_coloured(OUT, 0, SECOND_STRIPE_COLOUR, 0);
else
HTML__first_html_column_coloured(OUT, 0, FIRST_STRIPE_COLOUR, 0);
{
#line 906 "inform7/Chapter 14/Extension Census.w"
{
#line 923 "inform7/Chapter 14/Extension Census.w"
char *bulletornot = UNINDEXED_SYMBOL;
if (Extensions__Census__ecd_used(ecd)) { bulletornot = INDEXED_SYMBOL; key_bullet = TRUE; }
WRITE("&nbsp;%s", bulletornot);
Extensions__IDs__begin_extension_link(OUT, &(ecd->ecd_id), ecd->rubric);
if (d != CE_BY_AUTHOR) {
WRITE("<font color=\"#404040\">%s", ecd->ecd_id.raw_title);
if (Platform__strlen(ecd->ecd_id.raw_title) + Platform__strlen(ecd->ecd_id.raw_author_name) > 45)
WRITE("<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
else
WRITE(" ");
WRITE("by %s</font>", ecd->ecd_id.raw_author_name);
} else {
WRITE("<font color=\"#404040\">%s</font>", ecd->ecd_id.raw_title);
}
Extensions__IDs__end_extension_link(OUT, &(ecd->ecd_id));
if (ecd->VM_requirement[0]) {
{
#line 952 "inform7/Chapter 14/Extension Census.w"
wording W = Feeds__feed_text(ecd->VM_requirement);
Feeds__feed_text("Another firebreak. ");
WRITE("&nbsp;");
VirtualMachines__write_icons(OUT, Wordings__trim_last_word(Wordings__trim_last_word(W)));
}
#line 941 "inform7/Chapter 14/Extension Census.w"
;
key_vms = TRUE;
}
}
#line 906 "inform7/Chapter 14/Extension Census.w"
;
HTML__next_html_column_nw(OUT, 0);
if (d != CE_BY_TITLE) {
{
#line 960 "inform7/Chapter 14/Extension Census.w"
if (ecd->version_text[0])
WRITE("<small>v&nbsp;%s</small>", ecd->version_text);
else
WRITE("<small>--</small>");
}
#line 909 "inform7/Chapter 14/Extension Census.w"
;
HTML__next_html_column_nw(OUT, 0);
}
{
#line 968 "inform7/Chapter 14/Extension Census.w"
char *opener = "<img src='inform:/doc_images/folder4.png' border=0>";
pathname *area = pathname_of_extensions[EXTERNAL_FS_AREA];
if (ecd->built_in) { opener = BUILT_IN_SYMBOL; key_builtin = TRUE; }
if (ecd->overriding_a_built_in_extension) {
opener = OVERRIDING_SYMBOL; key_override = TRUE;
}
if (ecd->project_specific) {
opener = PROJECT_SPECIFIC_SYMBOL; key_pspec = TRUE;
area = pathname_of_extensions[MATERIALS_FS_AREA];
}
if (ecd->built_in) WRITE("%s", opener);
else HTML__Javascript__open_file(OUT, area, ecd->ecd_id.raw_author_name, opener);
}
#line 912 "inform7/Chapter 14/Extension Census.w"
;
HTML__next_html_column_w(OUT, 0);
{
#line 984 "inform7/Chapter 14/Extension Census.w"
if ((d == CE_BY_DATE) || (d == CE_BY_INSTALL)) {
WRITE("<small>%s</small>", Extensions__IDs__get_usage_date(&(ecd->ecd_id)));
} else if (d == CE_BY_LENGTH) {
WRITE("<small>%s</small>", Extensions__IDs__get_word_count(&(ecd->ecd_id)));
} else {
if (ecd->rubric[0])
WRITE("<small>%s</small>", ecd->rubric);
else
WRITE("<small>--</small>");
}
}
#line 914 "inform7/Chapter 14/Extension Census.w"
;
}
#line 789 "inform7/Chapter 14/Extension Census.w"
;
HTML__end_html_row(OUT);
}
{
#line 838 "inform7/Chapter 14/Extension Census.w"
{
#line 848 "inform7/Chapter 14/Extension Census.w"
int span = 4;
if (d == CE_BY_TITLE) span = 3;
HTML__first_html_column_coloured(OUT, 0, CENSUS_TITLING_BG, span);
WRITE("<font color=\"%s\">&nbsp;", CENSUS_TITLING_FG);
}
#line 838 "inform7/Chapter 14/Extension Census.w"
;
WRITE("<small>%d extensions installed</small>", no_entries);
{
#line 856 "inform7/Chapter 14/Extension Census.w"
WRITE("</font>");
HTML__end_html_row(OUT);
}
#line 840 "inform7/Chapter 14/Extension Census.w"
;
}
#line 792 "inform7/Chapter 14/Extension Census.w"
;
HTML__end_html_table(OUT);
}
#line 640 "inform7/Chapter 14/Extension Census.w"
;
WRITE("</div>\n");
}
{
#line 737 "inform7/Chapter 14/Extension Census.w"
if ((key_builtin) || (key_override) || (key_bullet) || (key_vms) || (key_pspec)) {
WRITE("<p>Key: ");
if (key_bullet) WRITE("%s Used&nbsp;", INDEXED_SYMBOL);
if (key_builtin) WRITE("%s Built in&nbsp;", BUILT_IN_SYMBOL);
if (key_pspec) WRITE("%s Project specific&nbsp;", PROJECT_SPECIFIC_SYMBOL);
if (key_override) WRITE("%s Your version overrides "
"the one built in&nbsp;", OVERRIDING_SYMBOL);
if (key_vms) {
WRITE("<br>");
VirtualMachines__write_key(OUT);
}
}
}
#line 643 "inform7/Chapter 14/Extension Census.w"
;
Extensions__Census__transcribe_census_errors(OUT);
Memory__I7_free(sorted_census_results, EXTENSION_DICTIONARY_MREASON);
}
#line 998 "inform7/Chapter 14/Extension Census.w"
int Extensions__Census__installation_region(extension_census_datum *ecd) {
if (ecd->project_specific) return 0;
if (ecd->built_in) return 1;
if (ecd->overriding_a_built_in_extension) return 2;
return 3;
}
int Extensions__Census__ecd_used(extension_census_datum *ecd) {
if ((Extensions__IDs__no_times_used_in_context(
&(ecd->ecd_id), LOADED_EIDBC) > 0) ||
(Extensions__IDs__no_times_used_in_context(
&(ecd->ecd_id), DICTIONARY_REFERRED_EIDBC) > 0))
return TRUE;
return FALSE;
}
#line 1017 "inform7/Chapter 14/Extension Census.w"
int Extensions__Census__compare_ecd_by_title(const void *ecd1, const void *ecd2) {
extension_census_datum *e1 = *((extension_census_datum **) ecd1);
extension_census_datum *e2 = *((extension_census_datum **) ecd2);
return Extensions__IDs__compare_by_title(&(e1->ecd_id), &(e2->ecd_id));
}
int Extensions__Census__compare_ecd_by_author(const void *ecd1, const void *ecd2) {
extension_census_datum *e1 = *((extension_census_datum **) ecd1);
extension_census_datum *e2 = *((extension_census_datum **) ecd2);
return Extensions__IDs__compare(&(e1->ecd_id), &(e2->ecd_id));
}
int Extensions__Census__compare_ecd_by_installation(const void *ecd1, const void *ecd2) {
extension_census_datum *e1 = *((extension_census_datum **) ecd1);
extension_census_datum *e2 = *((extension_census_datum **) ecd2);
int d = Extensions__Census__installation_region(e1) - Extensions__Census__installation_region(e2);
if (d != 0) return d;
return Extensions__IDs__compare_by_title(&(e1->ecd_id), &(e2->ecd_id));
}
int Extensions__Census__compare_ecd_by_date(const void *ecd1, const void *ecd2) {
extension_census_datum *e1 = *((extension_census_datum **) ecd1);
extension_census_datum *e2 = *((extension_census_datum **) ecd2);
return Extensions__IDs__compare_by_date(&(e1->ecd_id), &(e2->ecd_id));
}
int Extensions__Census__compare_ecd_by_length(const void *ecd1, const void *ecd2) {
extension_census_datum *e1 = *((extension_census_datum **) ecd1);
extension_census_datum *e2 = *((extension_census_datum **) ecd2);
return Extensions__IDs__compare_by_length(&(e1->ecd_id), &(e2->ecd_id));
}
#line 109 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__log_entry(extension_dictionary_entry *ede) {
LOG("ede: %4d %d |%s|%s|%s|%s|\n", ede->allocation_id,
ede->erased, ede->ede_id.author_name, ede->ede_id.title,
ede->entry_text, ede->type);
}
void Extensions__Dictionary__log_extension_dictionary(void) {
extension_dictionary_entry *ede;
int n=0;
LOGIF(EXTENSIONS_CENSUS, "Extension dictionary:\n");
LOOP_OVER(ede, extension_dictionary_entry) {
n++; LOGIF(EXTENSIONS_CENSUS, "$d", ede);
}
if (n==0) LOGIF(EXTENSIONS_CENSUS, "no entries\n");
}
#line 137 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__erase_entries_of_uninstalled_extensions(void) {
extension_dictionary_entry *ede;
LOGIF(EXTENSIONS_CENSUS, "Erasure of dictionary entries for uninstalled extensions\n");
LOOP_OVER(ede, extension_dictionary_entry)
if ((ede->erased == FALSE) &&
(Extensions__IDs__no_times_used_in_context(&(ede->ede_id), INSTALLED_EIDBC) == 0)) {
ede->erased = TRUE;
LOGIF(EXTENSIONS_CENSUS, "Erased $d", ede);
}
}
#line 156 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__erase_entries(extension_file *ef) {
extension_dictionary_entry *ede;
LOGIF(EXTENSIONS_CENSUS, "Erasure of dictionary entries for $x\n", ef);
LOOP_OVER(ede, extension_dictionary_entry)
if ((ede->erased == FALSE) &&
(Extensions__IDs__match(&(ede->ede_id), &(ef->ef_id)))) {
ede->erased = TRUE;
LOGIF(EXTENSIONS_CENSUS, "Erased $d", ede);
}
}
#line 171 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__new_entry(char *category, extension_file *ef, wording W) {
char headword[MAX_ED_HEADWORD_LENGTH];
if (Wordings__nonempty(W)) { /* a safety precaution: never index the empty text */
Wordings__to_string_raw_truncated(headword, MAX_ED_HEADWORD_LENGTH, W);
Extensions__Dictionary__new_dictionary_entry_raw(category, ef->ef_id.author_name, ef->ef_id.title, headword);
}
}
void Extensions__Dictionary__new_entry_from_string(char *category, extension_file *ef, char *headword) {
Extensions__Dictionary__new_dictionary_entry_raw(category, ef->ef_id.author_name, ef->ef_id.title, headword);
}
void Extensions__Dictionary__new_dictionary_entry_raw(char *category, char *author, char *title, char *headword) {
extension_dictionary_entry *ede = CREATE(extension_dictionary_entry);
Extensions__IDs__new(&(ede->ede_id), author, title, DICTIONARY_REFERRED_EIDBC);
Extensions__IDs__truncated_strcpy(ede->entry_text, headword, MAX_ED_HEADWORD_LENGTH);
Extensions__IDs__truncated_strcpy(ede->type, category, MAX_ED_CATEGORY_LENGTH);
if (strcmp(category, "indexing") == 0) {
char *p, *udate = NULL;
char sdate[128];
int mode = 0, wc = 0, sdi = 0;
for (p = ede->entry_text; *p; p++) {
if (p[0] == '/') { mode = 1; continue; }
if (p[0] == ':') { mode = 2; continue; }
switch (mode) {
case 0:
if ((isdigit(*p)) && (sdi<127)) sdate[sdi++] = *p;
break;
case 1:
if (isdigit(*p)) wc = 10*wc + ((int) *p) - ((int) '0');
break;
case 2:
if (udate == NULL) udate = p;
break;
}
}
sdate[sdi] = 0;
if (sdi > 0) Extensions__IDs__set_sort_date(&(ede->ede_id), sdate);
if (wc > 0) Extensions__IDs__set_word_count(&(ede->ede_id), wc);
if (udate) Extensions__IDs__set_usage_date(&(ede->ede_id), udate);
}
ede->erased = FALSE;
ede->next_in_sorted_dictionary = NULL;
LOGIF(EXTENSIONS_CENSUS, "Created $d", ede);
}
#line 222 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__load(void) {
FILE *DICTF; FILE *EMPTY_DICTF;
char line_entry[MAX_ED_LINE_LENGTH];
{
#line 245 "inform7/Chapter 14/Extension Dictionary.w"
DICTF = Platform__iso_fopen(filename_of_extensions_dictionary, "r");
if (DICTF == NULL) {
LOGIF(EXTENSIONS_CENSUS, "Creating new empty dictionary file\n");
EMPTY_DICTF = Platform__iso_fopen(filename_of_extensions_dictionary, "w");
if (EMPTY_DICTF == NULL) return;
fclose(EMPTY_DICTF);
DICTF = Platform__iso_fopen(filename_of_extensions_dictionary, "r");
if (DICTF == NULL)
Problems__Fatal__filename_related(
"Unable to open dictionary file", filename_of_extensions_dictionary);
}
}
#line 226 "inform7/Chapter 14/Extension Dictionary.w"
;
LOGIF(EXTENSIONS_CENSUS, "Reading dictionary file\n");
while (Platform__truncated_iso_fgets(DICTF, line_entry, MAX_ED_LINE_LENGTH-1) >= 1)
{
#line 265 "inform7/Chapter 14/Extension Dictionary.w"
int strokes = 0, pos = 0, inpos = 0;
char author[MAX_ED_LINE_LENGTH], title[MAX_ED_LINE_LENGTH];
char headword[MAX_ED_LINE_LENGTH], category[MAX_ED_LINE_LENGTH];
author[0] = 0; title[0] = 0; headword[0] = 0; category[0] = 0;
while (strokes <= 4) {
if ((line_entry[pos] == 0) || (inpos >= MAX_ED_LINE_LENGTH-1)) break;
if (line_entry[pos] == '|') {
pos++; strokes++; inpos = 0; continue;
}
switch(strokes) {
case 1: author[inpos] = line_entry[pos]; author[++inpos] = 0; break;
case 2: title[inpos] = line_entry[pos]; title[++inpos] = 0; break;
case 3: headword[inpos] = line_entry[pos]; headword[++inpos] = 0; break;
case 4: category[inpos] = line_entry[pos]; category[++inpos] = 0; break;
}
pos++;
}
if (strokes >= 5) Extensions__Dictionary__new_dictionary_entry_raw(category, author, title, headword);
}
#line 230 "inform7/Chapter 14/Extension Dictionary.w"
;
LOGIF(EXTENSIONS_CENSUS, "Finished reading dictionary file\n");
fclose(DICTF);
}
#line 287 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__time_stamp(extension_file *ef) {
char dbuff[128];
char *ascday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
char *ascmon[] = { "January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December" };
sprintf(dbuff, "%04d%02d%02d%02d%02d%02d/%d:%s %d %s %d %02d:%02d",
the_present->tm_year+1900, the_present->tm_mon + 1, the_present->tm_mday,
the_present->tm_hour, the_present->tm_min, the_present->tm_sec,
SourceFiles__total_word_count(
Extensions__Files__get_corresponding_source_file(ef)),
ascday[the_present->tm_wday], the_present->tm_mday,
ascmon[the_present->tm_mon], the_present->tm_year+1900,
the_present->tm_hour, the_present->tm_min);
Extensions__Dictionary__new_entry_from_string("indexing", ef, dbuff);
}
#line 307 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__write_back(void) {
extension_dictionary_entry *ede;
text_stream DICTF_struct;
text_stream *DICTF = &DICTF_struct;
if (STREAM_OPEN_TO_FILE(DICTF, filename_of_extensions_dictionary, UTF8_ENC) == FALSE) return;
LOGIF(EXTENSIONS_CENSUS, "Writing dictionary file\n");
LOOP_OVER(ede, extension_dictionary_entry)
if (ede->erased == FALSE) {
LOGIF(EXTENSIONS_CENSUS, "Writing $d", ede);
{
#line 338 "inform7/Chapter 14/Extension Dictionary.w"
WRITE_TO(DICTF, "|%s|%s|%s|%s|\n",
ede->ede_id.author_name, ede->ede_id.title,
ede->entry_text, ede->type);
}
#line 319 "inform7/Chapter 14/Extension Dictionary.w"
;
} else LOGIF(EXTENSIONS_CENSUS, "Suppressing $d\n", ede);
LOGIF(EXTENSIONS_CENSUS, "Finished writing dictionary file\n");
STREAM_CLOSE(DICTF);
}
#line 356 "inform7/Chapter 14/Extension Dictionary.w"
int Extensions__Dictionary__sort_extension_dictionary(void) {
extension_dictionary_entry **sorted_extension_dictionary = NULL;
int no_entries = 0;
LOGIF(EXTENSIONS_CENSUS, "Beginning dictionary sort\n");
sorted_extension_dictionary = NULL;
{
#line 402 "inform7/Chapter 14/Extension Dictionary.w"
extension_dictionary_entry *ede;
int i, j;
LOOP_OVER(ede, extension_dictionary_entry)
if (ede->erased == FALSE) {
no_entries++;
strcpy(ede->sorting, ede->entry_text);
for (i=0, j=0; ede->entry_text[j]; j++)
if (ede->entry_text[j] != ' ')
ede->sorting[i++] = Platform__tolower(ede->entry_text[j]);
ede->sorting[i] = 0;
sprintf(ede->sorting + i, "-%09d", ede->allocation_id);
LOGIF(EXTENSIONS_CENSUS, "Sorted under '%s': $d", ede->sorting, ede);
}
}
#line 363 "inform7/Chapter 14/Extension Dictionary.w"
;
if (no_entries == 0) {
first_in_sorted_dictionary = NULL;
return 0;
}
{
#line 420 "inform7/Chapter 14/Extension Dictionary.w"
extension_dictionary_entry *ede;
int i = 0;
sorted_extension_dictionary = Memory__I7_calloc(no_entries,
sizeof(extension_dictionary_entry *), EXTENSION_DICTIONARY_MREASON);
LOOP_OVER(ede, extension_dictionary_entry) {
if (ede->erased == FALSE)
sorted_extension_dictionary[i++] = ede;
}
}
#line 370 "inform7/Chapter 14/Extension Dictionary.w"
;
qsort(sorted_extension_dictionary, (size_t) no_entries, sizeof(extension_dictionary_entry *),
Extensions__Dictionary__compare_ed_entries);
{
#line 432 "inform7/Chapter 14/Extension Dictionary.w"
int i;
first_in_sorted_dictionary = sorted_extension_dictionary[0];
for (i=0; i<no_entries-1; i++)
sorted_extension_dictionary[i]->next_in_sorted_dictionary =
sorted_extension_dictionary[i+1];
if (no_entries > 0)
sorted_extension_dictionary[no_entries-1]->next_in_sorted_dictionary = NULL;
}
#line 375 "inform7/Chapter 14/Extension Dictionary.w"
;
{
#line 443 "inform7/Chapter 14/Extension Dictionary.w"
Memory__I7_free(sorted_extension_dictionary, EXTENSION_DICTIONARY_MREASON);
}
#line 376 "inform7/Chapter 14/Extension Dictionary.w"
;
LOGIF(EXTENSIONS_CENSUS, "Sorted dictionary: %d entries\n", no_entries);
return no_entries;
}
#line 451 "inform7/Chapter 14/Extension Dictionary.w"
int Extensions__Dictionary__compare_ed_entries(const void *elem1, const void *elem2) {
const extension_dictionary_entry **e1 = (const extension_dictionary_entry **) elem1;
const extension_dictionary_entry **e2 = (const extension_dictionary_entry **) elem2;
if ((*e1 == NULL) || (*e2 == NULL))
internal_error("Disaster while sorting extension dictionary");
return strcmp((*e1)->sorting, (*e2)->sorting);
}
#line 467 "inform7/Chapter 14/Extension Dictionary.w"
known_extension_clash *Extensions__Dictionary__kec_new(extension_dictionary_entry *L, extension_dictionary_entry *R,
int first_known_flag) {
known_extension_clash *kec = CREATE(known_extension_clash);
kec->leftx = L;
kec->rightx = R;
kec->number_clashes = 1;
kec->first_known = first_known_flag;
kec->next = NULL;
return kec;
}
#line 531 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__extension_clash(extension_dictionary_entry *ede1, extension_dictionary_entry *ede2) {
extension_dictionary_entry *left = NULL, *right = NULL;
extension_identifier *leftx, *rightx;
known_extension_clash *kec;
if ((ede1 == NULL) || (ede2 == NULL)) internal_error("bad extension clash");
int d = Extensions__IDs__compare(&(ede1->ede_id), &(ede2->ede_id)); /* compare source extensions */
{
#line 561 "inform7/Chapter 14/Extension Dictionary.w"
if (d == 0) return; /* both definitions come from the same extension */
if ((strcmp(ede1->type, "property") == 0) && (strcmp(ede2->type, "property") != 0)) return;
if ((strcmp(ede1->type, "property") != 0) && (strcmp(ede2->type, "property") == 0)) return;
}
#line 539 "inform7/Chapter 14/Extension Dictionary.w"
;
if (d < 0) { left = ede1; right = ede2; }
if (d > 0) { left = ede2; right = ede1; }
leftx = &(left->ede_id); rightx = &(right->ede_id);
LOOP_OVER(kec, known_extension_clash)
if ((kec->first_known) && (Extensions__IDs__match(leftx, &(kec->leftx->ede_id)))) {
{
#line 574 "inform7/Chapter 14/Extension Dictionary.w"
while (kec) {
if (Extensions__IDs__match(rightx, &(kec->rightx->ede_id))) {
kec->number_clashes++; return;
}
if (kec->next == NULL) {
kec->next = Extensions__Dictionary__kec_new(left, right, FALSE); return;
}
kec = kec->next;
}
}
#line 547 "inform7/Chapter 14/Extension Dictionary.w"
;
return;
}
kec = Extensions__Dictionary__kec_new(left, right, TRUE);
}
#line 588 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__list_known_extension_clashes(OUTPUT_STREAM) {
known_extension_clash *kec;
if (NUMBER_CREATED(known_extension_clash) == 0) return;
{
#line 601 "inform7/Chapter 14/Extension Dictionary.w"
WRITE("<p>\n<b>Clashes found.</b> The dictionary above shows that some "
"extensions make incompatible definitions of the same words or phrases. "
"When two extensions disagree like this, it is not necessarily a bad "
"sign (they might simply be two ways to approach the same problem), "
"but in general it means that it may not be safe to use both "
"extensions at the same time. The following list shows some potential "
"clashes.<p>\n");
}
#line 591 "inform7/Chapter 14/Extension Dictionary.w"
;
LOOP_OVER(kec, known_extension_clash)
if (kec->first_known)
{
#line 613 "inform7/Chapter 14/Extension Dictionary.w"
known_extension_clash *example;
WRITE("<b>");
Extensions__IDs__write_to_HTML_file(OUT, &(kec->leftx->ede_id), FALSE);
WRITE("</b>: ");
for (example = kec; example; example = example->next) {
WRITE("clash with <b>");
Extensions__IDs__write_to_HTML_file(OUT, &(example->rightx->ede_id), FALSE);
WRITE("</b>");
if (example->number_clashes > 1)
WRITE(" (on %d names, for instance ", example->number_clashes);
else WRITE(" (on ");
Text__to_stream(OUT, example->leftx->entry_text);
WRITE(")");
if (example->next) WRITE("; ");
}
WRITE("<p>\n");
}
#line 594 "inform7/Chapter 14/Extension Dictionary.w"
;
}
#line 636 "inform7/Chapter 14/Extension Dictionary.w"
void Extensions__Dictionary__write_to_HTML(OUTPUT_STREAM) {
WRITE("<p>Whenever an extension is used, its definitions are entered into the "
"following index. (Thus, a newly installed but never-used extension "
"is not indexed yet.).</p>");
HTML__end_html_row(OUT);
HTML__end_html_table(OUT);
int n;
char first_letter = 'a';
extension_dictionary_entry *ede, *previous_ede, *next_ede;
Extensions__Dictionary__erase_entries_of_uninstalled_extensions();
n = Extensions__Dictionary__sort_extension_dictionary();
if (n <= 0) return;
for (previous_ede = NULL, ede = first_in_sorted_dictionary; ede;
previous_ede = ede, ede = ede->next_in_sorted_dictionary) {
if (strcmp(ede->type, "indexing") == 0) continue;
next_ede = ede->next_in_sorted_dictionary;
char this_first = Platform__tolower(ede->entry_text[0]);
if (first_letter != this_first) {
WRITE("<br>"); first_letter = this_first;
}
{
#line 672 "inform7/Chapter 14/Extension Dictionary.w"
int tint = FALSE;
if (EDES_DEFINE_SAME_WORD(ede, previous_ede)) tint = TRUE;
while (EDES_DEFINE_SAME_WORD(ede, next_ede)) {
tint = TRUE;
Extensions__Dictionary__extension_clash(ede, next_ede);
next_ede = next_ede->next_in_sorted_dictionary;
}
WRITE("<p style='margin:0px; padding:0px;'>");
if (tint) WRITE("<font color=\"%s\">", TINT_FOR_SAME_WORD);
Text__to_stream(OUT, ede->entry_text);
if (tint) WRITE("</font>");
WRITE(" - <i>%s</i>&nbsp;&nbsp;&nbsp;<small>", ede->type);
Extensions__IDs__write_link_to_HTML_file(OUT, &(ede->ede_id));
WRITE("</small></p>");
}
#line 656 "inform7/Chapter 14/Extension Dictionary.w"
;
}
Extensions__Dictionary__list_known_extension_clashes(OUT);
}
#line 14 "inform7/Chapter 14/Extension Documentation.w"
void Extensions__Documentation__write_detailed(extension_file *ef) {
Extensions__Documentation__write_extension_documentation(NULL, ef);
}
void Extensions__Documentation__write_sketchy(extension_census_datum *ecd) {
Extensions__Documentation__write_extension_documentation(ecd, NULL);
}
#line 40 "inform7/Chapter 14/Extension Documentation.w"
void Extensions__Documentation__write_extension_documentation(extension_census_datum *ecd, extension_file *ef) {
int c, eg_count;
eg_count = Extensions__Documentation__write_extension_documentation_page(ecd, ef, -1);
for (c=1; c<=eg_count; c++)
Extensions__Documentation__write_extension_documentation_page(ecd, ef, c);
}
#line 61 "inform7/Chapter 14/Extension Documentation.w"
int Extensions__Documentation__write_extension_documentation_page(extension_census_datum *ecd, extension_file *ef,
int eg_number) {
extension_identifier *eid = NULL;
text_stream DOCF_struct;
text_stream *DOCF = &DOCF_struct;
FILE *TEST_DOCF;
int page_exists_already, no_egs = 0;
char leaf[MAX_FILENAME_LENGTH];
if (ecd) eid = &(ecd->ecd_id); else if (ef) eid = &(ef->ef_id);
else internal_error("WEDP incorrectly called");
LOGIF(EXTENSIONS_CENSUS, "WEDP %s (%s by %s)/%d\n",
(ecd)?"ecd":" ef", eid->title, eid->author_name, eg_number);
strcpy(leaf, eid->title);
if (eg_number > 0) sprintf(leaf+Platform__strlen(leaf), "-eg%d", eg_number);
filename *name = Locations__of_extension_documentation(leaf, eid->author_name);
page_exists_already = FALSE;
TEST_DOCF = Platform__iso_fopen(name, "r");
if (TEST_DOCF) { page_exists_already = TRUE; fclose(TEST_DOCF); }
LOGIF(EXTENSIONS_CENSUS, "WEDP %s: %f\n", (page_exists_already)?"exists":"does not exist",
name);
if (ecd) {
if ((page_exists_already == FALSE) || (census_mode))
{
#line 116 "inform7/Chapter 14/Extension Documentation.w"
feed_t id = Feeds__begin();
Feeds__feed_text(eid->raw_author_name);
Feeds__feed_text(" ");
wording AW = Feeds__end(id);
id = Feeds__begin();
Feeds__feed_text(eid->raw_title);
Feeds__feed_text(" ");
wording TW = Feeds__end(id);
Feeds__feed_text("This sentence provides a firebreak, no more. ");
if (Preform__parse_nt_against_word_range(unsuitable_name_NTM, AW, NULL, NULL)) return 0;
if (Preform__parse_nt_against_word_range(unsuitable_name_NTM, TW, NULL, NULL)) return 0;
ef = Extensions__Inclusion__load(AW, TW, -1, EMPTY_WORDING);
if (ef == NULL) return 0; /* shouldn't happen: it was there only moments ago */
Extensions__Documentation__write_extension_documentation(NULL, ef);
}
#line 88 "inform7/Chapter 14/Extension Documentation.w"
;
return 0; /* ensure no requests sent for further pages about the ECD: see below */
}
if (ef == NULL) internal_error("null EF in extension documentation writer");
if (Pathnames__create_in_file_system(
Pathnames__subfolder(pathname_of_extension_docs_inner, eid->author_name)) == 0)
return 0;
if (STREAM_OPEN_TO_FILE(DOCF, name, UTF8_ENC) == FALSE)
return 0; /* if we lack permissions, e.g., then write no documentation */
{
#line 138 "inform7/Chapter 14/Extension Documentation.w"
FILE *TEMPLATE = Platform__iso_fopen(filename_of_extension_file_documentation_model, "r");
if (TEMPLATE == NULL)
Problems__Fatal__filename_related("Unable to open model extension documentation file for reading",
filename_of_extension_file_documentation_model);
char line_of_template[LONGEST_LINE_IN_EX_TEMPLATE];
int skipping_between_markers = FALSE;
while (!(feof(TEMPLATE))) {
int n = Platform__truncated_iso_fgets(TEMPLATE, line_of_template, LONGEST_LINE_IN_EX_TEMPLATE);
if (n < 0) break; /* file I/O error or end of file */
if (strcmp(line_of_template, "<a name=on>") == 0) {
{
#line 162 "inform7/Chapter 14/Extension Documentation.w"
WRITE_TO(DOCF, "<p>");
if (Extensions__IDs__is_standard_rules(eid) == FALSE)
{
#line 180 "inform7/Chapter 14/Extension Documentation.w"
char inclusion_text[MAX_EXTENSION_TITLE_LENGTH + MAX_EXTENSION_AUTHOR_LENGTH + 50];
sprintf(inclusion_text, "Include %s by %s.\n\n\n", eid->title, eid->author_name);
HTML__Javascript__paste(DOCF, inclusion_text);
WRITE_TO(DOCF, "&nbsp;");
}
#line 164 "inform7/Chapter 14/Extension Documentation.w"
;
WRITE_TO(DOCF, "<b>");
Extensions__IDs__write_to_HTML_file(DOCF, eid, TRUE);
WRITE_TO(DOCF, "</b><p><small>");
{
#line 188 "inform7/Chapter 14/Extension Documentation.w"
if (Wordings__nonempty(ef->VM_restriction_text)) {
Wordings__to_stream_raw(DOCF, ef->VM_restriction_text);
WRITE_TO(DOCF, "&nbsp;");
VirtualMachines__write_icons(DOCF, ef->VM_restriction_text);
}
}
#line 168 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 197 "inform7/Chapter 14/Extension Documentation.w"
char the_version[MAX_VERSION_NUMBER_LENGTH+1];
if (ef->version_loaded >= 0)
Wordings__to_string_raw(the_version, Wordings__one_word(ef->version_loaded));
else the_version[0] = 0;
if (the_version[0]) WRITE_TO(DOCF, "<p>Version %s", the_version);
if (ef->loaded_from_built_in_area) {
if (the_version[0] == 0) WRITE_TO(DOCF, "<p>Extension");
WRITE_TO(DOCF, " built in to Inform");
}
}
#line 169 "inform7/Chapter 14/Extension Documentation.w"
;
WRITE_TO(DOCF, "</small><p>");
{
#line 211 "inform7/Chapter 14/Extension Documentation.w"
if (ef->rubric_as_lexed[0])
WRITE_TO(DOCF, "%s<p>", ef->rubric_as_lexed);
if (ef->extra_credit_as_lexed[0])
WRITE_TO(DOCF, "<i>%s</i><p>", ef->extra_credit_as_lexed);
}
#line 171 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 222 "inform7/Chapter 14/Extension Documentation.w"
if (Wordings__nonempty(ef->documentation_text))
HTML__Documentation__set_table_of_contents(ef->documentation_text, DOCF, leaf);
}
#line 172 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 241 "inform7/Chapter 14/Extension Documentation.w"
Extensions__Dictionary__erase_entries(ef);
Extensions__Dictionary__time_stamp(ef);
{
#line 262 "inform7/Chapter 14/Extension Documentation.w"
kind *K;
int kc = 0;
LOOP_OVER_BASE_KINDS(K) {
parse_node *S = Kinds__Behaviour__get_creating_sentence(K);
if (S) {
if (Lexer__file_of_origin(Wordings__first_wn(ParseTree__get_text(S))) == ef->read_into_file) {
wording W = Kinds__Behaviour__get_name(K, FALSE);
kc = Extensions__Documentation__document_headword(DOCF, kc, ef, "Kinds", "kind", W);
kind *S = Kinds__Compare__super(K);
if (S) {
W = Kinds__Behaviour__get_name(S, FALSE);
if (Wordings__nonempty(W)) {
WRITE_TO(DOCF, " (a kind of ");
Wordings__to_stream_raw(DOCF, W);
WRITE_TO(DOCF, ")");
}
}
}
}
}
if (kc != 0) WRITE_TO(DOCF, "<p>");
}
#line 244 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 287 "inform7/Chapter 14/Extension Documentation.w"
instance *I;
int kc = 0;
LOOP_OVER_OBJECT_INSTANCES(I) {
wording OW = Instances__get_name(I, FALSE);
if ((Instances__get_creating_sentence(I)) && (Wordings__nonempty(OW))) {
if (Lexer__file_of_origin(
Wordings__first_wn(ParseTree__get_text(Instances__get_creating_sentence(I))))
== ef->read_into_file) {
char name_of_its_kind[512];
kind *k = Instances__to_kind(I);
wording W = Kinds__Behaviour__get_name(k, FALSE);
Wordings__to_string_raw(name_of_its_kind, W);
kc = Extensions__Documentation__document_headword(DOCF, kc, ef, "Physical creations",
name_of_its_kind, OW);
WRITE_TO(DOCF, " (a ");
Wordings__to_stream_raw(DOCF, W);
WRITE_TO(DOCF, ")");
}
}
}
if (kc != 0) WRITE_TO(DOCF, "<p>");
}
#line 245 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 312 "inform7/Chapter 14/Extension Documentation.w"
nonlocal_variable *q;
int kc = 0;
LOOP_OVER(q, nonlocal_variable)
if ((Wordings__first_wn(q->name) >= 0) &&
(NonlocalVariables__is_global(q)) &&
(Lexer__file_of_origin(Wordings__first_wn(q->name)) == ef->read_into_file) &&
(Sentences__Headings__indexed(Wordings__heading_of(q->name)))) {
if (Preform__parse_nt_against_word_range(value_understood_variable_name_NTM, q->name, NULL, NULL) == FALSE)
kc = Extensions__Documentation__document_headword(DOCF,
kc, ef, "Values that vary", "value", q->name);
}
if (kc != 0) WRITE_TO(DOCF, "<p>");
}
#line 247 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 328 "inform7/Chapter 14/Extension Documentation.w"
instance *q;
int kc = 0;
LOOP_OVER_ENUMERATION_INSTANCES(q) {
wording NW = Instances__get_name(q, FALSE);
if ((Wordings__nonempty(NW)) && (Lexer__file_of_origin(Wordings__first_wn(NW)) == ef->read_into_file))
kc = Extensions__Documentation__document_headword(DOCF, kc, ef, "Values", "value", NW);
}
if (kc != 0) WRITE_TO(DOCF, "<p>");
}
#line 248 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 340 "inform7/Chapter 14/Extension Documentation.w"
named_action_pattern *nap;
int kc = 0;
LOOP_OVER(nap, named_action_pattern)
if (Lexer__file_of_origin(Wordings__first_wn(nap->text_of_declaration)) == ef->read_into_file)
kc = Extensions__Documentation__document_headword(DOCF, kc, ef, "Kinds of action", "kind of action",
nap->text_of_declaration);
if (kc != 0) WRITE_TO(DOCF, "<p>");
}
#line 250 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 351 "inform7/Chapter 14/Extension Documentation.w"
action_name *acn;
int kc = 0;
LOOP_OVER(acn, action_name)
if (Lexer__file_of_origin(Wordings__first_wn(acn->present_name)) == ef->read_into_file)
kc = Extensions__Documentation__document_headword(DOCF, kc, ef, "Actions", "action",
acn->present_name);
if (kc != 0) WRITE_TO(DOCF, "<p>");
}
#line 251 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 362 "inform7/Chapter 14/Extension Documentation.w"
Index__Lexicon__list_verbs_in_file(DOCF, ef->read_into_file, ef);
}
#line 253 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 367 "inform7/Chapter 14/Extension Documentation.w"
adjectival_phrase *adj;
int kc = 0;
LOOP_OVER(adj, adjectival_phrase) {
wording W = Adjectives__Phrases__get_text(adj, FALSE);
if ((Wordings__nonempty(W)) &&
(Lexer__file_of_origin(Wordings__first_wn(W)) == ef->read_into_file))
kc = Extensions__Documentation__document_headword(DOCF, kc, ef, "Adjectives", "adjective", W);
}
if (kc != 0) WRITE_TO(DOCF, "<p>");
}
#line 254 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 380 "inform7/Chapter 14/Extension Documentation.w"
property *prn;
int kc = 0;
LOOP_OVER(prn, property)
if ((Wordings__nonempty(prn->name)) &&
(Properties__is_shown_in_index(prn)) &&
(Lexer__file_of_origin(Wordings__first_wn(prn->name)) == ef->read_into_file))
kc = Extensions__Documentation__document_headword(DOCF, kc, ef, "Properties", "property",
prn->name);
if (kc != 0) WRITE_TO(DOCF, "<p>");
}
#line 255 "inform7/Chapter 14/Extension Documentation.w"
;
{
#line 393 "inform7/Chapter 14/Extension Documentation.w"
use_option *uo;
int kc = 0;
LOOP_OVER(uo, use_option)
if ((Wordings__first_wn(uo->name) >= 0) &&
(Lexer__file_of_origin(Wordings__first_wn(uo->name)) == ef->read_into_file))
kc = Extensions__Documentation__document_headword(DOCF, kc, ef, "Use options", "use option",
uo->name);
if (kc != 0) WRITE_TO(DOCF, "<p>");
}
#line 257 "inform7/Chapter 14/Extension Documentation.w"
;
}
#line 173 "inform7/Chapter 14/Extension Documentation.w"
;
WRITE_TO(DOCF, "<p><hr><p>");
{
#line 228 "inform7/Chapter 14/Extension Documentation.w"
if (Wordings__nonempty(ef->documentation_text))
no_egs = HTML__Documentation__set_body_text(ef->documentation_text, DOCF, eg_number, leaf);
else
WRITE_TO(DOCF, "The extension provides no documentation.");
}
#line 175 "inform7/Chapter 14/Extension Documentation.w"
;
}
#line 149 "inform7/Chapter 14/Extension Documentation.w"
;
skipping_between_markers = TRUE;
}
if (skipping_between_markers == FALSE) WRITE_TO(DOCF, "%s", line_of_template);
if (strcmp(line_of_template, "<a name=off>") == 0)
skipping_between_markers = FALSE;
}
fclose(TEMPLATE);
}
#line 100 "inform7/Chapter 14/Extension Documentation.w"
;
STREAM_CLOSE(DOCF);
return no_egs;
}
#line 407 "inform7/Chapter 14/Extension Documentation.w"
int Extensions__Documentation__document_headword(OUTPUT_STREAM, int kc, extension_file *ef, char *par_heading,
char *category, wording W) {
if (kc++ == 0) WRITE("%s: ", par_heading);
else WRITE(", ");
WRITE("<b>");
Wordings__to_stream_raw(OUT, W);
WRITE("</b>");
Extensions__Dictionary__new_entry(category, ef, W);
return kc;
}
#line 99 "inform7/Chapter 15/Traverse for Assertions.w"
int sentence_handlers_initialised = FALSE;
parse_node *assembly_position = NULL; /* where assembled sentences are added */
void Assertions__Traverse__traverse(int pass) {
Assertions__Traverse__new_discussion(); /* clear memory of what the subject and object of discussion are */
traverse = pass;
trace_sentences = FALSE;
if (sentence_handlers_initialised == FALSE)
{
#line 155 "inform7/Chapter 15/Traverse for Assertions.w"
sentence_handlers_initialised = TRUE;
{
#line 169 "inform7/Chapter 15/Traverse for Assertions.w"
int i;
for (i=0; i<MAX_OF_NTS_AND_VBS; i++) {
how_to_handle_nodes[i] = NULL;
how_to_handle_sentences[i] = NULL;
}
}
#line 156 "inform7/Chapter 15/Traverse for Assertions.w"
;
TemplateFiles__register_sentence_handlers();
}
#line 107 "inform7/Chapter 15/Traverse for Assertions.w"
;
parse_node *last = NULL;
ParseTree__traverse_ppn(Assertions__Traverse__visit, &last);
if (pass == 2)
{
#line 137 "inform7/Chapter 15/Traverse for Assertions.w"
current_sentence = last;
assembly_position = current_sentence;
Plugins__Call__complete_model(1);
ParseTree__traverse_from_ppn(last, Assertions__Traverse__visit, &last);
}
#line 112 "inform7/Chapter 15/Traverse for Assertions.w"
;
}
#line 145 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__visit(parse_node *p, parse_node **last) {
assembly_position = current_sentence;
{
#line 178 "inform7/Chapter 15/Traverse for Assertions.w"
if ((p->down) && (p->down->next)) {
parse_node *apparent_subject = p->down->next;
if ((ParseTree__get_type(apparent_subject) == WITH_NT) &&
(apparent_subject->down) &&
(apparent_subject->down->next)) {
wording W = Wordings__up_to(ParseTree__get_text(apparent_subject->down),
Wordings__last_wn(ParseTree__get_text(apparent_subject->down->next)));
parse_node *ap = SParser__parse_excerpt(MISCELLANEOUS_MC, W);
if (Rvalues__is_CONSTANT_of_kind(ap, K_action_name)) {
ParseTree__set_type_and_clear_annotations(apparent_subject, PROPER_NOUN_NT);
ParseTree__set_text(apparent_subject, W);
apparent_subject->down = NULL;
}
}
}
}
#line 147 "inform7/Chapter 15/Traverse for Assertions.w"
;
*last = p;
{
#line 197 "inform7/Chapter 15/Traverse for Assertions.w"
if ((trace_sentences) && (ParseTree__get_type(p) != TRACE_NT))
LOG("\n[$w]\n", ParseTree__get_text(p));
{
#line 209 "inform7/Chapter 15/Traverse for Assertions.w"
if (ParseTree__get_type(p) == ROOT_NT) return;
int n = (int) (ParseTree__get_type(p) - BASE_OF_ENUMERATED_NTS);
if (((n >= 0) && (n < MAX_OF_NTS_AND_VBS)) && (how_to_handle_nodes[n])) {
int desired = how_to_handle_nodes[n]->handle_on_traverse;
if (((traverse == desired) || (desired == 0)) &&
(how_to_handle_nodes[n]->handling_routine))
(*(how_to_handle_nodes[n]->handling_routine))(p);
return;
}
}
#line 200 "inform7/Chapter 15/Traverse for Assertions.w"
;
LOG("$T\n", p);
internal_error("uncaught assertion");
}
#line 149 "inform7/Chapter 15/Traverse for Assertions.w"
;
}
#line 227 "inform7/Chapter 15/Traverse for Assertions.w"
sentence_handler TRACE_SH_handler =
{ TRACE_NT, -1, 0, Assertions__Traverse__switch_sentence_trace };
void Assertions__Traverse__switch_sentence_trace(parse_node *PN) {
if (Wordings__length(ParseTree__get_text(PN)) > 1) {
int tr = telemetry_recording;
telemetry_recording = TRUE;
Log__write_to_telemetry_file(Lexer__word_text(Wordings__last_wn(ParseTree__get_text(PN))));
telemetry_recording = FALSE;
Problems__Issue__sentence_problem(_p_(PM_TelemetryAccepted),
"that's a message for the Author, not me",
"so I'll note it down in the Telemetry file (if you're keeping one.)");
telemetry_recording = tr;
} else {
trace_sentences = 1 - trace_sentences;
if (traverse == 1) Log__tracing_on(trace_sentences, "Pass 1");
else Log__tracing_on(trace_sentences, "Pass 2");
}
}
#line 253 "inform7/Chapter 15/Traverse for Assertions.w"
sentence_handler SENTENCE_SH_handler =
{ SENTENCE_NT, -1, 0, Assertions__Traverse__handle_sentence_with_primary_verb };
void Assertions__Traverse__handle_sentence_with_primary_verb(parse_node *p) {
prevailing_mood = UNKNOWN_CE;
if (ParseTree__int_annotation(p, language_element_ANNOT)) return;
if (ParseTree__int_annotation(p, you_can_ignore_ANNOT)) return;
if (p->down == NULL)
{
#line 274 "inform7/Chapter 15/Traverse for Assertions.w"
if ((Wordings__length(ParseTree__get_text(p)) == 1) &&
(Vocabulary__test_flags(Wordings__first_wn(ParseTree__get_text(p)), TEXT_MC+TEXTWITHSUBS_MC))) {
if (traverse == 2) Assertions__Traverse__set_appearance(Wordings__first_wn(ParseTree__get_text(p)));
return;
}
Preform__parse_nt_against_word_range(no_verb_diagnosis_NTM, ParseTree__get_text(p), NULL, NULL);
return;
}
#line 261 "inform7/Chapter 15/Traverse for Assertions.w"
;
internal_error_if_node_type_wrong(p->down, AVERB_NT);
prevailing_mood = ParseTree__int_annotation(p->down, verbal_certainty_ANNOT);
{
#line 364 "inform7/Chapter 15/Traverse for Assertions.w"
if ((p->down->next) && (p->down->next->next)) {
if ((Wordings__mismatched_brackets(ParseTree__get_text(p->down->next))) ||
(Wordings__mismatched_brackets(ParseTree__get_text(p->down->next->next)))) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2,
Wordings__one_word(Wordings__last_wn(ParseTree__get_text(p->down->next)) + 1));
Problems__quote_wording(3, ParseTree__get_text(p->down->next));
Problems__quote_wording(4, ParseTree__get_text(p->down->next->next));
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
if (Wordings__nonempty(ParseTree__get_text(p->down->next->next)))
Problems__issue_problem_segment(
"I must be misreading the sentence %1. The verb "
"looks to me like '%2', but then the brackets don't "
"match in what I have left: '%3' and '%4'.");
else
Problems__issue_problem_segment(
"I must be misreading the sentence %1. The verb "
"looks to me like '%2', but then the brackets don't "
"match in what I have left: '%3'.");
Problems__issue_problem_end();
return;
}
}
}
#line 264 "inform7/Chapter 15/Traverse for Assertions.w"
;
{
#line 288 "inform7/Chapter 15/Traverse for Assertions.w"
int vn = ParseTree__int_annotation(p->down, verb_id_ANNOT);
if ((vn < 0) || (vn >= MAX_OF_NTS_AND_VBS)) {
LOG("Unimplemented verb %d\n", ParseTree__int_annotation(p->down, verb_id_ANNOT));
internal_error_on_node_type(p->down);
}
if (how_to_handle_sentences[vn]) {
int desired = how_to_handle_sentences[vn]->handle_on_traverse;
if (((traverse == desired) || (desired == 0)) &&
(how_to_handle_sentences[vn]->handling_routine))
(*(how_to_handle_sentences[vn]->handling_routine))(p);
}
}
#line 265 "inform7/Chapter 15/Traverse for Assertions.w"
;
}
#line 306 "inform7/Chapter 15/Traverse for Assertions.w"
int no_verb_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 315 "inform7/Chapter 15/Traverse for Assertions.w"
Problems__Issue__sentence_problem(_p_(PM_RuleWithoutColon),
"I can't find a verb that I know how to deal with, so can't do anything "
"with this sentence. It looks as if it might be a rule definition",
"but if so then it is lacking the necessary colon (or comma). "
"The punctuation style for rules is 'Rule conditions: do this; "
"do that; do some more.' Perhaps you used a full stop instead "
"of the colon?");
}
#line 307 "inform7/Chapter 15/Traverse for Assertions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 326 "inform7/Chapter 15/Traverse for Assertions.w"
Problems__Issue__sentence_problem(_p_(PM_IfOutsidePhrase),
"I can't find a verb that I know how to deal with. This looks like an 'if' "
"phrase which has slipped its moorings",
"so I am ignoring it. ('If' phrases, like all other such "
"instructions, belong inside definitions of rules or phrases - "
"not as sentences which have no context. Maybe a full stop or a "
"skipped line was accidentally used instead of semicolon, so that you "
"inadvertently ended the last rule early?)");
}
#line 308 "inform7/Chapter 15/Traverse for Assertions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 338 "inform7/Chapter 15/Traverse for Assertions.w"
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_NoSuchVerbComma));
Problems__issue_problem_segment(
"In the sentence %1, I can't find a verb that I know how to deal with. "
"(I notice there's a comma here, which is sometimes used to abbreviate "
"rules which would normally be written with a colon - for instance, "
"'Before taking: say \"You draw breath.\"' can be abbreviated to 'Before "
"taking, say...' - but that's only allowed for Before, Instead and "
"After rules. I mention all this in case you meant this sentence "
"as a rule in some rulebook, but used a comma where there should "
"have been a colon ':'?)");
Problems__issue_problem_end();
}
#line 309 "inform7/Chapter 15/Traverse for Assertions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 354 "inform7/Chapter 15/Traverse for Assertions.w"
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_NoSuchVerb));
Problems__issue_problem_segment(
"In the sentence %1, I can't find a verb that I know how to deal with.");
Problems__issue_problem_end();
}
#line 310 "inform7/Chapter 15/Traverse for Assertions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 311 "inform7/Chapter 15/Traverse for Assertions.w"
#line 399 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__set_appearance(int wn) {
if (near_start_of_extension >= 1)
{
#line 415 "inform7/Chapter 15/Traverse for Assertions.w"
source_file *pos = Lexer__file_of_origin(wn);
extension_file *ef = SourceFiles__get_extension_corresponding(pos);
if (ef) {
Text__dequote_word(wn);
char *quoted_text = Lexer__word_text(wn);
switch (near_start_of_extension++) {
case 1: Extensions__Files__set_rubric(ef, quoted_text); break;
case 2: Extensions__Files__set_extra_credit(ef, quoted_text);
near_start_of_extension = 0; break;
}
}
return;
}
#line 400 "inform7/Chapter 15/Traverse for Assertions.w"
;
inference_subject *infs = Assertions__Traverse__get_current_subject();
if (infs == NULL)
{
#line 431 "inform7/Chapter 15/Traverse for Assertions.w"
Problems__Issue__sentence_problem(_p_(PM_TextWithoutSubject),
"I'm not sure what you're referring to",
"that is, I can't decide to what room or thing you intend that text to belong. "
"Perhaps you could rephrase this more explicitly? ('The description of the Inner "
"Sanctum is...')");
return;
}
#line 403 "inform7/Chapter 15/Traverse for Assertions.w"
;
parse_node *spec = Rvalues__from_wording(Wordings__one_word(wn));
Properties__Appearance__infer(infs, spec);
}
#line 464 "inform7/Chapter 15/Traverse for Assertions.w"
inference_subject *object_of_sentences = NULL, *subject_of_sentences = NULL;
int subject_seems_to_be_plural = FALSE;
inference_subject *Assertions__Traverse__get_current_subject(void) {
return subject_of_sentences;
}
inference_subject *Assertions__Traverse__get_current_object(void) {
return object_of_sentences;
}
int Assertions__Traverse__get_current_subject_plurality(void) {
return subject_seems_to_be_plural;
}
#line 494 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__new_discussion(void) {
if (subject_of_sentences)
LOGIF(PRONOUNS, "[Forgotten subject of sentences: $j]\n", subject_of_sentences);
if (subject_of_sentences)
LOGIF(PRONOUNS, "[Forgotten object of sentences: $j]\n", object_of_sentences);
subject_of_sentences = NULL; object_of_sentences = NULL;
}
void Assertions__Traverse__change_discussion_topic(inference_subject *infsx,
inference_subject *infsy, inference_subject *infsy_full) {
inference_subject *old_sub = subject_of_sentences, *old_obj = object_of_sentences;
subject_seems_to_be_plural = FALSE;
if (Wordings__length(ParseTree__get_text(current_sentence)) > 1) near_start_of_extension = 0;
ParseTree__set_interpretation_of_subject(current_sentence, subject_of_sentences);
if (ParseTree__has_annotation(current_sentence, implicit_in_creation_of_ANNOT))
return;
if ((PL__Map__is_a_direction(infsx)) &&
((InferenceSubjects__as_object_instance(infsx) == NULL) ||
(InferenceSubjects__as_object_instance(infsy_full)))) infsx = NULL;
if (infsx) subject_of_sentences = infsx;
if ((infsy) && (InferenceSubjects__domain(infsy) == NULL)) object_of_sentences = infsy;
else if (infsx) object_of_sentences = infsx;
if (subject_of_sentences != old_sub)
LOGIF(PRONOUNS, "[Changed subject of sentences to $j]\n",
subject_of_sentences);
if (object_of_sentences != old_obj)
LOGIF(PRONOUNS, "[Changed object of sentences to $j]\n",
object_of_sentences);
}
#line 529 "inform7/Chapter 15/Traverse for Assertions.w"
void Assertions__Traverse__subject_of_discussion_a_list(void) {
subject_seems_to_be_plural = TRUE;
}
#line 39 "inform7/Chapter 15/To Be and To Have.w"
sentence_handler ASSERT_SH_handler = { SENTENCE_NT, ASSERT_VB, 0, Assertions__Copular__to_be };
void Assertions__Copular__to_be(parse_node *pv) {
parse_node *px = pv->down->next;
parse_node *py = pv->down->next->next;
if ((Wordings__length(ParseTree__get_text(px)) > 1)
&& (Vocabulary__test_flags(
Wordings__first_wn(ParseTree__get_text(px)), TEXT_MC+TEXTWITHSUBS_MC))) {
Problems__Issue__sentence_problem(_p_(PM_TextNotClosing),
"it looks as if perhaps you did not intend that to read as a "
"single sentence",
"and possibly the text in quotes was supposed to stand as "
"as a sentence on its own? (The convention is that if text "
"ends in a full stop, exclamation or question mark, perhaps "
"with a close bracket or quotation mark involved as well, then "
"that punctuation mark also closes the sentence to which the "
"text belongs: but otherwise the words following the quoted "
"text are considered part of the same sentence.)");
return;
}
Assertions__Copular__make_assertion(px, py);
}
#line 75 "inform7/Chapter 15/To Be and To Have.w"
sentence_handler HAS_SH_handler = { SENTENCE_NT, HAS_VB, 0, Assertions__Copular__to_have };
void Assertions__Copular__to_have(parse_node *pv) {
parse_node *px = pv->down->next;
parse_node *py = pv->down->next->next;
{
#line 97 "inform7/Chapter 15/To Be and To Have.w"
if (ParseTree__get_type(py) == X_OF_Y_NT) {
Problems__Issue__sentence_problem(_p_(PM_SuperfluousOf),
"the 'of' here appears superfluous",
"assuming the sentence aims to give a property value of something. "
"(For instance, if we want to declare the carrying capacity of "
"something, the normal Inform practice is to say 'The box has "
"carrying capacity 10' rather than 'The box has a carrying capacity "
"of 10'.)");
return;
}
if (ParseTree__get_type(py) == WITH_NT) {
Problems__Issue__sentence_problem(_p_(PM_SuperfluousWith),
"the 'has ... with' here appears to be a mixture of two ways to "
"give something properties",
"that is, 'The box is a container with capacity 10.' and 'The box "
"has capacity 10.'");
return;
}
}
#line 81 "inform7/Chapter 15/To Be and To Have.w"
;
if (ParseTree__get_type(py) == CALLED_NT)
{
#line 120 "inform7/Chapter 15/To Be and To Have.w"
if (Wordings__match(ParseTree__get_text(py->down->next), ParseTree__get_text(py->down))) {
Problems__Issue__sentence_problem(_p_(PM_SuperfluousCalled),
"'called' should be used only when the name is different from the kind",
"so this sentence should be simplified. For example, 'A door has a "
"colour called colour' should be written more simply as 'A door has "
"a colour'; but 'called' can be used for something like 'A door has "
"a number called the street number'.");
return;
} else {
ParseTree__set_type(py, PROPERTYCALLED_NT);
if (ParseTree__get_type(py->down) == AND_NT) {
int L = ParseTree__left_edge_of(py->down),
R = ParseTree__right_edge_of(py->down);
Preform__parse_nt_against_word_range(nounphrase_articled_NTM, Wordings__new(L, R), NULL, NULL);
parse_node *pn = most_recent_result_p;
pn->next = py->down->next;
py->down = pn;
LOG("Thus $T", py);
}
px->next = ParseTree__new(ALLOWED_NT);
px->next->down = py;
int prohibited = Preform__parse_nt_against_word_range(prohibited_property_owners_NTM, ParseTree__get_text(px), NULL, NULL);
if (!prohibited) {
Preform__parse_nt_against_word_range(nounphrase_articled_list_NTM, ParseTree__get_text(py->down->next), NULL, NULL);
py->down->next = most_recent_result_p;
}
}
py = px->next;
}
#line 84 "inform7/Chapter 15/To Be and To Have.w"
else if (Preform__parse_nt_against_word_range(k_kind_NTM, ParseTree__get_text(py), NULL, NULL))
{
#line 157 "inform7/Chapter 15/To Be and To Have.w"
px->next = ParseTree__new(ALLOWED_NT);
px->next->down = py;
py = px->next;
}
#line 86 "inform7/Chapter 15/To Be and To Have.w"
else
{
#line 165 "inform7/Chapter 15/To Be and To Have.w"
ParseTree__set_type(py, PROPERTY_LIST_NT);
}
#line 88 "inform7/Chapter 15/To Be and To Have.w"
;
ParseTree__annotate_int(pv->down, verb_id_ANNOT, ASSERT_VB);
Assertions__Copular__to_be(pv); /* and start again as if it had been |ASSERT_VB| all along */
}
#line 186 "inform7/Chapter 15/To Be and To Have.w"
void Assertions__Copular__make_assertion(parse_node *px, parse_node *py) {
if (traverse == 1) {
int pc = problem_count;
if (!(Preform__parse_nt_against_word_range(s_existential_np_NTM, ParseTree__get_text(px), NULL, NULL)))
Assertions__Refiner__refine(px, ALLOW_CREATION);
Assertions__Refiner__refine(py, ALLOW_CREATION);
if (problem_count > pc) return;
if (Assertions__Creator__consult_the_creator(px, py) == FALSE) return;
}
if (trace_sentences) ParseTree__log_subtree(current_sentence);
if (Preform__parse_nt_against_word_range(s_existential_np_NTM, ParseTree__get_text(px), NULL, NULL)) {
if (traverse == 1) Assertions__Copular__make_existential_assertion(py);
px = py;
} else {
Assertions__Maker__make_assertion_recursive(px, py);
}
{
#line 221 "inform7/Chapter 15/To Be and To Have.w"
inference_subject *infsx = NULL, *infsy = NULL, *infsy_full = NULL;
infsx = Assertions__Copular__discussed_at_node(px);
infsy_full = Assertions__Copular__discussed_at_node(py);
if (ParseTree__get_type(py) != KIND_NT) infsy = ParseTree__get_subject(py);
Assertions__Traverse__change_discussion_topic(infsx, infsy, infsy_full);
if (ParseTree__get_type(px) == AND_NT) Assertions__Traverse__subject_of_discussion_a_list();
if (ParseTree__int_annotation(current_sentence, clears_pronouns_ANNOT))
Assertions__Traverse__new_discussion();
}
#line 203 "inform7/Chapter 15/To Be and To Have.w"
;
}
#line 233 "inform7/Chapter 15/To Be and To Have.w"
inference_subject *Assertions__Copular__discussed_at_node(parse_node *pn) {
inference_subject *infs = NULL;
if (ParseTree__get_type(pn) != KIND_NT) infs = ParseTree__get_subject(pn);
if ((ParseTree__get_type(pn) == RELATIONSHIP_NT) && (pn->down) &&
(ParseTree__get_type(pn->down) == PROPER_NOUN_NT))
infs = ParseTree__get_subject(pn->down);
if ((ParseTree__get_type(pn) == WITH_NT) && (pn->down) &&
(ParseTree__get_type(pn->down) == PROPER_NOUN_NT))
infs = ParseTree__get_subject(pn->down);
return infs;
}
#line 248 "inform7/Chapter 15/To Be and To Have.w"
void Assertions__Copular__make_existential_assertion(parse_node *py) {
if (ParseTree__get_type(py) == WITH_NT) {
Assertions__Copular__make_existential_assertion(py->down); return;
}
if (ParseTree__get_type(py) == AND_NT) {
Assertions__Copular__make_existential_assertion(py->down);
Assertions__Copular__make_existential_assertion(py->down->next);
return;
}
if (ParseTree__get_type(py) == COMMON_NOUN_NT) {
if ((InferenceSubjects__is_a_kind_of_object(ParseTree__get_subject(py))) ||
(Kinds__Compare__eq(K_object, InferenceSubjects__as_kind(ParseTree__get_subject(py)))))
Assertions__Creator__convert_instance_to_nounphrase(py, NULL);
else
Problems__Issue__sentence_problem(_p_(PM_ThereIsVague),
"'there is...' can only be used to create objects",
"and not instances of other kinds.'");
}
}
#line 20 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__noun_from_infs(parse_node *p, inference_subject *infs) {
Assertions__Refiner__pn_make_COMMON_or_PROPER(p, infs);
ParseTree__set_evaluation(p, InferenceSubjects__as_constant(infs));
}
void Assertions__Refiner__noun_from_value(parse_node *p, parse_node *spec) {
inference_subject *infs = NULL;
if (Specifications__to_proposition(spec)) {
pcalc_prop *prop = Specifications__to_proposition(spec);
parse_node *val = Calculus__Propositions__describes_value(prop);
if (val) infs = InferenceSubjects__from_specification(val);
else {
kind *K = Calculus__Variables__kind_of_variable_0(prop);
if (Kinds__Compare__lt(K, K_object) == FALSE) K = K_object;
infs = Kinds__Behaviour__as_subject(K);
}
Assertions__Refiner__pn_noun_details_from_spec(p, spec);
} else infs = InferenceSubjects__from_specification(spec);
Assertions__Refiner__pn_make_COMMON_or_PROPER(p, infs);
ParseTree__set_evaluation(p, spec);
}
#line 51 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__pn_noun_details_from_spec(parse_node *p, parse_node *spec) {
pcalc_prop *prop = Descriptions__get_quantified_prop(spec);
ParseTree__set_creation_proposition(p, Calculus__Propositions__copy(prop));
int N = Descriptions__get_quantification_parameter(spec);
if (N > 0) ParseTree__annotate_int(p, multiplicity_ANNOT, N);
}
#line 70 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__pn_make_COMMON_or_PROPER(parse_node *p, inference_subject *infs) {
if ((infs) && (InferenceSubjects__domain(infs))) ParseTree__set_type(p, COMMON_NOUN_NT);
else ParseTree__set_type(p, PROPER_NOUN_NT);
ParseTree__set_subject(p, infs);
}
#line 82 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__copy_noun_details(parse_node *to, parse_node *from) {
ParseTree__set_type(to, ParseTree__get_type(from));
ParseTree__set_evaluation(to, ParseTree__get_evaluation(from));
ParseTree__set_creation_proposition(to, ParseTree__get_creation_proposition(from));
ParseTree__set_subject(to, ParseTree__get_subject(from));
ParseTree__annotate_int(to, multiplicity_ANNOT, ParseTree__int_annotation(from, multiplicity_ANNOT));
ParseTree__annotate_int(to, nowhere_ANNOT, ParseTree__int_annotation(from, nowhere_ANNOT));
ParseTree__annotate_int(to, creation_site_ANNOT, ParseTree__int_annotation(from, creation_site_ANNOT));
}
#line 104 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__pn_make_adjective(parse_node *p, adjective_usage *ale, parse_node *spec) {
adjectival_phrase *aph = Adjectives__Usages__get_aph(ale);
ParseTree__set_type(p, ADJECTIVE_NT);
ParseTree__set_aph(p, aph);
ParseTree__set_evaluation(p, NULL);
Assertions__Refiner__pn_noun_details_from_spec(p, spec);
if (Adjectives__Usages__get_parity(ale)) ParseTree__annotate_int(p, negated_boolean_ANNOT, FALSE);
else ParseTree__annotate_int(p, negated_boolean_ANNOT, TRUE);
}
#line 118 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__coerce_adjectival_usage_to_noun(parse_node *leaf) {
if ((leaf) && (ParseTree__get_type(leaf) == ADJECTIVE_NT)) {
instance *q = Adjectives__Phrases__has_ENUMERATIVE_meaning(ParseTree__get_aph(leaf));
if (q) Assertions__Refiner__noun_from_value(leaf, Rvalues__from_instance(q));
}
}
#line 137 "inform7/Chapter 15/Refine Parse Tree.w"
int forbid_nowhere = FALSE;
void Assertions__Refiner__refine(parse_node *p, int creation_rule) {
if (p == NULL) internal_error("Refine parse tree on null pn");
if (ParseTree__int_annotation(p, resolved_ANNOT)) return;
ParseTree__annotate_int(p, resolved_ANNOT, TRUE);
LOGIF(NOUN_RESOLUTION, "Refine subtree (%s creation):\n$T",
((creation_rule == FORBID_CREATION)?"forbid":
((creation_rule == ALLOW_CREATION)?"allow":"mandate")), p);
LOG_INDENT;
Assertions__Refiner__refine_parse_tree_inner(p, creation_rule);
LOG_OUTDENT;
LOGIF(NOUN_RESOLUTION, "Refined subtree is:\n$T", p);
}
#line 158 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__refine_parse_tree_inner(parse_node *p, int creation_rule) {
switch(ParseTree__get_type(p)) {
case X_OF_Y_NT:
{
#line 175 "inform7/Chapter 15/Refine Parse Tree.w"
Assertions__Refiner__refine(p->down, creation_rule);
Assertions__Refiner__refine(p->down->next, FORBID_CREATION);
}
#line 160 "inform7/Chapter 15/Refine Parse Tree.w"
; return;
case WITH_NT:
{
#line 186 "inform7/Chapter 15/Refine Parse Tree.w"
Assertions__Refiner__refine(p->down, creation_rule);
Assertions__Refiner__perform_with_surgery(p);
if (ParseTree__get_type(p) == WITH_NT) {
wording W = Wordings__new(Wordings__first_wn(ParseTree__get_text(p->down)),
Wordings__last_wn(ParseTree__get_text(p->down->next)));
if (Wordings__nonempty(W)) {
if (Preform__parse_nt_against_word_range(action_pattern_NTM, W, NULL, NULL)) {
ParseTree__set_type(p, ACTION_NT);
ParseTree__set_action_meaning(p, most_recent_result_p);
ParseTree__set_text(p, W); p->down = NULL;
}
}
}
if (ParseTree__int_annotation(p, resolved_ANNOT) == FALSE)
{
#line 204 "inform7/Chapter 15/Refine Parse Tree.w"
ParseTree__annotate_int(p, resolved_ANNOT, FALSE);
Assertions__Refiner__refine(p, creation_rule);
return;
}
#line 199 "inform7/Chapter 15/Refine Parse Tree.w"
;
}
#line 161 "inform7/Chapter 15/Refine Parse Tree.w"
; return;
case AND_NT:
{
#line 211 "inform7/Chapter 15/Refine Parse Tree.w"
Assertions__Refiner__refine(p->down, creation_rule);
Assertions__Refiner__refine(p->down->next, creation_rule);
Assertions__Refiner__perform_and_surgery(p);
}
#line 162 "inform7/Chapter 15/Refine Parse Tree.w"
; return;
case RELATIONSHIP_NT:
{
#line 253 "inform7/Chapter 15/Refine Parse Tree.w"
Assertions__Refiner__perform_location_surgery(p);
if (ParseTree__get_type(p) == AND_NT)
{
#line 204 "inform7/Chapter 15/Refine Parse Tree.w"
ParseTree__annotate_int(p, resolved_ANNOT, FALSE);
Assertions__Refiner__refine(p, creation_rule);
return;
}
#line 254 "inform7/Chapter 15/Refine Parse Tree.w"
;
if (p->down) {
Assertions__Refiner__refine(p->down, creation_rule);
binary_predicate *bp = ParseTree__get_relationship(p);
if (bp) {
instance *dir = PL__MapDirections__get_mapping_direction(BinaryPredicates__get_reversal(bp));
if (dir == NULL) dir = PL__MapDirections__get_mapping_direction(bp);
if (dir)
{
#line 273 "inform7/Chapter 15/Refine Parse Tree.w"
LOGIF(NOUN_RESOLUTION, "Directional predicate with BP %s ($O)\n",
BinaryPredicates__get_log_name(bp), dir);
ParseTree__annotate_int(p, relationship_node_type_ANNOT, DIRECTION_RELN);
wording DW = Instances__get_name(dir, FALSE);
p->down->next = Sentences__NPs__new_raw(DW);
Assertions__Refiner__noun_from_infs(p->down->next, Instances__as_subject(dir));
ParseTree__annotate_int(p->down->next, resolved_ANNOT, TRUE);
}
#line 262 "inform7/Chapter 15/Refine Parse Tree.w"
;
}
if (p->down->next) Assertions__Refiner__refine(p->down->next, creation_rule);
}
}
#line 163 "inform7/Chapter 15/Refine Parse Tree.w"
; return;
case CALLED_NT:
{
#line 226 "inform7/Chapter 15/Refine Parse Tree.w"
if ((ParseTree__get_type(p->down) == RELATIONSHIP_NT) && (p->down->down)) {
Assertions__Refiner__perform_called_surgery(p);
{
#line 204 "inform7/Chapter 15/Refine Parse Tree.w"
ParseTree__annotate_int(p, resolved_ANNOT, FALSE);
Assertions__Refiner__refine(p, creation_rule);
return;
}
#line 228 "inform7/Chapter 15/Refine Parse Tree.w"
;
}
Assertions__Refiner__refine(p->down, FORBID_CREATION);
if (ParseTree__int_annotation(p->down, multiplicity_ANNOT) > 1) {
Problems__Issue__sentence_problem(_p_(PM_MultipleCalled),
"I can only make a single 'called' thing at a time",
"or rather, the 'called' is only allowed to apply to one thing "
"at a time. For instance, 'A thing called a vodka and tonic is "
"on the table.' is allowed, but 'Two things called vodka and tonic' "
"is not.");
}
forbid_nowhere = TRUE;
if (creation_rule == FORBID_CREATION)
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"'called' can't be used in this context",
"and is best reserved for full sentences.");
else Assertions__Refiner__refine(p->down->next, MANDATE_CREATION);
forbid_nowhere = FALSE;
}
#line 164 "inform7/Chapter 15/Refine Parse Tree.w"
; return;
case KIND_NT:
{
#line 288 "inform7/Chapter 15/Refine Parse Tree.w"
inference_subject *kind_of_what = Kinds__Behaviour__as_subject(K_object);
if (p->down) {
parse_node *what = p->down;
Assertions__Refiner__refine(what, FORBID_CREATION);
kind_of_what = ParseTree__get_subject(what);
}
if ((kind_of_what == NULL) || (InferenceSubjects__domain(kind_of_what) == NULL))
{
#line 305 "inform7/Chapter 15/Refine Parse Tree.w"
if ((InferenceSubjects__is_an_object(kind_of_what)) ||
(InferenceSubjects__is_a_kind_of_object(kind_of_what))) {
Problems__Issue__sentence_problem(_p_(PM_KindOfInstance),
"kinds can only be made from other kinds",
"so 'a kind of container' is allowed but 'a kind of Mona Lisa' (where "
"Mona Lisa is a specific thing you've already made), wouldn't be "
"allowed. There is only one Mona Lisa.");
kind_of_what = Kinds__Behaviour__as_subject(K_object);
} else {
Problems__Issue__sentence_problem(_p_(PM_KindOfActualValue),
"I don't recognise that as a kind",
"such as 'room' or 'door': it would need to be straightforwardly the name "
"of a kind, and not be qualified with adjectives like 'open'.");
kind_of_what = Kinds__Behaviour__as_subject(K_value);
}
}
#line 295 "inform7/Chapter 15/Refine Parse Tree.w"
;
if ((InferenceSubjects__as_nonobject_kind(kind_of_what)) &&
(kind_of_what != Kinds__Behaviour__as_subject(K_value)) &&
(kind_of_what != Kinds__Behaviour__as_subject(K_object)))
{
#line 324 "inform7/Chapter 15/Refine Parse Tree.w"
Problems__Issue__sentence_problem(_p_(PM_KindOfExotica),
"you are only allowed to create kinds of objects (things, rooms, and "
"so on) and kinds of 'value'",
"so for example 'colour is a kind of value' is allowed but 'prime is "
"a kind of number' is not.");
kind_of_what = Kinds__Behaviour__as_subject(K_value);
}
#line 299 "inform7/Chapter 15/Refine Parse Tree.w"
;
ParseTree__set_subject(p, kind_of_what);
}
#line 165 "inform7/Chapter 15/Refine Parse Tree.w"
; return;
case PROPER_NOUN_NT:
{
#line 339 "inform7/Chapter 15/Refine Parse Tree.w"
{
#line 357 "inform7/Chapter 15/Refine Parse Tree.w"
if (ParseTree__int_annotation(p, implicitly_refers_to_ANNOT)) {
Plugins__Call__refine_implicit_noun(p);
return;
}
if (Wordings__empty(ParseTree__get_text(p))) {
ParseTree__log_subtree(current_sentence);
internal_error("Tried to resolve malformed noun-phrase");
}
}
#line 339 "inform7/Chapter 15/Refine Parse Tree.w"
;
{
#line 379 "inform7/Chapter 15/Refine Parse Tree.w"
property *prn = NULL;
wording PW = EMPTY_WORDING, OW = EMPTY_WORDING;
if (Preform__parse_nt_against_word_range(newfound_property_of_NTM, ParseTree__get_text(p), NULL, NULL)) {
prn = most_recent_result_p;
PW = GET_RW(newfound_property_of_NTM, 1);
OW = GET_RW(newfound_property_of_NTM, 2);
}
if ((prn) && (Properties__is_value_property(prn)) &&
(Properties__Valued__coincides_with_kind(prn))) {
LOGIF(NOUN_RESOLUTION, "Resolving new-property of: $Y\n", prn);
ParseTree__set_type(p, X_OF_Y_NT);
Preform__parse_nt_against_word_range(nounphrase_articled_NTM, OW, NULL, NULL);
p->down = most_recent_result_p;
Preform__parse_nt_against_word_range(nounphrase_as_object_NTM, PW, NULL, NULL);
p->down->next = most_recent_result_p;
ParseTree__annotate_int(p, resolved_ANNOT, FALSE);
LOGIF(NOUN_RESOLUTION, "Resolved new-property to:\n$T\n", p);
Assertions__Refiner__refine(p, creation_rule);
return;
}
}
#line 340 "inform7/Chapter 15/Refine Parse Tree.w"
;
{
#line 404 "inform7/Chapter 15/Refine Parse Tree.w"
if (ParseTree__int_annotation(p, nounphrase_article_ANNOT) == IT_ART) {
if ((Preform__parse_nt_against_word_range(nominative_pronoun_NTM, ParseTree__get_text(p), NULL, NULL)) &&
(most_recent_result == 2) &&
(Assertions__Traverse__get_current_subject_plurality())) {
Problems__Issue__sentence_problem(_p_(PM_EnigmaticThey),
"I'm unable to handle 'they' here",
"since it looks as if it needs to refer to more than one "
"object here, and that's something I can't manage.");
return;
}
if (Assertions__Traverse__get_current_object() == NULL) {
Problems__Issue__sentence_problem(_p_(PM_EnigmaticPronoun),
"I'm not sure what to make of the pronoun here",
"since it is unclear what previously mentioned thing "
"is being referred to. In general, it's best only to use "
"'it' where it's unambiguous, and it may be worth noting "
"that 'they' is not allowed to stand for more than one "
"object at a time.");
return;
}
inference_subject *referent = Assertions__Traverse__get_current_object();
if (referent) Assertions__Refiner__noun_from_infs(p, referent);
LOGIF(PRONOUNS, "Interpreting 'it' as $j\n$P", referent, current_sentence);
return;
}
}
#line 341 "inform7/Chapter 15/Refine Parse Tree.w"
;
if (forbid_nowhere == FALSE)
{
#line 434 "inform7/Chapter 15/Refine Parse Tree.w"
if (Plugins__Call__act_on_special_NPs(p)) return;
}
#line 342 "inform7/Chapter 15/Refine Parse Tree.w"
;
if (creation_rule != MANDATE_CREATION)
{
#line 439 "inform7/Chapter 15/Refine Parse Tree.w"
parse_node *spec = NULL;
{
#line 458 "inform7/Chapter 15/Refine Parse Tree.w"
if (Preform__parse_nt_against_word_range(value_property_name_NTM, ParseTree__get_text(p), NULL, NULL))
spec = Rvalues__from_property(most_recent_result_p);
}
#line 440 "inform7/Chapter 15/Refine Parse Tree.w"
;
if (spec == NULL)
{
#line 490 "inform7/Chapter 15/Refine Parse Tree.w"
if (Preform__parse_nt_against_word_range(assertion_np_as_value_NTM, ParseTree__get_text(p), NULL, NULL)) {
if (most_recent_result == FALSE) return;
spec = most_recent_result_p;
} else {
spec = Specifications__new_UNKNOWN(ParseTree__get_text(p));
}
if (Descriptions__get_quantifier(spec))
{
#line 508 "inform7/Chapter 15/Refine Parse Tree.w"
if (Quantifiers__can_be_used_in_assertions(Descriptions__get_quantifier(spec)) == FALSE) {
LOG("$T\nSo $D\n", current_sentence, Specifications__to_proposition(spec));
Problems__Issue__sentence_problem(_p_(PM_ComplexDeterminer),
"complicated determiners are not allowed in assertions",
"so for instance 'More than three people are in the Dining Room' "
"or 'None of the containers is open' will be rejected. Only "
"simple numbers will be allowed, as in examples like 'Three "
"people are in the Dining Room.'");
return;
}
if (Descriptions__get_quantifier(spec) == for_all_quantifier) {
kind *K = Specifications__to_kind(spec);
if ((K) &&
(Descriptions__to_instance(spec) == NULL) &&
(Descriptions__number_of_adjectives_applied_to(spec) == 0)) {
ParseTree__set_subject(p, Kinds__Behaviour__as_subject(K));
ParseTree__set_type(p, EVERY_NT);
return;
}
Problems__Issue__sentence_problem(_p_(PM_ComplexEvery),
"in an assertion 'every' or 'all' can only be used with a kind",
"so for instance 'A coin is in every container' is all right, "
"because 'container' is a kind, but not 'A coin is in every "
"open container', because 'open container' is now a kind "
"qualified by a property which may come or go during play. "
"(This problem sometimes happens because a thing has been "
"called something like an 'all in one survival kit' - if you "
"need that sort of name, try using 'called' to set it.)");
return;
}
}
#line 497 "inform7/Chapter 15/Refine Parse Tree.w"
;
LOGIF(NOUN_RESOLUTION, "Noun phrase $w parsed as value: $P\n", ParseTree__get_text(p), spec);
}
#line 441 "inform7/Chapter 15/Refine Parse Tree.w"
;
if ((ParseTree__is(spec, NONLOCAL_VARIABLE_VNT)) ||
(ParseTree__is(spec, CONSTANT_VNT))) {
Assertions__Refiner__noun_from_value(p, spec);
return;
}
if (Specifications__is_description(spec))
{
#line 566 "inform7/Chapter 15/Refine Parse Tree.w"
ParseTree__set_subject(p, NULL);
if (Descriptions__is_complex(spec)) {
Assertions__Refiner__noun_from_value(p, spec);
return;
}
{
#line 602 "inform7/Chapter 15/Refine Parse Tree.w"
if (!((Descriptions__to_instance(spec)) &&
((Descriptions__number_of_adjectives_applied_to(spec) > 0) ||
(ParseTree__int_annotation(p, nounphrase_article_ANNOT) != DEF_ART)))) {
Assertions__Refiner__refine_from_simple_description(p, spec);
return;
}
}
#line 571 "inform7/Chapter 15/Refine Parse Tree.w"
;
}
#line 448 "inform7/Chapter 15/Refine Parse Tree.w"
;
{
#line 550 "inform7/Chapter 15/Refine Parse Tree.w"
if (ParseTree__int_annotation(p, nounphrase_article_ANNOT) == NO_ART) {
if (Preform__parse_nt_against_word_range(action_pattern_NTM, ParseTree__get_text(p), NULL, NULL)) {
ParseTree__set_type(p, ACTION_NT);
ParseTree__set_action_meaning(p, most_recent_result_p);
return;
}
}
}
#line 449 "inform7/Chapter 15/Refine Parse Tree.w"
;
}
#line 345 "inform7/Chapter 15/Refine Parse Tree.w"
;
if (creation_rule != FORBID_CREATION) ParseTree__set_type(p, CREATED_NT);
else ParseTree__set_subject(p, NULL);
}
#line 166 "inform7/Chapter 15/Refine Parse Tree.w"
; return;
}
}
#line 373 "inform7/Chapter 15/Refine Parse Tree.w"
int newfound_property_of_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 375 "inform7/Chapter 15/Refine Parse Tree.w"
#line 481 "inform7/Chapter 15/Refine Parse Tree.w"
int assertion_np_as_value_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 464 "inform7/Chapter 15/Refine Parse Tree.w"
*X = FALSE;
Problems__Issue__sentence_problem(_p_(PM_VagueVariable),
"'variable' is too vague a description",
"because it doesn't say what kind of value should go into the variable. "
"'number variable' or 'a number that varies' - whatever kind of value you "
"need - would be much clearer.");
}
#line 482 "inform7/Chapter 15/Refine Parse Tree.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 486 "inform7/Chapter 15/Refine Parse Tree.w"
#line 619 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__refine_from_simple_description(parse_node *p, parse_node *spec) {
inference_subject *head = NULL;
{
#line 639 "inform7/Chapter 15/Refine Parse Tree.w"
if (Descriptions__to_instance(spec)) {
head = Instances__as_subject(Descriptions__to_instance(spec));
if (head) {
Assertions__Refiner__noun_from_infs(p, head);
Assertions__Refiner__pn_noun_details_from_spec(p, spec);
}
} else if (Descriptions__makes_kind_explicit(spec)) {
kind *K = Specifications__to_kind(spec);
head = Kinds__Behaviour__as_subject(K);
Assertions__Refiner__noun_from_infs(p, head);
ParseTree__set_evaluation(p, Specifications__from_kind(K));
Assertions__Refiner__pn_noun_details_from_spec(p, spec);
}
}
#line 621 "inform7/Chapter 15/Refine Parse Tree.w"
;
if (Descriptions__number_of_adjectives_applied_to(spec) > 0) {
if (head)
{
#line 658 "inform7/Chapter 15/Refine Parse Tree.w"
parse_node *lower_copy = ParseTree__new(PROPER_NOUN_NT);
ParseTree__copy(lower_copy, p);
ParseTree__set_type(p, WITH_NT);
p->down = lower_copy;
lower_copy->next = ParseTree__new(PROPER_NOUN_NT);
p = lower_copy->next;
}
#line 623 "inform7/Chapter 15/Refine Parse Tree.w"
;
{
#line 671 "inform7/Chapter 15/Refine Parse Tree.w"
int no_adjectives = Descriptions__number_of_adjectives_applied_to(spec);
if (no_adjectives == 1) {
Assertions__Refiner__pn_make_adjective(p,
Descriptions__first_adjective_usage(spec), spec);
} else {
ParseTree__set_type_and_clear_annotations(p, AND_NT);
adjective_usage *ale;
int i = 0;
parse_node *AND_p = p;
pcalc_prop *ale_prop = NULL;
LOOP_THROUGH_ADJECTIVE_LIST(ale, ale_prop, spec) {
i++;
parse_node *p3 = ParseTree__new(ADJECTIVE_NT);
Assertions__Refiner__pn_make_adjective(p3, ale, spec);
if (i < no_adjectives) {
AND_p->down = p3;
if (i+1 < no_adjectives) {
p3->next = ParseTree__new(AND_NT);
AND_p = p3->next;
}
} else {
AND_p->down->next = p3;
}
}
}
}
#line 624 "inform7/Chapter 15/Refine Parse Tree.w"
;
}
}
#line 745 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__perform_and_surgery(parse_node *p) {
parse_node *x, *a_p, *w_p, *p1_p, *p2_p, *i_p;
if ((ParseTree__get_type(p->down) == ADJECTIVE_NT)
&& (ParseTree__get_type(p->down->next) == WITH_NT)) {
a_p = p; p1_p = p->down; w_p = p->down->next;
i_p = w_p->down; p2_p = i_p->next;
ParseTree__set_type(a_p, WITH_NT);
ParseTree__set_type_and_clear_annotations(w_p, AND_NT);
ParseTree__set_subject(a_p, ParseTree__get_subject(w_p));
ParseTree__set_subject(w_p, NULL);
x = a_p; a_p = w_p; w_p = x;
w_p->down = i_p;
i_p->next = a_p;
a_p->down = p1_p;
a_p->down->next = p2_p;
}
}
#line 792 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__perform_with_surgery(parse_node *p) {
parse_node *inst, *prop_1, *prop_2;
if ((ParseTree__get_type(p) == WITH_NT) && (ParseTree__get_type(p->down) == WITH_NT)) {
inst = p->down->down;
prop_1 = p->down->down->next;
prop_2 = p->down->next;
p->down = inst;
p->down->next = ParseTree__new(AND_NT);
p->down->next->down = prop_1;
p->down->next->down->next = prop_2;
}
}
#line 825 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__perform_location_surgery(parse_node *p) {
parse_node *old_and, *old_np1, *old_loc2;
if ((ParseTree__get_type(p) == RELATIONSHIP_NT) &&
(p->down) && (ParseTree__get_type(p->down) == AND_NT) &&
(p->down->down) && (p->down->down->next) &&
(ParseTree__get_type(p->down->down->next) == RELATIONSHIP_NT)) {
ParseTree__annotate_int(p, resolved_ANNOT, FALSE); /* otherwise this will be wrongly copied */
old_and = p->down;
old_np1 = old_and->down;
old_loc2 = old_and->down->next;
ParseTree__copy(old_and, p); /* making this the new first location node */
ParseTree__set_type_and_clear_annotations(p, AND_NT); /* and this is new AND */
p->down = old_and;
old_and->down = old_np1;
old_and->next = old_loc2;
old_np1->next = NULL;
}
}
#line 864 "inform7/Chapter 15/Refine Parse Tree.w"
void Assertions__Refiner__perform_called_surgery(parse_node *p) {
parse_node *x_pn = p->down->down->next; /* "north" in the example */
parse_node *name_pn = p->down->next; /* "hot and cold room" in the example */
ParseTree__set_type(p, RELATIONSHIP_NT);
ParseTree__annotate_int(p, relationship_node_type_ANNOT,
ParseTree__int_annotation(p->down, relationship_node_type_ANNOT));
ParseTree__set_type(p->down, CALLED_NT);
p->down->next = x_pn;
p->down->down->next = name_pn;
}
#line 36 "inform7/Chapter 15/The Creator.w"
int problem_count_when_creator_started;
int Assertions__Creator__consult_the_creator(parse_node *px, parse_node *py) {
problem_count_when_creator_started = problem_count;
if (Preform__parse_nt_against_word_range(s_existential_np_NTM, ParseTree__get_text(px), NULL, NULL))
{
#line 60 "inform7/Chapter 15/The Creator.w"
Assertions__Creator__noun_creator(py, NULL, NULL);
}
#line 41 "inform7/Chapter 15/The Creator.w"
else
{
#line 76 "inform7/Chapter 15/The Creator.w"
{
#line 102 "inform7/Chapter 15/The Creator.w"
if ((Assertions__Creator__actionlike(px)) && (ParseTree__get_type(py) == CREATED_NT))
ParseTree__set_type(py, ACTION_NT);
if ((Assertions__Creator__actionlike(px)) && (Assertions__Creator__actionlike(py))) {
Assertions__Creator__to_action_node(px);
Assertions__Creator__to_action_node(py);
}
if ((ParseTree__get_type(px) == ACTION_NT) && (ParseTree__get_type(py) == KIND_NT))
ParseTree__set_type(px, CREATED_NT);
}
#line 76 "inform7/Chapter 15/The Creator.w"
;
parse_node *govx = NULL, *govy = NULL;
kind *kindx = NULL, *kindy = NULL;
{
#line 134 "inform7/Chapter 15/The Creator.w"
binary_predicate *bp = Assertions__Creator__bp_of_subtree(py);
if (bp == NULL) bp = Assertions__Creator__bp_of_subtree(px);
if (bp) {
kindx = Kinds__weaken(BinaryPredicates__term_kind(bp, 0));
kindy = Kinds__weaken(BinaryPredicates__term_kind(bp, 1));
if ((bp == R_containment) ||
(BinaryPredicates__get_reversal(bp) == R_containment)) { kindx = K_object; kindy = K_object; }
}
if ((kindx == NULL) || (kindy == NULL)) {
kindx = Assertions__Creator__kind_of_subtree(px, &govx);
kindy = Assertions__Creator__kind_of_subtree(py, &govy);
}
}
#line 79 "inform7/Chapter 15/The Creator.w"
;
Assertions__Creator__noun_creator(px, kindy, govy);
Assertions__Creator__noun_creator(py, kindx, govx);
}
#line 43 "inform7/Chapter 15/The Creator.w"
;
if (problem_count > problem_count_when_creator_started) return FALSE;
return TRUE;
}
#line 150 "inform7/Chapter 15/The Creator.w"
int Assertions__Creator__actionlike(parse_node *p) {
if (ParseTree__get_type(p) == ACTION_NT) return TRUE;
if (ParseTree__get_type(p) == PROPER_NOUN_NT) {
parse_node *spec = ParseTree__get_evaluation(p);
if (Rvalues__is_CONSTANT_of_kind(spec, K_stored_action))
return TRUE;
}
return FALSE;
}
void Assertions__Creator__to_action_node(parse_node *p) {
if (ParseTree__get_type(p) == ACTION_NT) return;
if (ParseTree__get_type(p) == PROPER_NOUN_NT) {
parse_node *spec = ParseTree__get_evaluation(p);
if (Rvalues__is_CONSTANT_of_kind(spec, K_stored_action)) {
action_pattern *ap = ParseTree__get_constant_action_pattern(spec);
ParseTree__set_type(p, ACTION_NT);
ParseTree__set_action_meaning(p, ap);
return;
}
}
internal_error("misapplied to_action_node");
}
#line 177 "inform7/Chapter 15/The Creator.w"
binary_predicate *Assertions__Creator__bp_of_subtree(parse_node *p) {
if ((p) && (ParseTree__get_type(p) == RELATIONSHIP_NT)) return ParseTree__get_relationship(p);
return NULL;
}
#line 185 "inform7/Chapter 15/The Creator.w"
kind *Assertions__Creator__kind_of_subtree(parse_node *p, parse_node **governing) {
if (p == NULL) return NULL;
switch (ParseTree__get_type(p)) {
case AND_NT:
{
#line 205 "inform7/Chapter 15/The Creator.w"
kind *left = Assertions__Creator__kind_of_subtree(p->down, governing);
kind *right = Assertions__Creator__kind_of_subtree(p->down->next, governing);
if (left) return left;
return right;
}
#line 188 "inform7/Chapter 15/The Creator.w"
;
case WITH_NT: return Assertions__Creator__kind_of_subtree(p->down, governing); /* the owner, not the property */
case KIND_NT:
{
#line 214 "inform7/Chapter 15/The Creator.w"
*governing = p;
return InferenceSubjects__domain(ParseTree__get_subject(p));
}
#line 190 "inform7/Chapter 15/The Creator.w"
;
default: {
parse_node *spec = ParseTree__get_evaluation(p);
{
#line 220 "inform7/Chapter 15/The Creator.w"
if ((Specifications__is_new_variable_like(spec)) ||
(Specifications__is_kind_like(spec))) {
kind *found = Specifications__to_kind(spec);
if (Specifications__is_new_variable_like(spec))
found = K_value; /* Specifications__kind_of_new_variable_like(spec); */
else if (Specifications__is_kind_like(spec)) found = Specifications__to_kind(spec);
if (found) {
*governing = p;
if (Kinds__Compare__le(found, K_object)) return K_object;
}
return found;
}
}
#line 193 "inform7/Chapter 15/The Creator.w"
;
{
#line 236 "inform7/Chapter 15/The Creator.w"
if ((prevailing_mood == INITIALLY_CE) || (prevailing_mood == CERTAIN_CE)) {
if ((ParseTree__is(spec, CONSTANT_VNT)) ||
(Lvalues__is_constant_NONLOCAL_VARIABLE(spec))) {
*governing = p;
return Kinds__weaken(Specifications__to_kind(spec));
}
}
}
#line 194 "inform7/Chapter 15/The Creator.w"
;
{
#line 258 "inform7/Chapter 15/The Creator.w"
if (Specifications__is_description(spec)) {
*governing = p;
return Specifications__to_kind(spec);
}
}
#line 195 "inform7/Chapter 15/The Creator.w"
;
{
#line 247 "inform7/Chapter 15/The Creator.w"
if (Rvalues__is_CONSTANT_construction(spec, CON_property)) {
property *prn = Rvalues__to_property(spec);
if ((Properties__is_either_or(prn) == FALSE) &&
(Properties__Valued__coincides_with_kind(prn)))
return Properties__Valued__kind(prn);
}
}
#line 196 "inform7/Chapter 15/The Creator.w"
;
}
}
return NULL;
}
#line 286 "inform7/Chapter 15/The Creator.w"
table *allow_tabular_definitions_from = NULL;
void Assertions__Creator__tabular_definitions(table *t) {
allow_tabular_definitions_from = t;
}
void Assertions__Creator__noun_creator(parse_node *p, kind *create_as, parse_node *governor) {
switch (ParseTree__get_type(p)) {
case CALLED_NT:
{
#line 303 "inform7/Chapter 15/The Creator.w"
if ((prevailing_mood == IMPOSSIBLE_CE) || (prevailing_mood == UNLIKELY_CE)) {
Problems__Issue__sentence_problem(_p_(PM_NegativeCreation),
"sentences are only allowed to say that things do exist",
"not that they don't.");
}
}
#line 293 "inform7/Chapter 15/The Creator.w"
;
{
#line 326 "inform7/Chapter 15/The Creator.w"
parse_node *what_to_make_node = p->down; /* e.g., "a man" */
parse_node *called_name_node = p->down->next; /* a |CREATED_NT| node, e.g., "Peter" */
if ((ParseTree__get_type(what_to_make_node) != COMMON_NOUN_NT) &&
(ParseTree__get_type(what_to_make_node) != WITH_NT)) {
{
#line 383 "inform7/Chapter 15/The Creator.w"
LOG("$T\n", what_to_make_node);
Problems__Issue__sentence_problem(_p_(PM_CalledWithoutKind),
"I can only make 'a something called whatever' when the something is a kind I know",
"possibly qualified with adjectives. For instance, 'an open door called the Marble "
"Door' is fine because 'door' is the name of a kind and 'open' is an adjective "
"which means something for doors. But 'a grand archway called the Great Gates' "
"would not normally mean anything to me, because 'archway' is not one of the "
"standard kinds in Inform. (Try consulting the Kinds index.)");
/* now recover from the error as best we can: */
ParseTree__set_type(p, CREATED_NT);
ParseTree__set_text(p, ParseTree__get_text(called_name_node));
p->down = NULL;
}
#line 331 "inform7/Chapter 15/The Creator.w"
; return;
}
parse_node *local_governor = NULL;
kind *local_create_as = Assertions__Creator__kind_of_subtree(what_to_make_node, &local_governor);
if (local_create_as == NULL) { local_create_as = create_as; local_governor = governor; }
Assertions__Creator__noun_creator(called_name_node, local_create_as, local_governor);
{
#line 348 "inform7/Chapter 15/The Creator.w"
parse_node *p_sibling = p->next;
ParseTree__copy(p, called_name_node); p->down = NULL; p->next = p_sibling;
inference_subject *new_creation = ParseTree__get_subject(p);
inference_subject *its_domain = ParseTree__get_subject(what_to_make_node);
if ((new_creation) && (its_domain))
Calculus__Propositions__Abstract__assert_kind_of_subject(new_creation, its_domain,
Specifications__to_proposition(ParseTree__get_evaluation(what_to_make_node)));
if (ParseTree__get_type(what_to_make_node) == WITH_NT)
Assertions__PropertyKnowledge__assert_property_list(p, what_to_make_node->down->next);
}
#line 339 "inform7/Chapter 15/The Creator.w"
;
{
#line 371 "inform7/Chapter 15/The Creator.w"
if ((ParseTree__get_type(called_name_node) == PROPER_NOUN_NT) &&
(ParseTree__int_annotation(called_name_node, nounphrase_article_ANNOT) == DEF_ART)) {
inference_subject *subj = ParseTree__get_subject(p);
if ((InferenceSubjects__is_an_object(subj)) ||
(InferenceSubjects__is_a_kind_of_object(subj)))
PL__Naming__object_takes_definite_article(subj);
}
}
#line 340 "inform7/Chapter 15/The Creator.w"
;
}
#line 293 "inform7/Chapter 15/The Creator.w"
; return;
case CREATED_NT:
{
#line 303 "inform7/Chapter 15/The Creator.w"
if ((prevailing_mood == IMPOSSIBLE_CE) || (prevailing_mood == UNLIKELY_CE)) {
Problems__Issue__sentence_problem(_p_(PM_NegativeCreation),
"sentences are only allowed to say that things do exist",
"not that they don't.");
}
}
#line 294 "inform7/Chapter 15/The Creator.w"
;
{
#line 415 "inform7/Chapter 15/The Creator.w"
wording W = ParseTree__get_text(p);
if (Wordings__empty(W)) internal_error("CREATED node without name");
if (Preform__parse_nt_against_word_range(grammatical_gender_marker_NTM, W, NULL, NULL)) {
W = GET_RW(grammatical_gender_marker_NTM, 1);
ParseTree__annotate_int(p, gender_reference_ANNOT, -(most_recent_result + 1));
}
if (Preform__parse_nt_against_word_range(creation_problem_diagnosis_NTM, W, NULL, NULL)) W = EMPTY_WORDING;
ParseTree__set_text(p, W);
if (((create_as == NULL) || (Kinds__Compare__le(create_as, K_object))) &&
(prevailing_mood != INITIALLY_CE) &&
(prevailing_mood != CERTAIN_CE)) {
instance *recent_creation = NULL;
if (Wordings__nonempty(W))
{
#line 613 "inform7/Chapter 15/The Creator.w"
recent_creation = Instances__parse_object(W);
if (recent_creation) {
wording RW = Instances__get_name(recent_creation, FALSE);
if ((Wordings__nonempty(RW)) && (Wordings__match(W, RW) == FALSE))
recent_creation = NULL;
}
if (recent_creation == NULL)
{
#line 625 "inform7/Chapter 15/The Creator.w"
int is_a_kind = FALSE;
if ((governor) && (ParseTree__get_type(governor) == KIND_NT)) is_a_kind = TRUE;
pcalc_prop *prop = Calculus__Propositions__Abstract__to_create_something(K_object, W);
if (is_a_kind)
prop = Calculus__Propositions__concatenate(prop, Calculus__Propositions__Abstract__to_make_a_kind(K_object));
Calculus__Propositions__Assert__assert_true(prop, CERTAIN_CE);
if (is_a_kind == FALSE) {
recent_creation = latest_instance;
if (ParseTree__int_annotation(p, plural_reference_ANNOT))
PL__Naming__object_now_has_plural_name(recent_creation);
if (ParseTree__int_annotation(p, nounphrase_article_ANNOT) == NO_ART)
PL__Naming__object_now_has_proper_name(recent_creation);
int g = ParseTree__int_annotation(p, gender_reference_ANNOT);
if ((g != 0) &&
(P_grammatical_gender) &&
(no_ggs_recorded == NO_GRAMMATICAL_GENDERS)) {
int c = LIKELY_CE;
if (g < 0) { c = CERTAIN_CE; g = -g; }
Properties__Valued__assert(P_grammatical_gender,
Instances__as_subject(recent_creation),
Rvalues__from_instance(grammatical_genders[g-1]),
c);
}
} else {
parse_node *val = Specifications__from_kind(latest_base_kind_of_value);
Assertions__Refiner__noun_from_value(p, val);
ParseTree__annotate_int(p, creation_site_ANNOT, TRUE);
}
}
#line 620 "inform7/Chapter 15/The Creator.w"
;
}
#line 427 "inform7/Chapter 15/The Creator.w"
;
if (recent_creation) {
Assertions__Refiner__noun_from_infs(p, Instances__as_subject(recent_creation));
ParseTree__annotate_int(p, creation_site_ANNOT, TRUE);
}
} else {
parse_node *val = NULL;
if (Wordings__nonempty(W))
{
#line 659 "inform7/Chapter 15/The Creator.w"
parse_node *governing_spec = ParseTree__get_evaluation(governor);
if ((governor) && (ParseTree__get_type(governor) == KIND_NT))
{
#line 686 "inform7/Chapter 15/The Creator.w"
pcalc_prop *prop = Calculus__Propositions__Abstract__to_create_something(NULL, W);
prop = Calculus__Propositions__concatenate(prop, Calculus__Propositions__Abstract__to_make_a_kind(K_value));
Calculus__Propositions__Assert__assert_true(prop, prevailing_mood);
val = Specifications__from_kind(latest_base_kind_of_value);
}
#line 661 "inform7/Chapter 15/The Creator.w"
else if ((Specifications__is_new_variable_like(governing_spec)) ||
(prevailing_mood == INITIALLY_CE) ||
(prevailing_mood == CERTAIN_CE))
{
#line 694 "inform7/Chapter 15/The Creator.w"
kind *domain = ParseTree__get_kind_of_value(governing_spec);
if (domain == NULL) domain = Kinds__weaken(Specifications__to_kind(governing_spec));
if (Specifications__is_new_variable_like(governing_spec))
domain = Specifications__kind_of_new_variable_like(governing_spec);
if (Kinds__contains(domain, Kinds__get_construct(K_understanding)))
{
#line 745 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NoTopicsThatVary),
"'topics that vary' are not allowed",
"that is, a variable is not allowed to have 'topic' as its kind of value. "
"(This would cause too much ambiguity with text variables, whose values "
"look exactly the same.)");
}
#line 699 "inform7/Chapter 15/The Creator.w"
;
pcalc_prop *prop = Calculus__Propositions__Abstract__to_create_something(domain, W);
if (prevailing_mood == CERTAIN_CE)
prop = Calculus__Propositions__concatenate(prop, Calculus__Propositions__Abstract__to_make_a_const());
else
prop = Calculus__Propositions__concatenate(prop, Calculus__Propositions__Abstract__to_make_a_var());
Calculus__Propositions__Assert__assert_true(prop, prevailing_mood);
val = Lvalues__new_actual_NONLOCAL_VARIABLE(latest_nonlocal_variable);
}
#line 665 "inform7/Chapter 15/The Creator.w"
else if (Kinds__get_construct(create_as) == CON_rulebook)
{
#line 723 "inform7/Chapter 15/The Creator.w"
kind *basis = NULL, *producing = NULL;
Kinds__binary_construction_material(create_as, &basis, &producing);
if (Kinds__Compare__eq(basis, K_value)) basis = K_action_name;
if (Kinds__Compare__eq(producing, K_value)) producing = K_nil;
create_as = Kinds__binary_construction(CON_rulebook, basis, producing);
if (governor)
ParseTree__set_evaluation(governor,
Specifications__from_kind(create_as));
rulebook *rb = Rulebooks__new(create_as, W);
val = Rvalues__from_rulebook(rb);
ParseTree__annotate_int(current_sentence, clears_pronouns_ANNOT, TRUE);
}
#line 667 "inform7/Chapter 15/The Creator.w"
else if (Kinds__get_construct(create_as) == CON_activity)
{
#line 738 "inform7/Chapter 15/The Creator.w"
activity *av = Activities__new(create_as, W);
val = Rvalues__from_activity(av);
ParseTree__annotate_int(current_sentence, clears_pronouns_ANNOT, TRUE);
}
#line 669 "inform7/Chapter 15/The Creator.w"
else if ((Kinds__Behaviour__definite(create_as)) && (Kinds__Behaviour__is_quasinumerical(create_as)))
{
#line 754 "inform7/Chapter 15/The Creator.w"
if (Preform__parse_nt_against_word_range(equation_name_NTM, W, NULL, NULL)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_kind(3, create_as);
Problems__Issue__handmade_problem(_p_(PM_MixedConstantsEquation));
Problems__issue_problem_segment(
"The sentence %1 reads to me as if '%2' refers to something "
"I should create as brand new - %3. But that can't be right, "
"and I suspect this may be because you've tried to create an "
"Equation but not given it a new paragraph.");
Problems__issue_problem_end();
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_kind(3, create_as);
Problems__Issue__handmade_problem(_p_(PM_MixedConstants));
Problems__issue_problem_segment(
"The sentence %1 reads to me as if '%2' refers to something "
"I should create as brand new - %3. But that can't be right, "
"because this is a kind of value where I can't simply invent "
"new values. (Just as the numbers are ..., 1, 2, 3, ... and "
"I can't invent a new one called 'Susan'.)");
Problems__issue_problem_end();
}
}
#line 671 "inform7/Chapter 15/The Creator.w"
else if ((Kinds__Behaviour__definite(create_as)) &&
(Kinds__Behaviour__defined_by_table(create_as)) &&
(Kinds__Behaviour__defined_by_table(create_as) != allow_tabular_definitions_from))
{
#line 782 "inform7/Chapter 15/The Creator.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_kind(3, create_as);
Problems__quote_table(4, Kinds__Behaviour__defined_by_table(create_as));
Problems__Issue__handmade_problem(_p_(PM_TableOfExistingKind2));
Problems__issue_problem_segment(
"The sentence %1 reads to me as if '%2' refers to something "
"I should create as brand new - %3. That looks reasonable, since "
"this is a kind which does have named values, but it's not "
"allowed because this is a kind which is defined by the rows "
"of a table (%4), not in isolated sentences like this one.");
Problems__issue_problem_end();
}
#line 675 "inform7/Chapter 15/The Creator.w"
else if ((Kinds__Behaviour__definite(create_as)) && (Kinds__Behaviour__has_named_constant_values(create_as)))
{
#line 711 "inform7/Chapter 15/The Creator.w"
pcalc_prop *prop = Calculus__Propositions__Abstract__to_create_something(create_as, W);
pcalc_prop *such_that = ParseTree__get_creation_proposition(governor);
if (such_that) prop = Calculus__Propositions__concatenate(prop, such_that);
Calculus__Propositions__Assert__assert_true(prop, prevailing_mood);
val = Rvalues__from_instance(latest_instance);
}
#line 677 "inform7/Chapter 15/The Creator.w"
else
{
#line 799 "inform7/Chapter 15/The Creator.w"
if (problem_count_when_creator_started == problem_count) {
LOG("$w: $u\n$T\n", W, create_as, governor);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_kind(3, create_as);
Problems__Issue__handmade_problem(_p_(PM_NoNewInstances));
Problems__issue_problem_segment(
"The sentence %1 reads to me as if '%2' refers to something "
"I should create as brand new - %3. But that can't be right, "
"because this is a kind of value where I can't simply invent "
"new values. (Just as the numbers are ..., 1, 2, 3, ... and "
"I can't invent a new one called 'Susan'.) %P"
"Perhaps you wanted not to invent a constant but to make a "
"variable - that is, to give a name for a value which will "
"change during play. If so, try something like 'The bonus "
"is a number which varies'. %P"
"Or perhaps you wanted to create a name as an alias for a "
"constant value. If so, try something like 'The lucky number "
"is always 8.' But this only makes a new name for the existing "
"number 8, it doesn't invent a new number.");
Problems__issue_problem_end();
}
}
#line 679 "inform7/Chapter 15/The Creator.w"
;
Index__DocReferences__position_of_symbol(&W);
ParseTree__set_text(p, W);
}
#line 434 "inform7/Chapter 15/The Creator.w"
;
Assertions__Refiner__noun_from_value(p, val);
if (val) ParseTree__annotate_int(p, creation_site_ANNOT, TRUE);
}
}
#line 294 "inform7/Chapter 15/The Creator.w"
; return;
}
parse_node *ch;
for (ch = p->down; ch; ch = ch->next) Assertions__Creator__noun_creator(ch, create_as, governor);
}
#line 400 "inform7/Chapter 15/The Creator.w"
int grammatical_gender_marker_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 402 "inform7/Chapter 15/The Creator.w"
int grammatical_gender_abbreviation_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 407 "inform7/Chapter 15/The Creator.w"
#line 444 "inform7/Chapter 15/The Creator.w"
int creation_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 472 "inform7/Chapter 15/The Creator.w"
Problems__Issue__sentence_problem(_p_(PM_NameIsArticle),
"this seems to give something a name which consists only of an article",
"that is, 'a', 'an', 'the' or 'some'. This is not allowed since the "
"potential for confusion is too high. (If you need, say, a room which "
"the player sees as just 'A', you can get this effect with: 'A-Room is "
"a room with printed name \"A\".')");
}
#line 445 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 482 "inform7/Chapter 15/The Creator.w"
Problems__Issue__sentence_problem(_p_(PM_NameWithBrackets),
"this seems to give something a name which contains brackets '(' or ')'",
"which is not allowed since the potential for confusion with other uses "
"for brackets in Inform source text is too high. (If you need, say, a "
"room which the player sees as 'Fillmore (West)', you can get this "
"effect with: 'Fillmore West is a room with printed name \"Fillmore "
"(West)\".')");
}
#line 446 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 482 "inform7/Chapter 15/The Creator.w"
Problems__Issue__sentence_problem(_p_(PM_NameWithBrackets),
"this seems to give something a name which contains brackets '(' or ')'",
"which is not allowed since the potential for confusion with other uses "
"for brackets in Inform source text is too high. (If you need, say, a "
"room which the player sees as 'Fillmore (West)', you can get this "
"effect with: 'Fillmore West is a room with printed name \"Fillmore "
"(West)\".')");
}
#line 447 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 482 "inform7/Chapter 15/The Creator.w"
Problems__Issue__sentence_problem(_p_(PM_NameWithBrackets),
"this seems to give something a name which contains brackets '(' or ')'",
"which is not allowed since the potential for confusion with other uses "
"for brackets in Inform source text is too high. (If you need, say, a "
"room which the player sees as 'Fillmore (West)', you can get this "
"effect with: 'Fillmore West is a room with printed name \"Fillmore "
"(West)\".')");
}
#line 448 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 493 "inform7/Chapter 15/The Creator.w"
WRITE_TO(STDERR, "*** Exit(1) requested for testing purposes ***\n");
STREAM_FLUSH(STDERR);
Problems__Issue__sentence_problem(_p_(PM_Crash1),
"this uses the first secret hieroglyph of dreadful power",
"which forces me to crash. (It's for testing the way I crash, in fact. "
"If this is a genuine inconvenience to you, get in touch with my authors.)");
exit(1);
}
#line 449 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 504 "inform7/Chapter 15/The Creator.w"
WRITE_TO(STDERR, "*** Exit(10) requested for testing purposes ***\n");
STREAM_FLUSH(STDERR);
Problems__Issue__sentence_problem(_p_(PM_Crash10),
"this uses the second secret hieroglyph of dreadful power",
"which forces me to crash. (It's for testing the way I crash, in fact. "
"If this is a genuine inconvenience to you, get in touch with my authors.)");
exit(10);
}
#line 450 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 515 "inform7/Chapter 15/The Creator.w"
WRITE_TO(STDERR, "*** Exit(11) requested for testing purposes ***\n");
STREAM_FLUSH(STDERR);
Problems__Issue__sentence_problem(_p_(PM_Crash11),
"this uses the third secret hieroglyph of dreadful power",
"which forces me to crash. (It's for testing the way I crash, in fact. "
"If this is a genuine inconvenience to you, get in touch with my authors.)");
exit(11);
}
#line 451 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7:
{
#line 526 "inform7/Chapter 15/The Creator.w"
LOG("$T\n", current_sentence);
Problems__Issue__sentence_problem(_p_(PM_StartsWithComma),
"this seems to refer to something whose name begins with a comma",
"which is forbidden. Perhaps you used a comma in punctuating a sentence? "
"Inform generally doesn't like this because it reserves commas for "
"specific purposes such as dividing rules or 'if' phrases.");
}
#line 452 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8:
{
#line 536 "inform7/Chapter 15/The Creator.w"
Problems__Issue__sentence_problem(_p_(PM_EndsWithComma),
"this seems to refer to something whose name ends with a comma",
"which is forbidden. Perhaps you used a comma in punctuating a sentence? "
"Inform generally doesn't like this because it reserves commas for "
"specific purposes such as dividing rules or 'if' phrases.");
}
#line 453 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9:
{
#line 545 "inform7/Chapter 15/The Creator.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_ObjectIncWhen));
Problems__issue_problem_segment(
"The sentence %1 seems to be talking about a previously unknown room or "
"thing called %2. Ordinarily, I would create this, but because the name "
"contains the word 'when' or 'while' I'm going to say no. %P"
"That's because this far more often happens by mistake than deliberately. "
"For instance, people sometimes type lines like 'Jumping when the actor "
"is on the trampoline is high-jumping.' But in fact although 'jumping' "
"is an action, 'Jumping when...' is not - 'when' can't be used here "
"(though it can be used in rule preambles). So the sentence is instead "
"read as making an object 'jumping when the actor' and putting it on top "
"of another one, 'trampoline is high-jumping'. This can lead to a lot of "
"confusion. %P"
"If you genuinely do want an object whose name contains the word 'when', "
"try something like: 'In the box is a thing called When worlds collide.'");
Problems__issue_problem_end();
}
#line 454 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10:
{
#line 567 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameWithText),
"this seems to give something a name which contains "
"double-quoted text",
"which is not allowed. If you do need quotes in a name, one option "
"would be to write something like 'In the Saloon is 'Black' Jacques "
"Bernoulli.'; but this problem message is often caused by an "
"accident in punctuation, in which case you never intended to "
"create an object - you thought that the text ended a sentence "
"because it finished with sentence-ending punctuation, when in "
"fact it didn't, so that I read the next words as following on.");
}
#line 455 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 456 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 457 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 458 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 459 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 460 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 16:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 461 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 17:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 462 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 18:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 463 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 19:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 464 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 20:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 465 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 21:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 466 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 22:
{
#line 581 "inform7/Chapter 15/The Creator.w"
Problems__Issue__assertion_problem(_p_(PM_NameReserved),
"this seems to give something a name which is reserved for Inform's "
"own internal use",
"so is not allowed. There are only a few of these - 'storage', "
"'variable', 'condition', 'phrase' and 'action', for example. But "
"whatever you were making here, you'll need to call it something "
"else.");
}
#line 467 "inform7/Chapter 15/The Creator.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 468 "inform7/Chapter 15/The Creator.w"
#line 825 "inform7/Chapter 15/The Creator.w"
int Assertions__Creator__vet_name(wording W) {
if (Preform__parse_nt_against_word_range(creation_problem_diagnosis_NTM, W, NULL, NULL)) return FALSE;
return TRUE;
}
#line 850 "inform7/Chapter 15/The Creator.w"
int name_stubs_count = 0;
void Assertions__Creator__convert_instance_to_nounphrase(parse_node *p, binary_predicate *hinge_relation) {
{
#line 303 "inform7/Chapter 15/The Creator.w"
if ((prevailing_mood == IMPOSSIBLE_CE) || (prevailing_mood == UNLIKELY_CE)) {
Problems__Issue__sentence_problem(_p_(PM_NegativeCreation),
"sentences are only allowed to say that things do exist",
"not that they don't.");
}
}
#line 853 "inform7/Chapter 15/The Creator.w"
;
int confect_name_flag = FALSE;
if ((hinge_relation) && (BinaryPredicates__is_the_wrong_way_round(hinge_relation)))
hinge_relation = BinaryPredicates__get_reversal(hinge_relation);
if (hinge_relation == R_incorporation) confect_name_flag = TRUE;
int instance_count;
wording CW = EMPTY_WORDING; /* the calling */
if (Preform__parse_nt_against_word_range(text_ending_with_a_calling_NTM, ParseTree__get_text(p), NULL, NULL)) {
ParseTree__set_text(p, GET_RW(text_ending_with_a_calling_NTM, 1)); /* the text before the bracketed clause */
CW = GET_RW(text_ending_with_a_calling_NTM, 2); /* the bracketed text */
if (Preform__parse_nt_against_word_range(article_NTM, CW, NULL, NULL)) {
{
#line 899 "inform7/Chapter 15/The Creator.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, CW);
Problems__Issue__handmade_problem(_p_(PM_CalledArticle));
Problems__issue_problem_segment(
"The sentence %1 seems to be asking me to create something whose "
"name, '%2', is just an article - this isn't allowed.");
Problems__issue_problem_end();
}
#line 864 "inform7/Chapter 15/The Creator.w"
;
CW = EMPTY_WORDING;
}
}
kind *instance_kind = K_object;
if (Specifications__is_kind_like(ParseTree__get_evaluation(p)))
instance_kind = Specifications__to_kind(ParseTree__get_evaluation(p));
if ((Kinds__Compare__le(instance_kind, K_object) == FALSE) &&
(Kinds__Behaviour__has_named_constant_values(instance_kind) == FALSE))
{
#line 885 "inform7/Chapter 15/The Creator.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, instance_kind);
Problems__Issue__handmade_problem(_p_(PM_CantCreateImplicitly));
Problems__issue_problem_segment(
"The sentence %1 seems to be asking me to create a new value (%2) "
"in order to be part of a relationship, but this isn't a kind of "
"value which I can just create new values for.");
Problems__issue_problem_end();
instance_kind = K_object;
ParseTree__annotate_int(p, multiplicity_ANNOT, 1);
}
#line 873 "inform7/Chapter 15/The Creator.w"
;
{
#line 916 "inform7/Chapter 15/The Creator.w"
instance_count = ParseTree__int_annotation(p, multiplicity_ANNOT);
if (instance_count < 1) instance_count = 1;
if (instance_count > MAX_DUPLICATES_AT_ONCE) {
Problems__Issue__assertion_problem(_p_(PM_TooManyDuplicates),
"at most 100 duplicates can be made at any one time",
"so '157 chairs are in the UN General Assembly' will not be allowed. The "
"system for handling duplicates during play becomes too slow and awkward "
"when there are so many.");
instance_count = MAX_DUPLICATES_AT_ONCE;
}
}
#line 874 "inform7/Chapter 15/The Creator.w"
;
parse_node *list_subtree = ParseTree__new(COMMON_NOUN_NT);
parse_node *original_next = p->next;
{
#line 932 "inform7/Chapter 15/The Creator.w"
parse_node *attach_to = list_subtree;
int i;
for (i=1; i<=instance_count; i++) {
inference_subject *new_instance = NULL;
{
#line 953 "inform7/Chapter 15/The Creator.w"
inference_subject *named_after = NULL;
wording NW = EMPTY_WORDING, NAW = EMPTY_WORDING;
int propriety = FALSE;
{
#line 980 "inform7/Chapter 15/The Creator.w"
inference_subject *owner = ParseTree__get_implicit_in_creation_of(current_sentence);
if ((owner) && (instance_count == 1) &&
((confect_name_flag) ||
(Kinds__Compare__le(instance_kind, K_object) == FALSE) || (Wordings__nonempty(CW)))) {
wording OW = InferenceSubjects__get_name_text(owner);
inference_subject *subject_here = ParseTree__get_subject(p);
if (subject_here) {
NW = InferenceSubjects__get_name_text(subject_here);
}
if ((Wordings__nonempty(OW)) && (Wordings__nonempty(NW)) && (Wordings__empty(CW))) {
feed_t id = Feeds__begin();
char confected_name[32];
sprintf(confected_name, " its ");
Feeds__feed_text_expanding_strings(confected_name);
Feeds__feed_wording(NW);
CW = Feeds__end(id);
}
if (Wordings__nonempty(CW)) {
named_after = owner;
NAW = NW;
feed_t id = Feeds__begin();
LOOP_THROUGH_WORDING(j, CW) {
if (Preform__parse_nt_against_word_range(possessive_third_person_NTM, Wordings__one_word(j), NULL, NULL))
{
#line 1019 "inform7/Chapter 15/The Creator.w"
char confected_name[MAX_WORD_LENGTH+10];
if (Plugins__Call__irregular_genitive(owner, confected_name, &propriety) == FALSE) {
if (Wordings__empty(OW)) {
confected_name[0] = 0;
} else {
if (Wordings__length(OW) > 1)
Feeds__feed_wording(Wordings__trim_last_word(OW));
Wordings__to_string_raw(confected_name, Wordings__one_word(Wordings__last_wn(OW)));
if (Platform__strlen(confected_name) < MAX_WORD_LENGTH-3)
sprintf(confected_name+Platform__strlen(confected_name), "'s ");
}
}
Feeds__feed_text_expanding_strings(confected_name);
}
#line 1004 "inform7/Chapter 15/The Creator.w"
else if (Preform__parse_nt_against_word_range(pronoun_NTM, Wordings__one_word(j), NULL, NULL))
{
#line 1036 "inform7/Chapter 15/The Creator.w"
Feeds__feed_wording(OW);
}
#line 1006 "inform7/Chapter 15/The Creator.w"
else Feeds__feed_wording(Wordings__one_word(j));
}
NW = Feeds__end(id);
LOGIF(NOUN_RESOLUTION, "Confecting the name: <$w>\n", NW);
} else {
NW = EMPTY_WORDING;
}
}
}
#line 956 "inform7/Chapter 15/The Creator.w"
;
if (Kinds__Compare__le(instance_kind, K_object) == FALSE)
{
#line 1041 "inform7/Chapter 15/The Creator.w"
wording SW = EMPTY_WORDING;
if (Wordings__empty(NW))
SW = InferenceSubjects__get_name_text(Kinds__Behaviour__as_subject(instance_kind));
else if (Preform__parse_nt_against_word_range(s_constant_value_NTM, NW, NULL, NULL)) SW = NW;
if (Wordings__nonempty(SW)) {
char textual_count[32];
sprintf(textual_count, " %d ", ++name_stubs_count);
feed_t id = Feeds__begin();
Feeds__feed_wording(SW);
Feeds__feed_text_expanding_strings(textual_count);
NW = Feeds__end(id);
}
}
#line 958 "inform7/Chapter 15/The Creator.w"
;
NW = Wordings__truncate(NW, 32); /* truncate to the maximum length */
parse_node *pz = ParseTree__new(PROPER_NOUN_NT);
pcalc_prop *prop = Calculus__Propositions__Abstract__to_create_something(instance_kind, NW);
Calculus__Propositions__Assert__assert_true(prop, prevailing_mood);
new_instance = Instances__as_subject(latest_instance);
if (named_after) {
PL__Naming__transfer_details(named_after, new_instance);
Assertions__Assemblies__name_object_after(new_instance, named_after, NAW);
if ((InferenceSubjects__is_an_object(named_after) == FALSE) &&
(InferenceSubjects__is_a_kind_of_object(named_after) == FALSE)) propriety = TRUE;
}
if (propriety) PL__Naming__now_has_proper_name(new_instance);
Assertions__Refiner__noun_from_infs(pz, new_instance);
ParseTree__annotate_int(pz, creation_site_ANNOT, TRUE);
Assertions__Maker__make_assertion_recursive(pz, p);
}
#line 936 "inform7/Chapter 15/The Creator.w"
;
if (i < instance_count) {
ParseTree__set_type_and_clear_annotations(attach_to, AND_NT);
attach_to->down = ParseTree__new(PROPER_NOUN_NT);
Assertions__Refiner__noun_from_infs(attach_to->down, new_instance);
ParseTree__annotate_int(attach_to->down, creation_site_ANNOT, TRUE);
attach_to->down->next = ParseTree__new(PROPER_NOUN_NT);
attach_to = attach_to->down->next;
} else {
Assertions__Refiner__noun_from_infs(attach_to, new_instance);
ParseTree__annotate_int(attach_to, creation_site_ANNOT, TRUE);
}
}
}
#line 877 "inform7/Chapter 15/The Creator.w"
;
ParseTree__copy(p, list_subtree);
p->next = original_next;
}
#line 1060 "inform7/Chapter 15/The Creator.w"
int text_ending_with_a_calling_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1063 "inform7/Chapter 15/The Creator.w"
int text_including_a_calling_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1066 "inform7/Chapter 15/The Creator.w"
#line 1077 "inform7/Chapter 15/The Creator.w"
int unsuitable_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1081 "inform7/Chapter 15/The Creator.w"
int unsuitable_name_for_locals_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1086 "inform7/Chapter 15/The Creator.w"
int unfortunate_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1090 "inform7/Chapter 15/The Creator.w"
#line 1094 "inform7/Chapter 15/The Creator.w"
int Assertions__Creator__vet_name_for_noun(wording W) {
if (Preform__parse_nt_against_word_range(unfortunate_name_NTM, W, NULL, NULL)) {
Problems__Issue__sentence_problem(_p_(PM_NameBestAvoided),
"this is a name which is best avoided",
"because it would lead to confusion inside Inform. In general, try "
"to avoid punctuation, quotation marks, or the words 'with' or "
"'having' in names like this. (Hyphens are fine, so by all means "
"use a name like 'Church-with-Spire', if that will help.)");
return FALSE;
}
return TRUE;
}
#line 46 "inform7/Chapter 15/Make Assertions.w"
matrix_entry assertion_matrix[ASSERTION_MATRIX_DIM] = {
/* A, W, XY, K, A, PL, A, A, R, E, CN, PN */
{ AND_NT, { 1, 2, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1 } },
{ WITH_NT, { 3, 4, 3, 3, 3, 3, 3, 3, 14, 16, 3, 3 } },
{ X_OF_Y_NT, { 5, 2, 6, 7, 9, 7, 7, 7, 20, 16, 23, 7 } },
{ KIND_NT, { 5, 2, 8, 8, 9, 8, 8, 8, 8, 16, 8, 8 } },
{ ALLOWED_NT, { 5, 2, 10, 10, 9, 10, 10, 10, 10, 25, 25, 25 } },
{ PROPERTY_LIST_NT, { 5, 2, 11, 12, 9, 18, 22, 19, 20, 16, 18, 18 } },
{ ADJECTIVE_NT, { 5, 2, 13, 12, 9, 22, 22, 24, 20, 16, 29, 29 } },
{ ACTION_NT, { 5, 2, 11, 19, 9, 19, 19, 27, 20, 16, 32, 32 } },
{ RELATIONSHIP_NT, { 5, 15, 21, 20, 9, 20, 42, 20, 28, 31, 34, 36 } },
{ EVERY_NT, { 17, 17, 17, 17, 17, 17, 17, 17, 17, 33, 17, 17 } },
{ COMMON_NOUN_NT, { 5, 2, 11, 12, 9, 18, 30, 19, 35, 16, 38, 39 } },
{ PROPER_NOUN_NT, { 5, 2, 26, 12, 9, 18, 30, 19, 37, 16, 40, 41 } } };
#line 66 "inform7/Chapter 15/Make Assertions.w"
int Assertions__Maker__which_assertion_case(parse_node *px, parse_node *py) {
if (px == NULL) internal_error("make assertion with px NULL");
if (py == NULL) internal_error("make assertion with py NULL");
if ((ParseTree__allow_in_assertions(px) == FALSE) ||
(ParseTree__allow_in_assertions(py) == FALSE)) {
ParseTree__log_subtree(px);
ParseTree__log_subtree(py);
internal_error("make assertion with improper nodes");
}
int i, x=-1, y=-1;
node_type_t wx = ParseTree__get_type(px), wy = ParseTree__get_type(py);
for (i=0; i<ASSERTION_MATRIX_DIM; i++) {
if (assertion_matrix[i].row_node_type == wx) x=i;
if (assertion_matrix[i].row_node_type == wy) y=i;
}
if ((x<0) || (y<0)) {
ParseTree__log_subtree(px);
ParseTree__log_subtree(py);
internal_error("make assertion with node type not in matrix");
}
return assertion_matrix[y].cases[x];
}
#line 92 "inform7/Chapter 15/Make Assertions.w"
void Assertions__Maker__make_assertion_recursive(parse_node *px, parse_node *py) {
LOG_INDENT;
Assertions__Maker__make_assertion_recursive_inner(px, py);
LOG_OUTDENT;
}
void Assertions__Maker__make_assertion_recursive_inner(parse_node *px, parse_node *py) {
{
#line 115 "inform7/Chapter 15/Make Assertions.w"
int pc = problem_count;
if (Plugins__Call__intervene_in_assertion(px, py)) return;
if (problem_count > pc) return;
}
#line 99 "inform7/Chapter 15/Make Assertions.w"
;
if (traverse == 2)
{
#line 122 "inform7/Chapter 15/Make Assertions.w"
if ((prevailing_mood == INITIALLY_CE) &&
((ParseTree__get_type(px) != PROPER_NOUN_NT) ||
(ParseTree__get_type(py) != PROPER_NOUN_NT))) {
Problems__Issue__sentence_problem(_p_(PM_MisplacedInitially),
"you can only say 'initially' when creating variables using 'is'",
"so 'The squirrel population is initially 0' is fine, but not "
"'The acorn is initially carried by Mr Hedges.' - probably you "
"only need to remove the word 'initially'.");
return;
}
if ((prevailing_mood != UNKNOWN_CE) &&
(Rvalues__is_CONSTANT_construction(ParseTree__get_evaluation(px), CON_property) == FALSE) &&
(Lvalues__is_actual_NONLOCAL_VARIABLE(ParseTree__get_evaluation(px)) == FALSE) &&
(ParseTree__get_type(px) == PROPER_NOUN_NT)) {
Problems__Issue__sentence_problem(_p_(PM_VagueAboutSpecific),
"you can only equivocate with 'usually', 'rarely', "
"'always' and the like when talking about kinds of thing",
"because when a specific thing is involved you should say "
"definitely one way or another. 'A cave is usually dark' is "
"fine, but not 'the Mystic Wood is usually dark'.");
return;
}
if (((ParseTree__get_type(px) == COMMON_NOUN_NT)
&& (ParseTree__get_evaluation(px)) && (ParseTree__int_annotation(px, multiplicity_ANNOT) > 1)
&& (ParseTree__get_type(py) != RELATIONSHIP_NT)) ||
((ParseTree__get_type(py) == COMMON_NOUN_NT)
&& (ParseTree__get_evaluation(py)) && (ParseTree__int_annotation(py, multiplicity_ANNOT) > 1)
&& (ParseTree__get_type(px) != RELATIONSHIP_NT))) {
Problems__Issue__sentence_problem(_p_(PM_MultiplyVague),
"multiple objects can only be put into relationships",
"by saying something like 'In the Drawing Room are two women.', "
"and all other assertions with multiple objects are disallowed: "
"so 'Three doors are open.' is rejected - I can't tell which three.");
return;
}
}
#line 100 "inform7/Chapter 15/Make Assertions.w"
;
if (prevailing_mood == INITIALLY_CE) prevailing_mood = LIKELY_CE;
int ma_case = Assertions__Maker__which_assertion_case(px, py);
LOGIF(ASSERTIONS, "[$w/$N] =%d [$w/$N]\n",
ParseTree__get_text(px), ParseTree__get_type(px), ma_case,
ParseTree__get_text(py), ParseTree__get_type(py));
{
#line 164 "inform7/Chapter 15/Make Assertions.w"
switch(ma_case) {
case 1:
{
#line 214 "inform7/Chapter 15/Make Assertions.w"
parse_node *across = py->down;
int np = problem_count;
while (across) {
if (np == problem_count) Assertions__Maker__make_assertion_recursive(px, across);
across = across->next;
}
}
#line 165 "inform7/Chapter 15/Make Assertions.w"
; return;
case 2:
{
#line 237 "inform7/Chapter 15/Make Assertions.w"
if ((ParseTree__get_type(px->down) == COMMON_NOUN_NT) &&
(Assertions__Maker__is_adjlist(px->down->next)) &&
(Assertions__Maker__is_adjlist(py))) {
Assertions__Implications__new(px, py);
} else if ((ParseTree__get_type(px->down) == PROPER_NOUN_NT) &&
(ParseTree__get_type(px->next) == COMMON_NOUN_NT)) {
int np = problem_count;
Assertions__Maker__make_assertion_recursive(px->down, py); /* A is B */
if (problem_count == np)
Assertions__Maker__make_assertion_recursive(px->down, px->down->next); /* A is I */
} else {
int np = problem_count;
Assertions__Maker__make_assertion_recursive(px->down, py); /* A is B */
if (problem_count == np)
Assertions__Maker__make_assertion_recursive(px->down->next, py); /* I is B */
}
}
#line 166 "inform7/Chapter 15/Make Assertions.w"
; return;
case 3:
{
#line 274 "inform7/Chapter 15/Make Assertions.w"
if ((ParseTree__get_type(px) == PROPER_NOUN_NT) &&
(PL__Map__is_a_direction(ParseTree__get_subject(px))) &&
(ParseTree__get_type(py->down) == PROPER_NOUN_NT)) {
int np = problem_count;
Assertions__Maker__make_assertion_recursive(px, py->down); /* A is a B */
if (problem_count == np)
Assertions__Maker__make_assertion_recursive(py->down, py->down->next); /* B is I */
} else {
int np = problem_count;
Assertions__Maker__make_assertion_recursive(px, py->down); /* A is a B */
if (problem_count == np)
Assertions__Maker__make_assertion_recursive(px, py->down->next); /* A is I */
}
}
#line 167 "inform7/Chapter 15/Make Assertions.w"
; return;
case 4:
{
#line 293 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_WithIsWith),
"you can't say that one general description is another ",
"for instance by writing 'A container with carrying capacity 10 is a "
"container with description \"Handy.\"'.");
}
#line 168 "inform7/Chapter 15/Make Assertions.w"
; return;
case 5:
{
#line 301 "inform7/Chapter 15/Make Assertions.w"
parse_node *across = px->down;
int np = problem_count;
while (across) {
if (np == problem_count) Assertions__Maker__make_assertion_recursive(across, py);
across = across->next;
}
}
#line 169 "inform7/Chapter 15/Make Assertions.w"
; return;
case 6:
{
#line 312 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_XofYisZofW),
"this seems to say two different properties are not simply equal "
"but somehow the same thing",
"like saying that 'the printed name of the millpond is the "
"printed name of the village pond'. This puts me in a quandary: "
"which should be changed to match the other, and what if I am "
"unable to work out the value of either one?");
}
#line 170 "inform7/Chapter 15/Make Assertions.w"
; return;
case 7:
{
#line 323 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_BadXofY),
"this is the wrong way around if you want to specify a property",
"like saying that '10 is the score of the platinum pyramid', "
"which is poor style. (Though sweet are the uses of adversity.)");
}
#line 171 "inform7/Chapter 15/Make Assertions.w"
; return;
case 8:
{
#line 340 "inform7/Chapter 15/Make Assertions.w"
if (traverse == 2) return;
if ((py->down) && (ParseTree__get_type(py->down) == KIND_NT))
{
#line 438 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_KindOfKindDisallowed),
"you aren't allowed to make new kinds of kinds",
"only kinds of things which already exist. So 'A fox is a kind of animal' "
"is fine, but 'A tricky kind is a kind of kind' isn't allowed.");
return;
}
#line 342 "inform7/Chapter 15/Make Assertions.w"
;
if ((py->down) && (ParseTree__get_type(py->down) == EVERY_NT))
{
#line 447 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_KindOfEveryDisallowed),
"you aren't allowed to make a kind of everything",
"or of everything matching a description. 'A badger is a kind of animal' "
"is fine, but 'A gene is a kind of every animal' isn't allowed. (Probably "
"you just need to get rid of the word 'every'.)");
return;
}
#line 344 "inform7/Chapter 15/Make Assertions.w"
;
if (prevailing_mood != UNKNOWN_CE)
{
#line 457 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_KindUncertainDisallowed),
"you aren't allowed to make a kind in a way expressing certainty or doubt",
"so 'A badger is a kind of animal' is fine, but 'A fungus is usually a "
"kind of every animal' isn't allowed, and nor is 'A fern is never a kind "
"of animal'. When you tell me about kinds, you have to tell me certainly.");
return;
}
#line 346 "inform7/Chapter 15/Make Assertions.w"
;
inference_subject *inst = ParseTree__get_subject(px);
inference_subject *kind_of_what = ParseTree__get_subject(py);
if (kind_of_what == NULL) internal_error("KIND node without subject");
if ((InferenceSubjects__is_an_object(inst)) ||
(InferenceSubjects__is_a_kind_of_object(inst))) {
if ((InferenceSubjects__domain(inst) == FALSE) &&
(InferenceSubjects__where_created(inst) != current_sentence))
{
#line 376 "inform7/Chapter 15/Make Assertions.w"
Problems__quote_subject(1, inst);
Problems__quote_source(2, current_sentence);
Problems__quote_source(3, InferenceSubjects__where_created(inst));
Problems__Issue__handmade_problem(_p_(PM_InstanceNowKind));
Problems__issue_problem_segment(
"You wrote '%2', but that seems to say that some "
"room or thing already created ('%1', created by '%3') is now to "
"become a kind. To prevent a variety of possible misunderstandings, "
"this is not allowed: when a kind is created, the name given has "
"to be a name not so far used. (Sometimes this happens due to "
"confusion between names. For instance, if a room called 'Marble "
"archway' exists, then Inform reads 'An archway is a kind of thing', "
"Inform will read 'archway' as a reference to the existing room, "
"not as a new name. To solve this, put the sentences the other way "
"round.)");
Problems__issue_problem_end();
return;
}
#line 356 "inform7/Chapter 15/Make Assertions.w"
;
pcalc_prop *subject_to = NULL;
if (py->down) {
if (ParseTree__get_type(py->down) == WITH_NT)
subject_to = ParseTree__get_creation_proposition(py->down);
else
subject_to = Specifications__to_proposition(ParseTree__get_evaluation(py->down));
}
Calculus__Propositions__Abstract__assert_kind_of_subject(inst, kind_of_what, subject_to);
return;
}
{
#line 397 "inform7/Chapter 15/Make Assertions.w"
if (ParseTree__get_type(px) == PROPER_NOUN_NT) {
property *prn = Rvalues__to_property(
ParseTree__get_evaluation(px));
if (prn) {
Problems__quote_source(1, current_sentence);
Problems__quote_property(2, prn);
Problems__quote_wording_as_source(3, prn->name);
Problems__Issue__handmade_problem(_p_(PM_KindAsProperty));
Problems__issue_problem_segment(
"You wrote '%1', but that seems to say that a property "
"(%3) has to be a kind as well. It is sometimes okay for a "
"property to have the same name as a kind, but only when that "
"kind is what it stores, and there shouldn't be a sentence "
"like this one to declare the kind - it will be made when the "
"property is made, and doesn't need to be made again.");
Problems__issue_problem_end();
return;
}
}
}
#line 370 "inform7/Chapter 15/Make Assertions.w"
;
{
#line 420 "inform7/Chapter 15/Make Assertions.w"
if (ParseTree__get_type(px) == PROPER_NOUN_NT) {
parse_node *val = ParseTree__get_evaluation(px);
if (ParseTree__is(val, CONSTANT_VNT)) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind_of(2, val);
Problems__quote_wording_as_source(3, ParseTree__get_text(px));
Problems__Issue__handmade_problem(_p_(PM_KindAsActualValue));
Problems__issue_problem_segment(
"You wrote '%1', but that seems to say that a value already "
"in existence (%3) has to be a kind as well. (It's %2.)");
Problems__issue_problem_end();
return;
}
}
}
#line 371 "inform7/Chapter 15/Make Assertions.w"
;
}
#line 172 "inform7/Chapter 15/Make Assertions.w"
; return;
case 9:
{
#line 467 "inform7/Chapter 15/Make Assertions.w"
internal_error("Forbidden case 9 in make assertion has occurred.");
}
#line 173 "inform7/Chapter 15/Make Assertions.w"
; return;
case 10:
{
#line 477 "inform7/Chapter 15/Make Assertions.w"
if (ParseTree__get_type(px) == KIND_NT)
{
#line 767 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_TooVagueForVariables),
"this is too vague a description of the owner of the property",
"so that I don't know where to put this. Something like 'A person "
"has a number called age' is fine, but 'A kind has a number called "
"age' is not. Which kind?");
}
#line 478 "inform7/Chapter 15/Make Assertions.w"
else
{
#line 776 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_HasNoVariables),
"only an object, kind, rulebook, action or activity can be allowed to have "
"properties or variables",
"so for instance 'A door has a colour' is fine but not 'A number has a length'.");
return;
}
#line 480 "inform7/Chapter 15/Make Assertions.w"
;
}
#line 174 "inform7/Chapter 15/Make Assertions.w"
; return;
case 11:
{
#line 488 "inform7/Chapter 15/Make Assertions.w"
if (ParseTree__get_type(py) == COMMON_NOUN_NT) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(py));
Problems__quote_kind_of(3, ParseTree__get_evaluation(py));
Problems__Issue__handmade_problem(_p_(PM_PropertyObj2));
Problems__issue_problem_segment(
"In %1 you give a value of a property as '%2', but it "
"seems to be a general description of a value (%3) rather than "
"nailing down exactly what the value should be.");
Problems__issue_problem_end();
return;
}
if (ParseTree__get_type(py) == ACTION_NT) {
action_pattern *ap = ParseTree__get_action_meaning(py);
if ((ap) && (PL__Actions__Patterns__is_unspecific(ap) == FALSE) &&
(PL__Actions__Patterns__is_overspecific(ap) == FALSE)) {
parse_node *val = Rvalues__from_action_pattern(ap);
Assertions__Refiner__noun_from_value(py, val);
Assertions__Maker__make_assertion_recursive(px, py);
return;
}
}
Problems__Issue__assertion_problem(_p_(PM_PeculiarProperty),
"that is a very peculiar property value",
"and ought to be something more definite and explicit.");
}
#line 175 "inform7/Chapter 15/Make Assertions.w"
; return;
case 12:
{
#line 517 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_KindOfIs),
"that seems to say that a new kind is the same as something else",
"like saying 'A kind of container is a canister': which ought to be put the "
"other way round, 'A canister is a kind of container'.");
}
#line 176 "inform7/Chapter 15/Make Assertions.w"
; return;
case 13:
{
#line 525 "inform7/Chapter 15/Make Assertions.w"
if (traverse == 1) return;
if (Adjectives__Phrases__has_ENUMERATIVE_meaning(ParseTree__get_aph(py))) {
property *prn = Properties__Valued__obtain(ParseTree__get_text(px->down->next));
if (ParseTree__get_type(px->down) == WITH_NT) {
Problems__Issue__assertion_problem(_p_(PM_EOOwnerMutable),
"either/or properties have to be given to clearly identifiable "
"owners",
"rather than to a collection of owners which might vary during "
"play. (It is possible to get around this using 'implications', "
"but it's better to avoid the need.)");
} else {
Sentences__NPs__turn_player_to_yourself(px->down);
Assertions__PropertyKnowledge__assert_property_value_from_property_subtree_infs(prn,
ParseTree__get_subject(px->down), py);
}
} else {
Problems__Issue__assertion_problem(_p_(PM_NonAdjectivalProperty),
"that property can't be used adjectivally as a value",
"since it is an adjective applying to a thing but is "
"not a name from a range of possibilities.");
}
}
#line 177 "inform7/Chapter 15/Make Assertions.w"
; return;
case 14:
{
#line 553 "inform7/Chapter 15/Make Assertions.w"
Assertions__Maker__make_assertion_recursive(px, py->down);
Assertions__Maker__make_assertion_recursive(py->down, py->down->next);
}
#line 178 "inform7/Chapter 15/Make Assertions.w"
; return;
case 15:
{
#line 559 "inform7/Chapter 15/Make Assertions.w"
Assertions__Maker__make_assertion_recursive(px->down, py);
Assertions__Maker__make_assertion_recursive(px->down, px->down->next);
}
#line 179 "inform7/Chapter 15/Make Assertions.w"
; return;
case 16:
{
#line 565 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_BadEvery),
"'every' (or 'always') can't be used in that way",
"and should be reserved for sentences like 'A coin is in every room'.");
}
#line 180 "inform7/Chapter 15/Make Assertions.w"
; return;
case 17:
{
#line 575 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_BadEvery2),
"'every' can't be used in that way",
"and should be reserved for sentences like 'A coin is in every room'.");
}
#line 181 "inform7/Chapter 15/Make Assertions.w"
; return;
case 18:
{
#line 593 "inform7/Chapter 15/Make Assertions.w"
if (traverse == 1) return;
if ((ParseTree__get_type(px) == PROPER_NOUN_NT) &&
(Rvalues__is_CONSTANT_construction(ParseTree__get_evaluation(px), CON_rulebook))) {
Rulebooks__parse_properties(Rvalues__to_rulebook(ParseTree__get_evaluation(px)),
Wordings__new(ParseTree__left_edge_of(py), ParseTree__right_edge_of(py)));
return;
}
if (ParseTree__get_type(px) == PROPERTY_LIST_NT) Assertions__PropertyKnowledge__assert_property_list(py, px);
else Assertions__PropertyKnowledge__assert_property_list(px, py);
}
#line 182 "inform7/Chapter 15/Make Assertions.w"
; return;
case 19:
{
#line 609 "inform7/Chapter 15/Make Assertions.w"
if (ParseTree__get_subject(py))
Problems__Issue__assertion_problem(_p_(PM_ActionEquated),
"an action can't be the same as a thing",
"so my guess is that this is an attempt to categorise an action which went "
"wrong because there was already something of that name in existence. For "
"instance, 'Taking something is theft' would fail if 'theft' was already a "
"value. (But it can also happen with a sentence which tries to set several "
"actions at once to a named kind of action, like 'Taking and dropping are "
"manipulation.' - only one can be named at a time.)");
else
Problems__Issue__assertion_problem(_p_(PM_ActionEquated2),
"that means something else already",
"so it will only confuse things if we use it for a kind of action.");
}
#line 183 "inform7/Chapter 15/Make Assertions.w"
; return;
case 20:
{
#line 629 "inform7/Chapter 15/Make Assertions.w"
if (Sentences__NPs__turn_player_to_yourself(px)) { Assertions__Maker__make_assertion_recursive(px, py); return; }
if (Sentences__NPs__turn_player_to_yourself(py)) { Assertions__Maker__make_assertion_recursive(px, py); return; }
Problems__Issue__assertion_problem(_p_(PM_IntangibleRelated),
"this seems to give a worldly relationship to something intangible",
"like saying that 'in the box is a text'. Perhaps it came "
"to this because you gave something physical a name which was "
"accidentally something meaningful to me in another context? "
"If so, you may be able to get around it by rewording ('In the "
"box is a medieval text') or in extremis by using 'called' "
"('In the box is a thing called text').");
}
#line 184 "inform7/Chapter 15/Make Assertions.w"
; return;
case 21:
{
#line 645 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_XofYRelated),
"this seems to say that a property of something is not simply equal "
"to what happens at the moment to satisfy some relationship, but "
"conceptually the same as that relationship",
"like saying 'the position of the weathervane is east of the "
"church'. It would be fine to say 'the position of the weathervane "
"is east' or 'the position of the weathervane is the meadow', "
"because 'east' and 'meadow' are definite things.");
}
#line 185 "inform7/Chapter 15/Make Assertions.w"
; return;
case 22:
{
#line 667 "inform7/Chapter 15/Make Assertions.w"
Assertions__Refiner__coerce_adjectival_usage_to_noun(px);
if (ParseTree__get_type(px) == PROPER_NOUN_NT) {
Assertions__Maker__make_assertion_recursive(px, py);
return;
}
if (traverse == 2) Assertions__Implications__new(px, py);
}
#line 186 "inform7/Chapter 15/Make Assertions.w"
; return;
case 23:
{
#line 677 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_DescriptionIsOther),
"this seems to say that a general description is something else",
"like saying that 'a door is 20'.");
}
#line 187 "inform7/Chapter 15/Make Assertions.w"
; return;
case 24:
{
#line 686 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_ActionAdjective),
"that is already the name of a property",
"so it will only confuse things if we use it for a kind of action.");
}
#line 188 "inform7/Chapter 15/Make Assertions.w"
; return;
case 25:
{
#line 696 "inform7/Chapter 15/Make Assertions.w"
if (Sentences__NPs__turn_player_to_yourself(px)) {
Assertions__Maker__make_assertion_recursive(px, py); return;
}
parse_node *spec = ParseTree__get_evaluation(px);
if ((ParseTree__get_subject(px) == NULL) &&
(Rvalues__is_CONSTANT_construction(spec, CON_property))) {
property *prn = ParseTree__get_constant_property(spec);
if ((prn) && (Properties__Valued__coincides_with_kind(prn))) {
kind *K = Properties__Valued__kind(prn);
ParseTree__set_type_and_clear_annotations(px, COMMON_NOUN_NT);
ParseTree__set_subject(px, Kinds__Behaviour__as_subject(K));
ParseTree__set_evaluation(px, Specifications__from_kind(K));
}
}
if (ParseTree__get_subject(px) == NULL) {
kind *K = Specifications__to_kind(spec);
if (ParseTree__is(spec, CONSTANT_VNT)) {
if (Plugins__Call__offered_property(K, spec, py->down)) return;
if (Kinds__get_construct(K) == CON_activity)
{
#line 726 "inform7/Chapter 15/Make Assertions.w"
activity *av = Rvalues__to_activity(spec);
if (av == NULL) internal_error("failed to extract activity structure");
if (traverse == 2) {
if (Preform__parse_nt_against_word_range(activity_name_formal_NTM, ParseTree__get_text(px), NULL, NULL))
Activities__add_variable(av, py->down);
else
Problems__Issue__assertion_problem(_p_(PM_BadActivityRef),
"an activity has to be formally referred to in a way making clear that "
"it is indeed a rulebook when we give it named values",
"to reduce the risk of ambiguity. So 'The printing the banner text "
"activity has a number called the accumulated vanity' is fine, but "
"'Printing the banner text has a number called...' is not. (I'm "
"insisting on the presence of the word 'activity' because the "
"syntax is so close to that for giving properties to objects, and "
"it's important to avoid mistakes here.)");
}
return;
}
#line 715 "inform7/Chapter 15/Make Assertions.w"
;
if (Kinds__get_construct(K) == CON_rulebook)
{
#line 747 "inform7/Chapter 15/Make Assertions.w"
rulebook *rb = Rvalues__to_rulebook(spec);
if (rb == NULL) internal_error("failed to extract rulebook structure");
if (traverse == 2) {
if (Preform__parse_nt_against_word_range(rulebook_name_formal_NTM, ParseTree__get_text(px), NULL, NULL))
Rulebooks__add_variable(rb, py->down);
else
Problems__Issue__assertion_problem(_p_(PM_BadRulebookRef),
"a rulebook has to be formally referred to in a way making clear that "
"it is indeed a rulebook when we give it named values",
"to reduce the risk of ambiguity. So 'The every turn rulebook has a "
"number called the accumulated bonus' is fine, but 'Every turn has a "
"number called...' is not. (I'm insisting on the presence of the word "
"'rulebook' because the syntax is so close to that for giving "
"properties to objects, and it's important to avoid mistakes here.)");
}
return;
}
#line 716 "inform7/Chapter 15/Make Assertions.w"
;
}
{
#line 776 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_HasNoVariables),
"only an object, kind, rulebook, action or activity can be allowed to have "
"properties or variables",
"so for instance 'A door has a colour' is fine but not 'A number has a length'.");
return;
}
#line 718 "inform7/Chapter 15/Make Assertions.w"
;
}
if (traverse == 1) Assertions__Property__recursively_declare_properties(px, py->down);
}
#line 189 "inform7/Chapter 15/Make Assertions.w"
; return;
case 26:
{
#line 793 "inform7/Chapter 15/Make Assertions.w"
if (traverse == 1) return;
Sentences__NPs__turn_player_to_yourself(px->down);
if (Preform__parse_nt_against_word_range(negated_clause_NTM, ParseTree__get_text(py), NULL, NULL)) {
Problems__Issue__negative_sentence_problem(_p_(PM_NonValue)); return;
}
parse_node *owner = ParseTree__get_evaluation(px->down);
property *prn = Properties__Valued__obtain(ParseTree__get_text(px->down->next));
if (prn == P_specification)
{
#line 832 "inform7/Chapter 15/Make Assertions.w"
wording W = ParseTree__get_text(py);
{
#line 855 "inform7/Chapter 15/Make Assertions.w"
if ((Preform__parse_nt_against_word_range(s_literal_NTM, W, NULL, NULL)) && (Rvalues__is_CONSTANT_of_kind(most_recent_result_p, K_text))) {
Text__dequote_word(Wordings__first_wn(W));
} else {
Problems__Issue__assertion_problem(_p_(PM_SpecNotText),
"this tries to set a specification to something other than literal quoted text",
"which will not work. 'Specification' is a special property used only to "
"annotate the Index, and specifically the Kinds index, so it makes no sense to "
"set this property to anything other than text.");
return;
}
}
#line 833 "inform7/Chapter 15/Make Assertions.w"
;
if (Specifications__is_kind_like(owner)) {
kind *K = Specifications__to_kind(owner);
if (Kinds__Compare__lt(K, K_object) == FALSE) {
Kinds__Behaviour__set_specification_text(K, Lexer__word_text(Wordings__first_wn(W)));
return;
}
} else if (Plugins__Call__offered_specification(owner, W)) {
return;
} else if (ParseTree__get_type(px->down) != COMMON_NOUN_NT) {
LOG("$T\n", current_sentence);
Problems__Issue__assertion_problem(_p_(PM_Unspecifiable),
"this tries to set specification text for a particular value",
"rather than a kind of value. 'Specification' is a special property used "
"only to annotate the Index, and it makes no sense to set this property for "
"anything other than a kind of value, a kind of object or an action.");
return;
}
}
#line 801 "inform7/Chapter 15/Make Assertions.w"
;
Assertions__Refiner__coerce_adjectival_usage_to_noun(px->down);
if ((ParseTree__get_type(px->down) == PROPER_NOUN_NT) ||
(ParseTree__get_type(px->down) == COMMON_NOUN_NT)) {
inference_subject *owner_infs = ParseTree__get_subject(px->down);
if (owner_infs == NULL) {
if (Preform__parse_nt_against_word_range(k_kind_NTM, ParseTree__get_text(px->down), NULL, NULL))
owner_infs = Kinds__Behaviour__as_subject(most_recent_result_p);
}
if ((Specifications__is_description(owner)) &&
(Specifications__is_kind_like(owner) == FALSE))
{
#line 869 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_OverspecifiedSpec),
"this tries to set a property for something more complicated than a single thing "
"named without qualifications",
"and that isn't allowed. For instance, 'The description of the Great Portal is "
"\"It's open.\"' is fine, but 'The description of the Great Portal in the Palace "
"is \"It's open.\"' is not allowed, because it tries to qualify 'Great Portal' "
"with the extra clause 'in the Palace'. (If you need to make a description which "
"changes based on where something is, or where it is seen from, try using text "
"substitutions.)");
}
#line 813 "inform7/Chapter 15/Make Assertions.w"
else if (owner_infs)
Assertions__PropertyKnowledge__assert_property_value_from_property_subtree_infs(prn, owner_infs, py);
else
{
#line 882 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_BadInferenceSubject),
"this tries to set a property for a value which can't have properties",
"and that isn't allowed. For instance, 'The description of the Great Portal is "
"\"It's open.\"' would be fine, if Great Portal were a room, but 'The description "
"of 6 is \"Sixish.\"' would not, because the number 6 isn't allowed to have "
"properties.");
}
#line 816 "inform7/Chapter 15/Make Assertions.w"
;
return;
}
{
#line 892 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_GeneralitySpec),
"this tries to set a property for a complicated generality of items all at once",
"which can lead to ambiguities. For instance, 'The description of an open door "
"is \"It's open.\"' is not allowed: if we followed Inform's normal conventions "
"strictly, that would be an instruction to create a new, nameless, open door and "
"give it the description. But this is very unlikely to be what the writer "
"intended, given the presence of the adjective to make it seem as if a particular "
"door is meant. So in fact we reject such sentences unless they refer only to a "
"kind, without adjectives: 'The description of a door is \"It's a door.\"' is "
"fine. (If the idea is actually to make the description change in play, we could "
"write a rule like 'Instead of examining an open door, say \"It's open.\"'; or "
"we could set the description of every door to \"[if open]It's open.[otherwise]It's "
"closed.\".)");
}
#line 820 "inform7/Chapter 15/Make Assertions.w"
;
}
#line 190 "inform7/Chapter 15/Make Assertions.w"
; return;
case 27:
{
#line 909 "inform7/Chapter 15/Make Assertions.w"
if (traverse == 1) return;
action_pattern *apx = ParseTree__get_action_meaning(px);
action_pattern *apy = ParseTree__get_action_meaning(py);
if ((PL__Actions__Patterns__is_valid(apy)) &&
(PL__Actions__Patterns__is_named(apy) == FALSE)) {
LOG("Actions: $A and $A\n", apx, apy);
Problems__Issue__assertion_problem(_p_(PM_ActionsEquated),
"two actions are rather oddly equated here",
"which would only make sense if the second were a named pattern of actions "
"like (say) 'unseemly behaviour'.");
} else PL__Actions__Patterns__categorise_as(apx, ParseTree__get_text(py));
}
#line 191 "inform7/Chapter 15/Make Assertions.w"
; return;
case 28:
{
#line 931 "inform7/Chapter 15/Make Assertions.w"
if ((ParseTree__int_annotation(px, relationship_node_type_ANNOT) == DIRECTION_RELN) &&
(ParseTree__int_annotation(py, relationship_node_type_ANNOT) == DIRECTION_RELN)) {
PL__Map__enter_one_way_mode();
Assertions__Maker__make_assertion_recursive(px, py->down);
Assertions__Maker__make_assertion_recursive(px->down, py);
PL__Map__exit_one_way_mode();
return;
}
Problems__Issue__assertion_problem(_p_(PM_RelationsEquated),
"this says that two different relations are the same",
"like saying that 'in the box is on the table'. (Sometimes this "
"happens if I misinterpret names of places like 'In Prison' or "
"'East of Fissure'.)");
}
#line 192 "inform7/Chapter 15/Make Assertions.w"
; return;
case 29:
{
#line 950 "inform7/Chapter 15/Make Assertions.w"
Sentences__NPs__turn_player_to_yourself(px);
if (traverse == 2) Assertions__PropertyKnowledge__assert_property_list(px, py);
}
#line 193 "inform7/Chapter 15/Make Assertions.w"
; return;
case 30:
{
#line 959 "inform7/Chapter 15/Make Assertions.w"
if (ParseTree__get_subject(py))
Problems__Issue__assertion_problem(_p_(PM_AdjectiveIsObject),
"that seems to say that an adjective is a noun",
"like saying 'Open are the doubled doors': which I'm picky about, preferring "
"it written the other way about ('The doubled doors are open'). Less poetic, "
"but clearer style.");
else
Problems__Issue__assertion_problem(_p_(PM_AdjectiveIsValue),
"that suggests that an adjective has some sort of value",
"like saying 'Open is a number' or 'Scenery is 5': but of course an adjective "
"represents something which is either true or false.");
}
#line 194 "inform7/Chapter 15/Make Assertions.w"
; return;
case 31:
{
#line 974 "inform7/Chapter 15/Make Assertions.w"
if (traverse == 1) Assertions__Assemblies__make_generalisation(px, py);
}
#line 195 "inform7/Chapter 15/Make Assertions.w"
; return;
case 32:
{
#line 979 "inform7/Chapter 15/Make Assertions.w"
if ((ParseTree__get_subject(px)) && (InferenceSubjects__domain(ParseTree__get_subject(px)))) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, py);
Problems__Issue__handmade_problem(_p_(PM_KindIsAction));
Problems__issue_problem_segment(
"You wrote %1: unfortunately %2 is already the name of an action, "
"and it would only confuse things if we used it for a value as well.");
Problems__issue_problem_end();
} else {
Problems__Issue__assertion_problem(_p_(PM_ObjectIsAction),
"that is putting the definition back to front",
"since I need these categorisations of actions to take the form 'Kissing a "
"woman is love', not 'Love is kissing a woman'. (This is really because it "
"is better style: love might be many other things too, and we don't want to "
"imply that the present definition is all-inclusive.)");
}
}
#line 196 "inform7/Chapter 15/Make Assertions.w"
; return;
case 33:
{
#line 999 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__assertion_problem(_p_(PM_EveryEquated),
"I can't do that", "Dave.");
}
#line 197 "inform7/Chapter 15/Make Assertions.w"
; return;
case 34:
{
#line 1009 "inform7/Chapter 15/Make Assertions.w"
{
#line 1052 "inform7/Chapter 15/Make Assertions.w"
if ((py->down) && (ParseTree__get_type(py->down) == EVERY_NT)) {
if (traverse == 1) Assertions__Assemblies__make_generalisation(py, px);
return;
}
}
#line 1009 "inform7/Chapter 15/Make Assertions.w"
;
{
#line 1067 "inform7/Chapter 15/Make Assertions.w"
if (ParseTree__int_annotation(px, multiplicity_ANNOT) >= 1) {
Assertions__Creator__convert_instance_to_nounphrase(px, NULL);
Assertions__Maker__make_assertion_recursive(py, px);
return;
}
}
#line 1010 "inform7/Chapter 15/Make Assertions.w"
;
{
#line 1078 "inform7/Chapter 15/Make Assertions.w"
binary_predicate *bp = ParseTree__get_relationship(py);
if ((bp) && ((Properties__SettingRelations__bp_sets_a_property(bp)) ||
(BinaryPredicates__relates_values_not_objects(bp)))) {
if (traverse == 2) Assertions__Relational__assert_subtree_in_relationship(px, py);
return;
}
}
#line 1011 "inform7/Chapter 15/Make Assertions.w"
;
{
#line 1090 "inform7/Chapter 15/Make Assertions.w"
if (ParseTree__int_annotation(current_sentence, sentence_is_existential_ANNOT)) {
Assertions__Creator__convert_instance_to_nounphrase(px, NULL);
Assertions__Maker__make_assertion_recursive(py, px);
return;
}
}
#line 1012 "inform7/Chapter 15/Make Assertions.w"
;
if (prevailing_mood == CERTAIN_CE) {
ParseTree__set_subject(px,
Kinds__Behaviour__as_subject(
Specifications__to_kind(
ParseTree__get_evaluation(px))));
ParseTree__set_type(px, EVERY_NT);
Assertions__Maker__make_assertion_recursive(px, py);
return;
}
if (Kinds__Compare__le(Specifications__to_kind(ParseTree__get_evaluation(px)), K_object))
Problems__Issue__assertion_problem(_p_(PM_KindRelated),
"something described only by its kind should not be given a "
"specific place or role in the world",
"to avoid ambiguity. For instance, suppose 'car' is a kind. Then "
"we are not allowed to say 'a car is in the garage': there's too "
"much risk of confusion between whether an individual (but "
"nameless) car is referred to, or whether cars are generically to "
"be found there. Sentences of this form are therefore prohibited, "
"though more specific ones like 'a car called Genevieve is in the "
"garage' are fine, as is the reverse, 'In the garage is a car.'");
else
Problems__Issue__assertion_problem(_p_(PM_KOVRelated),
"this seems to give a worldly relationship to something intangible",
"possibly due to an accidental clash of names between a kind of "
"value and something in the real world. "
"I sometimes read sentences like 'There is a number on the "
"door' or 'A text is in the prayer-box' literally - thinking "
"you mean a whole number or a piece of double-quoted text, and "
"not realising you intended to make a brass number-plate or "
"an old book. If that's the trouble, you can use 'called': "
"for instance, 'In the prayer-box is a thing called the text.'");
}
#line 198 "inform7/Chapter 15/Make Assertions.w"
; return;
case 35:
{
#line 1101 "inform7/Chapter 15/Make Assertions.w"
if ((px->down) && (ParseTree__get_type(px->down) == EVERY_NT)) {
if (traverse == 1) Assertions__Assemblies__make_generalisation(px, py);
} else {
Assertions__Creator__convert_instance_to_nounphrase(py, ParseTree__get_relationship(px));
Assertions__Maker__make_assertion_recursive(px, py);
}
}
#line 199 "inform7/Chapter 15/Make Assertions.w"
; return;
case 36:
{
#line 1113 "inform7/Chapter 15/Make Assertions.w"
if (Sentences__NPs__turn_player_to_yourself(px)) {
Assertions__Maker__make_assertion_recursive(px, py); return;
}
Assertions__Maker__instantiate_related_common_nouns(py);
if (traverse == 2) Assertions__Relational__assert_subtree_in_relationship(px, py);
}
#line 200 "inform7/Chapter 15/Make Assertions.w"
; return;
case 37:
{
#line 1122 "inform7/Chapter 15/Make Assertions.w"
if (Sentences__NPs__turn_player_to_yourself(py)) { Assertions__Maker__make_assertion_recursive(px, py); return; }
Assertions__Maker__instantiate_related_common_nouns(px);
if (traverse == 2) Assertions__Relational__assert_subtree_in_relationship(py, px);
}
#line 201 "inform7/Chapter 15/Make Assertions.w"
; return;
case 38:
{
#line 1140 "inform7/Chapter 15/Make Assertions.w"
{
#line 1170 "inform7/Chapter 15/Make Assertions.w"
if ((Specifications__is_new_variable_like(ParseTree__get_evaluation(px))) &&
(Specifications__is_new_variable_like(ParseTree__get_evaluation(py)))) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(px));
Problems__quote_wording(3, ParseTree__get_text(py));
Problems__Issue__handmade_problem(_p_(PM_VariablesEquated));
Problems__issue_problem_segment(
"The sentence %1 seems to tell me that '%2', which describes "
"a kind of variable, is the same as '%3', another description "
"of a kind of variable - but that doesn't make sense to me. "
"(Perhaps you intended one of these to be a specific variable, "
"but chose a wording which looked accidentally like a "
"general description?)");
Problems__issue_problem_end();
return;
}
}
#line 1140 "inform7/Chapter 15/Make Assertions.w"
;
{
#line 1190 "inform7/Chapter 15/Make Assertions.w"
if (Specifications__is_new_variable_like(ParseTree__get_evaluation(py))) {
Problems__Issue__assertion_problem(_p_(PM_VarKOVClash),
"the name supplied for this new variable is a piece of text "
"which is not available because it has a rival meaning already",
"as a result of definitions made elsewhere. (Sometimes these "
"are indirect: for instance, defining a column in a table "
"called 'question' can make a name like 'container in question' "
"suddenly ambiguous and thus unsuitable to be a variable "
"name.) If you're getting this Problem message in the Standard "
"Rules or some other extension you need to use, then your "
"only option is to hunt through your own source text to see "
"what you have defined which might cause this clash.");
return;
}
}
#line 1141 "inform7/Chapter 15/Make Assertions.w"
;
inference_subject *left_object = ParseTree__get_subject(px);
inference_subject *right_kind = ParseTree__get_subject(py);
Problems__quote_source(1, current_sentence);
Problems__quote_subject(2, left_object);
Problems__quote_subject(3, right_kind);
if (left_object == right_kind) {
Problems__Issue__handmade_problem(_p_(PM_SameKindEquated));
Problems__issue_problem_segment(
"The sentence %1 seems to be telling me that two descriptions, "
"both forms of %2, are the same. That's a little puzzling - "
"like saying that 'An open container is a container.' %P"
NAME_DESCRIPTION_CLASH_NOTE);
Problems__issue_problem_end();
} else {
Problems__Issue__handmade_problem(_p_(PM_DescriptionsEquated));
Problems__issue_problem_segment(
"The sentence %1 seems to be telling me that two descriptions, "
"one a form of %2 and the other of %3, are the same. That's a "
"little puzzling - like saying that 'An open door is a container.' %P"
NAME_DESCRIPTION_CLASH_NOTE);
Problems__issue_problem_end();
}
}
#line 202 "inform7/Chapter 15/Make Assertions.w"
; return;
case 39:
{
#line 1223 "inform7/Chapter 15/Make Assertions.w"
if ((InferenceSubjects__is_an_object(ParseTree__get_subject(px))) ||
(InferenceSubjects__is_a_kind_of_object(ParseTree__get_subject(px)))) {
if ((ParseTree__get_subject(py) != Kinds__Behaviour__as_subject(K_object)) &&
(InferenceSubjects__is_a_kind_of_object(ParseTree__get_subject(py)) == FALSE))
Assertions__Maker__issue_value_equation_problem(px, py);
else
{
#line 1361 "inform7/Chapter 15/Make Assertions.w"
inference_subject *left_object = ParseTree__get_subject(px);
pcalc_prop *prop = ParseTree__get_creation_proposition(py);
if (prop) {
if ((Calculus__Variables__number_free(prop) == 0) && (left_object)) {
LOG("Proposition is: $D\n", prop);
Problems__Issue__subject_problem_at_sentence(_p_(PM_SubjectNotFree),
left_object,
"seems to be set equal to something in a complicated relationship "
"with something else again",
"which is too much for me. Perhaps you're trying to do two things "
"at once, and it would be clearer to write it as two sentences?");
return;
}
Calculus__Propositions__Assert__assert_true_about(prop, left_object, prevailing_mood);
} else {
kind *K = Specifications__to_kind(ParseTree__get_evaluation(py));
if (K) {
pcalc_prop *prop = Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0));
Calculus__Propositions__Assert__assert_true_about(prop, left_object, prevailing_mood);
}
}
}
#line 1228 "inform7/Chapter 15/Make Assertions.w"
;
return;
}
parse_node *g_spec = ParseTree__get_evaluation(py);
parse_node *a_spec = ParseTree__get_evaluation(px);
kind *g_kind = Specifications__to_kind(g_spec);
if (Specifications__is_new_variable_like(g_spec))
g_kind = Specifications__kind_of_new_variable_like(g_spec);
kind *a_kind = Specifications__to_kind(a_spec);
int var_set = FALSE;
if ((Rvalues__to_instance(a_spec)) ||
(Lvalues__get_storage_form(a_spec) == NONLOCAL_VARIABLE_VNT)) {
var_set = TRUE;
if (Specifications__is_new_variable_like(g_spec))
{
#line 1273 "inform7/Chapter 15/Make Assertions.w"
nonlocal_variable *nlv =
ParseTree__get_constant_nonlocal_variable(ParseTree__get_evaluation(px));
parse_node *val = ParseTree__get_evaluation(py);
kind *kind_as_declared = NonlocalVariables__kind(nlv);
kind *constant_kind = Specifications__to_kind(val);
if (Specifications__is_new_variable_like(val))
constant_kind = Specifications__kind_of_new_variable_like(val);
if (Kinds__Compare__le(constant_kind, kind_as_declared) == FALSE) {
LOG("$u, $u\n", kind_as_declared, constant_kind);
Problems__quote_source(1, current_sentence);
if (nlv)
Problems__quote_wording(2, nlv->name);
else
Problems__quote_wording(2, ParseTree__get_text(px));
Problems__quote_kind(3, constant_kind);
if (nlv)
Problems__quote_kind(4, kind_as_declared);
else
Problems__quote_kind(4, Specifications__to_kind(ParseTree__get_evaluation(px)));
Problems__Issue__handmade_problem(_p_(PM_GlobalRedeclared));
Problems__issue_problem_segment(
"The sentence %1 seems to tell me that '%2', which has already been "
"declared as %4, is instead %3 - but that would be a contradiction.");
Problems__issue_problem_end();
} else {
if (Kinds__Compare__eq(kind_as_declared, constant_kind) == FALSE)
NonlocalVariables__set_kind(nlv, constant_kind);
}
return;
}
#line 1242 "inform7/Chapter 15/Make Assertions.w"
;
}
if (((Specifications__is_kind_like(g_spec)) ||
(Specifications__is_new_variable_like(g_spec)) ||
(Specifications__is_description(g_spec)))
&& (a_kind)) {
if (Kinds__Compare__eq(a_kind, g_kind))
{
#line 1309 "inform7/Chapter 15/Make Assertions.w"
if ((var_set == FALSE) && (Kinds__Compare__eq(a_kind, K_number))) {
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_Sarcasm1));
Problems__issue_problem_segment(
"%1: Grateful as I generally am for your guidance, "
"I think perhaps I could manage without this sentence.");
Problems__issue_problem_end();
}
if ((var_set == FALSE) && (Kinds__Compare__eq(a_kind, K_text))) {
TEMPORARY_STREAM;
Strings__TextLiterals__compile_literal(TEMP, ParseTree__get_text(px));
CLOSE_TEMPORARY_STREAM;
}
return;
}
#line 1250 "inform7/Chapter 15/Make Assertions.w"
;
if (Kinds__get_construct(a_kind) == CON_description)
{
#line 1347 "inform7/Chapter 15/Make Assertions.w"
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_DescAsLiteral));
Problems__issue_problem_segment("%1: this seems to be using a description "
"as if it were a constant value, which isn't allowed. (Descriptions "
"can only be used as values to a limited extent.)");
Problems__issue_problem_end();
return;
}
#line 1252 "inform7/Chapter 15/Make Assertions.w"
;
}
if (var_set == FALSE)
{
#line 1327 "inform7/Chapter 15/Make Assertions.w"
if (Kinds__Compare__eq(a_kind, K_number)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(px));
Problems__Issue__handmade_problem(_p_(PM_Sarcasm2));
Problems__issue_problem_segment("%1: That, sir, is a damnable lie. '%2' is a number.");
Problems__issue_problem_end();
return;
}
if (Kinds__Compare__eq(a_kind, K_text)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(px));
Problems__Issue__handmade_problem(_p_(PM_Sarcasm3));
Problems__issue_problem_segment("%1: And I am the King of Siam. '%2' is some text.");
Problems__issue_problem_end();
return;
}
}
#line 1254 "inform7/Chapter 15/Make Assertions.w"
;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(px));
Problems__quote_kind_of(3, a_spec);
Problems__Issue__handmade_problem(_p_(PM_ChangedKind));
Problems__issue_problem_segment(
"Before reading %1, I already knew that '%2' is %3, "
"and it is too late to change now.");
Problems__issue_problem_end();
}
#line 203 "inform7/Chapter 15/Make Assertions.w"
; return;
case 40:
{
#line 1386 "inform7/Chapter 15/Make Assertions.w"
parse_node *spec = ParseTree__get_evaluation(py);
{
#line 1401 "inform7/Chapter 15/Make Assertions.w"
if (Rvalues__to_instance(spec)) {
kind *c_kind = Instances__to_kind(Rvalues__to_instance(spec));
kind *v_kind = Specifications__to_kind(ParseTree__get_evaluation(px));
if ((v_kind == NULL) || (Kinds__Compare__eq(c_kind, v_kind))) return;
}
}
#line 1387 "inform7/Chapter 15/Make Assertions.w"
;
if (Kinds__Compare__le(Specifications__to_kind(ParseTree__get_evaluation(py)), K_object))
Assertions__Maker__issue_value_equation_problem(py, px);
else Problems__Issue__assertion_problem(_p_(PM_CommonIsProper),
"this seems to say that a general description is something else",
"like saying that 'a door is 20'.");
}
#line 204 "inform7/Chapter 15/Make Assertions.w"
; return;
case 41:
{
#line 1421 "inform7/Chapter 15/Make Assertions.w"
{
#line 1609 "inform7/Chapter 15/Make Assertions.w"
if (Rvalues__is_CONSTANT_construction(ParseTree__get_evaluation(px), CON_property)) {
inference_subject *talking_about = Assertions__Traverse__get_current_subject();
if (talking_about == NULL)
Problems__Issue__assertion_problem(_p_(PM_NothingDiscussed),
"nothing is under discussion which might have this property",
"so this is like starting with 'The description is \"Orange.\"': "
"I can't tell what of.");
else if (traverse == 2) {
if (Preform__parse_nt_against_word_range(negated_clause_NTM, ParseTree__get_text(py), NULL, NULL))
Problems__Issue__negative_sentence_problem(_p_(PM_NonValue2));
else Assertions__PropertyKnowledge__assert_property_value_from_property_subtree_infs(
Rvalues__to_property(ParseTree__get_evaluation(px)), talking_about, py);
}
return;
}
}
#line 1421 "inform7/Chapter 15/Make Assertions.w"
;
{
#line 1636 "inform7/Chapter 15/Make Assertions.w"
parse_node *constant = ParseTree__get_evaluation(px);
if ((Rvalues__to_instance(constant)) ||
(Specifications__is_kind_like(constant))) {
instance *q = Rvalues__to_instance(ParseTree__get_evaluation(py));
property *pname = Kinds__Behaviour__get_coinciding_property(Instances__to_kind(q));
if (pname) {
if (traverse == 2)
Assertions__PropertyKnowledge__assert_property_value_from_property_subtree_infs(pname, Instances__as_subject(q), py);
return;
}
}
}
#line 1422 "inform7/Chapter 15/Make Assertions.w"
;
{
#line 1651 "inform7/Chapter 15/Make Assertions.w"
parse_node *constant = ParseTree__get_evaluation(px);
parse_node *val = ParseTree__get_evaluation(py);
if ((Rvalues__is_CONSTANT_of_kind(constant, K_response)) &&
(Rvalues__is_CONSTANT_of_kind(val, K_text))) {
rule *R = Rvalues__to_rule(constant);
int c = ParseTree__int_annotation(constant, response_code_ANNOT);
Strings__assert_response_value(R, c, ParseTree__get_text(val));
return;
}
}
#line 1423 "inform7/Chapter 15/Make Assertions.w"
;
{
#line 1589 "inform7/Chapter 15/Make Assertions.w"
if (Lvalues__get_storage_form(ParseTree__get_evaluation(px)) == NONLOCAL_VARIABLE_VNT) {
nonlocal_variable *nlv = ParseTree__get_constant_nonlocal_variable(ParseTree__get_evaluation(px));
if (nlv) {
parse_node *val = ParseTree__get_evaluation(py);
if (val) ParseTree__set_text(val, ParseTree__get_text(py));
val = NonlocalVariables__substitute_constants(val);
if (traverse == 2) {
Assertions__PropertyKnowledge__initialise_global_variable(nlv, val);
} else {
if (ParseTree__is(val, CONSTANT_VNT))
if (Plugins__Call__variable_set_warning(nlv, val))
Assertions__PropertyKnowledge__initialise_global_variable(nlv, val);
}
return;
}
}
}
#line 1424 "inform7/Chapter 15/Make Assertions.w"
;
{
#line 1671 "inform7/Chapter 15/Make Assertions.w"
if (Rvalues__is_CONSTANT_construction(ParseTree__get_evaluation(py), CON_property)) {
property *prn = Rvalues__to_property(ParseTree__get_evaluation(py));
if ((Properties__is_either_or(prn) == FALSE) &&
(Properties__Valued__coincides_with_kind(prn))) {
kind *K = Properties__Valued__kind(prn);
ParseTree__set_type_and_clear_annotations(py, COMMON_NOUN_NT);
ParseTree__set_evaluation(py, Specifications__from_kind(K));
Assertions__Maker__make_assertion_recursive(px, py);
return;
}
}
}
#line 1425 "inform7/Chapter 15/Make Assertions.w"
;
kind *K = Specifications__to_kind(ParseTree__get_evaluation(py));
property *pname = Kinds__Behaviour__get_coinciding_property(K);
if (pname) {
if (traverse == 2)
Assertions__PropertyKnowledge__assert_property_value_from_property_subtree_infs(pname, ParseTree__get_subject(px), py);
return;
}
if ((PL__Map__is_a_direction(ParseTree__get_subject(px))) ||
(PL__Map__is_a_direction(ParseTree__get_subject(py))))
{
#line 1461 "inform7/Chapter 15/Make Assertions.w"
if (Assertions__Traverse__get_current_subject() == NULL) {
Problems__Issue__assertion_problem(_p_(PM_NoMapOrigin),
"no location is under discussion to be the origin of this map connection",
"so this is like starting with 'North is the Aviary': I can't tell where from.");
return;
}
inference_subject *target = ParseTree__get_subject(py), *way = ParseTree__get_subject(px);
if (PL__Map__is_a_direction(target)) {
target = ParseTree__get_subject(px); way = ParseTree__get_subject(py);
}
if (traverse == 2) {
if (target == NULL) {
Problems__Issue__assertion_problem(_p_(PM_MapNonObject),
"this seems to make a map connection to something which is "
"not an object",
"like saying '20 is north'. This is an odd thing "
"to say, and makes me think that I've misunderstood you.");
} else {
PL__Map__connect(Assertions__Traverse__get_current_subject(), target, way);
}
}
}
#line 1437 "inform7/Chapter 15/Make Assertions.w"
else if (Rvalues__is_object(ParseTree__get_evaluation(py)))
{
#line 1486 "inform7/Chapter 15/Make Assertions.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(px));
Problems__quote_wording(3, ParseTree__get_text(py));
if (ParseTree__get_subject(px) == ParseTree__get_subject(py))
Problems__Issue__assertion_problem(_p_(PM_ProperIsItself),
"this seems to say that something is itself",
"like saying 'the coin is the coin'. This is an odd thing "
"to say, and makes me think that I've misunderstood you.");
else if (Preform__parse_nt_against_word_range(control_structure_phrase_NTM, ParseTree__get_text(px), NULL, NULL)) {
Problems__Issue__handmade_problem(_p_(PM_IfInAssertion));
Problems__issue_problem_segment(
"I am reading the sentence %1 as a declaration of the initial "
"state of the world, so I'm expecting that it will be definite. "
"The only way I can construe it that way is by thinking that "
"'%2' and '%3' are two different things, but that doesn't make "
"sense, and the 'if' makes me think that perhaps you did not "
"mean this as a definite statement after all. Although 'if...' "
"is often used in rules and definitions of what to do in given "
"circumstances, it shouldn't be used in a direct assertion.");
Problems__issue_problem_end();
} else if (Rvalues__is_object(
ParseTree__get_evaluation(px)))
{
#line 1529 "inform7/Chapter 15/Make Assertions.w"
{
#line 1548 "inform7/Chapter 15/Make Assertions.w"
char *P, *Q, *In;
int variant = 0;
if (rng_seed_at_start_of_play == 0) variant = (time(0))&15;
switch(variant) {
case 1: P = "the chalk"; Q = "the cheese"; In = "Dairy Products School"; break;
case 2: P = "St Peter"; Q = "St Paul"; In = "Pearly Gates"; break;
case 3: P = "Tom"; Q = "Jerry"; In = "Mouse-Hole"; break;
case 4: P = "Clark Kent"; Q = "Lex Luthor"; In = "Metropolis"; break;
case 5: P = "Ron"; Q = "Hermione"; In = "Hogsmeade"; break;
case 6: P = "Tarzan"; Q = "Jane"; In = "Treehouse"; break;
case 7: P = "Adam"; Q = "Eve"; In = "Land of Nod"; break;
case 8: P = "Laurel"; Q = "Hardy"; In = "Blue-Ridge Mountains"; break;
case 9: P = "Aeschylus"; Q = "Euripides"; In = "Underworld"; break;
case 10: P = "Choucas"; Q = "Hibou"; In = "The Hall"; break;
case 11: P = "John"; Q = "Paul"; In = "Abbey Road"; break;
case 12: P = "Poirot"; Q = "Hastings"; In = "St Mary Mead"; break;
case 13: P = "House"; Q = "Wilson"; In = "Princeton Plainsboro"; break;
case 14: P = "Adams"; Q = "Jefferson"; In = "Virginia"; break;
case 15: P = "Antony"; Q = "Cleopatra"; In = "Alexandria"; break;
case 16: P = "Emmet"; Q = "Wildstyle"; In = "Bricksburg"; break;
case 17: P = "Stanley"; Q = "Livingstone"; In = "Africa"; break;
case 18: P = "Jeeves"; Q = "Wooster"; In = "Totleigh Towers"; break;
case 19: P = "John"; Q = "Timus"; In = "The Lab"; break;
default: P = "the hawk"; Q = "the handsaw"; In = "Elsinore"; break;
}
Problems__quote_text(4, P); Problems__quote_text(5, Q); Problems__quote_text(6, In);
}
#line 1529 "inform7/Chapter 15/Make Assertions.w"
;
Problems__Issue__handmade_problem(_p_(PM_ChalkCheese));
Problems__issue_problem_segment(
"The sentence %1 appears to say two things are the same - I am reading '%2' "
"and '%3' as two different things, and therefore it makes no sense to say "
"that one is the other: it would be like saying that '%4 is %5'. It would "
"be all right if the second thing were the name of a kind, perhaps with "
"properties: for instance '%6 is a lighted room' says that something "
"called %6 exists and that it is a 'room', which is a kind I know about, "
"combined with a property called 'lighted' which I also know about.");
Problems__Issue__diagnose_further();
Problems__issue_problem_end();
}
#line 1509 "inform7/Chapter 15/Make Assertions.w"
else
{
#line 1515 "inform7/Chapter 15/Make Assertions.w"
Problems__quote_kind_of(4, ParseTree__get_evaluation(px));
Problems__quote_kind_of(5, ParseTree__get_evaluation(py));
Problems__Issue__handmade_problem(_p_(PM_ObjectAndValueEquated));
Problems__issue_problem_segment(
"The sentence %1 seems to say that '%2', which I think is %4, and "
"'%3', which I think is %5, are the same. %P"
"That can't be right, so I must have misunderstood. Perhaps you "
"intended to make something new, but it accidentally had the same "
"name as something already existing?");
Problems__issue_problem_end();
}
#line 1510 "inform7/Chapter 15/Make Assertions.w"
;
}
#line 1439 "inform7/Chapter 15/Make Assertions.w"
else if (Rvalues__is_CONSTANT_construction(ParseTree__get_evaluation(py), CON_property))
Problems__Issue__assertion_problem(_p_(PM_ObjectIsProperty),
"that seems to say that some object is a property",
"like saying 'The brick building is the description': if you want to specify "
"the description of the current object, try putting the sentence the other way "
"around ('The description is...').");
else if (ParseTree__get_subject(px)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(px));
Problems__Issue__handmade_problem(_p_(PM_ObjectIsValue));
Problems__issue_problem_segment(
"I am reading the sentence %1 as saying that a thing called "
"'%2' is a value, but this makes no sense to me - it would be "
"like saying 'the chair is 10'.");
Problems__issue_problem_end();
}
else
{
#line 1686 "inform7/Chapter 15/Make Assertions.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(px));
Problems__quote_wording(3, ParseTree__get_text(py));
Problems__quote_kind_of(4, ParseTree__get_evaluation(px));
Problems__quote_kind_of(5, ParseTree__get_evaluation(py));
if (Kinds__Compare__eq(Specifications__to_kind(ParseTree__get_evaluation(px)),
Specifications__to_kind(ParseTree__get_evaluation(py)))) {
Problems__Issue__handmade_problem(_p_(PM_SimilarValuesEquated));
Problems__issue_problem_segment(
"Before reading %1, I already knew that '%2' is %4 and "
"'%3' likewise: so they are specific values, and saying "
"that they are equal will not make it so.");
Problems__issue_problem_end();
} else {
Problems__Issue__handmade_problem(_p_(PM_DissimilarValuesEquated));
Problems__issue_problem_segment(
"Before reading %1, I already knew that '%2' is %4 and "
"'%3' is %5: so they are specific values, and saying "
"that they are equal will not make it so.");
Problems__issue_problem_end();
}
}
#line 1456 "inform7/Chapter 15/Make Assertions.w"
;
}
#line 205 "inform7/Chapter 15/Make Assertions.w"
; return;
case 42:
{
#line 1742 "inform7/Chapter 15/Make Assertions.w"
if ((Assertions__Maker__convert_adjective_to_noun(px)) || (Assertions__Maker__convert_adjective_to_noun(py->down))) {
Assertions__Maker__make_assertion_recursive(px, py);
return;
}
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"that seems to relate an adjective to something",
"which must be wrong. (This can sometimes happen if the same word can "
"be used both as an adjective and a noun, and I misunderstand.)");
}
#line 206 "inform7/Chapter 15/Make Assertions.w"
; return;
default: LOG("Unimplemented assertion case %d\n", ma_case);
internal_error("No implementation for make assertion case");
}
}
#line 109 "inform7/Chapter 15/Make Assertions.w"
;
}
#line 1719 "inform7/Chapter 15/Make Assertions.w"
int something_loose_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 1725 "inform7/Chapter 15/Make Assertions.w"
Problems__Issue__sentence_problem(_p_(PM_EquatesSomethingToValue),
"that seems to say that an object is the same as a value",
"which must be wrong. This can happen if the word 'something' is "
"used loosely - I read it as 'some thing', so I think it has to "
"refer to a thing, which is a kind of object. A sentence like "
"'Something called mauve is a colour' trips me up because mauve "
"is a value, so it isn't an object, and doesn't match 'something'.");
}
#line 1720 "inform7/Chapter 15/Make Assertions.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1721 "inform7/Chapter 15/Make Assertions.w"
#line 1755 "inform7/Chapter 15/Make Assertions.w"
int Assertions__Maker__convert_adjective_to_noun(parse_node *p) {
if ((ParseTree__get_type(p) == ADJECTIVE_NT) &&
(ParseTree__int_annotation(p, negated_boolean_ANNOT) == FALSE)) {
if (Preform__parse_nt_against_word_range(s_value_NTM, ParseTree__get_text(p), NULL, NULL))
Assertions__Refiner__noun_from_value(p, most_recent_result_p);
if (ParseTree__get_type(p) != ADJECTIVE_NT) return TRUE;
}
return FALSE;
}
#line 1768 "inform7/Chapter 15/Make Assertions.w"
void Assertions__Maker__issue_value_equation_problem(parse_node *px, parse_node *py) {
if ((current_sentence) &&
(Preform__parse_nt_against_word_range(something_loose_diagnosis_NTM, ParseTree__get_text(current_sentence), NULL, NULL)))
return;
if ((ParseTree__get_type(px) != PROPER_NOUN_NT) ||
((ParseTree__get_type(py) != PROPER_NOUN_NT) && (ParseTree__get_type(py) != COMMON_NOUN_NT))) {
ParseTree__log_subtree(px); ParseTree__log_subtree(py);
internal_error("Assert PX of type PY on bad node types");
}
ParseTree__log_subtree(px); ParseTree__log_subtree(py);
if ((ParseTree__get_subject(px)) &&
(InferenceSubjects__where_created(ParseTree__get_subject(px)) != current_sentence)) {
Problems__quote_wording(1, ParseTree__get_text(px));
Problems__quote_source(2, current_sentence);
Problems__quote_source(3, InferenceSubjects__where_created(ParseTree__get_subject(px)));
Problems__Issue__handmade_problem(_p_(PM_CantUncreate));
Problems__issue_problem_segment(
"In order to act on %2, I seem to need to give "
"a new meaning to '%1', something which was created by the earlier "
"sentence %3. That must be wrong somehow: I'm guessing that there "
"is an accidental clash of names. This sometimes happens when "
"adjectives are being made after objects whose names include them: "
"for instance, defining 'big' as an adjective after having already "
"made a 'big top'. The simplest way to avoid this is to define "
"the adjectives in question first.");
Problems__issue_problem_end();
return;
}
if ((ParseTree__get_type(px) == PROPER_NOUN_NT) && (ParseTree__get_type(py) == COMMON_NOUN_NT)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(py));
if (Wordings__nonempty(ParseTree__get_text(px))) Problems__quote_wording(3, ParseTree__get_text(px));
else Problems__quote_text(3, "(something not given an explicit name)");
Problems__Issue__handmade_problem(_p_(PM_IdentityUnclear));
Problems__issue_problem_segment(
"The sentence %1 seems to tell me that '%2' and '%3' have to be "
"the same, but it looks odd to me. '%2' is something generic - "
"not something definite; but '%3' is (presumably) something "
"specific. So it's as if you'd written 'A room is the Sydney "
"Opera House'. (Which room, exactly? You see the trouble.)");
Problems__issue_problem_end();
return;
}
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"that seems to say that an object is the same as a value",
"which must be wrong.");
}
#line 1823 "inform7/Chapter 15/Make Assertions.w"
void Assertions__Maker__instantiate_related_common_nouns(parse_node *p) {
Assertions__Maker__instantiate_related_common_nouns_r(p, p->down);
}
void Assertions__Maker__instantiate_related_common_nouns_r(parse_node *from, parse_node *at) {
if (at == NULL) return;
if (ParseTree__get_type(at) == COMMON_NOUN_NT)
Assertions__Creator__convert_instance_to_nounphrase(at,
ParseTree__get_relationship(from));
if (ParseTree__get_type(at) == AND_NT) {
Assertions__Maker__instantiate_related_common_nouns_r(from, at->down);
Assertions__Maker__instantiate_related_common_nouns_r(from, at->down->next);
}
if (ParseTree__get_type(at) == WITH_NT) {
Assertions__Maker__instantiate_related_common_nouns_r(from, at->down);
Assertions__PropertyKnowledge__assert_property_list(at->down, at->down->next);
}
}
#line 1845 "inform7/Chapter 15/Make Assertions.w"
int Assertions__Maker__is_adjlist(parse_node *p) {
if (p == NULL) return FALSE;
switch (ParseTree__get_type(p)) {
case ADJECTIVE_NT: return TRUE;
case AND_NT: return ((Assertions__Maker__is_adjlist(p->down)) && (Assertions__Maker__is_adjlist(p->down->next)));
default: return FALSE;
}
}
#line 13 "inform7/Chapter 15/Property Knowledge.w"
void Assertions__PropertyKnowledge__initialise_global_variable(nonlocal_variable *q, parse_node *val) {
Assertions__PropertyKnowledge__igv_dash(q, val, FALSE);
}
void Assertions__PropertyKnowledge__verify_global_variable(nonlocal_variable *q) {
parse_node *init = NonlocalVariables__get_initial_value(q);
if (init) Assertions__PropertyKnowledge__igv_dash(q, init, TRUE);
}
#line 25 "inform7/Chapter 15/Property Knowledge.w"
void Assertions__PropertyKnowledge__igv_dash(nonlocal_variable *q, parse_node *val, int verification_stage) {
if (q == NULL) internal_error("tried to initialise null variable");
kind *kind_as_declared = NonlocalVariables__kind(q);
kind *constant_kind = Specifications__to_kind(val);
int outcome = Kinds__Compare__compatible(constant_kind, kind_as_declared);
int throw_problem = FALSE;
if (outcome == NEVER_MATCH) throw_problem = TRUE;
if ((verification_stage) && (outcome == SOMETIMES_MATCH)) throw_problem = TRUE;
if (throw_problem)
{
#line 65 "inform7/Chapter 15/Property Knowledge.w"
LOG("Variable: $u; constant: $u\n", kind_as_declared, constant_kind);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, q->name);
Problems__quote_wording(3, ParseTree__get_text(val));
Problems__quote_kind(4, kind_as_declared);
Problems__quote_kind(5, constant_kind);
if ((Kinds__Compare__lt(kind_as_declared, K_object)) &&
(Rvalues__is_nothing_object_constant(val))) {
Problems__Issue__handmade_problem(_p_(PM_QuantityKindNothing));
Problems__issue_problem_segment(
"The sentence %1 tells me that '%2', which should be %4 that varies, is to "
"have the initial value 'nothing'. This is allowed as an 'object which varies', "
"but the rules are stricter for %4.");
Problems__issue_problem_end();
} else {
Problems__Issue__handmade_problem(_p_(PM_GlobalKindWrong));
Problems__issue_problem_segment(
"The sentence %1 tells me that '%2', which is %4 that varies, "
"should start out with the value '%3', but this is %5 and not %4.");
if ((Kinds__Compare__le(constant_kind, K_object)) &&
(!Kinds__Compare__le(kind_as_declared, K_object)))
Problems__issue_problem_segment(
" %PIn sentences like this, when I can't understand some text, "
"I often assume that it's meant to be a new object. So it may "
"be that you intended '%3' to be something quite different, "
"but I just didn't get it.");
Problems__Issue__diagnose_further();
Problems__issue_problem_end();
}
return;
}
#line 36 "inform7/Chapter 15/Property Knowledge.w"
;
if (verification_stage) return;
parse_node *var = Lvalues__new_actual_NONLOCAL_VARIABLE(q);
pcalc_prop *prop = Calculus__Propositions__Abstract__to_set_relation(R_equality, NULL, var, NULL, val);
Calculus__Propositions__Assert__assert_true(prop, prevailing_mood);
}
#line 105 "inform7/Chapter 15/Property Knowledge.w"
void Assertions__PropertyKnowledge__assert_property_value_from_property_subtree_infs(property *prn,
inference_subject *owner, parse_node *val_subtree) {
pcalc_prop *prop = Calculus__Propositions__Abstract__from_property_subtree(prn, val_subtree);
if (owner == NULL)
{
#line 173 "inform7/Chapter 15/Property Knowledge.w"
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_PropForBadKOV));
Problems__issue_problem_segment(
"The sentence %1 looked to me as if it might be trying to assign certain properties "
"to something which is not allowed to have them.");
Problems__issue_problem_end();
return;
}
#line 108 "inform7/Chapter 15/Property Knowledge.w"
;
Calculus__Propositions__Assert__assert_true_about(prop, owner, prevailing_mood);
}
void Assertions__PropertyKnowledge__assert_property_list(parse_node *owner_subtree, parse_node *list_subtree) {
{
#line 152 "inform7/Chapter 15/Property Knowledge.w"
parse_node *owner_spec = ParseTree__get_evaluation(owner_subtree);
if (Specifications__is_description(owner_spec)) {
if ((Calculus__Propositions__contains_binary_predicate(Specifications__to_proposition(owner_spec))) ||
(Descriptions__number_of_adjectives_applied_to(owner_spec) > 0) ||
(Calculus__Propositions__contains_adjective(Specifications__to_proposition(owner_spec)))) {
Problems__quote_source(1, current_sentence);
Problems__quote_spec(2, owner_spec);
Problems__Issue__handmade_problem(_p_(PM_RelationAPL));
Problems__issue_problem_segment(
"The sentence %1 looked to me as if it might be trying to assign certain "
"properties to something described in a way (%2) which involved a clause "
"which can't be properly determined until the game is running, so that at "
"this point it's impossible to act upon.");
Problems__issue_problem_end();
return;
}
}
}
#line 113 "inform7/Chapter 15/Property Knowledge.w"
;
inference_subject *owner = ParseTree__get_subject(owner_subtree);
if (owner == NULL) {
parse_node *owner_spec = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, ParseTree__get_text(owner_subtree), NULL, NULL))
owner_spec = most_recent_result_p;
if ((Specifications__is_description(owner_spec)) &&
(Descriptions__is_qualified(owner_spec) == FALSE)) {
kind *K = Specifications__to_kind(owner_spec);
if (K) owner = Kinds__Behaviour__as_subject(K);
}
}
if (owner == NULL)
{
#line 173 "inform7/Chapter 15/Property Knowledge.w"
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_PropForBadKOV));
Problems__issue_problem_segment(
"The sentence %1 looked to me as if it might be trying to assign certain properties "
"to something which is not allowed to have them.");
Problems__issue_problem_end();
return;
}
#line 125 "inform7/Chapter 15/Property Knowledge.w"
;
kind *kind_clue = NULL;
{
#line 141 "inform7/Chapter 15/Property Knowledge.w"
if (owner) {
kind_clue = InferenceSubjects__domain(owner);
if (kind_clue == NULL) kind_clue = InferenceSubjects__domain(InferenceSubjects__narrowest_broader_subject(owner));
if ((InferenceSubjects__is_an_object(owner)) ||
(InferenceSubjects__is_a_kind_of_object(owner)))
kind_clue = K_object;
}
}
#line 127 "inform7/Chapter 15/Property Knowledge.w"
;
pcalc_prop *prop = Calculus__Propositions__Abstract__from_property_list(list_subtree, kind_clue);
Calculus__Propositions__Assert__assert_true_about(prop, owner, prevailing_mood);
}
#line 191 "inform7/Chapter 15/Property Knowledge.w"
parse_node *Assertions__PropertyKnowledge__property_value_from_property_subtree(property *prn, parse_node *py) {
if (Properties__is_either_or(prn)) {
if (py == NULL)
{
#line 211 "inform7/Chapter 15/Property Knowledge.w"
Problems__quote_source(1, current_sentence);
Problems__quote_property(3, prn);
Problems__Issue__handmade_problem(_p_(PM_HasBareAdjective));
Problems__issue_problem_segment(
"In %1 you write about the %3 property as if it were some kind of value "
"or possession, but %3 is an either/or property - something is either "
"%3 or not. (For example, it's incorrect to say 'The glass box has "
"transparent'; the right way is just 'The glass box is transparent.')");
Problems__issue_problem_end();
return NULL;
}
#line 193 "inform7/Chapter 15/Property Knowledge.w"
;
{
#line 225 "inform7/Chapter 15/Property Knowledge.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(py));
Problems__quote_property(3, prn);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"In %1 you give a value of the %3 property as '%2', but %3 is an either/or "
"property - something is either %3 or not, so there is no value involved.");
Problems__issue_problem_end();
return NULL;
}
#line 194 "inform7/Chapter 15/Property Knowledge.w"
;
}
{
#line 238 "inform7/Chapter 15/Property Knowledge.w"
Assertions__Refiner__coerce_adjectival_usage_to_noun(py);
switch(ParseTree__get_type(py)) {
case PROPER_NOUN_NT:
if ((ParseTree__get_evaluation(py) == NULL) ||
(ParseTree__is(ParseTree__get_evaluation(py), UNKNOWN_VNT))) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(py));
Problems__quote_property(3, prn);
Problems__Issue__handmade_problem(_p_(PM_PropertyValueUnknown));
Problems__issue_problem_segment(
"You wrote %1, but that seems to set a property %3 to the "
"value '%2', which I don't recognise as meaning anything.");
Problems__issue_problem_end();
return NULL;
}
break; /* (this is fine -- there's a well-expressed value) */
case COMMON_NOUN_NT:
Problems__Issue__sentence_problem(_p_(PM_PropertyInstance),
"this property value makes no sense to me",
"since it looks as if it contains a relative clause. Sometimes this "
"happens if a clause follows directly on, and I have misunderstood to "
"what it belongs. For instance: 'The widget is a door with matching "
"key a thing in the Ballroom' is read with 'a thing in the Ballroom' as "
"the value of the 'matching key' property, not with 'in the Ballroom' "
"applying to the door.");
return NULL;
case X_OF_Y_NT:
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"something grammatically odd has happened here",
"possibly to do with the unexpected 'of' in what seems to be a list of "
"property values?");
return NULL;
case FROM_NT:
case WITH_NT:
Problems__Issue__sentence_problem(_p_(PM_MisplacedFrom),
"something grammatically odd has happened here",
"possibly to do with the unexpected 'from' or 'with' in what seems "
"to be a list of property values? Maybe there is some punctuation missing.");
return NULL;
default:
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(py));
Problems__quote_property(3, prn);
Problems__Issue__handmade_problem(_p_(PM_PeculiarPropertyValue));
Problems__issue_problem_segment(
"You wrote %1, but that seems to set a property %3 to the "
"value '%2', which really doesn't make sense.");
Problems__issue_problem_end();
return NULL;
}
}
#line 196 "inform7/Chapter 15/Property Knowledge.w"
;
parse_node *val = NonlocalVariables__substitute_constants(
ParseTree__get_evaluation(py));
kind *property_kind = Properties__Valued__kind(prn);
if ((ParseTree__is_value(val)) && (ParseTree__is(val, CONSTANT_VNT) == FALSE))
{
#line 292 "inform7/Chapter 15/Property Knowledge.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(py));
Problems__quote_kind(3, property_kind);
Problems__quote_property(4, prn);
Problems__Issue__handmade_problem(_p_(PM_PropertyNonConstant));
Problems__issue_problem_segment(
"In %1 you give a value of the %4 property as '%2', "
"and while this does make sense as %3, it is a value which "
"exists and changes during play, and which doesn't make sense to "
"use when setting up the initial state of things.");
Problems__issue_problem_end();
return NULL;
}
#line 203 "inform7/Chapter 15/Property Knowledge.w"
;
return val;
}
#line 16 "inform7/Chapter 15/Relation Knowledge.w"
void Assertions__Relational__assert_subtree_in_relationship(parse_node *value, parse_node *relationship_subtree) {
if ((value == NULL) || (relationship_subtree == NULL))
internal_error("assert relation between null subtrees");
if (ParseTree__get_type(relationship_subtree) != RELATIONSHIP_NT)
internal_error("asserted malformed relationship subtree");
if (ParseTree__get_type(value) == AND_NT) {
Assertions__Relational__assert_subtree_in_relationship(value->down, relationship_subtree);
Assertions__Relational__assert_subtree_in_relationship(value->down->next, relationship_subtree);
return;
}
switch(ParseTree__int_annotation(relationship_subtree, relationship_node_type_ANNOT)) {
case STANDARD_RELN:
{
#line 38 "inform7/Chapter 15/Relation Knowledge.w"
binary_predicate *bp = BinaryPredicates__get_reversal(ParseTree__get_relationship(relationship_subtree));
if (bp == NULL) internal_error("asserted bp-less relationship subtree");
Properties__SettingRelations__fix_property_bp(bp);
Assertions__Relational__assert_relation_between_subtrees(value, bp, relationship_subtree->down);
break;
}
#line 28 "inform7/Chapter 15/Relation Knowledge.w"
;
case PARENTAGE_HERE_RELN:
{
#line 47 "inform7/Chapter 15/Relation Knowledge.w"
if (ParseTree__get_subject(value) == NULL) {
Problems__Issue__sentence_problem(_p_(PM_HereFailedOnNothing),
"that is an assertion which puts nothing 'here'",
"which looks as if it might be trying to give me negative rather "
"than positive information. There's no need to tell me something "
"like 'Here is nothing.': just don't put anything there.");
} else {
Calculus__Propositions__Assert__assert_true_about(
Calculus__Propositions__Abstract__to_put_here(),
ParseTree__get_subject(value), prevailing_mood);
}
break;
}
#line 29 "inform7/Chapter 15/Relation Knowledge.w"
;
case DIRECTION_RELN:
{
#line 63 "inform7/Chapter 15/Relation Knowledge.w"
{
#line 100 "inform7/Chapter 15/Relation Knowledge.w"
if ((relationship_subtree->down == NULL) ||
(relationship_subtree->down->next == NULL) ||
(relationship_subtree->down->next->next != NULL))
internal_error("malformed DIRECTION");
if (ParseTree__get_type(relationship_subtree->down) != PROPER_NOUN_NT) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"this is not straightforward in saying which room (or door) leads away from",
"and should just name the source.");
break;
}
if (ParseTree__get_type(relationship_subtree->down->next) != PROPER_NOUN_NT) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"this is not straightforward in saying which direction the room (or door) lies in",
"and should just name the direction.");
break;
}
}
#line 63 "inform7/Chapter 15/Relation Knowledge.w"
;
Assertions__Relational__substitute_at_node(relationship_subtree->down);
Assertions__Relational__substitute_at_node(relationship_subtree->down->next);
inference_subject *iy = ParseTree__get_subject(relationship_subtree->down);
inference_subject *id = ParseTree__get_subject(relationship_subtree->down->next);
if (iy == NULL) {
if (Rvalues__is_nothing_object_constant(
ParseTree__get_evaluation(relationship_subtree->down)))
Problems__Issue__sentence_problem(_p_(PM_MapFromNowhere),
"the source of a map connection can't be nowhere",
"so sentences like 'The pink door is south of nowhere.' are not "
"allowed.");
else
Problems__Issue__sentence_problem(_p_(PM_MapFromNonroom2),
"the source of a map connection has to be a room or door",
"so sentences like 'The pink door is south of 0.' are not "
"allowed.");
break;
}
if ((iy == NULL) || (id == NULL))
internal_error("malformed directional subtree");
if (Rvalues__is_nothing_object_constant(value))
PL__Map__connect(iy, NULL, id);
else if (Rvalues__is_object(ParseTree__get_evaluation(value)))
PL__Map__connect(iy, ParseTree__get_subject(value), id);
else {
LOG("Val is $P\n", value);
Problems__Issue__sentence_problem(_p_(PM_MapToNonobject),
"the destination of a map connection has to be either a room, "
"a door or 'nowhere'",
"but here the destination doesn't even seem to be an object.");
}
break;
}
#line 30 "inform7/Chapter 15/Relation Knowledge.w"
;
default: internal_error("unknown RELATIONSHIP node type");
}
}
#line 120 "inform7/Chapter 15/Relation Knowledge.w"
void Assertions__Relational__substitute_at_node(parse_node *p) {
parse_node *spec = ParseTree__get_evaluation(p);
spec = NonlocalVariables__substitute_constants(spec);
Assertions__Refiner__noun_from_value(p, spec);
}
#line 131 "inform7/Chapter 15/Relation Knowledge.w"
void Assertions__Relational__assert_relation_between_subtrees(parse_node *px, binary_predicate *bp, parse_node *py) {
if (ParseTree__get_type(py) == AND_NT) {
Assertions__Relational__assert_relation_between_subtrees(px, bp, py->down);
Assertions__Relational__assert_relation_between_subtrees(px, bp, py->down->next);
return;
}
if (ParseTree__get_type(py) == WITH_NT) {
Assertions__Relational__assert_relation_between_subtrees(px, bp, py->down);
return;
}
if (ParseTree__get_type(py) == EVERY_NT)
{
#line 191 "inform7/Chapter 15/Relation Knowledge.w"
Problems__Issue__sentence_problem(_p_(PM_EveryWrongSide),
"'every' can only be used on the other side of the verb",
"because of limitations in Inform (but also to avoid certain possible "
"ambiguities). In general, 'every' should be applied to the subject of an "
"assertion sentence and not the object. Thus 'Sir Francis prefers every "
"blonde' is not allowed, but 'Every blonde is preferred by Sir Francis' is. "
"(It would be different if, instead of Sir Francis who's just one man, "
"the name of a kind appeared: 'A vehicle is in every room' is fine, for "
"example, because 'vehicle' is a kind.)");
return;
}
#line 141 "inform7/Chapter 15/Relation Knowledge.w"
;
/* reverse the relation (and swap the terms) to ensure it's the right way round */
if (BinaryPredicates__is_the_wrong_way_round(bp)) {
parse_node *pz = px; px = py; py = pz;
bp = BinaryPredicates__get_reversal(bp);
}
{
#line 160 "inform7/Chapter 15/Relation Knowledge.w"
Assertions__Refiner__coerce_adjectival_usage_to_noun(px); Sentences__NPs__turn_player_to_yourself(px);
Assertions__Refiner__coerce_adjectival_usage_to_noun(py); Sentences__NPs__turn_player_to_yourself(py);
if (((ParseTree__get_type(px) != PROPER_NOUN_NT) && (ParseTree__get_type(px) != COMMON_NOUN_NT)) ||
((ParseTree__get_type(py) != PROPER_NOUN_NT) && (ParseTree__get_type(py) != COMMON_NOUN_NT))) {
Problems__Issue__sentence_problem(_p_(PM_BadRelation),
"this description of a relationship makes no sense to me",
"and should be something like 'X is in Y' (or 'on' or 'part of Y'); "
"or else 'X is here' or 'X is east of Y'.");
return;
}
}
#line 149 "inform7/Chapter 15/Relation Knowledge.w"
;
{
#line 175 "inform7/Chapter 15/Relation Knowledge.w"
if ((BinaryPredicates__relates_values_not_objects(bp)) &&
(((ParseTree__get_subject(px)) && (InferenceSubjects__domain(ParseTree__get_subject(px)))) ||
((ParseTree__get_subject(py)) && (InferenceSubjects__domain(ParseTree__get_subject(py)))))) {
Problems__Issue__sentence_problem(_p_(PM_KindRelatedToValue),
"relations between objects and values have to be made one "
"object at a time",
"not using kinds of object to make multiple relationships in "
"a single sentence. (Sorry for this restriction. It's sometimes "
"possible to get around it using words like 'every': for example, "
"'Every person is in the Ballroom.' is allowed.)");
return;
}
}
#line 150 "inform7/Chapter 15/Relation Knowledge.w"
;
Calculus__Propositions__Assert__assert_true(
Calculus__Propositions__Abstract__to_set_relation(bp, ParseTree__get_subject(px), ParseTree__get_evaluation(px), ParseTree__get_subject(py), ParseTree__get_evaluation(py)),
prevailing_mood);
}
#line 75 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__initialise_assemblies_data(assemblies_data *ad) {
ad->generalisation_list = NULL;
ad->applications_so_far = NULL;
ad->named_after = NULL;
ad->named_after_text = EMPTY_WORDING;
}
#line 85 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__name_object_after(inference_subject *infs, inference_subject *after, wording W) {
assemblies_data *ad = InferenceSubjects__get_assemblies_data(infs);
ad->named_after = after;
ad->named_after_text = W;
}
#line 94 "inform7/Chapter 15/Assemblies.w"
inference_subject *Assertions__Assemblies__what_this_is_named_after(inference_subject *infs) {
assemblies_data *ad = InferenceSubjects__get_assemblies_data(infs);
return ad->named_after;
}
wording Assertions__Assemblies__get_named_after_text(inference_subject *infs) {
assemblies_data *ad = InferenceSubjects__get_assemblies_data(infs);
return ad->named_after_text;
}
#line 118 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__make_generalisation(parse_node *look_for, parse_node *what_to_make) {
parse_node *EVERY_node = NULL;
if (ParseTree__get_type(look_for) == EVERY_NT) EVERY_node = look_for;
else if ((look_for->down) && (ParseTree__get_type(look_for->down) == EVERY_NT))
EVERY_node = look_for->down;
else internal_error("Generalisation without EVERY node");
inference_subject *k = ParseTree__get_subject(EVERY_node);
if (k == NULL) internal_error("Malformed EVERY node");
if ((Assertions__Assemblies__subtree_mentions_kind(look_for,k,0)) ||
(Assertions__Assemblies__subtree_mentions_kind(what_to_make,k,0)))
{
#line 206 "inform7/Chapter 15/Assemblies.w"
LOG("Generalisation:\n");
ParseTree__log_subtree(look_for);
ParseTree__log_subtree(what_to_make);
Problems__Issue__sentence_problem(_p_(PM_AssemblyRegress),
"this generalisation would be too dangerous",
"because it would lead to infinite regress in the assembly process. Sometimes "
"this happens if you have set up matters with text like 'A container is in every "
"container.'.");
return;
}
#line 129 "inform7/Chapter 15/Assemblies.w"
;
{
#line 155 "inform7/Chapter 15/Assemblies.w"
kind *instance_kind = InferenceSubjects__as_nonobject_kind(k);
if ((instance_kind) &&
(Kinds__Compare__le(instance_kind, K_object) == FALSE) &&
(Kinds__Behaviour__has_named_constant_values(instance_kind) == FALSE)) {
ParseTree__log_subtree(look_for);
ParseTree__log_subtree(what_to_make);
Problems__Issue__sentence_problem(_p_(PM_AssemblyOnFixedKind),
"this generalisation can't be made",
"because I only use generalisations to talk about values which can be "
"created as needed, like things or scenes - not about those always "
"existing in fixed ranges, like numbers or times.");
return;
}
}
#line 131 "inform7/Chapter 15/Assemblies.w"
;
{
#line 172 "inform7/Chapter 15/Assemblies.w"
if ((what_to_make) && (ParseTree__get_type(what_to_make->down) == EVERY_NT)) {
ParseTree__log_subtree(look_for);
ParseTree__log_subtree(what_to_make);
Problems__Issue__sentence_problem(_p_(PM_AssemblyOnBothSides),
"this generalisation can't be made",
"because it uses 'every' or some similar generalisation on both sides, "
"which is too rich for my taste.");
return;
}
}
#line 132 "inform7/Chapter 15/Assemblies.w"
;
{
#line 185 "inform7/Chapter 15/Assemblies.w"
parse_node *val = ParseTree__get_evaluation(what_to_make);
if ((val) && (Descriptions__is_adjectives_plus_kind(val))) {
Assertions__Refiner__refine_from_simple_description(what_to_make, ParseTree__duplicate(val));
}
}
#line 133 "inform7/Chapter 15/Assemblies.w"
;
ParseTree__set_text(EVERY_node, EMPTY_WORDING);
generalisation *g = CREATE(generalisation);
g->look_for = look_for;
g->what_to_make = what_to_make;
g->substitute_at = EVERY_node;
{
#line 193 "inform7/Chapter 15/Assemblies.w"
assemblies_data *ad = InferenceSubjects__get_assemblies_data(k);
if (ad->generalisation_list == NULL)
ad->generalisation_list = g;
else {
generalisation *g2 = ad->generalisation_list;
while (g2->next) g2 = g2->next;
g2->next = g;
}
g->next = NULL;
}
#line 142 "inform7/Chapter 15/Assemblies.w"
;
ParseTree__annotate_int(current_sentence, you_can_ignore_ANNOT, TRUE);
LOGIF(ASSEMBLIES, "New generalisation made concerning $j:\nLook for: $T\nMake: $T\n",
k, g->look_for, g->what_to_make);
Assertions__Assemblies__ensure_all_generalisations_made(k);
}
#line 219 "inform7/Chapter 15/Assemblies.w"
int Assertions__Assemblies__subtree_mentions_kind(parse_node *subtree, inference_subject *k, int level) {
if ((ParseTree__get_type(subtree) == COMMON_NOUN_NT) &&
(ParseTree__get_subject(subtree) == k)) return TRUE;
if ((subtree->down) && (Assertions__Assemblies__subtree_mentions_kind(subtree->down, k, level+1)))
return TRUE;
if ((level>0) && (subtree->next) && (Assertions__Assemblies__subtree_mentions_kind(subtree->next, k, level)))
return TRUE;
return FALSE;
}
#line 235 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__ensure_all_generalisations_made(inference_subject *k) {
inference_subject *infs;
LOOP_OVER(infs, inference_subject)
if ((InferenceSubjects__is_within(infs, k)) && (InferenceSubjects__domain(infs) == NULL))
Assertions__Assemblies__satisfies_generalisations(infs);
}
#line 249 "inform7/Chapter 15/Assemblies.w"
void Assertions__Assemblies__satisfies_generalisations(inference_subject *infs) {
if (InferenceSubjects__domain(infs)) return;
inference_subject *k;
for (k = InferenceSubjects__narrowest_broader_subject(infs); k; k = InferenceSubjects__narrowest_broader_subject(k)) {
application *app;
for (app = InferenceSubjects__get_assemblies_data(infs)->applications_so_far; app; app = app->next)
if (app->generalisation_owner == k)
break;
{
#line 266 "inform7/Chapter 15/Assemblies.w"
generalisation *ignore_up_to = (app)?(app->latest_applied):NULL;
generalisation *g;
for (g = InferenceSubjects__get_assemblies_data(k)->generalisation_list; g; g=g->next) {
if (ignore_up_to) {
if (g == ignore_up_to) ignore_up_to = NULL;
continue;
}
if (app == NULL)
{
#line 281 "inform7/Chapter 15/Assemblies.w"
app = CREATE(application);
app->generalisation_owner = k;
app->next = InferenceSubjects__get_assemblies_data(infs)->applications_so_far;
InferenceSubjects__get_assemblies_data(infs)->applications_so_far = app;
}
#line 273 "inform7/Chapter 15/Assemblies.w"
;
app->latest_applied = g;
Assertions__Assemblies__satisfies_generalisation(infs, g);
}
}
#line 257 "inform7/Chapter 15/Assemblies.w"
;
}
}
#line 316 "inform7/Chapter 15/Assemblies.w"
int implicit_recursion_exception = FALSE; /* thrown when we've gone into infinite regress */
void Assertions__Assemblies__satisfies_generalisation(inference_subject *infs, generalisation *g) {
inference_subject *counterpart = NULL; int snatcher = FALSE;
if (Plugins__Call__detect_bodysnatching(infs, &snatcher, &counterpart)) {
LOGIF(ASSEMBLIES, "Body-snatcher found! Subj $j, snatcher %d, counterpart $j\n",
infs, snatcher, counterpart);
if (snatcher) return;
}
inference_subject *infs_k = ParseTree__get_subject(g->substitute_at);
{
#line 371 "inform7/Chapter 15/Assemblies.w"
if (implicit_recursion_exception) return;
if (ParseTree__int_annotation(current_sentence, implicitness_count_ANNOT) >= MAX_ASSEMBLY_SIZE) {
implicit_recursion_exception = TRUE;
Problems__quote_source(1, current_sentence);
Problems__quote_subject(2, infs_k);
int max = MAX_ASSEMBLY_SIZE;
Problems__quote_number(3, &max);
Problems__Issue__handmade_problem(_p_(PM_AssemblyLoop));
Problems__issue_problem_segment(
"Making a new %2 seems to result in an assembly which can never end, "
"or which at any rate led to some %3 further constructions "
"before I panicked. This problem tends to occur if instructions "
"are given which cause kinds to create each other forever: "
"for instance, 'Every device is on a supporter. Every supporter "
"is in a container. Every container is part of a device.'");
Problems__issue_problem_end();
return;
}
}
#line 325 "inform7/Chapter 15/Assemblies.w"
;
parse_node *new_sentence = ParseTree__new(SENTENCE_NT);
/* mark this sentence as implicit, and increase its generation count: */
ParseTree__set_implicit_in_creation_of(new_sentence, infs);
ParseTree__annotate_int(new_sentence, implicitness_count_ANNOT,
ParseTree__int_annotation(current_sentence, implicitness_count_ANNOT) + 1);
ParseTree__set_text(new_sentence, ParseTree__get_text(current_sentence));
/* temporarily make the |EVERY_NT| node refer to the specific new |infs|: */
Assertions__Refiner__noun_from_infs(g->substitute_at, infs);
/* make the new sentence an assertion: */
new_sentence->down = ParseTree__new(AVERB_NT);
ParseTree__annotate_int(new_sentence->down, verb_id_ANNOT, ASSERT_VB);
new_sentence->down->next = ParseTree__new(CREATED_NT);
ParseTree__copy_subtree(g->look_for, new_sentence->down->next, 0);
new_sentence->down->next->next = ParseTree__new(CREATED_NT);
ParseTree__copy_subtree(g->what_to_make, new_sentence->down->next->next, 0);
new_sentence->down->next->next->next = NULL;
/* restore the |EVERY_NT| node, now that the tree containing it has been copied: */
ParseTree__set_type(g->substitute_at, EVERY_NT);
ParseTree__set_subject(g->substitute_at, infs_k);
/* insert this sentence after the current assembly position: */
new_sentence->next = assembly_position->next;
assembly_position->next = new_sentence;
assembly_position = new_sentence;
LOGIF(ASSEMBLIES,
"Subject $j satisfies generalisation %d (from $j), making sentence:\n$T",
infs, g->allocation_id, infs_k, new_sentence);
}
#line 44 "inform7/Chapter 15/Implications.w"
void Assertions__Implications__new(parse_node *px, parse_node *py) {
if (prevailing_mood == CERTAIN_CE)
{
#line 57 "inform7/Chapter 15/Implications.w"
Problems__Issue__sentence_problem(_p_(PM_ImplicationCertain),
"that's an implication which is too certain for me",
"since a sentence like this talks about a generality of things in terms of "
"one either/or property implying another, and I can only handle those as "
"likelihoods. You should probably add 'usually' somewhere: e.g., 'An open "
"door is usually openable'. (But implications can have unpredictable "
"consequences: best to avoid them altogether where possible.)");
return;
}
#line 45 "inform7/Chapter 15/Implications.w"
;
if (ParseTree__get_type(py) == AND_NT) {
Assertions__Implications__new(px, py->down);
Assertions__Implications__new(px, py->down->next);
return;
}
{
#line 69 "inform7/Chapter 15/Implications.w"
inference_subject *premiss_kind = NULL;
pcalc_prop *premiss = NULL;
{
#line 89 "inform7/Chapter 15/Implications.w"
parse_node *loc = px;
if (ParseTree__get_type(loc) == WITH_NT) loc = loc->down;
premiss_kind = ParseTree__get_subject(loc);
premiss = ParseTree__get_creation_proposition(loc);
if (premiss_kind == NULL) premiss_kind = Kinds__Behaviour__as_subject(K_thing);
}
#line 71 "inform7/Chapter 15/Implications.w"
;
{
#line 98 "inform7/Chapter 15/Implications.w"
if (Calculus__Propositions__Assert__testable_at_compile_time(premiss) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_BadImplicationDomain),
"that's an implication where the condition to qualify is not "
"one that I can determine in advance of the start of play",
"since it involves more than simple either/or properties "
"plus a kind. (For example, adjectives like 'adjacent' or "
"'visible' here are too difficult to determine.)");
return;
}
}
#line 72 "inform7/Chapter 15/Implications.w"
;
{
#line 111 "inform7/Chapter 15/Implications.w"
property *prn = Adjectives__Phrases__has_EORP_meaning(ParseTree__get_aph(py), NULL);
if (prn == NULL) {
Problems__Issue__sentence_problem(_p_(PM_ImplicationValueProperty),
"that's an implication where the outcome is an adjective other than "
"a simple either/or property",
"which is the only form of implication I can handle.");
return;
}
}
#line 73 "inform7/Chapter 15/Implications.w"
;
implication *imp = CREATE(implication);
imp->if_spec = premiss;
imp->then_pn = py;
imp->implied_likelihood = prevailing_mood;
imp->next_implication = InferenceSubjects__get_implications(premiss_kind);
InferenceSubjects__set_implications(premiss_kind, imp);
LOGIF(IMPLICATIONS, "Forming implication for $j: $D implies\n $T",
premiss_kind, imp->if_spec, imp->then_pn);
}
#line 51 "inform7/Chapter 15/Implications.w"
;
}
#line 139 "inform7/Chapter 15/Implications.w"
void Assertions__Implications__consider_all(inference_subject *infs) {
if (InferenceSubjects__domain(infs)) return;
int ongoing = TRUE;
while (ongoing) {
{
#line 155 "inform7/Chapter 15/Implications.w"
property *prn;
LOOP_OVER(prn, property) {
possession_marker *pom = Properties__get_possession_marker(prn);
pom->possessed = FALSE;
pom->possession_certainty = UNKNOWN_CE;
}
}
#line 143 "inform7/Chapter 15/Implications.w"
;
Assertions__Implications__set_possessed_flags(infs);
ongoing = Assertions__Implications__check_implications_of(infs, infs);
}
}
#line 166 "inform7/Chapter 15/Implications.w"
void Assertions__Implications__set_possessed_flags(inference_subject *infs) {
inference_subject *k = InferenceSubjects__narrowest_broader_subject(infs);
if (k) Assertions__Implications__set_possessed_flags(k);
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
property *prn = World__Inferences__get_property(inf);
if ((Properties__is_either_or(prn)) && (World__Inferences__get_certainty(inf) != UNKNOWN_CE))
{
#line 183 "inform7/Chapter 15/Implications.w"
int truth_state = TRUE, certainty = World__Inferences__get_certainty(inf);
if (certainty < 0) { certainty = -certainty; truth_state = FALSE; }
possession_marker *pom = Properties__get_possession_marker(prn);
{
#line 199 "inform7/Chapter 15/Implications.w"
if (pom->possession_certainty < certainty) {
pom->possessed = truth_state;
pom->possession_certainty = certainty;
}
}
#line 187 "inform7/Chapter 15/Implications.w"
;
if (Properties__EitherOr__get_negation(prn)) {
prn = Properties__EitherOr__get_negation(prn);
pom = Properties__get_possession_marker(prn);
truth_state = (truth_state)?FALSE:TRUE;
{
#line 199 "inform7/Chapter 15/Implications.w"
if (pom->possession_certainty < certainty) {
pom->possessed = truth_state;
pom->possession_certainty = certainty;
}
}
#line 193 "inform7/Chapter 15/Implications.w"
;
}
}
#line 174 "inform7/Chapter 15/Implications.w"
;
}
}
#line 214 "inform7/Chapter 15/Implications.w"
int Assertions__Implications__check_implications_of(inference_subject *domain, inference_subject *candidate) {
inference_subject *k = InferenceSubjects__narrowest_broader_subject(domain);
if ((k) && (Assertions__Implications__check_implications_of(k, candidate))) return TRUE;
if (InferenceSubjects__get_implications(domain))
LOGIF(IMPLICATIONS, "Considering implications about $j as they apply to $j:\n",
domain, candidate);
implication *imp;
for (imp = InferenceSubjects__get_implications(domain); imp; imp = imp->next_implication)
{
#line 232 "inform7/Chapter 15/Implications.w"
int conclusion_state = TRUE;
if (ParseTree__int_annotation(imp->then_pn, negated_boolean_ANNOT)) conclusion_state = FALSE;
if (imp->implied_likelihood < 0) conclusion_state = (conclusion_state)?FALSE:TRUE;
LOGIF(IMPLICATIONS, "$D => $T (certainty %d; changed state %d)\n",
imp->if_spec, imp->then_pn, imp->implied_likelihood, conclusion_state);
property *conclusion_prop = Adjectives__Phrases__has_EORP_meaning(ParseTree__get_aph(imp->then_pn), NULL);
{
#line 257 "inform7/Chapter 15/Implications.w"
if ((conclusion_prop == NULL) ||
(World__Permissions__find(candidate, conclusion_prop, TRUE) == NULL)) {
LOGIF(IMPLICATIONS, "IMPOSSIBLE: property not provided\n");
continue;
}
}
#line 240 "inform7/Chapter 15/Implications.w"
;
possession_marker *pom = Properties__get_possession_marker(conclusion_prop);
{
#line 265 "inform7/Chapter 15/Implications.w"
LOGIF(IMPLICATIONS, "Possession marker has (certainty %d; possessed state %d)\n",
pom->possession_certainty, pom->possessed);
if (pom->possessed == conclusion_state) {
LOGIF(IMPLICATIONS, "REDUNDANT: property already correct\n");
continue;
}
if (pom->possession_certainty == CERTAIN_CE) {
LOGIF(IMPLICATIONS, "IRRELEVANT: property already settled\n");
continue;
}
}
#line 243 "inform7/Chapter 15/Implications.w"
;
int candidate_qualifies = Calculus__Propositions__Assert__test_at_compile_time(imp->if_spec, candidate);
if (candidate_qualifies) {
LOGIF(IMPLICATIONS, "PASS: changing property $Y of $j\n", conclusion_prop, candidate);
{
#line 279 "inform7/Chapter 15/Implications.w"
adjectival_phrase *aph = Properties__EitherOr__get_aph(conclusion_prop);
pcalc_prop *prop = Calculus__Atoms__KIND_new(InferenceSubjects__domain(domain), Calculus__Terms__new_variable(0));
if (conclusion_state == FALSE) {
prop = Calculus__Propositions__concatenate(prop, Calculus__Atoms__new(NEGATION_OPEN_ATOM));
prop = Calculus__Propositions__concatenate(prop, Calculus__Atoms__unary_PREDICATE_from_aph(aph, FALSE));
prop = Calculus__Propositions__concatenate(prop, Calculus__Atoms__new(NEGATION_CLOSE_ATOM));
} else {
prop = Calculus__Propositions__concatenate(prop, Calculus__Atoms__unary_PREDICATE_from_aph(aph, FALSE));
}
Calculus__Propositions__Assert__assert_true_about(prop, candidate, CERTAIN_CE);
return TRUE;
}
#line 249 "inform7/Chapter 15/Implications.w"
;
} else {
LOGIF(IMPLICATIONS, "FAIL: take no action\n");
}
}
#line 224 "inform7/Chapter 15/Implications.w"
;
return FALSE;
}
#line 21 "inform7/Chapter 15/Property Declarations.w"
sentence_handler CANBE_SH_handler =
{ SENTENCE_NT, CANBE_VB, 1, Assertions__Property__declare_property_can_be };
#line 31 "inform7/Chapter 15/Property Declarations.w"
int forbidden_property_owners_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 39 "inform7/Chapter 15/Property Declarations.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_PropertyOfKind1),
"this seems to give a property to all kinds, rather than to objects or "
"values",
"which are the only things capable of having properties. For instance, "
"'A vehicle has a number called maximum speed' is fine, but not 'A kind "
"has a number called coolness rating'.");
}
#line 32 "inform7/Chapter 15/Property Declarations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 39 "inform7/Chapter 15/Property Declarations.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_PropertyOfKind1),
"this seems to give a property to all kinds, rather than to objects or "
"values",
"which are the only things capable of having properties. For instance, "
"'A vehicle has a number called maximum speed' is fine, but not 'A kind "
"has a number called coolness rating'.");
}
#line 33 "inform7/Chapter 15/Property Declarations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 50 "inform7/Chapter 15/Property Declarations.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_PropertyOfPronoun),
"it's often a little ambiguous to declare properties for 'it'",
"so it seems best to spell this out by saying exactly what the "
"property's owner or owners would be.");
}
#line 34 "inform7/Chapter 15/Property Declarations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 35 "inform7/Chapter 15/Property Declarations.w"
#line 65 "inform7/Chapter 15/Property Declarations.w"
void Assertions__Property__declare_property_can_be(parse_node *p) {
parse_node *the_owner = p->down->next;
parse_node *the_list = the_owner->next;
Preform__parse_nt_against_word_range(can_be_sentence_object_NTM, ParseTree__get_text(the_list), NULL, NULL);
int either_flag = most_recent_result;
the_list->down = most_recent_result_p;
the_list = the_list->down;
wording CNW = EMPTY_WORDING;
if (the_list->next) CNW = ParseTree__get_text(the_list->next);
Assertions__Refiner__refine(the_owner, FORBID_CREATION);
{
#line 163 "inform7/Chapter 15/Property Declarations.w"
if (ParseTree__get_type(the_owner) == WITH_NT) {
Problems__Issue__sentence_problem(_p_(PM_QualifiedCanBe),
"only a room, a thing or a kind can have such adjectives applied to it",
"and qualifications cannot be used. It makes no sense to say 'An open door "
"can be rickety or sturdy' because the door still has to have the property "
"even at times when it is not open: we must instead just say 'A door can be "
"rickety or sturdy'.");
return;
}
}
#line 78 "inform7/Chapter 15/Property Declarations.w"
;
int count = Assertions__Property__list_length(the_list);
{
#line 148 "inform7/Chapter 15/Property Declarations.w"
if ((Wordings__nonempty(CNW)) && (count < 3)) {
Problems__Issue__sentence_problem(_p_(PM_ThisIsEitherOr),
"a name can only be supplied using '... (this is...)' when a new property "
"is being made with three or more named alternatives",
"whereas here a simpler either/or property is being made with just one or "
"two possibilities - which means these named outcomes are the property names "
"themselves. For instance, 'A book can be mint or foxed' makes two either/or "
"properties, one called 'mint', the other called 'foxed'. So 'A book can "
"be mint or foxed (this is the cover state)' is not allowed.");
return;
}
}
#line 81 "inform7/Chapter 15/Property Declarations.w"
;
wording FW = EMPTY_WORDING;
if (count == 1) FW = ParseTree__get_text(the_list);
else FW = ParseTree__get_text(the_list->down);
{
#line 185 "inform7/Chapter 15/Property Declarations.w"
if ((either_flag) && (count != 2)) {
Problems__Issue__sentence_problem(_p_(PM_EitherOnThree),
"that looks like an attempt to use 'either' other than to lay out exactly "
"two possibilities",
"which is not allowed. (Technically it ought to be legal to have a property "
"whose name actually starts with 'either' but the confusion would be just "
"too awful to contemplate.)");
return;
}
}
#line 86 "inform7/Chapter 15/Property Declarations.w"
;
wording SW = EMPTY_WORDING;
if (count >= 2) SW = ParseTree__get_text(the_list->down->next);
if (Preform__parse_nt_against_word_range(forbidden_property_owners_NTM, ParseTree__get_text(the_owner), NULL, NULL)) return;
inference_subject *owner_infs = NULL;
{
#line 198 "inform7/Chapter 15/Property Declarations.w"
parse_node *owner_spec = ParseTree__get_evaluation(the_owner);
if (Lvalues__is_actual_NONLOCAL_VARIABLE(owner_spec))
{
#line 234 "inform7/Chapter 15/Property Declarations.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(the_owner));
Problems__Issue__handmade_problem(_p_(PM_VariableCantHaveProperties));
Problems__issue_problem_segment(
"The sentence %1 looked to me as if it might be trying to create an either/or "
"property which would be held by a variable ('%2'). But because '%2' can have "
"different values at different times, it's not clear who or what should have "
"the property. "
"%PThe most common case of this is saying something like 'The player can "
"be ambitious'. 'The player' is actually a variable, because the perspective "
"of play can change. Instead either say 'A person can be ambitious' or, if "
"you really only want the default player to be involved, 'Yourself can be "
"ambitious'.");
Problems__issue_problem_end();
return;
}
#line 200 "inform7/Chapter 15/Property Declarations.w"
;
if (Descriptions__is_qualified(owner_spec))
{
#line 253 "inform7/Chapter 15/Property Declarations.w"
Problems__Issue__sentence_problem(_p_(PM_OwnerTimeDependent),
"ownership of a property is something that has to be always true or "
"always false",
"so that 'a room can be secret' is fine - a room is always a room - "
"but 'a dark room can be secret' is not - a room might be dark some "
"of the time, and lighted the rest of the time. You need to give a "
"straightforward owner, and not qualify it with adjectives or "
"other conditions.");
return;
}
#line 202 "inform7/Chapter 15/Property Declarations.w"
;
owner_infs = ParseTree__get_subject(the_owner);
if (owner_infs == NULL) {
owner_spec = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, ParseTree__get_text(the_owner), NULL, NULL))
owner_infs = Kinds__Behaviour__as_subject(Specifications__to_kind(most_recent_result_p));
}
kind *K = InferenceSubjects__domain(owner_infs);
if ((K) && (Kinds__Behaviour__has_properties(K) == FALSE))
{
#line 216 "inform7/Chapter 15/Property Declarations.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(PM_ValueCantHaveProperties));
Problems__issue_problem_segment(
"The sentence %1 looked to me as if it might be trying to create an either/or "
"property which would be held by all of the values of a rather large kind "
"(%2). But this is a kind which is not allowed to have properties, because "
"the storage requirements would be too difficult. For instance, scenes can "
"have properties like this, but numbers can't: that's because there are only "
"a few, named scenes, but there is an almost unlimited range of numbers. (That "
"doesn't mean you can't create adjectives using 'Definition: ...' - it's "
"only when storage would be needed that this limitation kicks in.)");
Problems__issue_problem_end();
return;
}
#line 211 "inform7/Chapter 15/Property Declarations.w"
;
}
#line 93 "inform7/Chapter 15/Property Declarations.w"
;
if (owner_infs == NULL)
{
#line 266 "inform7/Chapter 15/Property Declarations.w"
Problems__Issue__sentence_problem(_p_(PM_NonObjectCanBe),
"only a room, a thing or a kind can have such adjectives applied to it",
"so that 'a dead end can be secret' is fine but 'taking can be secret' would "
"not be, since 'taking' is an action and not a room, thing or kind.");
return;
}
#line 94 "inform7/Chapter 15/Property Declarations.w"
;
if (count <= 2)
{
#line 276 "inform7/Chapter 15/Property Declarations.w"
char *error_text = NULL;
wording EW = FW;
property *already = NULL;
if (Preform__parse_nt_against_word_range(property_name_NTM, FW, NULL, NULL)) already = most_recent_result_p;
{
#line 305 "inform7/Chapter 15/Property Declarations.w"
if (already) {
if (Properties__is_either_or(already) == FALSE)
error_text = "this already has a meaning as a value property";
} else {
if (Preform__parse_nt_against_word_range(s_type_expression_or_value_NTM, FW, NULL, NULL)) {
parse_node *spec = most_recent_result_p;
if (Specifications__is_description(spec) == FALSE)
error_text = "this already has a meaning";
}
}
}
#line 281 "inform7/Chapter 15/Property Declarations.w"
;
if ((count == 2) && (error_text == NULL)) {
EW = SW;
{
#line 319 "inform7/Chapter 15/Property Declarations.w"
if (Preform__parse_nt_against_word_range(negated_clause_NTM, EW, NULL, NULL)) {
wording EPW = GET_RW(negated_clause_NTM, 1);
property *not_what = NULL;
if (Preform__parse_nt_against_word_range(property_name_NTM, EPW, NULL, NULL)) not_what = most_recent_result_p;
if ((not_what) && (not_what != already))
error_text =
"this is 'not' compounded with an existing either/or "
"property, which would cause horrible ambiguities";
}
}
#line 285 "inform7/Chapter 15/Property Declarations.w"
;
property *alreadybar = NULL;
if (Preform__parse_nt_against_word_range(property_name_NTM, EW, NULL, NULL)) alreadybar = most_recent_result_p;
{
#line 332 "inform7/Chapter 15/Property Declarations.w"
if (alreadybar) {
if (Properties__is_either_or(alreadybar) == FALSE)
error_text = "this already has a meaning as a value property";
else if ((already) &&
(Properties__EitherOr__get_negation(already) != alreadybar))
error_text = "this is not the same negation as the last "
"time this either/or property was used";
else if ((already == NULL) ||
(Properties__EitherOr__get_negation(already) != alreadybar))
error_text =
"this already has a meaning as an either/or property";
} else {
if (Preform__parse_nt_against_word_range(s_type_expression_or_value_NTM, EW, NULL, NULL)) {
parse_node *spec = most_recent_result_p;
if (Specifications__is_description(spec) == FALSE)
error_text = "this already has a meaning";
}
}
}
#line 288 "inform7/Chapter 15/Property Declarations.w"
;
}
if (error_text) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, EW);
Problems__quote_text(3, error_text);
Problems__Issue__handmade_problem(_p_(PM_MiscellaneousEOProblem));
Problems__issue_problem_segment(
"In %1, you proposed the new either/or property '%2': but %3.");
Problems__issue_problem_end();
return;
}
}
#line 96 "inform7/Chapter 15/Property Declarations.w"
;
property *prn = NULL;
int already_created_instances = FALSE;
{
#line 354 "inform7/Chapter 15/Property Declarations.w"
if (count <= 2) prn = Properties__EitherOr__obtain(FW, owner_infs);
else prn = Properties__Conditions__new(owner_infs, CNW, the_list,
&already_created_instances);
Calculus__Propositions__Assert__assert_true_about(Calculus__Propositions__Abstract__to_provide_property(prn),
owner_infs, prevailing_mood);
}
#line 100 "inform7/Chapter 15/Property Declarations.w"
;
if (already_created_instances == FALSE) {
if (count == 2)
{
#line 363 "inform7/Chapter 15/Property Declarations.w"
property *prnbar = Properties__EitherOr__obtain(SW, owner_infs);
Calculus__Propositions__Assert__assert_true_about(Calculus__Propositions__Abstract__to_provide_property(prnbar),
owner_infs, prevailing_mood);
Properties__EitherOr__make_negations(prn, prnbar);
}
#line 102 "inform7/Chapter 15/Property Declarations.w"
;
if (count >= 3)
{
#line 399 "inform7/Chapter 15/Property Declarations.w"
parse_node *option;
kind *condition_kind = Properties__Valued__kind(prn);
for (option = the_list; option; option = (option->down)?(option->down->next):NULL) {
wording PW;
if (ParseTree__get_type(option) == AND_NT)
PW = ParseTree__get_text(option->down);
else
PW = ParseTree__get_text(option);
{
#line 420 "inform7/Chapter 15/Property Declarations.w"
if (Preform__parse_nt_against_word_range(s_type_expression_or_value_NTM, PW, NULL, NULL)) {
parse_node *spec = most_recent_result_p;
int exempt = FALSE;
if ((Specifications__is_description(spec)) &&
(Descriptions__is_qualified(spec))) exempt = TRUE;
if (Rvalues__is_CONSTANT_construction(spec, CON_property)) exempt = TRUE;
if (exempt == FALSE) {
LOG("Already means: $P\n", spec);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, PW);
Problems__quote_spec(3, spec);
Problems__Issue__handmade_problem(_p_(PM_PropertyAlreadyKnown));
Problems__issue_problem_segment(
"In %1, one of the values you supply as a possibility is '%2', but this "
"already has a meaning (as %3).");
Problems__issue_problem_end();
return;
}
}
}
#line 407 "inform7/Chapter 15/Property Declarations.w"
;
{
#line 443 "inform7/Chapter 15/Property Declarations.w"
property *already = NULL;
if (Preform__parse_nt_against_word_range(property_name_NTM, PW, NULL, NULL)) already = most_recent_result_p;
if ((already) && (Properties__is_either_or(already))) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, PW);
Problems__Issue__handmade_problem(_p_(PM_EOClashesWithCondition));
Problems__issue_problem_segment(
"In %1, one of the values you supply as a possibility is '%2', but this "
"already has a meaning as an either-or property. The same adjective "
"can't be used both ways, so you'll have to use a different word here.");
Problems__issue_problem_end();
return;
}
}
#line 408 "inform7/Chapter 15/Property Declarations.w"
;
pcalc_prop *prop = Calculus__Propositions__Abstract__to_create_something(condition_kind, PW);
Calculus__Propositions__Assert__assert_true(prop, prevailing_mood);
}
}
#line 103 "inform7/Chapter 15/Property Declarations.w"
;
}
}
#line 110 "inform7/Chapter 15/Property Declarations.w"
int Assertions__Property__list_length(parse_node *P) {
if (P == NULL) internal_error("Ooops");
if (ParseTree__get_type(P) == AND_NT)
return Assertions__Property__list_length(P->down) + Assertions__Property__list_length(P->down->next);
return 1;
}
#line 126 "inform7/Chapter 15/Property Declarations.w"
int can_be_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; *XP = RP[1]; ((parse_node *) RP[1])->next = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE; *XP = RP[1]; ((parse_node *) RP[1])->next = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = FALSE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 131 "inform7/Chapter 15/Property Declarations.w"
int condition_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 135 "inform7/Chapter 15/Property Declarations.w"
int condition_name_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 140 "inform7/Chapter 15/Property Declarations.w"
int condition_name_innermost_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 144 "inform7/Chapter 15/Property Declarations.w"
#line 474 "inform7/Chapter 15/Property Declarations.w"
property *Assertions__Property__recursively_declare_properties(parse_node *owner_ref, parse_node *p) {
switch(ParseTree__get_type(p)) {
case AND_NT:
Assertions__Property__recursively_declare_properties(owner_ref, p->down);
Assertions__Property__recursively_declare_properties(owner_ref, p->down->next);
break;
case PROPERTYCALLED_NT:
{
#line 534 "inform7/Chapter 15/Property Declarations.w"
parse_node *kind_ref = p->down;
parse_node *prn_ref = p->down->next;
Assertions__Property__recursively_call_properties(owner_ref, kind_ref, prn_ref);
return NULL;
}
#line 480 "inform7/Chapter 15/Property Declarations.w"
;
case PROPER_NOUN_NT:
{
#line 492 "inform7/Chapter 15/Property Declarations.w"
if ((Preform__parse_nt_against_word_range(k_kind_NTM, ParseTree__get_text(p), NULL, NULL)) &&
((most_recent_result_p == K_number) || (most_recent_result_p == K_text))) {
Problems__Issue__assertion_problem(_p_(PM_BareProperty),
"this would create a property called 'number' or 'text'",
"and although bare names of kinds are usually allowed as properties, "
"these aren't. Instead, try '... has a number called position.' or "
"something like that, to give the property a name.");
}
inference_subject *owner_infs = ParseTree__get_subject(owner_ref);
kind *K = InferenceSubjects__domain(owner_infs);
Kinds__Behaviour__convert_to_enumeration(K); /* if that's possible; does nothing if not */
if ((K) && (Kinds__Behaviour__has_properties(K) == FALSE))
{
#line 513 "inform7/Chapter 15/Property Declarations.w"
if ((Kinds__Compare__eq(K, K_action_name)) ||
(Kinds__get_construct(K) == CON_activity) ||
(Kinds__get_construct(K) == CON_rulebook))
Problems__Issue__assertion_problem(_p_(PM_ValueCantHaveVProperties2),
"this is a kind of value which is not allowed to have properties of its own",
"because this would cause confusion with variables, which are more useful in "
"most cases. (See the Kinds index for which kinds can have properties.)");
else
Problems__Issue__assertion_problem(_p_(PM_ValueCantHaveVProperties),
"this is a kind of value which is not allowed to have properties of its own",
"because this would be impossible to store in any sensible way. For instance, "
"'A scene has a number called difficulty.' is fine because there are not many "
"scenes and I know them all, but 'A number has a text called French translation.' "
"is not allowed, because storing something for every possible number takes an "
"impossible amount of space. (See the Kinds index for which kinds can have "
"properties.)");
owner_infs = Kinds__Behaviour__as_subject(K_object);
}
#line 504 "inform7/Chapter 15/Property Declarations.w"
;
property *prn = Properties__Valued__obtain(ParseTree__get_text(p));
Calculus__Propositions__Assert__assert_true_about(Calculus__Propositions__Abstract__to_provide_property(prn),
owner_infs, prevailing_mood);
return prn;
}
#line 481 "inform7/Chapter 15/Property Declarations.w"
;
default:
internal_error("Assertions__Property__recursively_declare_properties on a node of unknown type");
}
return NULL;
}
#line 545 "inform7/Chapter 15/Property Declarations.w"
void Assertions__Property__recursively_call_properties(parse_node *owner_ref, parse_node *kind_ref, parse_node *prn_ref) {
switch(ParseTree__get_type(prn_ref)) {
case AND_NT:
Assertions__Property__recursively_call_properties(owner_ref, kind_ref, prn_ref->down);
Assertions__Property__recursively_call_properties(owner_ref, kind_ref, prn_ref->down->next);
break;
default:
{
#line 559 "inform7/Chapter 15/Property Declarations.w"
property *prn = Assertions__Property__recursively_declare_properties(owner_ref, prn_ref);
kind *K = NULL;
{
#line 571 "inform7/Chapter 15/Property Declarations.w"
if (Preform__parse_nt_against_word_range(k_kind_NTM, ParseTree__get_text(kind_ref), NULL, NULL)) K = most_recent_result_p;
else
{
#line 577 "inform7/Chapter 15/Property Declarations.w"
parse_node *spec = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, ParseTree__get_text(kind_ref), NULL, NULL))
spec = most_recent_result_p;
LOG("Offending SP: $T", spec);
if (Specifications__is_new_variable_like(spec)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(kind_ref));
Problems__Issue__handmade_problem(_p_(PM_RedundantThatVaries));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make a new named property - "
"a value associated with an object and which has a name. But you write this "
"as if it were a variable, which is not allowed because it would confuse "
"things. For example, 'A scene has a number that varies called the completion "
"bonus.' is not allowed - it should just be 'A scene has a number called "
"the completion bonus.', that is, without the 'that varies'.");
Problems__issue_problem_end();
} else if (Specifications__is_description(spec)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(kind_ref));
Problems__Issue__handmade_problem(_p_(PM_PropertyTooSpecific));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make a new named property - "
"a value associated with an object and which has a name. The request seems to "
"say that the value in question is '%2', but this is too specific a description. "
"(Instead, a kind of value (such as 'number') or a kind of object (such as 'room' "
"or 'thing') should be given. To get a property whose contents can be any kind "
"of object, use 'object'.)");
Problems__issue_problem_end();
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(kind_ref));
Problems__Issue__handmade_problem(_p_(PM_PropertyKindUnknown));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is not the name of a kind of value which I know (such "
"as 'number' or 'text').");
Problems__issue_problem_end();
}
return;
}
#line 572 "inform7/Chapter 15/Property Declarations.w"
;
}
#line 561 "inform7/Chapter 15/Property Declarations.w"
;
{
#line 619 "inform7/Chapter 15/Property Declarations.w"
if (Kinds__Compare__eq(K, K_value)) {
if (prn == P_variable_initial_value) return;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(kind_ref));
Problems__Issue__handmade_problem(_p_(PM_PropertyKindVague));
Problems__issue_problem_segment(
"You wrote %1, but saying that a property is a 'value' does not give me a clear "
"enough idea what it will hold. You need to say what kind of value: for instance, "
"'A door has a number called street address.' is allowed because 'number' is "
"specific about the kind of value.");
Problems__issue_problem_end();
return;
}
}
#line 562 "inform7/Chapter 15/Property Declarations.w"
;
kind *current_kind = Properties__Valued__kind(prn);
if (current_kind == NULL) Properties__Valued__set_kind(prn, K);
else if (Kinds__Compare__eq(current_kind, K) == FALSE)
{
#line 636 "inform7/Chapter 15/Property Declarations.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(kind_ref));
Problems__quote_property(3, prn);
Problems__quote_kind(4, current_kind);
Problems__Issue__handmade_problem(_p_(PM_PropertyKindClashes));
Problems__issue_problem_segment(
"You wrote %1, but '%2' contradicts what I previously thought about the property "
"%3, which was that it was %4.");
Problems__issue_problem_end();
return;
}
#line 566 "inform7/Chapter 15/Property Declarations.w"
;
}
#line 552 "inform7/Chapter 15/Property Declarations.w"
;
}
}
#line 24 "inform7/Chapter 16/Architecture of the S-Parser.w"
int s_plain_text_NTMR(wording W, int *X, void **XP) {
#line 25 "inform7/Chapter 16/Architecture of the S-Parser.w"
*XP = Specifications__new_UNKNOWN(W);
return TRUE;
}
#line 40 "inform7/Chapter 16/Architecture of the S-Parser.w"
int s_plain_text_with_equals_NTMR(wording W, int *X, void **XP) {
#line 41 "inform7/Chapter 16/Architecture of the S-Parser.w"
LOOP_THROUGH_WORDING(i, W) {
char *p = Lexer__word_raw_text(i);
for (int j=0; p[j]; j++)
if (p[j] == '=') {
*XP = Specifications__new_UNKNOWN(W);
return TRUE;
}
}
return FALSE;
}
#line 64 "inform7/Chapter 16/Architecture of the S-Parser.w"
int s_value_NTMR(wording W, int *X, void **XP) {
#line 65 "inform7/Chapter 16/Architecture of the S-Parser.w"
parse_node *spec = SParser__parse_with_cache(W, 0, s_value_uncached_NTM);
if (ParseTree__is(spec, UNKNOWN_VNT)) return FALSE;
*XP = spec;
return TRUE;
}
#line 76 "inform7/Chapter 16/Architecture of the S-Parser.w"
int s_condition_NTMR(wording W, int *X, void **XP) {
#line 77 "inform7/Chapter 16/Architecture of the S-Parser.w"
LocalVariables__make_necessary_callings(W);
parse_node *spec = SParser__parse_with_cache(W, 1, s_condition_uncached_NTM);
if (ParseTree__is(spec, UNKNOWN_VNT)) return FALSE;
*XP = spec;
return TRUE;
}
#line 88 "inform7/Chapter 16/Architecture of the S-Parser.w"
int s_non_action_condition_NTMR(wording W, int *X, void **XP) {
#line 89 "inform7/Chapter 16/Architecture of the S-Parser.w"
LocalVariables__make_necessary_callings(W);
int old_state = PL__Actions__Patterns__suppress();
parse_node *spec = SParser__parse_with_cache(W, 2, s_condition_uncached_NTM);
PL__Actions__Patterns__resume(old_state);
if (ParseTree__is(spec, UNKNOWN_VNT)) return FALSE;
*XP = spec;
return TRUE;
}
#line 103 "inform7/Chapter 16/Architecture of the S-Parser.w"
int s_type_expression_NTMR(wording W, int *X, void **XP) {
#line 104 "inform7/Chapter 16/Architecture of the S-Parser.w"
parse_node *spec = SParser__parse_with_cache(W, 3, s_type_expression_uncached_NTM);
if (ParseTree__is(spec, UNKNOWN_VNT)) return FALSE;
*XP = spec;
return TRUE;
}
#line 119 "inform7/Chapter 16/Architecture of the S-Parser.w"
int s_descriptive_type_expression_NTMR(wording W, int *X, void **XP) {
#line 120 "inform7/Chapter 16/Architecture of the S-Parser.w"
parse_node *spec = SParser__parse_with_cache(W, 4, s_descriptive_type_expression_uncached_NTM);
if (ParseTree__is(spec, UNKNOWN_VNT)) return FALSE;
*XP = spec;
return TRUE;
}
#line 132 "inform7/Chapter 16/Architecture of the S-Parser.w"
int s_type_expression_or_value_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 135 "inform7/Chapter 16/Architecture of the S-Parser.w"
#line 140 "inform7/Chapter 16/Architecture of the S-Parser.w"
int s_explicit_action_NTMR(wording W, int *X, void **XP) {
#line 141 "inform7/Chapter 16/Architecture of the S-Parser.w"
parse_node *S = NULL;
int p = permit_trying_omission;
permit_trying_omission = TRUE;
if (Preform__parse_nt_against_word_range(s_condition_uncached_NTM, W, NULL, NULL)) S = most_recent_result_p;
permit_trying_omission = p;
if (S) {
if (Rvalues__is_CONSTANT_of_kind(S, K_stored_action)) {
*XP = S; return TRUE;
} else if (Conditions__is_TEST_ACTION(S)) {
*XP = S->down;
return TRUE;
} else return FALSE;
}
return FALSE;
}
int s_constant_action_NTMR(wording W, int *X, void **XP) {
#line 158 "inform7/Chapter 16/Architecture of the S-Parser.w"
parse_node *S = NULL;
int p = permit_trying_omission;
permit_trying_omission = TRUE;
int p2 = permit_nonconstant_action_parameters;
permit_nonconstant_action_parameters = FALSE;
if (Preform__parse_nt_against_word_range(s_condition_uncached_NTM, W, NULL, NULL)) S = most_recent_result_p;
permit_trying_omission = p;
permit_nonconstant_action_parameters = p2;
if (S) {
if (Rvalues__is_CONSTANT_of_kind(S, K_stored_action)) {
*XP = S; return TRUE;
} else if (Conditions__is_TEST_ACTION(S)) {
*XP = S->down;
return TRUE;
} else return FALSE;
}
return FALSE;
}
#line 195 "inform7/Chapter 16/Architecture of the S-Parser.w"
#line 200 "inform7/Chapter 16/Architecture of the S-Parser.w"
int expression_cache_has_been_used = FALSE;
expression_cache contextual_cache[NUMBER_OF_CACHED_NONTERMINALS];
#line 207 "inform7/Chapter 16/Architecture of the S-Parser.w"
parse_node *SParser__parse_with_cache(wording W, int context, nonterminal *nt) {
if (Wordings__empty(W)) return Specifications__new_UNKNOWN(W);
if ((context < 0) || (context >= NUMBER_OF_CACHED_NONTERMINALS))
internal_error ("bad expression parsing context");
{
#line 230 "inform7/Chapter 16/Architecture of the S-Parser.w"
expression_cache *ec = &(contextual_cache[context]);
if (expression_cache_has_been_used == FALSE) {
SParser__warn_expression_cache(); /* this empties all the caches */
expression_cache_has_been_used = TRUE;
}
for (int i=0; i<ec->pe_cache_size; i++)
if (Wordings__eq(W, ec->pe_cache[i].cached_query))
return ec->pe_cache[i].cached_result;
}
#line 211 "inform7/Chapter 16/Architecture of the S-Parser.w"
;
int unwanted = 0; parse_node *spec = NULL;
int plm = preform_lookahead_mode;
preform_lookahead_mode = FALSE;
if (Preform__parse_nt_against_word_range(nt, W, &unwanted, (void **) &spec)) {
if (Wordings__empty(ParseTree__get_text(spec))) ParseTree__set_text(spec, W);
} else spec = Specifications__new_UNKNOWN(W);
preform_lookahead_mode = plm;
{
#line 245 "inform7/Chapter 16/Architecture of the S-Parser.w"
expression_cache *ec = &(contextual_cache[context]);
ec->pe_cache[ec->pe_cache_posn].cached_query = W;
ec->pe_cache[ec->pe_cache_posn].cached_result = spec;
ec->pe_cache_posn++;
if (ec->pe_cache_size < MAXIMUM_CACHE_SIZE) ec->pe_cache_size++;
if (ec->pe_cache_posn == MAXIMUM_CACHE_SIZE) ec->pe_cache_posn = 0;
}
#line 221 "inform7/Chapter 16/Architecture of the S-Parser.w"
;
ParseTree__verify_structure(spec);
return spec;
}
#line 276 "inform7/Chapter 16/Architecture of the S-Parser.w"
void SParser__warn_expression_cache(void) {
for (int i=0; i<NUMBER_OF_CACHED_NONTERMINALS; i++) {
contextual_cache[i].pe_cache_size = 0;
contextual_cache[i].pe_cache_posn = 0;
}
}
#line 292 "inform7/Chapter 16/Architecture of the S-Parser.w"
void SParser__parse_void_phrase(parse_node *p) {
SParser__parse_phrase_inner(p, FALSE);
}
void SParser__parse_say_term(parse_node *p) {
SParser__parse_phrase_inner(p, TRUE);
}
void SParser__parse_phrase_inner(parse_node *p, int as_say_term) {
if (p == NULL) internal_error("no node to parse");
p->down = NULL;
if (Wordings__nonempty(ParseTree__get_text(p))) {
parse_node *results = NULL;
if ((as_say_term == FALSE) && (Preform__parse_nt_against_word_range(s_command_NTM, ParseTree__get_text(p), NULL, NULL))) results = most_recent_result_p;
if ((as_say_term) && (Preform__parse_nt_against_word_range(s_say_command_NTM, ParseTree__get_text(p), NULL, NULL))) results = most_recent_result_p;
if ((results) && (results->down)) p->down = results->down->down;
}
}
#line 82 "inform7/Chapter 16/Parse Excerpts.w"
int force_maximal_parsing = FALSE;
parse_node *SParser__parse_excerpt_maximal(unsigned int mc_bitmap, wording W) {
int s = force_maximal_parsing;
force_maximal_parsing = TRUE;
parse_node *p = SParser__parse_excerpt(mc_bitmap, W);
force_maximal_parsing = s;
return p;
}
parse_node *SParser__parse_excerpt(unsigned int mc_bitmap, wording W) {
int parsing_mode, h;
parse_node *results = NULL;
no_calls_to_parse_excerpt++;
if (Wordings__empty(W)) return NULL;
while (Wordings__paired_brackets(W)) W = Wordings__trim_both_ends(W);
if (Wordings__empty(W)) return NULL;
h = 0;
{
#line 134 "inform7/Chapter 16/Parse Excerpts.w"
parsing_mode = 0;
if (mc_bitmap & EXACT_PARSING_BITMAP) parsing_mode |= EXACT_PM;
if (mc_bitmap & SUBSET_PARSING_BITMAP) parsing_mode |= SUBSET_PM;
if (mc_bitmap & PARAMETRISED_PARSING_BITMAP) parsing_mode |= PARAMETRISED_PM;
if (force_maximal_parsing) parsing_mode = MAXIMAL_PM;
}
#line 103 "inform7/Chapter 16/Parse Excerpts.w"
;
{
#line 151 "inform7/Chapter 16/Parse Excerpts.w"
if (mc_bitmap & SAY_PHRASE_MC) {
char *tx = Lexer__word_raw_text(Wordings__first_wn(W));
if ((tx[0]) && (isupper(tx[0])) &&
((tx[1] == 0) || (Vocabulary__used_case_sensitively(Lexer__word(Wordings__first_wn(W)))))) {
h = h | CAPITALISED_VARIANT_FORM;
}
}
}
#line 104 "inform7/Chapter 16/Parse Excerpts.w"
;
{
#line 164 "inform7/Chapter 16/Parse Excerpts.w"
if (parsing_mode & PARAMETRISED_PM) {
if ((mc_bitmap & SAY_PHRASE_MC) == 0) W = Articles__remove_the(W);
} else {
W = Articles__remove_article(W);
}
}
#line 105 "inform7/Chapter 16/Parse Excerpts.w"
;
h = h | Wordings__hash_code(W);
LOGIF(EXCERPT_PARSING,
"Parsing excerpt <$w> hash %08x mc $N mode %d\n", W, h, mc_bitmap, parsing_mode);
switch(parsing_mode) {
case EXACT_PM:
{
#line 189 "inform7/Chapter 16/Parse Excerpts.w"
parse_node *p;
vocabulary_entry *v = Lexer__word(Wordings__first_wn(W));
if (v == NULL) internal_error("Unidentified word when parsing");
if ((v->flags) & mc_bitmap)
for (p = v->start_list; p; p = p->next_alternative)
{
#line 199 "inform7/Chapter 16/Parse Excerpts.w"
if (EXCERPT_MEANING_RELEVANT(p) && (h == ParseTree__get_meaning(p)->excerpt_hash)) {
EXAMINE_EXCERPT_MEANING_IN_DETAIL;
if (ParseTree__get_meaning(p)->no_em_tokens == Wordings__length(W)) {
int j, k, err;
for (j=0, k=Wordings__first_wn(W), err = FALSE; j<ParseTree__get_meaning(p)->no_em_tokens; j++, k++)
if (ParseTree__get_meaning(p)->em_tokens[j] != Lexer__word(k)) { err=TRUE; break; }
if (err == FALSE)
results = SParser__result(ParseTree__get_meaning(p), 1, results);
}
}
}
#line 194 "inform7/Chapter 16/Parse Excerpts.w"
;
}
#line 113 "inform7/Chapter 16/Parse Excerpts.w"
; break;
case MAXIMAL_PM:
{
#line 213 "inform7/Chapter 16/Parse Excerpts.w"
vocabulary_entry *v = Lexer__word(Wordings__first_wn(W));
if (v == NULL) internal_error("Unidentified word when parsing");
if ((v->flags) & mc_bitmap) {
parse_node *p, *best_p = NULL; int best_score = 0;
for (p = v->start_list; p; p = p->next_alternative)
{
#line 230 "inform7/Chapter 16/Parse Excerpts.w"
if (EXCERPT_MEANING_RELEVANT(p) &&
((h & ParseTree__get_meaning(p)->excerpt_hash) == ParseTree__get_meaning(p)->excerpt_hash)) {
EXAMINE_EXCERPT_MEANING_IN_DETAIL;
if (ParseTree__get_meaning(p)->no_em_tokens <= Wordings__length(W)) {
int j, k, err;
for (err=FALSE, j=0, k=Wordings__first_wn(W); j<ParseTree__get_meaning(p)->no_em_tokens; j++, k++)
if (ParseTree__get_meaning(p)->em_tokens[j] != Lexer__word(k)) { err = TRUE; break; }
if ((err == FALSE) && (j>best_score)) {
best_p = p; best_score = j;
}
}
}
}
#line 218 "inform7/Chapter 16/Parse Excerpts.w"
;
if (best_p)
results =
SParser__result(
ParseTree__get_meaning(best_p), best_score, results);
}
}
#line 114 "inform7/Chapter 16/Parse Excerpts.w"
; break;
case PARAMETRISED_PM:
{
#line 248 "inform7/Chapter 16/Parse Excerpts.w"
vocabulary_entry *v = Lexer__word(Wordings__first_wn(W));
if (v == NULL) internal_error("Unidentified word when parsing");
parse_node *p;
if (mc_bitmap & SAY_PHRASE_MC) {
for (p = blank_says_p; p; p = p->next_alternative) {
parse_node *this_result =
ParseTree__new_with_words(SAY_PHRASE_MC, W);
wording SW = ParseTree__get_text(this_result);
ParseTree__copy(this_result, p);
ParseTree__set_text(this_result, SW);
this_result->down = Specifications__new_UNKNOWN(W);
this_result->next_alternative = results;
results = this_result;
no_meanings_tried++, no_meanings_tried_in_detail++;
}
}
for (p = v->start_list; p; p = p->next_alternative)
{
#line 284 "inform7/Chapter 16/Parse Excerpts.w"
int eh = ParseTree__get_meaning(p)->excerpt_hash;
if (EXCERPT_MEANING_RELEVANT(p) &&
((h & eh) == eh) &&
((ParseTree__get_meaning(p)->em_tokens[0] == 0) ||
((h & CAPITALISED_VARIANT_FORM) == (eh & CAPITALISED_VARIANT_FORM)))) {
int no_tokens_to_match = ParseTree__get_meaning(p)->no_em_tokens;
wording saved_W = W;
wording params_W[MAX_TOKENS_PER_EXCERPT_MEANING];
wording ph_opt_W = EMPTY_WORDING;
int bl; /* the "bracket level" (0 for unbracketed, 1 for inside one pair, etc.) */
int j, scan_pos, t, err;
EXAMINE_EXCERPT_MEANING_IN_DETAIL;
{
#line 317 "inform7/Chapter 16/Parse Excerpts.w"
phrase *ph = RETRIEVE_POINTER_phrase(ParseTree__get_meaning(p)->data);
if (Routines__ToPhrases__allows_options(ph)) {
LOGIF(EXCERPT_PARSING, "Looking for phrase options\n");
for (bl=0, scan_pos=Wordings__first_wn(W)+1; scan_pos<Wordings__last_wn(W); scan_pos++) {
if ((Lexer__word(scan_pos) == COMMA_V) && (bl==0)) {
ph_opt_W = Wordings__from(W, scan_pos+1);
W = Wordings__up_to(W, scan_pos-1);
LOGIF(EXCERPT_PARSING, "Found phrase options <$w>\n", ph_opt_W);
break;
}
{
#line 393 "inform7/Chapter 16/Parse Excerpts.w"
if ((Lexer__word(scan_pos) == OPENBRACKET_V) || (Lexer__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Lexer__word(scan_pos) == CLOSEBRACKET_V) || (Lexer__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 327 "inform7/Chapter 16/Parse Excerpts.w"
;
}
}
}
#line 297 "inform7/Chapter 16/Parse Excerpts.w"
;
for (err=FALSE, j=0, scan_pos=Wordings__first_wn(W), t=0, bl=0;
(j<no_tokens_to_match) && (scan_pos<=Wordings__last_wn(W)); j++) {
LOGIF(EXCERPT_PARSING, "j=%d, scan_pos=%d, t=%d\n", j, scan_pos, t);
vocabulary_entry *this_word = ParseTree__get_meaning(p)->em_tokens[j];
if (this_word)
{
#line 334 "inform7/Chapter 16/Parse Excerpts.w"
if (this_word != Lexer__word(scan_pos)) { err=TRUE; break; }
if (this_word == word_to_suppress_in_phrases) { err=TRUE; break; }
scan_pos++;
}
#line 302 "inform7/Chapter 16/Parse Excerpts.w"
else if (j == no_tokens_to_match-1)
{
#line 341 "inform7/Chapter 16/Parse Excerpts.w"
params_W[t++] = Wordings__from(W, scan_pos);
scan_pos = Wordings__last_wn(W) + 1;
}
#line 304 "inform7/Chapter 16/Parse Excerpts.w"
else
{
#line 347 "inform7/Chapter 16/Parse Excerpts.w"
int fixed_words_at_end = 0;
for (; j+1+fixed_words_at_end < no_tokens_to_match; fixed_words_at_end++)
if (ParseTree__get_meaning(p)->em_tokens[j+1+fixed_words_at_end] == NULL) {
fixed_words_at_end = 0; break;
}
if (fixed_words_at_end > 0) {
params_W[t++] = Wordings__new(scan_pos, Wordings__last_wn(W) - fixed_words_at_end);
scan_pos = Wordings__last_wn(W) - fixed_words_at_end + 1;
} else {
vocabulary_entry *sentinel = ParseTree__get_meaning(p)->em_tokens[j+1];
int bl_initial = bl;
int start_word = scan_pos;
err = TRUE;
while (scan_pos <= Wordings__last_wn(W)) {
{
#line 393 "inform7/Chapter 16/Parse Excerpts.w"
if ((Lexer__word(scan_pos) == OPENBRACKET_V) || (Lexer__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Lexer__word(scan_pos) == CLOSEBRACKET_V) || (Lexer__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 362 "inform7/Chapter 16/Parse Excerpts.w"
;
if ((bl == bl_initial) && (scan_pos > start_word) &&
(sentinel == Lexer__word(scan_pos))) { err = FALSE; break; }
if (bl < bl_initial) break;
scan_pos++;
}
params_W[t++] = Wordings__new(start_word, scan_pos-1);
}
}
#line 306 "inform7/Chapter 16/Parse Excerpts.w"
;
}
LOGIF(EXCERPT_PARSING, "outcome has err=%d (hash here %08x)\n", err, ParseTree__get_meaning(p)->excerpt_hash);
{
#line 374 "inform7/Chapter 16/Parse Excerpts.w"
int x;
if (j<no_tokens_to_match) err = TRUE;
if (scan_pos <= Wordings__last_wn(W)) err = TRUE;
if (err == FALSE)
for (x=0; x<t; x++) {
if (Wordings__empty(params_W[x])) err = TRUE;
else {
int bl = 0;
LOOP_THROUGH_WORDING(scan_pos, params_W[x]) {
{
#line 393 "inform7/Chapter 16/Parse Excerpts.w"
if ((Lexer__word(scan_pos) == OPENBRACKET_V) || (Lexer__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Lexer__word(scan_pos) == CLOSEBRACKET_V) || (Lexer__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 383 "inform7/Chapter 16/Parse Excerpts.w"
;
if (bl < 0) err = TRUE;
}
if (bl != 0) err = TRUE;
}
}
}
#line 309 "inform7/Chapter 16/Parse Excerpts.w"
;
if (err == FALSE)
{
#line 400 "inform7/Chapter 16/Parse Excerpts.w"
parse_node *last_param = NULL;
parse_node *this_result =
ParseTree__new_with_words(ParseTree__get_meaning(p)->meaning_code, W);
ParseTree__set_meaning(this_result, ParseTree__get_meaning(p));
this_result->next_alternative = results;
ParseTree__set_score(this_result, 1);
if (Wordings__nonempty(ph_opt_W)) {
this_result->down = Specifications__new_UNKNOWN(ph_opt_W);
ParseTree__annotate_int(this_result->down, is_phrase_option_ANNOT, TRUE);
last_param = this_result->down;
}
for (int x=0; x<t; x++) {
parse_node *p2;
p2 = Specifications__new_UNKNOWN(params_W[x]);
if (last_param) last_param->next = p2;
else this_result->down = p2;
last_param = p2;
}
results = this_result;
}
#line 310 "inform7/Chapter 16/Parse Excerpts.w"
;
W = saved_W;
}
}
#line 265 "inform7/Chapter 16/Parse Excerpts.w"
;
if (Wordings__length(W) > 1) {
v = Lexer__word(Wordings__last_wn(W));
if (v == NULL) internal_error("Unidentified word when parsing");
for (p = v->end_list; p; p = p->next_alternative)
{
#line 284 "inform7/Chapter 16/Parse Excerpts.w"
int eh = ParseTree__get_meaning(p)->excerpt_hash;
if (EXCERPT_MEANING_RELEVANT(p) &&
((h & eh) == eh) &&
((ParseTree__get_meaning(p)->em_tokens[0] == 0) ||
((h & CAPITALISED_VARIANT_FORM) == (eh & CAPITALISED_VARIANT_FORM)))) {
int no_tokens_to_match = ParseTree__get_meaning(p)->no_em_tokens;
wording saved_W = W;
wording params_W[MAX_TOKENS_PER_EXCERPT_MEANING];
wording ph_opt_W = EMPTY_WORDING;
int bl; /* the "bracket level" (0 for unbracketed, 1 for inside one pair, etc.) */
int j, scan_pos, t, err;
EXAMINE_EXCERPT_MEANING_IN_DETAIL;
{
#line 317 "inform7/Chapter 16/Parse Excerpts.w"
phrase *ph = RETRIEVE_POINTER_phrase(ParseTree__get_meaning(p)->data);
if (Routines__ToPhrases__allows_options(ph)) {
LOGIF(EXCERPT_PARSING, "Looking for phrase options\n");
for (bl=0, scan_pos=Wordings__first_wn(W)+1; scan_pos<Wordings__last_wn(W); scan_pos++) {
if ((Lexer__word(scan_pos) == COMMA_V) && (bl==0)) {
ph_opt_W = Wordings__from(W, scan_pos+1);
W = Wordings__up_to(W, scan_pos-1);
LOGIF(EXCERPT_PARSING, "Found phrase options <$w>\n", ph_opt_W);
break;
}
{
#line 393 "inform7/Chapter 16/Parse Excerpts.w"
if ((Lexer__word(scan_pos) == OPENBRACKET_V) || (Lexer__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Lexer__word(scan_pos) == CLOSEBRACKET_V) || (Lexer__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 327 "inform7/Chapter 16/Parse Excerpts.w"
;
}
}
}
#line 297 "inform7/Chapter 16/Parse Excerpts.w"
;
for (err=FALSE, j=0, scan_pos=Wordings__first_wn(W), t=0, bl=0;
(j<no_tokens_to_match) && (scan_pos<=Wordings__last_wn(W)); j++) {
LOGIF(EXCERPT_PARSING, "j=%d, scan_pos=%d, t=%d\n", j, scan_pos, t);
vocabulary_entry *this_word = ParseTree__get_meaning(p)->em_tokens[j];
if (this_word)
{
#line 334 "inform7/Chapter 16/Parse Excerpts.w"
if (this_word != Lexer__word(scan_pos)) { err=TRUE; break; }
if (this_word == word_to_suppress_in_phrases) { err=TRUE; break; }
scan_pos++;
}
#line 302 "inform7/Chapter 16/Parse Excerpts.w"
else if (j == no_tokens_to_match-1)
{
#line 341 "inform7/Chapter 16/Parse Excerpts.w"
params_W[t++] = Wordings__from(W, scan_pos);
scan_pos = Wordings__last_wn(W) + 1;
}
#line 304 "inform7/Chapter 16/Parse Excerpts.w"
else
{
#line 347 "inform7/Chapter 16/Parse Excerpts.w"
int fixed_words_at_end = 0;
for (; j+1+fixed_words_at_end < no_tokens_to_match; fixed_words_at_end++)
if (ParseTree__get_meaning(p)->em_tokens[j+1+fixed_words_at_end] == NULL) {
fixed_words_at_end = 0; break;
}
if (fixed_words_at_end > 0) {
params_W[t++] = Wordings__new(scan_pos, Wordings__last_wn(W) - fixed_words_at_end);
scan_pos = Wordings__last_wn(W) - fixed_words_at_end + 1;
} else {
vocabulary_entry *sentinel = ParseTree__get_meaning(p)->em_tokens[j+1];
int bl_initial = bl;
int start_word = scan_pos;
err = TRUE;
while (scan_pos <= Wordings__last_wn(W)) {
{
#line 393 "inform7/Chapter 16/Parse Excerpts.w"
if ((Lexer__word(scan_pos) == OPENBRACKET_V) || (Lexer__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Lexer__word(scan_pos) == CLOSEBRACKET_V) || (Lexer__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 362 "inform7/Chapter 16/Parse Excerpts.w"
;
if ((bl == bl_initial) && (scan_pos > start_word) &&
(sentinel == Lexer__word(scan_pos))) { err = FALSE; break; }
if (bl < bl_initial) break;
scan_pos++;
}
params_W[t++] = Wordings__new(start_word, scan_pos-1);
}
}
#line 306 "inform7/Chapter 16/Parse Excerpts.w"
;
}
LOGIF(EXCERPT_PARSING, "outcome has err=%d (hash here %08x)\n", err, ParseTree__get_meaning(p)->excerpt_hash);
{
#line 374 "inform7/Chapter 16/Parse Excerpts.w"
int x;
if (j<no_tokens_to_match) err = TRUE;
if (scan_pos <= Wordings__last_wn(W)) err = TRUE;
if (err == FALSE)
for (x=0; x<t; x++) {
if (Wordings__empty(params_W[x])) err = TRUE;
else {
int bl = 0;
LOOP_THROUGH_WORDING(scan_pos, params_W[x]) {
{
#line 393 "inform7/Chapter 16/Parse Excerpts.w"
if ((Lexer__word(scan_pos) == OPENBRACKET_V) || (Lexer__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Lexer__word(scan_pos) == CLOSEBRACKET_V) || (Lexer__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 383 "inform7/Chapter 16/Parse Excerpts.w"
;
if (bl < 0) err = TRUE;
}
if (bl != 0) err = TRUE;
}
}
}
#line 309 "inform7/Chapter 16/Parse Excerpts.w"
;
if (err == FALSE)
{
#line 400 "inform7/Chapter 16/Parse Excerpts.w"
parse_node *last_param = NULL;
parse_node *this_result =
ParseTree__new_with_words(ParseTree__get_meaning(p)->meaning_code, W);
ParseTree__set_meaning(this_result, ParseTree__get_meaning(p));
this_result->next_alternative = results;
ParseTree__set_score(this_result, 1);
if (Wordings__nonempty(ph_opt_W)) {
this_result->down = Specifications__new_UNKNOWN(ph_opt_W);
ParseTree__annotate_int(this_result->down, is_phrase_option_ANNOT, TRUE);
last_param = this_result->down;
}
for (int x=0; x<t; x++) {
parse_node *p2;
p2 = Specifications__new_UNKNOWN(params_W[x]);
if (last_param) last_param->next = p2;
else this_result->down = p2;
last_param = p2;
}
results = this_result;
}
#line 310 "inform7/Chapter 16/Parse Excerpts.w"
;
W = saved_W;
}
}
#line 270 "inform7/Chapter 16/Parse Excerpts.w"
;
}
LOOP_THROUGH_WORDING(i, W)
if (i > Wordings__first_wn(W)) {
v = Lexer__word(i);
if (v == NULL) internal_error("Unidentified word when parsing");
for (p = v->middle_list; p; p = p->next_alternative)
{
#line 284 "inform7/Chapter 16/Parse Excerpts.w"
int eh = ParseTree__get_meaning(p)->excerpt_hash;
if (EXCERPT_MEANING_RELEVANT(p) &&
((h & eh) == eh) &&
((ParseTree__get_meaning(p)->em_tokens[0] == 0) ||
((h & CAPITALISED_VARIANT_FORM) == (eh & CAPITALISED_VARIANT_FORM)))) {
int no_tokens_to_match = ParseTree__get_meaning(p)->no_em_tokens;
wording saved_W = W;
wording params_W[MAX_TOKENS_PER_EXCERPT_MEANING];
wording ph_opt_W = EMPTY_WORDING;
int bl; /* the "bracket level" (0 for unbracketed, 1 for inside one pair, etc.) */
int j, scan_pos, t, err;
EXAMINE_EXCERPT_MEANING_IN_DETAIL;
{
#line 317 "inform7/Chapter 16/Parse Excerpts.w"
phrase *ph = RETRIEVE_POINTER_phrase(ParseTree__get_meaning(p)->data);
if (Routines__ToPhrases__allows_options(ph)) {
LOGIF(EXCERPT_PARSING, "Looking for phrase options\n");
for (bl=0, scan_pos=Wordings__first_wn(W)+1; scan_pos<Wordings__last_wn(W); scan_pos++) {
if ((Lexer__word(scan_pos) == COMMA_V) && (bl==0)) {
ph_opt_W = Wordings__from(W, scan_pos+1);
W = Wordings__up_to(W, scan_pos-1);
LOGIF(EXCERPT_PARSING, "Found phrase options <$w>\n", ph_opt_W);
break;
}
{
#line 393 "inform7/Chapter 16/Parse Excerpts.w"
if ((Lexer__word(scan_pos) == OPENBRACKET_V) || (Lexer__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Lexer__word(scan_pos) == CLOSEBRACKET_V) || (Lexer__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 327 "inform7/Chapter 16/Parse Excerpts.w"
;
}
}
}
#line 297 "inform7/Chapter 16/Parse Excerpts.w"
;
for (err=FALSE, j=0, scan_pos=Wordings__first_wn(W), t=0, bl=0;
(j<no_tokens_to_match) && (scan_pos<=Wordings__last_wn(W)); j++) {
LOGIF(EXCERPT_PARSING, "j=%d, scan_pos=%d, t=%d\n", j, scan_pos, t);
vocabulary_entry *this_word = ParseTree__get_meaning(p)->em_tokens[j];
if (this_word)
{
#line 334 "inform7/Chapter 16/Parse Excerpts.w"
if (this_word != Lexer__word(scan_pos)) { err=TRUE; break; }
if (this_word == word_to_suppress_in_phrases) { err=TRUE; break; }
scan_pos++;
}
#line 302 "inform7/Chapter 16/Parse Excerpts.w"
else if (j == no_tokens_to_match-1)
{
#line 341 "inform7/Chapter 16/Parse Excerpts.w"
params_W[t++] = Wordings__from(W, scan_pos);
scan_pos = Wordings__last_wn(W) + 1;
}
#line 304 "inform7/Chapter 16/Parse Excerpts.w"
else
{
#line 347 "inform7/Chapter 16/Parse Excerpts.w"
int fixed_words_at_end = 0;
for (; j+1+fixed_words_at_end < no_tokens_to_match; fixed_words_at_end++)
if (ParseTree__get_meaning(p)->em_tokens[j+1+fixed_words_at_end] == NULL) {
fixed_words_at_end = 0; break;
}
if (fixed_words_at_end > 0) {
params_W[t++] = Wordings__new(scan_pos, Wordings__last_wn(W) - fixed_words_at_end);
scan_pos = Wordings__last_wn(W) - fixed_words_at_end + 1;
} else {
vocabulary_entry *sentinel = ParseTree__get_meaning(p)->em_tokens[j+1];
int bl_initial = bl;
int start_word = scan_pos;
err = TRUE;
while (scan_pos <= Wordings__last_wn(W)) {
{
#line 393 "inform7/Chapter 16/Parse Excerpts.w"
if ((Lexer__word(scan_pos) == OPENBRACKET_V) || (Lexer__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Lexer__word(scan_pos) == CLOSEBRACKET_V) || (Lexer__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 362 "inform7/Chapter 16/Parse Excerpts.w"
;
if ((bl == bl_initial) && (scan_pos > start_word) &&
(sentinel == Lexer__word(scan_pos))) { err = FALSE; break; }
if (bl < bl_initial) break;
scan_pos++;
}
params_W[t++] = Wordings__new(start_word, scan_pos-1);
}
}
#line 306 "inform7/Chapter 16/Parse Excerpts.w"
;
}
LOGIF(EXCERPT_PARSING, "outcome has err=%d (hash here %08x)\n", err, ParseTree__get_meaning(p)->excerpt_hash);
{
#line 374 "inform7/Chapter 16/Parse Excerpts.w"
int x;
if (j<no_tokens_to_match) err = TRUE;
if (scan_pos <= Wordings__last_wn(W)) err = TRUE;
if (err == FALSE)
for (x=0; x<t; x++) {
if (Wordings__empty(params_W[x])) err = TRUE;
else {
int bl = 0;
LOOP_THROUGH_WORDING(scan_pos, params_W[x]) {
{
#line 393 "inform7/Chapter 16/Parse Excerpts.w"
if ((Lexer__word(scan_pos) == OPENBRACKET_V) || (Lexer__word(scan_pos) == OPENBRACE_V)) bl++;
if ((Lexer__word(scan_pos) == CLOSEBRACKET_V) || (Lexer__word(scan_pos) == CLOSEBRACE_V)) bl--;
}
#line 383 "inform7/Chapter 16/Parse Excerpts.w"
;
if (bl < 0) err = TRUE;
}
if (bl != 0) err = TRUE;
}
}
}
#line 309 "inform7/Chapter 16/Parse Excerpts.w"
;
if (err == FALSE)
{
#line 400 "inform7/Chapter 16/Parse Excerpts.w"
parse_node *last_param = NULL;
parse_node *this_result =
ParseTree__new_with_words(ParseTree__get_meaning(p)->meaning_code, W);
ParseTree__set_meaning(this_result, ParseTree__get_meaning(p));
this_result->next_alternative = results;
ParseTree__set_score(this_result, 1);
if (Wordings__nonempty(ph_opt_W)) {
this_result->down = Specifications__new_UNKNOWN(ph_opt_W);
ParseTree__annotate_int(this_result->down, is_phrase_option_ANNOT, TRUE);
last_param = this_result->down;
}
for (int x=0; x<t; x++) {
parse_node *p2;
p2 = Specifications__new_UNKNOWN(params_W[x]);
if (last_param) last_param->next = p2;
else this_result->down = p2;
last_param = p2;
}
results = this_result;
}
#line 310 "inform7/Chapter 16/Parse Excerpts.w"
;
W = saved_W;
}
}
#line 277 "inform7/Chapter 16/Parse Excerpts.w"
;
}
}
#line 115 "inform7/Chapter 16/Parse Excerpts.w"
; break;
case SUBSET_PM:
{
#line 431 "inform7/Chapter 16/Parse Excerpts.w"
if ((Wordings__length(W) == 1) &&
((Vocabulary__test_flags(Wordings__first_wn(W), NUMBER_MC)) != 0)) goto SubsetFailed;
int j = -1, k = -1;
LOOP_THROUGH_WORDING(i, W) {
vocabulary_entry *v = Lexer__word(i);
if (v == NULL) internal_error("Unidentified word when parsing");
if (Preform__test_vocabulary(v, article_NTM)) continue;
if (v->subset_list_length == 0) goto SubsetFailed;
if (v->subset_list_length > j) { j = v->subset_list_length; k = i; }
}
if (k >= 0) {
vocabulary_entry *v = Lexer__word(k);
parse_node *p;
for (p = v->subset_list; p; p = p->next_alternative)
{
#line 452 "inform7/Chapter 16/Parse Excerpts.w"
if (EXCERPT_MEANING_RELEVANT(p) && ((h & ParseTree__get_meaning(p)->excerpt_hash) == h)) {
EXAMINE_EXCERPT_MEANING_IN_DETAIL;
if (Wordings__length(W) <= ParseTree__get_meaning(p)->no_em_tokens) {
int err = FALSE;
if (ParseTree__get_meaning(p)->meaning_code == NAMETAG_MC) {
nametag *nt = RETRIEVE_POINTER_nametag(ParseTree__get_meaning(p)->data);
if ((nt) && (Nametags__exactitude(nt))) {
LOGIF(EXCERPT_PARSING, "Require exact matching of $M\n", ParseTree__get_meaning(p));
err = TRUE;
if (ParseTree__get_meaning(p)->no_em_tokens == Wordings__length(W)) {
for (j=0, k=Wordings__first_wn(W), err = FALSE;
j<ParseTree__get_meaning(p)->no_em_tokens; j++, k++)
if (ParseTree__get_meaning(p)->em_tokens[j] != Lexer__word(k)) {
err=TRUE; break;
}
}
goto SubsetMatchDecided;
}
}
LOOP_THROUGH_WORDING(k, W) {
err = TRUE;
for (j=0; j<ParseTree__get_meaning(p)->no_em_tokens; j++)
if (ParseTree__get_meaning(p)->em_tokens[j] == Lexer__word(k)) err=FALSE;
if (err) break;
}
SubsetMatchDecided:
if (err == FALSE) {
excerpt_meaning *em = ParseTree__get_meaning(p);
results = SParser__result(em,
100-((em->no_em_tokens) - (Wordings__length(W)-1)),
results);
}
}
}
}
#line 445 "inform7/Chapter 16/Parse Excerpts.w"
;
}
SubsetFailed: ;
}
#line 116 "inform7/Chapter 16/Parse Excerpts.w"
; break;
case 0: LOG("mc_bitmap: $N\n", mc_bitmap); internal_error("Unknown parsing mode");
default: LOG("mc_bitmap: $N\n", mc_bitmap); internal_error("Mixed parsing modes");
}
LOGIF(EXCERPT_PARSING, "Completed:\n$m", results);
parse_node *loopy; for (loopy = results; loopy; loopy = loopy->next_alternative)
no_matched_ems++;
if (results) no_successful_calls_to_parse_excerpt++;
return results;
}
#line 490 "inform7/Chapter 16/Parse Excerpts.w"
parse_node *SParser__result(excerpt_meaning *em, int score, parse_node *alternatives) {
parse_node *this_result;
if (em->registered_as_noun) {
parse_node *val = RETRIEVE_POINTER_parse_node(Semantics__Nouns__ExcerptMeanings__data(em));
this_result = ParseTree__new(INVALID_NT);
ParseTree__copy(this_result, val);
} else {
this_result = ParseTree__new(em->meaning_code);
ParseTree__set_meaning(this_result, em);
}
this_result->next_alternative = alternatives;
ParseTree__set_score(this_result, score);
return this_result;
}
#line 535 "inform7/Chapter 16/Parse Excerpts.w"
void SParser__debug_parser_statistics(void) {
LOG("no_calls_to_parse_excerpt = %d\n", no_calls_to_parse_excerpt);
LOG("no_meanings_tried = %d\n", no_meanings_tried);
LOG("no_meanings_tried_in_detail = %d\n", no_meanings_tried_in_detail);
LOG("no_successful_calls_to_parse_excerpt = %d\n", no_successful_calls_to_parse_excerpt);
LOG("no_matched_ems = %d\n", no_matched_ems);
LOG("number of excerpt meanings registered = %d\n", NUMBER_CREATED(excerpt_meaning));
if (Log__aspect_switched_on(EXCERPT_MEANINGS_DA)) Semantics__Nouns__ExcerptMeanings__log_all();
}
#line 20 "inform7/Chapter 16/Parse Literals.w"
int s_literal_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Rvalues__from_int(R[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Rvalues__from_int(-R[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = Rvalues__from_wording(W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = Rvalues__from_wording(W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *XP = RP[1] /* times\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 31 "inform7/Chapter 16/Parse Literals.w"
int s_literal_unit_notation_NTMR(wording W, int *X, void **XP) {
#line 33 "inform7/Chapter 16/Parse Literals.w"
literal_pattern *lp;
LOOP_OVER(lp, literal_pattern) {
int val;
kind *K = LiteralPatterns__match(lp, W, &val);
if (K) { *X = val; *XP = Rvalues__from_encoded_notation(K, val, W); return TRUE; }
}
return FALSE;
}
#line 49 "inform7/Chapter 16/Parse Literals.w"
int cardinal_number_in_words_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 63 "inform7/Chapter 16/Parse Literals.w"
#line 67 "inform7/Chapter 16/Parse Literals.w"
int ordinal_number_in_words_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 81 "inform7/Chapter 16/Parse Literals.w"
#line 94 "inform7/Chapter 16/Parse Literals.w"
int cardinal_number_NTMR(wording W, int *X, void **XP) {
#line 95 "inform7/Chapter 16/Parse Literals.w"
if (Vocabulary__test_flags(Wordings__first_wn(W), NUMBER_MC)) {
*X = Vocabulary__get_literal_number_value(Lexer__word(Wordings__first_wn(W)));
{
#line 130 "inform7/Chapter 16/Parse Literals.w"
if ((((*X) > 32767) || ((*X) < -32768)) &&
(VirtualMachines__is_16_bit())) {
Problems__Issue__sentence_problem(_p_(PM_LiteralOverflow),
"you use a number which is too large",
"at least with the Settings for this project as they currently "
"are. (Change to Glulx to be allowed to use much larger numbers.)");
/* to prevent repetitions: */
Vocabulary__set_literal_number_value(Lexer__word(Wordings__first_wn(W)), 1);
return FALSE;
}
}
#line 97 "inform7/Chapter 16/Parse Literals.w"
;
return TRUE;
}
return FALSE;
}
int ordinal_number_NTMR(wording W, int *X, void **XP) {
#line 104 "inform7/Chapter 16/Parse Literals.w"
if (Vocabulary__test_flags(Wordings__first_wn(W), ORDINAL_MC)) {
*X = Vocabulary__get_literal_number_value(Lexer__word(Wordings__first_wn(W)));
{
#line 130 "inform7/Chapter 16/Parse Literals.w"
if ((((*X) > 32767) || ((*X) < -32768)) &&
(VirtualMachines__is_16_bit())) {
Problems__Issue__sentence_problem(_p_(PM_LiteralOverflow),
"you use a number which is too large",
"at least with the Settings for this project as they currently "
"are. (Change to Glulx to be allowed to use much larger numbers.)");
/* to prevent repetitions: */
Vocabulary__set_literal_number_value(Lexer__word(Wordings__first_wn(W)), 1);
return FALSE;
}
}
#line 106 "inform7/Chapter 16/Parse Literals.w"
;
return TRUE;
}
return FALSE;
}
#line 115 "inform7/Chapter 16/Parse Literals.w"
int cardinal_number_unlimited_NTMR(wording W, int *X, void **XP) {
#line 116 "inform7/Chapter 16/Parse Literals.w"
if (Vocabulary__test_flags(Wordings__first_wn(W), NUMBER_MC)) {
*X = Vocabulary__get_literal_number_value(Lexer__word(Wordings__first_wn(W)));
return TRUE;
}
return FALSE;
}
#line 148 "inform7/Chapter 16/Parse Literals.w"
int quoted_text_NTMR(wording W, int *X, void **XP) {
#line 149 "inform7/Chapter 16/Parse Literals.w"
if ((Wordings__nonempty(W)) && (Vocabulary__test_flags(Wordings__first_wn(W), TEXT_MC+TEXTWITHSUBS_MC))) {
*X = Wordings__first_wn(W); return TRUE;
}
return FALSE;
}
int quoted_text_with_subs_NTMR(wording W, int *X, void **XP) {
#line 156 "inform7/Chapter 16/Parse Literals.w"
if ((Wordings__nonempty(W)) && (Vocabulary__test_flags(Wordings__first_wn(W), TEXTWITHSUBS_MC))) {
*X = Wordings__first_wn(W); return TRUE;
}
return FALSE;
}
int quoted_text_without_subs_NTMR(wording W, int *X, void **XP) {
#line 163 "inform7/Chapter 16/Parse Literals.w"
if ((Wordings__nonempty(W)) && (Vocabulary__test_flags(Wordings__first_wn(W), TEXT_MC))) {
*X = Wordings__first_wn(W); return TRUE;
}
return FALSE;
}
#line 173 "inform7/Chapter 16/Parse Literals.w"
int empty_text_NTMR(wording W, int *X, void **XP) {
#line 174 "inform7/Chapter 16/Parse Literals.w"
if ((Wordings__nonempty(W)) && (Text__compare_word_by_strcmp(Wordings__first_wn(W), "\"\""))) {
*X = Wordings__first_wn(W); return TRUE;
}
return FALSE;
}
#line 184 "inform7/Chapter 16/Parse Literals.w"
int response_letter_NTMR(wording W, int *X, void **XP) {
#line 185 "inform7/Chapter 16/Parse Literals.w"
char *p = Lexer__word_raw_text(Wordings__first_wn(W));
if ((p) && (p[0] >= 'A') && (p[0] <= 'Z') && (p[1] == 0)) {
*X = p[0] - 'A';
return TRUE;
}
return FALSE;
}
#line 200 "inform7/Chapter 16/Parse Literals.w"
int s_literal_truth_state_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Rvalues__from_boolean(FALSE, W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Rvalues__from_boolean(TRUE, W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 203 "inform7/Chapter 16/Parse Literals.w"
#line 207 "inform7/Chapter 16/Parse Literals.w"
int e_notation_problem_issued = FALSE;
#line 214 "inform7/Chapter 16/Parse Literals.w"
int s_literal_real_number_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Rvalues__from_IEEE_754(0x40490FDB, W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Rvalues__from_IEEE_754(0x402DF854, W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = Rvalues__from_IEEE_754(0x7F800000, W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = Rvalues__from_IEEE_754(0xFF800000, W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = Rvalues__from_IEEE_754((unsigned int) R[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 220 "inform7/Chapter 16/Parse Literals.w"
int literal_real_in_digits_NTMR(wording W, int *X, void **XP) {
#line 222 "inform7/Chapter 16/Parse Literals.w"
if ((Wordings__length(W) != 1) && (Wordings__length(W) != 3)) return FALSE;
char *p = Lexer__word_raw_text(Wordings__first_wn(W));
if (p) {
int expo=0; double intv=0, fracv=0;
int expocount=0, intcount=0, fraccount=0;
int signbit = 0;
int distinctive = FALSE; /* as a floating-point rather than integer number */
int i = 0;
{
#line 248 "inform7/Chapter 16/Parse Literals.w"
if (p[i] == '-') { signbit = 1; i++; }
else if (p[i] == '+') { signbit = 0; i++; }
}
#line 231 "inform7/Chapter 16/Parse Literals.w"
;
{
#line 254 "inform7/Chapter 16/Parse Literals.w"
while (isdigit(p[i])) {
intv = 10.0*intv + (p[i] - '0');
intcount++;
i++;
}
}
#line 232 "inform7/Chapter 16/Parse Literals.w"
;
{
#line 263 "inform7/Chapter 16/Parse Literals.w"
if (p[i] == '.') {
distinctive = TRUE;
i++;
double fracpow = 1.0;
while (isdigit(p[i])) {
fracpow *= 0.1;
fracv = fracv + fracpow*(p[i] - '0');
fraccount++;
i++;
}
}
}
#line 233 "inform7/Chapter 16/Parse Literals.w"
;
if (intcount + fraccount > 0) {
if ((Wordings__length(W) > 1) || (p[i]))
{
#line 278 "inform7/Chapter 16/Parse Literals.w"
char *q = p + i;
int e_notation_used = FALSE;
if (Wordings__length(W) > 1) {
if (q[0] != 0) return FALSE;
q = Lexer__word_raw_text(Wordings__first_wn(W) + 1);
if (!((Literals__ismultiplicationsign(q[0])) && (q[1] == 0))) return FALSE;
q = Lexer__word_raw_text(Wordings__first_wn(W) + 2);
} else {
if ((fraccount > 0) && ((q[0] == 'e') || (q[0] == 'E'))) e_notation_used = TRUE;
else if (!(Literals__ismultiplicationsign(q[0]))) return FALSE;
q++;
}
if (e_notation_used) {
i = 0;
} else {
if (!((q[0] == '1') && (q[1] == '0') && (q[2] == '^'))) return FALSE;
i = 3;
}
int exposign = 0;
if (q[i] == '+') i++; else if (q[i] == '-') { exposign = 1; i++; }
while (isdigit(q[i])) {
expo = 10*expo + (q[i] - '0');
expocount++;
i++;
}
if (q[i]) return FALSE;
if (expocount == 0) return FALSE;
if (exposign) { expo = -expo; }
distinctive = TRUE;
if ((e_notation_used) && (allow_engineering_notation == FALSE) &&
(e_notation_problem_issued == FALSE)) {
e_notation_problem_issued = TRUE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_WantonEngineering));
Problems__issue_problem_segment(
"In %1, you write '%2', which looks to me like the engineering "
"notation for a real number - I'm guessing that the 'e' means "
"exponent, so for example, 1E+6 means 1000000. Inform writes "
"numbers like this as 1 x 10^6, or if you prefer 1.0 x 10^6; "
"or you can use a multiplication sign instead of the 'x'.");
Problems__issue_problem_end();
}
}
#line 235 "inform7/Chapter 16/Parse Literals.w"
;
if ((distinctive) || (TEST_COMPILATION_MODE(CONSTANT_CMODE))) {
*X = Literals__construct_float(signbit, intv, fracv, expo);
return TRUE;
}
}
}
return FALSE;
}
#line 325 "inform7/Chapter 16/Parse Literals.w"
int Literals__ismultiplicationsign(char c) {
if ((c == 'x') || (c == '*')) return TRUE;
return FALSE;
}
#line 343 "inform7/Chapter 16/Parse Literals.w"
int Literals__construct_float(int signbit, double intv, double fracv, int expo) {
double absval = (intv + fracv) * Literals__ten_to_the(expo);
int sign = (signbit ? ((int) 0x80000000) : 0x0);
latest_constructed_real = absval; if (signbit) latest_constructed_real = -absval;
if (isinf(absval))
{
#line 406 "inform7/Chapter 16/Parse Literals.w"
return sign | 0x7f800000;
}
#line 349 "inform7/Chapter 16/Parse Literals.w"
;
if (isnan(absval))
{
#line 411 "inform7/Chapter 16/Parse Literals.w"
return sign | 0x7fc00000;
}
#line 350 "inform7/Chapter 16/Parse Literals.w"
;
double mant = frexp(absval, &expo);
{
#line 368 "inform7/Chapter 16/Parse Literals.w"
if ((0.5 <= mant) && (mant < 1.0)) {
mant *= 2.0;
expo--;
} else if (mant == 0.0) {
expo = 0;
} else
{
#line 406 "inform7/Chapter 16/Parse Literals.w"
return sign | 0x7f800000;
}
#line 373 "inform7/Chapter 16/Parse Literals.w"
;
}
#line 353 "inform7/Chapter 16/Parse Literals.w"
;
if (expo >= 128)
{
#line 406 "inform7/Chapter 16/Parse Literals.w"
return sign | 0x7f800000;
}
#line 355 "inform7/Chapter 16/Parse Literals.w"
;
if (expo < -126)
{
#line 379 "inform7/Chapter 16/Parse Literals.w"
mant = ldexp(mant, 126 + expo);
expo = 0; /* 0 now represents 10 to the minus 127 */
}
#line 356 "inform7/Chapter 16/Parse Literals.w"
else if (!(expo == 0 && mant == 0.0))
{
#line 385 "inform7/Chapter 16/Parse Literals.w"
expo += 127; /* 127 now represents 10 to the 0, that is, 1 */
mant -= 1.0; /* the mantissa was in the range [1, 2), is now in [0, 1) */
}
#line 357 "inform7/Chapter 16/Parse Literals.w"
;
int fbits = 0;
{
#line 397 "inform7/Chapter 16/Parse Literals.w"
fbits = (int) ((mant*8388608.0) + 0.5); /* round to nearest integer */
if (fbits >> 23) {
fbits = 0;
expo++; if (expo >= 255)
{
#line 406 "inform7/Chapter 16/Parse Literals.w"
return sign | 0x7f800000;
}
#line 400 "inform7/Chapter 16/Parse Literals.w"
;
}
}
#line 360 "inform7/Chapter 16/Parse Literals.w"
;
return (sign) | ((int)(expo << 23)) | (fbits);
}
#line 418 "inform7/Chapter 16/Parse Literals.w"
double Literals__ten_to_the(int expo) {
static double powers[POW10_RANGE*2+1] = {
0.00000001, 0.0000001, 0.000001, 0.00001, 0.0001, 0.001, 0.01, 0.1,
1.0,
10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0, 100000000.0
};
double res = 1.0;
if (expo < 0)
for (; expo < -POW10_RANGE; expo += POW10_RANGE)
res *= powers[0];
else
for (; expo > POW10_RANGE; expo -= POW10_RANGE)
res *= powers[POW10_RANGE*2];
return res * powers[POW10_RANGE+expo];
}
#line 18 "inform7/Chapter 16/Constants and Descriptions.w"
int s_constant_value_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Rvalues__new_nothing_object_constant();;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 30 "inform7/Chapter 16/Constants and Descriptions.w"
verb_conjugation *vc = (verb_conjugation *) (RP[1]);
parse_node *spec = Rvalues__from_verb_conjugation(vc);
ParseTree__set_text(spec, W);
*XP = spec;
}
#line 24 "inform7/Chapter 16/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 38 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *spec = RP[1];
ParseTree__set_kind_of_value(spec, K_response);
ParseTree__annotate_int(spec, response_code_ANNOT, R[2]);
*XP = spec;
}
#line 25 "inform7/Chapter 16/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 26 "inform7/Chapter 16/Constants and Descriptions.w"
#line 54 "inform7/Chapter 16/Constants and Descriptions.w"
int s_miscellaneous_proper_noun_NTMR(wording W, int *X, void **XP) {
#line 55 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = SParser__parse_excerpt(MISCELLANEOUS_MC, W);
if (p) {
if ((Rvalues__is_CONSTANT_of_kind(p, K_action_name)) ||
(Rvalues__is_CONSTANT_construction(p, CON_relation)) ||
(Rvalues__is_CONSTANT_construction(p, CON_rule))) {
*XP = p; return TRUE;
}
}
p = SParser__parse_excerpt(VARIABLE_MC, W);
if (p) {
nonlocal_variable *nlv = Lvalues__get_nonlocal_variable_if_any(p);
if (NonlocalVariables__is_constant(nlv)) {
*XP = p; return TRUE;
}
}
if ((Vocabulary__disjunction_of_flags(W)) & CONSTANT_VAL_BITMAP) {
p = SParser__parse_excerpt(CONSTANT_VAL_BITMAP, W);
if (p) { *XP = p; return TRUE; }
}
return FALSE;
}
#line 81 "inform7/Chapter 16/Constants and Descriptions.w"
int s_named_constant_NTMR(wording W, int *X, void **XP) {
#line 82 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = SParser__parse_excerpt(VARIABLE_MC, W);
if (p) {
nonlocal_variable *nlv = Lvalues__get_nonlocal_variable_if_any(p);
if (NonlocalVariables__is_constant(nlv)) {
*XP = p; return TRUE;
}
}
return FALSE;
}
#line 97 "inform7/Chapter 16/Constants and Descriptions.w"
int s_rulebook_outcome_name_NTMR(wording W, int *X, void **XP) {
#line 98 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = SParser__parse_excerpt(MISCELLANEOUS_MC, W);
if (Rvalues__is_CONSTANT_of_kind(p, K_rulebook_outcome)) {
*XP = p;
return TRUE;
}
return FALSE;
}
int s_use_option_name_NTMR(wording W, int *X, void **XP) {
#line 107 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = SParser__parse_excerpt(MISCELLANEOUS_MC, W);
if (Rvalues__is_CONSTANT_of_kind(p, K_use_option)) {
*XP = p; return TRUE;
}
return FALSE;
}
int s_rule_name_NTMR(wording W, int *X, void **XP) {
#line 115 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = SParser__parse_excerpt(MISCELLANEOUS_MC, W);
if (Rvalues__is_CONSTANT_construction(p, CON_rule)) {
*XP = p;
return TRUE;
}
return FALSE;
}
#line 129 "inform7/Chapter 16/Constants and Descriptions.w"
int s_table_column_name_NTMR(wording W, int *X, void **XP) {
#line 130 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = SParser__parse_excerpt(TABLE_COLUMN_MC, W);
if (p) { *XP = p; return TRUE; }
return FALSE;
}
#line 142 "inform7/Chapter 16/Constants and Descriptions.w"
int property_name_as_noun_phrase_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 145 "inform7/Chapter 16/Constants and Descriptions.w"
int s_property_name_NTMR(wording W, int *X, void **XP) {
#line 147 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = SParser__parse_excerpt(PROPERTY_MC, W);
if (p) {
*XP = p;
if (Preform__parse_nt_against_word_range(property_name_as_noun_phrase_NTM, W, NULL, NULL))
ParseTree__annotate_int(p, property_name_used_as_noun_ANNOT, TRUE);
else
ParseTree__annotate_int(p, property_name_used_as_noun_ANNOT, FALSE);
return TRUE;
}
return FALSE;
}
#line 180 "inform7/Chapter 16/Constants and Descriptions.w"
int s_adjective_list_as_desc_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = ParseTree__AdjectiveLists__add_adjlist(Descriptions__from_proposition(NULL, W), RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 182 "inform7/Chapter 16/Constants and Descriptions.w"
#line 240 "inform7/Chapter 16/Constants and Descriptions.w"
int s_adjective_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = 0; *XP = ParseTree__AdjectiveLists__make_adjlist(ParseTree__AdjectiveLists__negate_adjlist(RP[2]), W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = 0; *XP = ParseTree__AdjectiveLists__make_adjlist(RP[2], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = 0; *XP = ParseTree__AdjectiveLists__make_adjlist(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 244 "inform7/Chapter 16/Constants and Descriptions.w"
int s_adjective_list_unarticled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = 0; *XP = ParseTree__AdjectiveLists__negate_adjlist(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = 0; *XP = ParseTree__AdjectiveLists__join_adjlist(ParseTree__AdjectiveLists__negate_adjlist(RP[1]), RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = 0; *XP = ParseTree__AdjectiveLists__join_adjlist(RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 250 "inform7/Chapter 16/Constants and Descriptions.w"
#line 255 "inform7/Chapter 16/Constants and Descriptions.w"
int s_adjective_NTMR(wording W, int *X, void **XP) {
#line 256 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = SParser__parse_excerpt_maximal(ADJECTIVE_MC, W);
if (p) {
adjective_usage *ale = Adjectives__Usages__new(
RETRIEVE_POINTER_adjectival_phrase(Semantics__Nouns__ExcerptMeanings__data(ParseTree__get_meaning(p))),
TRUE);
*XP = Descriptions__from_proposition(NULL, W);
Descriptions__add_to_adjective_list(ale, *XP);
int sc = ParseTree__get_score(p);
if (sc == 0) internal_error("Length-scored maximal parse with length 0");
return Wordings__first_wn(W) + sc - 1;
}
return FALSE;
}
#line 287 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *ParseTree__AdjectiveLists__join_adjlist(parse_node *A, parse_node *B) {
adjective_usage *au;
pcalc_prop *au_prop = NULL;
LOOP_THROUGH_ADJECTIVE_LIST(au, au_prop, B)
Descriptions__add_to_adjective_list(Adjectives__Usages__copy(au), A);
return A;
}
parse_node *ParseTree__AdjectiveLists__join_adjlist_w(parse_node *A, parse_node *B) {
adjective_usage *au;
pcalc_prop *au_prop = NULL;
LOOP_THROUGH_ADJECTIVE_LIST(au, au_prop, B)
Descriptions__add_to_adjective_list_w(Adjectives__Usages__copy(au), A);
return A;
}
parse_node *ParseTree__AdjectiveLists__make_adjlist(parse_node *A, wording W) {
ParseTree__set_text(A, W);
return A;
}
parse_node *ParseTree__AdjectiveLists__negate_adjlist(parse_node *A) {
adjective_usage *au;
pcalc_prop *au_prop = NULL;
LOOP_THROUGH_ADJECTIVE_LIST(au, au_prop, A)
Adjectives__Usages__flip_parity(au);
return A;
}
#line 319 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *ParseTree__AdjectiveLists__add_adjlist(parse_node *spec, parse_node *adjlist) {
if (adjlist) {
instance *I = Rvalues__to_object_instance(spec);
if (I) spec = Descriptions__from_instance(I, ParseTree__get_text(spec));
ParseTree__AdjectiveLists__join_adjlist(spec, adjlist);
}
return spec;
}
parse_node *ParseTree__AdjectiveLists__add_adjlist_w(parse_node *spec, parse_node *adjlist) {
if (adjlist) {
instance *I = Rvalues__to_object_instance(spec);
if (I) spec = Descriptions__from_instance(I, ParseTree__get_text(spec));
ParseTree__AdjectiveLists__join_adjlist_w(spec, adjlist);
}
return spec;
}
#line 340 "inform7/Chapter 16/Constants and Descriptions.w"
int ParseTree__AdjectiveLists__adjlist_applies_to_kind(parse_node *A, kind *K) {
adjective_usage *au;
pcalc_prop *au_prop = NULL;
LOOP_THROUGH_ADJECTIVE_LIST(au, au_prop, A) {
adjectival_phrase *aph = Adjectives__Usages__get_aph(au);
if (Adjectives__Phrases__applicable_to(aph, K) == FALSE) return FALSE;
}
return TRUE;
}
#line 355 "inform7/Chapter 16/Constants and Descriptions.w"
kind *s_adj_domain = NULL;
#line 360 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *PM_DefiniteCommonNoun_issued_at = NULL;
parse_node *PM_SpecificCalling_issued_at = NULL;
parse_node *PM_PastSubordinate_issued_at = NULL;
#line 378 "inform7/Chapter 16/Constants and Descriptions.w"
int s_qualifiable_noun_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Specifications__from_kind(RP[1]); s_adj_domain = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1]; s_adj_domain = NULL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 381 "inform7/Chapter 16/Constants and Descriptions.w"
int s_qualifiable_common_noun_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Specifications__from_kind(RP[1]); s_adj_domain = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 384 "inform7/Chapter 16/Constants and Descriptions.w"
int s_qualifiable_proper_noun_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1]; s_adj_domain = NULL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 387 "inform7/Chapter 16/Constants and Descriptions.w"
#line 392 "inform7/Chapter 16/Constants and Descriptions.w"
int s_instance_name_NTMR(wording W, int *X, void **XP) {
#line 393 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = SParser__parse_excerpt(NAMETAG_MC, W);
if (p) {
nametag *nt = Nametags__disambiguate(p, MAX_NAMETAG_PRIORITY);
if ((nt) && (Nametags__priority(nt) == INSTANCE_PRIORITY)) {
instance *I = Rvalues__to_object_instance(
RETRIEVE_POINTER_parse_node(Nametags__tag_holder(nt)));
*XP = Rvalues__from_instance(I); return TRUE;
}
}
return FALSE;
}
#line 413 "inform7/Chapter 16/Constants and Descriptions.w"
int s_applicable_adjective_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1]; if ((s_adj_domain) && (ParseTree__AdjectiveLists__adjlist_applies_to_kind(RP[1], s_adj_domain) == FALSE)) return FALSE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 415 "inform7/Chapter 16/Constants and Descriptions.w"
#line 469 "inform7/Chapter 16/Constants and Descriptions.w"
int s_description_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 472 "inform7/Chapter 16/Constants and Descriptions.w"
int s_description_uncomposite_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 475 "inform7/Chapter 16/Constants and Descriptions.w"
int s_description_uncomposite_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 542 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = RP[1];
parse_node *c = RP[2];
if (ParseTree__is(p, CONSTANT_VNT)) {
if (PM_SpecificCalling_issued_at != current_sentence) {
PM_SpecificCalling_issued_at = current_sentence;
Problems__Issue__sentence_problem(_p_(PM_SpecificCalling),
"a 'called' name can only be given to something "
"which is described vaguely",
"and can't be given to a definite object or value. "
"So 'if a thing (called the gadget) is carried' is "
"allowed, but 'if the X-Ray Zapper (called the gadget) "
"is carried' isn't allowed - if it's the X-Ray Zapper, "
"then call it that.");
}
} else {
if (Frames__current_stack_frame()) {
wording C = ParseTree__get_text(c);
Descriptions__attach_calling(p, C);
kind *K = Specifications__to_kind(p);
LocalVariables__ensure_called_local(C, K);
}
}
*XP = p;
}
#line 477 "inform7/Chapter 16/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 479 "inform7/Chapter 16/Constants and Descriptions.w"
int s_description_uncalled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 573 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = RP[2];
parse_node *annotation = RP[1];
quantifier *quant = ParseTree__get_quant(annotation);
if (quant) {
if (Specifications__is_description(p)) {
Descriptions__quantify(p,
quant, ParseTree__int_annotation(annotation, quantification_parameter_ANNOT));
} else if (!((quant == exists_quantifier) && (ParseTree__is(p, CONSTANT_VNT))))
p = Specifications__new_UNKNOWN(W);
}
*XP = p;
}
#line 481 "inform7/Chapter 16/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = ParseTree__AdjectiveLists__add_adjlist_w(RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = RP[3];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 588 "inform7/Chapter 16/Constants and Descriptions.w"
*XP = RP[4];
if ((PM_DefiniteCommonNoun_issued_at != current_sentence) ||
(PM_DefiniteCommonNoun_issued_at == NULL)) {
PM_DefiniteCommonNoun_issued_at = current_sentence;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_DefiniteCommonNoun));
Problems__issue_problem_segment(
"In %1, I'm not able to understand what specific thing is meant "
"by the phrase '%2'. You use the definite article 'the', which "
"suggests you have a particular thing in mind, but then you go "
"on to refer to a kind rather than something definite. Quite "
"likely a human reading this sentence would find it obvious what "
"you mean, but I don't. %P"
"This often arises when writing something like: 'Instead of "
"opening a door when the door is closed' - where clearly a human "
"would understand that 'the door' refers to the same one in 'a "
"door' earlier. I can make sense of this only if you help: for "
"example, 'Instead of opening a door (called the portal) when "
"the portal is closed' would work. So would 'Instead of opening "
"a closed door'; or 'Instead of opening a door which is closed'. "
"All of these alternatives help me by making clear that only one "
"door is being talked about.");
Problems__issue_problem_end();
}
}
#line 485 "inform7/Chapter 16/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 489 "inform7/Chapter 16/Constants and Descriptions.w"
int s_description_unspecified_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = ParseTree__AdjectiveLists__add_adjlist(RP[2], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 493 "inform7/Chapter 16/Constants and Descriptions.w"
int s_common_description_unspecified_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = ParseTree__AdjectiveLists__add_adjlist(RP[2], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 497 "inform7/Chapter 16/Constants and Descriptions.w"
int s_proper_description_unspecified_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = ParseTree__AdjectiveLists__add_adjlist(RP[2], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 501 "inform7/Chapter 16/Constants and Descriptions.w"
int if_trying_omission_permitted_NTMR(wording W, int *X, void **XP) {
#line 503 "inform7/Chapter 16/Constants and Descriptions.w"
if (permit_trying_omission) return TRUE;
return FALSE;
}
int if_multiplicitous_NTMR(wording W, int *X, void **XP) {
#line 508 "inform7/Chapter 16/Constants and Descriptions.w"
if (s_value_uncached_NTM->multiplicitous) return TRUE;
return FALSE;
}
#line 516 "inform7/Chapter 16/Constants and Descriptions.w"
int s_description_nounless_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 519 "inform7/Chapter 16/Constants and Descriptions.w"
int s_description_nounless_uncomposite_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 542 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = RP[1];
parse_node *c = RP[2];
if (ParseTree__is(p, CONSTANT_VNT)) {
if (PM_SpecificCalling_issued_at != current_sentence) {
PM_SpecificCalling_issued_at = current_sentence;
Problems__Issue__sentence_problem(_p_(PM_SpecificCalling),
"a 'called' name can only be given to something "
"which is described vaguely",
"and can't be given to a definite object or value. "
"So 'if a thing (called the gadget) is carried' is "
"allowed, but 'if the X-Ray Zapper (called the gadget) "
"is carried' isn't allowed - if it's the X-Ray Zapper, "
"then call it that.");
}
} else {
if (Frames__current_stack_frame()) {
wording C = ParseTree__get_text(c);
Descriptions__attach_calling(p, C);
kind *K = Specifications__to_kind(p);
LocalVariables__ensure_called_local(C, K);
}
}
*XP = p;
}
#line 521 "inform7/Chapter 16/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 523 "inform7/Chapter 16/Constants and Descriptions.w"
int s_description_nounless_uncalled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 573 "inform7/Chapter 16/Constants and Descriptions.w"
parse_node *p = RP[2];
parse_node *annotation = RP[1];
quantifier *quant = ParseTree__get_quant(annotation);
if (quant) {
if (Specifications__is_description(p)) {
Descriptions__quantify(p,
quant, ParseTree__int_annotation(annotation, quantification_parameter_ANNOT));
} else if (!((quant == exists_quantifier) && (ParseTree__is(p, CONSTANT_VNT))))
p = Specifications__new_UNKNOWN(W);
}
*XP = p;
}
#line 525 "inform7/Chapter 16/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = ParseTree__AdjectiveLists__add_adjlist_w(RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = RP[3];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 588 "inform7/Chapter 16/Constants and Descriptions.w"
*XP = RP[4];
if ((PM_DefiniteCommonNoun_issued_at != current_sentence) ||
(PM_DefiniteCommonNoun_issued_at == NULL)) {
PM_DefiniteCommonNoun_issued_at = current_sentence;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_DefiniteCommonNoun));
Problems__issue_problem_segment(
"In %1, I'm not able to understand what specific thing is meant "
"by the phrase '%2'. You use the definite article 'the', which "
"suggests you have a particular thing in mind, but then you go "
"on to refer to a kind rather than something definite. Quite "
"likely a human reading this sentence would find it obvious what "
"you mean, but I don't. %P"
"This often arises when writing something like: 'Instead of "
"opening a door when the door is closed' - where clearly a human "
"would understand that 'the door' refers to the same one in 'a "
"door' earlier. I can make sense of this only if you help: for "
"example, 'Instead of opening a door (called the portal) when "
"the portal is closed' would work. So would 'Instead of opening "
"a closed door'; or 'Instead of opening a door which is closed'. "
"All of these alternatives help me by making clear that only one "
"door is being talked about.");
Problems__issue_problem_end();
}
}
#line 529 "inform7/Chapter 16/Constants and Descriptions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 533 "inform7/Chapter 16/Constants and Descriptions.w"
int s_description_nounless_unspecified_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = ParseTree__AdjectiveLists__add_adjlist(RP[2], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = ParseTree__AdjectiveLists__add_adjlist(Descriptions__from_proposition(NULL, W), RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 538 "inform7/Chapter 16/Constants and Descriptions.w"
#line 617 "inform7/Chapter 16/Constants and Descriptions.w"
int s_calling_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = ParseTree__new_with_words(UNKNOWN_VNT, s_calling_name_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = ParseTree__new_with_words(UNKNOWN_VNT, s_calling_name_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 620 "inform7/Chapter 16/Constants and Descriptions.w"
#line 634 "inform7/Chapter 16/Constants and Descriptions.w"
int s_specifier_NTMR(wording W, int *X, void **XP) {
#line 635 "inform7/Chapter 16/Constants and Descriptions.w"
int which_N = -1; quantifier *quantifier_used = NULL;
int x1 = Quantifiers__parse_against_text(W, &which_N, &quantifier_used);
if (x1 >= 0) {
if ((x1<Wordings__last_wn(W)) && (Preform__test_word(x1, article_NTM))) x1++;
parse_node *qp = Specifications__new_UNKNOWN(Wordings__up_to(W, x1-1));
ParseTree__set_quant(qp, quantifier_used);
ParseTree__annotate_int(qp, quantification_parameter_ANNOT, which_N);
*XP = qp;
return x1-1;
}
return 0;
}
#line 654 "inform7/Chapter 16/Constants and Descriptions.w"
int s_specifying_noun_NTMR(wording W, int *X, void **XP) {
#line 655 "inform7/Chapter 16/Constants and Descriptions.w"
wording DW = Wordings__first_word(W);
quantifier *quantifier_used = NULL; kind *some_kind = NULL;
Plugins__Call__parse_composite_NQs(&W, &DW, &quantifier_used, &some_kind);
if (some_kind) {
parse_node *p = Descriptions__from_kind(some_kind, TRUE);
if (quantifier_used)
Descriptions__quantify(p, quantifier_used, -1);
*XP = p;
return Wordings__first_wn(W) - 1;
}
return 0;
}
#line 58 "inform7/Chapter 16/Type Expressions and Values.w"
int s_type_expression_uncached_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 61 "inform7/Chapter 16/Type Expressions and Values.w"
int s_type_expression_unarticled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = Specifications__from_kind(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 71 "inform7/Chapter 16/Type Expressions and Values.w"
#line 85 "inform7/Chapter 16/Type Expressions and Values.w"
int s_descriptive_type_expression_uncached_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 88 "inform7/Chapter 16/Type Expressions and Values.w"
int s_descriptive_type_expression_unarticled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 92 "inform7/Chapter 16/Type Expressions and Values.w"
#line 106 "inform7/Chapter 16/Type Expressions and Values.w"
int s_variable_scope_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Specifications__new_new_variable_like(NULL);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 110 "inform7/Chapter 16/Type Expressions and Values.w"
int s_variable_contents_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Specifications__new_new_variable_like(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 121 "inform7/Chapter 16/Type Expressions and Values.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_TypeCantVary));
Problems__issue_problem_segment(
"In %1, '%2' is not a kind of value which a variable can safely have, "
"as it cannot ever vary.");
Problems__issue_problem_end();
*XP = Specifications__new_new_variable_like(K_object);
}
#line 113 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 121 "inform7/Chapter 16/Type Expressions and Values.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_TypeCantVary));
Problems__issue_problem_segment(
"In %1, '%2' is not a kind of value which a variable can safely have, "
"as it cannot ever vary.");
Problems__issue_problem_end();
*XP = Specifications__new_new_variable_like(K_object);
}
#line 114 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 133 "inform7/Chapter 16/Type Expressions and Values.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_TypeUnmaintainable));
Problems__issue_problem_segment(
"In %1, '%2' is not a kind of value which a variable can safely have, "
"as it cannot be guaranteed that the contents will always meet "
"this criterion.");
Problems__issue_problem_end();
*XP = Specifications__new_new_variable_like(K_object);
}
#line 115 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 133 "inform7/Chapter 16/Type Expressions and Values.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_TypeUnmaintainable));
Problems__issue_problem_segment(
"In %1, '%2' is not a kind of value which a variable can safely have, "
"as it cannot be guaranteed that the contents will always meet "
"this criterion.");
Problems__issue_problem_end();
*XP = Specifications__new_new_variable_like(K_object);
}
#line 116 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 117 "inform7/Chapter 16/Type Expressions and Values.w"
#line 146 "inform7/Chapter 16/Type Expressions and Values.w"
int let_equation_mode = FALSE;
kind *probable_noun_phrase_context = NULL;
#line 162 "inform7/Chapter 16/Type Expressions and Values.w"
int if_let_equation_mode_NTMR(wording W, int *X, void **XP) {
#line 163 "inform7/Chapter 16/Type Expressions and Values.w"
if (let_equation_mode) return TRUE;
return FALSE;
}
#line 172 "inform7/Chapter 16/Type Expressions and Values.w"
int if_pronoun_present_NTMR(wording W, int *X, void **XP) {
#line 173 "inform7/Chapter 16/Type Expressions and Values.w"
if (LocalVariables__is_possessive_form_of_it_enabled()) return TRUE;
return FALSE;
}
#line 182 "inform7/Chapter 16/Type Expressions and Values.w"
int if_table_column_expected_NTMR(wording W, int *X, void **XP) {
#line 183 "inform7/Chapter 16/Type Expressions and Values.w"
if (Kinds__get_construct(probable_noun_phrase_context) == CON_table_column)
return TRUE;
return FALSE;
}
int if_property_name_expected_NTMR(wording W, int *X, void **XP) {
#line 189 "inform7/Chapter 16/Type Expressions and Values.w"
if (Kinds__get_construct(probable_noun_phrase_context) == CON_property)
return TRUE;
return FALSE;
}
#line 245 "inform7/Chapter 16/Type Expressions and Values.w"
int s_value_uncached_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = SParser__val(RP[2], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = SParser__val(RP[2], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14:
{
#line 327 "inform7/Chapter 16/Type Expressions and Values.w"
*XP = SParser__val(SParser__p_o_val(RP[1], RP[2]), W);
}
#line 260 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15:
{
#line 318 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *lvspec =
Lvalues__new_LOCAL_VARIABLE(EMPTY_WORDING,
LocalVariables__it_variable());
parse_node *val = SParser__val(lvspec, EMPTY_WORDING);
*XP = SParser__val(SParser__p_o_val(RP[3], val), W);
}
#line 261 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 16:
{
#line 332 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *val = Lvalues__new_LIST_ENTRY(RP[2], RP[1]);
*XP = SParser__val(val, W);
}
#line 262 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 17: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 18: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 19: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 266 "inform7/Chapter 16/Type Expressions and Values.w"
#line 270 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *SParser__val(parse_node *v, wording W) {
ParseTree__set_text(v, W);
return v;
}
#line 278 "inform7/Chapter 16/Type Expressions and Values.w"
int s_equation_usage_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 286 "inform7/Chapter 16/Type Expressions and Values.w"
equation *eqn = Equations__new(ParseTree__get_text((parse_node *) RP[2]), TRUE);
parse_node *eq = Rvalues__from_equation(eqn);
Equations__set_wherewithal(eqn, ParseTree__get_text((parse_node *) RP[3]));
Equations__declare_local_variables(eqn);
Equations__examine(eqn);
*XP = SParser__val(eq, W);
}
#line 279 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 296 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *p = RP[1];
if (!(Rvalues__is_CONSTANT_of_kind(p, K_equation))) return FALSE;
parse_node *eq = p;
equation *eqn = Rvalues__to_equation(eq);
Equations__set_usage_notes(eqn, ParseTree__get_text((parse_node *) RP[2]));
Equations__declare_local_variables(eqn);
Equations__examine(eqn);
*XP = SParser__val(eq, W);
}
#line 280 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 308 "inform7/Chapter 16/Type Expressions and Values.w"
equation *eqn = Equations__new(ParseTree__get_text((parse_node *) RP[2]), TRUE);
parse_node *eq = Rvalues__from_equation(eqn);
Equations__declare_local_variables(eqn);
Equations__examine(eqn);
*XP = SParser__val(eq, W);
}
#line 281 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 282 "inform7/Chapter 16/Type Expressions and Values.w"
#line 338 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *SParser__p_o_val(parse_node *A, parse_node *B) {
parse_node *pts =
(ParseTree__get_type(A) == UNKNOWN_VNT) ?
Specifications__new_UNKNOWN(ParseTree__get_text(A)) :
A;
parse_node *vts = B;
parse_node *spec = Lvalues__new_PROPERTY_VALUE(pts, vts);
wording PW = ParseTree__get_text(A);
wording VW = ParseTree__get_text(B);
if ((Wordings__nonempty(PW)) && (Wordings__nonempty(VW))) {
wording MW = PW;
if (Wordings__first_wn(MW) > Wordings__first_wn(VW))
MW = Wordings__from(MW, Wordings__first_wn(VW));
if (Wordings__last_wn(MW) < Wordings__last_wn(VW))
MW = Wordings__up_to(MW, Wordings__last_wn(VW));
ParseTree__set_text(spec, MW);
}
return spec;
}
#line 367 "inform7/Chapter 16/Type Expressions and Values.w"
int s_variable_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 372 "inform7/Chapter 16/Type Expressions and Values.w"
int s_nonglobal_variable_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 377 "inform7/Chapter 16/Type Expressions and Values.w"
int s_variable_as_value_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = SParser__val(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 380 "inform7/Chapter 16/Type Expressions and Values.w"
#line 384 "inform7/Chapter 16/Type Expressions and Values.w"
int s_local_variable_NTMR(wording W, int *X, void **XP) {
#line 385 "inform7/Chapter 16/Type Expressions and Values.w"
local_variable *lvar = LocalVariables__parse(Frames__current_stack_frame(), W);
if (lvar) {
parse_node *spec = Lvalues__new_LOCAL_VARIABLE(W, lvar);
*XP = spec; return TRUE;
}
return FALSE;
}
#line 396 "inform7/Chapter 16/Type Expressions and Values.w"
int s_stacked_variable_NTMR(wording W, int *X, void **XP) {
#line 397 "inform7/Chapter 16/Type Expressions and Values.w"
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) return FALSE;
stacked_variable *stv = StackedVariables__parse_from_owner_list(
Frames__get_stvol(), W);
if (stv) {
parse_node *spec = Lvalues__new_actual_NONLOCAL_VARIABLE(
StackedVariables__get_variable(stv));
*XP = spec; return TRUE;
}
return FALSE;
}
#line 412 "inform7/Chapter 16/Type Expressions and Values.w"
int s_global_variable_NTMR(wording W, int *X, void **XP) {
#line 413 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *p = SParser__parse_excerpt(VARIABLE_MC, W);
if (p) { *XP = p; return TRUE; }
return FALSE;
}
#line 423 "inform7/Chapter 16/Type Expressions and Values.w"
int property_of_shape_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 425 "inform7/Chapter 16/Type Expressions and Values.w"
#line 430 "inform7/Chapter 16/Type Expressions and Values.w"
vocabulary_entry *property_word_to_suppress = NULL;
#line 435 "inform7/Chapter 16/Type Expressions and Values.w"
int s_value_phrase_non_of_NTMR(wording W, int *X, void **XP) {
#line 436 "inform7/Chapter 16/Type Expressions and Values.w"
W = Articles__remove_the(W);
vocabulary_entry *suppression = word_to_suppress_in_phrases;
if (Preform__parse_nt_against_word_range(property_of_shape_NTM, W, NULL, NULL)) {
if (property_word_to_suppress == NULL)
property_word_to_suppress = Preform__Nonparsing__word(property_of_shape_NTM, 0);
word_to_suppress_in_phrases = property_word_to_suppress;
}
parse_node *p = SParser__parse_excerpt(VALUE_PHRASE_MC, W);
word_to_suppress_in_phrases = suppression;
if (p) {
parse_node *spec = ParseTree__new_with_words(PHRASE_TO_DECIDE_VALUE_VNT, W);
SParser__add_ilist(spec, p);
*XP = spec; return TRUE;
}
return FALSE;
}
int s_value_phrase_NTMR(wording W, int *X, void **XP) {
#line 454 "inform7/Chapter 16/Type Expressions and Values.w"
W = Articles__remove_the(W);
parse_node *p = SParser__parse_excerpt(VALUE_PHRASE_MC, W);
if (p) {
parse_node *spec = ParseTree__new_with_words(PHRASE_TO_DECIDE_VALUE_VNT, W);
SParser__add_ilist(spec, p);
*XP = spec; return TRUE;
}
return FALSE;
}
#line 480 "inform7/Chapter 16/Type Expressions and Values.w"
int s_table_reference_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 490 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *spec = Lvalues__new_TABLE_ENTRY(W);
spec->down = RP[1];
if ((LocalVariables__are_we_using_table_lookup() == FALSE) &&
(problem_count == 0)) {
Problems__Issue__sentence_problem(_p_(PM_NoRowSelected),
"no row seems to have been chosen at this point",
"so it doesn't make sense to talk about the entries "
"within it. (By 'at this point', I mean the point "
"when the table will have to be looked at. This "
"might be at another time altogether if we are "
"storing away instructions for later in a text "
"substitution, e.g., writing 'now the description "
"of the player is \"Thoroughly [vanity entry].\";' "
"- remember that the substitution is acted on "
"when the text is printed, which could be at any "
"time, and no row will be chosen then.)");
}
*XP = spec;
}
#line 481 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 512 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *spec = Lvalues__new_TABLE_ENTRY(W);
spec->down = SParser__arg(RP[1]);
spec->down->next = SParser__arg(RP[2]);
spec->down->next->next = SParser__arg(RP[3]);
*XP = spec;
}
#line 482 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 521 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *spec = Lvalues__new_TABLE_ENTRY(W);
spec->down = SParser__arg(RP[1]);
spec->down->next = SParser__arg(RP[2]);
*XP = spec;
}
#line 483 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 529 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *spec = Lvalues__new_TABLE_ENTRY(W);
spec->down = SParser__arg(RP[1]);
spec->down->next = SParser__arg(RP[2]);
spec->down->next->next = SParser__arg(RP[3]);
spec->down->next->next->next = SParser__arg(RP[4]);
*XP = spec;
}
#line 484 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 539 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *spec = Lvalues__new_TABLE_ENTRY(W);
spec->down = SParser__arg(RP[1]);
spec->down->next = SParser__arg(RP[1]);
spec->down->next->next = SParser__arg(RP[2]);
spec->down->next->next->next = SParser__arg(RP[3]);
*XP = spec;
}
#line 485 "inform7/Chapter 16/Type Expressions and Values.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 486 "inform7/Chapter 16/Type Expressions and Values.w"
#line 549 "inform7/Chapter 16/Type Expressions and Values.w"
parse_node *SParser__arg(parse_node *val) {
if (val == NULL) return Specifications__new_UNKNOWN(EMPTY_WORDING);
return ParseTree__duplicate(val);
}
#line 559 "inform7/Chapter 16/Type Expressions and Values.w"
int s_action_pattern_as_value_NTMR(wording W, int *X, void **XP) {
#line 560 "inform7/Chapter 16/Type Expressions and Values.w"
if (Wordings__mismatched_brackets(W)) return FALSE;
if (Lexer__word(Wordings__first_wn(W)) == OPENBRACE_V) return FALSE;
int pto = permit_trying_omission;
if (Preform__parse_nt_against_word_range(definite_article_NTM, Wordings__first_word(W), NULL, NULL) == FALSE) permit_trying_omission = TRUE;
int r = Preform__parse_nt_against_word_range(action_pattern_NTM, W, NULL, NULL);
permit_trying_omission = pto;
if (r) {
action_pattern *ap = most_recent_result_p;
if ((ap->actor_spec) &&
(PL__Actions__Patterns__validate_parameter(ap->actor_spec, K_person) == FALSE)) {
r = Preform__parse_nt_against_word_range(action_pattern_NTM, W, NULL, NULL);
}
}
if (r) {
*XP = Conditions__new_TEST_ACTION(most_recent_result_p, W);
return TRUE;
}
return FALSE;
}
#line 37 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_sentence_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 72 "inform7/Chapter 16/Verbal and Relative Clauses.w"
parse_node *op = RP[2];
parse_node *test = op->down;
if (ParseTree__is(test, AMBIGUITY_NT)) test = test->down;
if (Specifications__is_description_like(test) == FALSE) return FAIL_NONTERMINAL;
*XP = SParser__Subtrees__to_specification(TRUE, W, NULL, op);
}
#line 38 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 61 "inform7/Chapter 16/Verbal and Relative Clauses.w"
SParser__Subtrees__correct_for_adjectives(RP[1], RP[2]);
*XP = SParser__Subtrees__to_specification(TRUE, W, RP[1], RP[2]);
}
#line 39 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 40 "inform7/Chapter 16/Verbal and Relative Clauses.w"
#line 52 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_existential_np_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = ParseTree__new(UNKNOWN_VNT);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 54 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_existential_verb_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = SParser__Subtrees__verb_marker(RP[1], NULL, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 57 "inform7/Chapter 16/Verbal and Relative Clauses.w"
#line 105 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_general_verb_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = SParser__Subtrees__verb_marker(RP[1], RP[2], meaning_of_player);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = SParser__Subtrees__verb_marker(RP[1], RP[2], RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = SParser__Subtrees__verb_marker(RP[1], NULL, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = SParser__Subtrees__verb_marker(RP[1], NULL, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = SParser__Subtrees__verb_marker(RP[1], NULL, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 111 "inform7/Chapter 16/Verbal and Relative Clauses.w"
#line 117 "inform7/Chapter 16/Verbal and Relative Clauses.w"
parse_node *SParser__Subtrees__verb_marker(verb_usage *vu, preposition_usage *pu, parse_node *np) {
parse_node *VP_part = ParseTree__new(UNKNOWN_VNT);
ParseTree__set_vu(VP_part, vu);
ParseTree__set_pu(VP_part, pu);
VP_part->down = np;
return VP_part;
}
#line 136 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_universal_relation_term_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = SParser__val(Rvalues__from_pair(RP[1], RP[2]), W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 138 "inform7/Chapter 16/Verbal and Relative Clauses.w"
#line 158 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_np_with_relative_clause_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 176 "inform7/Chapter 16/Verbal and Relative Clauses.w"
LOGIF(MATCHING, "So uncorrectedly RP[1] = $T\n", RP[1]);
LOGIF(MATCHING, "and uncorrectedly RP[2] = $T\n", RP[2]);
SParser__Subtrees__correct_for_adjectives(RP[1], RP[2]);
*XP = SParser__Subtrees__to_specification(FALSE, W, RP[1], RP[2]);
}
#line 159 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 176 "inform7/Chapter 16/Verbal and Relative Clauses.w"
LOGIF(MATCHING, "So uncorrectedly RP[1] = $T\n", RP[1]);
LOGIF(MATCHING, "and uncorrectedly RP[2] = $T\n", RP[2]);
SParser__Subtrees__correct_for_adjectives(RP[1], RP[2]);
*XP = SParser__Subtrees__to_specification(FALSE, W, RP[1], RP[2]);
}
#line 160 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 161 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_implied_relative_verb_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = SParser__Subtrees__verb_marker(regular_to_be, RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = SParser__Subtrees__verb_marker(negated_to_be, RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 165 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_relative_verb_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = SParser__Subtrees__verb_marker(RP[2], RP[3], meaning_of_player);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = SParser__Subtrees__verb_marker(RP[2], RP[3], RP[4]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = SParser__Subtrees__verb_marker(RP[2], NULL, RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = SParser__Subtrees__verb_marker(RP[2], NULL, RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = SParser__Subtrees__verb_marker(RP[2], NULL, RP[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 172 "inform7/Chapter 16/Verbal and Relative Clauses.w"
#line 187 "inform7/Chapter 16/Verbal and Relative Clauses.w"
void SParser__Subtrees__correct_for_adjectives(parse_node *A, parse_node *B) {
parse_node *subject_phrase_subtree, *object_phrase_subtree, *verb_phrase_subtree;
if (A == NULL) internal_error("SV childless");
subject_phrase_subtree = A;
verb_phrase_subtree = B;
if (verb_phrase_subtree->down == NULL)
internal_error("SV childless");
object_phrase_subtree = verb_phrase_subtree->down;
{
#line 206 "inform7/Chapter 16/Verbal and Relative Clauses.w"
if ((Rvalues__to_instance(object_phrase_subtree)) &&
(subject_phrase_subtree) &&
(Specifications__is_description_like(subject_phrase_subtree))) {
parse_node *adjq = object_phrase_subtree;
instance *I = Rvalues__to_instance(adjq);
if (Instances__get_adjectival_phrase(I)) {
adjective_usage *ale = Adjectives__Usages__new(Instances__get_adjectival_phrase(I), TRUE);
parse_node *spec = Descriptions__from_proposition(NULL, ParseTree__get_text(adjq));
Descriptions__add_to_adjective_list(ale, spec);
verb_phrase_subtree->down = spec;
}
}
}
#line 199 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
}
#line 233 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_purely_physical_description_NTMR(wording W, int *X, void **XP) {
#line 234 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s = force_all_SP_noun_phrases_to_be_physical;
force_all_SP_noun_phrases_to_be_physical = TRUE;
parse_node *p = NULL;
if (Preform__parse_nt_against_word_range(s_description_NTM, W, NULL, NULL)) p = most_recent_result_p;
force_all_SP_noun_phrases_to_be_physical = s;
if (p) { *XP = p; return TRUE; }
return FALSE;
}
int if_forced_physical_NTMR(wording W, int *X, void **XP) {
#line 244 "inform7/Chapter 16/Verbal and Relative Clauses.w"
if (force_all_SP_noun_phrases_to_be_physical) return TRUE;
return FALSE;
}
#line 254 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_noun_phrase_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 258 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_noun_phrase_nounless_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 263 "inform7/Chapter 16/Verbal and Relative Clauses.w"
#line 268 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int s_descriptive_np_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 281 "inform7/Chapter 16/Verbal and Relative Clauses.w"
return FAIL_NONTERMINAL;
}
#line 270 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 286 "inform7/Chapter 16/Verbal and Relative Clauses.w"
parse_node *sn = RP[1];
if (ParseTree__int_annotation(sn, converted_SN_ANNOT)) {
*XP = sn;
} else {
*XP = SParser__Subtrees__to_specification(FALSE, W, RP[1], NULL);
}
parse_node *pn = *XP;
ParseTree__set_text(pn, W);
}
#line 271 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 286 "inform7/Chapter 16/Verbal and Relative Clauses.w"
parse_node *sn = RP[1];
if (ParseTree__int_annotation(sn, converted_SN_ANNOT)) {
*XP = sn;
} else {
*XP = SParser__Subtrees__to_specification(FALSE, W, RP[1], NULL);
}
parse_node *pn = *XP;
ParseTree__set_text(pn, W);
}
#line 272 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 273 "inform7/Chapter 16/Verbal and Relative Clauses.w"
#line 301 "inform7/Chapter 16/Verbal and Relative Clauses.w"
parse_node *PM_DescLocalPast_location = NULL;
parse_node *SParser__Subtrees__to_specification(int SV_not_SN, wording W, parse_node *A, parse_node *B) {
parse_node *R = SParser__Subtrees__to_specification_inner(SV_not_SN, W, A, B);
return R;
}
parse_node *SParser__Subtrees__to_specification_inner(int SV_not_SN, wording W, parse_node *A, parse_node *B) {
parse_node *spec;
parse_node *subject_noun_phrase = NULL, *verb_phrase = NULL;
verb_usage *vu = NULL; preposition_usage *pu = NULL;
int verb_phrase_negated = FALSE;
if (ParseTree__is(A, AMBIGUITY_NT)) {
parse_node *amb = NULL;
for (parse_node *poss = A->down; poss; poss = poss->next_alternative) {
parse_node *one = ParseTree__duplicate(poss);
one->next_alternative = NULL;
parse_node *new_poss = SParser__Subtrees__to_specification(SV_not_SN, W, one, B);
if (!(ParseTree__is(new_poss, UNKNOWN_VNT)))
amb = ParseTree__add_possible_reading(amb, new_poss, W);
}
if (amb == NULL) amb = Specifications__new_UNKNOWN(W);
return amb;
}
if ((B) && (B->down) && (ParseTree__is(B->down, AMBIGUITY_NT))) {
parse_node *amb = NULL;
for (parse_node *poss = B->down->down; poss; poss = poss->next_alternative) {
parse_node *hmm = ParseTree__duplicate(B);
hmm->down = ParseTree__duplicate(poss);
hmm->down->next_alternative = NULL;
parse_node *new_poss = SParser__Subtrees__to_specification(SV_not_SN, W, A, hmm);
if (!(ParseTree__is(new_poss, UNKNOWN_VNT)))
amb = ParseTree__add_possible_reading(amb, new_poss, W);
}
if (amb == NULL) amb = Specifications__new_UNKNOWN(W);
return amb;
}
{
#line 355 "inform7/Chapter 16/Verbal and Relative Clauses.w"
if ((A) && (B == NULL)) {
B = SParser__Subtrees__verb_marker(regular_to_be, NULL, A);
A = ParseTree__new(UNKNOWN_VNT);
SV_not_SN = TRUE;
SParser__Subtrees__correct_for_adjectives(A, B);
}
}
#line 338 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
{
#line 366 "inform7/Chapter 16/Verbal and Relative Clauses.w"
subject_noun_phrase = A;
verb_phrase = B;
if (verb_phrase->down == NULL) Problems__Issue__s_subtree_error("VP childless");
if (ParseTree__get_type(verb_phrase) != UNKNOWN_VNT)
Problems__Issue__s_subtree_error("VP not a VP");
vu = ParseTree__get_vu(verb_phrase);
if (vu == NULL) Problems__Issue__s_subtree_error("verb null");
pu = ParseTree__get_pu(verb_phrase);
verb_phrase_negated = (Verbs__is_used_negatively(vu))?TRUE:FALSE;
if ((pu) && (Prepositions__implicitly_negates(pu)))
verb_phrase_negated = (verb_phrase_negated)?FALSE:TRUE;
}
#line 339 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
pcalc_term *subj = CREATE(pcalc_term);
*subj = Calculus__Terms__new_constant(NULL);
if (SV_not_SN)
{
#line 401 "inform7/Chapter 16/Verbal and Relative Clauses.w"
int pass = verb_phrase_negated, explicit_negation = FALSE;
if ((Verbs__is_used_negatively(vu)) && (Verbs__get_tense_used(vu) != IS_TENSE)) {
explicit_negation = TRUE; pass = FALSE;
}
spec = Conditions__new_TEST_PROPOSITION(
Calculus__Propositions__FromSentences__S_subtree(TRUE, W, A, B, subj, pass));
ParseTree__set_subject_term(spec, subj);
if (Wordings__nonempty(W)) ParseTree__set_text(spec, W);
if (Verbs__get_tense_used(vu) != IS_TENSE) {
if (Calculus__Variables__detect_locals(Specifications__to_proposition(spec), NULL) > 0)
{
#line 421 "inform7/Chapter 16/Verbal and Relative Clauses.w"
if (PM_DescLocalPast_location != current_sentence)
Problems__Issue__sentence_problem(_p_(PM_DescLocalPast),
"conditions written in the past tense cannot refer to "
"temporary values",
"because they have no past. For instance, the name given in a "
"'repeat...' can't be talked about as having existed before, and "
"similarly the pronoun 'it' changes its meaning often, so we can't "
"safely talk about 'it' in the past.");
PM_DescLocalPast_location = current_sentence;
}
#line 412 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
spec = Conditions__attach_tense(spec, Verbs__get_tense_used(vu));
}
if (explicit_negation)
spec = Conditions__negate(spec);
}
#line 344 "inform7/Chapter 16/Verbal and Relative Clauses.w"
else
{
#line 434 "inform7/Chapter 16/Verbal and Relative Clauses.w"
spec = Descriptions__from_proposition(
Calculus__Propositions__FromSentences__S_subtree(FALSE, W, A, B, subj, verb_phrase_negated), W);
ParseTree__set_subject_term(spec, subj);
ParseTree__annotate_int(spec, converted_SN_ANNOT, TRUE);
if (A)
{
#line 446 "inform7/Chapter 16/Verbal and Relative Clauses.w"
if (!((ParseTree__is(A, CONSTANT_VNT)) ||
(Specifications__is_description(A)) ||
(Lvalues__get_storage_form(A) == LOCAL_VARIABLE_VNT) ||
(Lvalues__get_storage_form(A) == NONLOCAL_VARIABLE_VNT)))
return Specifications__new_UNKNOWN(W);
}
#line 438 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
if (Verbs__get_tense_used(vu) != IS_TENSE) SParser__Subtrees__throw_past_problem(TRUE);
}
#line 345 "inform7/Chapter 16/Verbal and Relative Clauses.w"
;
return spec;
}
#line 455 "inform7/Chapter 16/Verbal and Relative Clauses.w"
void SParser__Subtrees__throw_past_problem(int desc) {
if (PM_PastSubordinate_issued_at != current_sentence) {
PM_PastSubordinate_issued_at = current_sentence;
Problems__Issue__sentence_problem(_p_(PM_PastSubordinate),
"subordinate clauses have to be in the present tense",
"so 'the Black Door was open' is fine, but not 'something which "
"was open'. Only the main verb can be in the past tense.");
}
}
#line 23 "inform7/Chapter 16/Conditions and Phrases.w"
int s_condition_uncached_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 26 "inform7/Chapter 16/Conditions and Phrases.w"
#line 32 "inform7/Chapter 16/Conditions and Phrases.w"
int s_condition_pure_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Conditions__new_LOGICAL_AND(RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = Conditions__new_LOGICAL_AND(RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = Conditions__new_LOGICAL_OR(RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = Conditions__new_LOGICAL_OR(RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 40 "inform7/Chapter 16/Conditions and Phrases.w"
#line 54 "inform7/Chapter 16/Conditions and Phrases.w"
int s_condition_with_chronology_NTMR(wording W, int *X, void **XP) {
#line 55 "inform7/Chapter 16/Conditions and Phrases.w"
time_period tp = TimePeriods__parse(W);
int end_of_non_time_part = TimePeriods__is_valid(&tp);
if ((end_of_non_time_part >= Wordings__first_wn(W)) &&
(Preform__parse_nt_against_word_range(s_condition_atomic_NTM, Wordings__up_to(W, end_of_non_time_part), NULL, NULL))) {
parse_node *atomic_cnd = most_recent_result_p;
parse_node *spec = atomic_cnd;
if (ParseTree__is(spec, CONSTANT_VNT)) {
action_pattern *ap = Rvalues__to_action_pattern(spec);
spec = Conditions__new_TEST_ACTION(ap, W);
}
*XP = Conditions__attach_historic_requirement(spec,
TimePeriods__store(tp));
return TRUE;
}
return FALSE;
}
#line 104 "inform7/Chapter 16/Conditions and Phrases.w"
int s_condition_atomic_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Conditions__negate(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = Conditions__negate(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = Conditions__negate(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 114 "inform7/Chapter 16/Conditions and Phrases.w"
#line 124 "inform7/Chapter 16/Conditions and Phrases.w"
int s_nonexistential_phrase_to_decide_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = NULL; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = Conditions__negate(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 128 "inform7/Chapter 16/Conditions and Phrases.w"
int s_existential_phrase_to_decide_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = NULL; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = Conditions__negate(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 133 "inform7/Chapter 16/Conditions and Phrases.w"
int existential_verb_phrase_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 136 "inform7/Chapter 16/Conditions and Phrases.w"
int s_phrase_to_decide_NTMR(wording W, int *X, void **XP) {
#line 138 "inform7/Chapter 16/Conditions and Phrases.w"
parse_node *p = SParser__parse_excerpt(COND_PHRASE_MC, W);
if (p) {
parse_node *spec = ParseTree__new_with_words(PHRASE_TO_DECIDE_VALUE_VNT, W);
SParser__add_ilist(spec, p);
parse_node *tval = ParseTree__new_with_words(TEST_VALUE_VNT, W);
tval->down = spec;
*XP = tval; return TRUE;
}
return FALSE;
}
#line 153 "inform7/Chapter 16/Conditions and Phrases.w"
int s_phrase_option_in_use_NTMR(wording W, int *X, void **XP) {
#line 154 "inform7/Chapter 16/Conditions and Phrases.w"
if (phrase_being_compiled) {
int i = Routines__ToPhrases__parse_phrase_option_used(phrase_being_compiled, W);
if (i >= 0) {
*XP = Conditions__new_TEST_PHRASE_OPTION(i);
return TRUE;
}
}
return FALSE;
}
#line 172 "inform7/Chapter 16/Conditions and Phrases.w"
int s_action_pattern_as_condition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Conditions__new_TEST_ACTION(RP[1], W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 174 "inform7/Chapter 16/Conditions and Phrases.w"
int s_action_pattern_as_negated_condition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Conditions__new_TEST_ACTION(RP[1], W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 177 "inform7/Chapter 16/Conditions and Phrases.w"
#line 181 "inform7/Chapter 16/Conditions and Phrases.w"
int s_past_action_pattern_as_condition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 190 "inform7/Chapter 16/Conditions and Phrases.w"
action_pattern *ap = RP[1];
if (PL__Actions__Patterns__makes_callings(ap)) {
Problems__Issue__sentence_problem(_p_(PM_PastActionCalled),
"a description of an action cannot both refer to past "
"history and also use '(called ...)'",
"because that would require Inform in general to remember "
"too much information about past events.");
return FALSE;
}
*XP = Conditions__new_TEST_ACTION(ap, W);
*XP = Conditions__attach_tense(*XP, HASBEEN_TENSE);
}
#line 182 "inform7/Chapter 16/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 183 "inform7/Chapter 16/Conditions and Phrases.w"
int s_past_action_pattern_as_negated_condition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 190 "inform7/Chapter 16/Conditions and Phrases.w"
action_pattern *ap = RP[1];
if (PL__Actions__Patterns__makes_callings(ap)) {
Problems__Issue__sentence_problem(_p_(PM_PastActionCalled),
"a description of an action cannot both refer to past "
"history and also use '(called ...)'",
"because that would require Inform in general to remember "
"too much information about past events.");
return FALSE;
}
*XP = Conditions__new_TEST_ACTION(ap, W);
*XP = Conditions__attach_tense(*XP, HASBEEN_TENSE);
}
#line 185 "inform7/Chapter 16/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 186 "inform7/Chapter 16/Conditions and Phrases.w"
#line 215 "inform7/Chapter 16/Conditions and Phrases.w"
int s_command_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 218 "inform7/Chapter 16/Conditions and Phrases.w"
int s_say_command_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 222 "inform7/Chapter 16/Conditions and Phrases.w"
#line 226 "inform7/Chapter 16/Conditions and Phrases.w"
int s_to_phrase_NTMR(wording W, int *X, void **XP) {
#line 227 "inform7/Chapter 16/Conditions and Phrases.w"
parse_node *p = SParser__parse_excerpt(VOID_PHRASE_MC, W);
if (p) {
parse_node *spec = ParseTree__new_with_words(PHRASE_TO_DECIDE_VALUE_VNT, W);
SParser__add_ilist(spec, p);
*XP = spec; return TRUE;
}
return FALSE;
}
#line 239 "inform7/Chapter 16/Conditions and Phrases.w"
int s_say_phrase_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = SParser__say_verb(RP[1], R[1], NULL, W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = SParser__say_adjective(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = SParser__say_verb(RP[1], R[1], NULL, W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 261 "inform7/Chapter 16/Conditions and Phrases.w"
int neg = FALSE;
if ((R[1]) || (R[2])) neg = TRUE;
*XP = SParser__say_verb(RP[2], neg, RP[1], W);
}
#line 243 "inform7/Chapter 16/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 261 "inform7/Chapter 16/Conditions and Phrases.w"
int neg = FALSE;
if ((R[1]) || (R[2])) neg = TRUE;
*XP = SParser__say_verb(RP[2], neg, RP[1], W);
}
#line 244 "inform7/Chapter 16/Conditions and Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = SParser__say_adjective(RP[1], W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 247 "inform7/Chapter 16/Conditions and Phrases.w"
int s_text_substitution_NTMR(wording W, int *X, void **XP) {
#line 249 "inform7/Chapter 16/Conditions and Phrases.w"
parse_node *p = SParser__parse_excerpt(SAY_PHRASE_MC, W);
if (p) {
parse_node *spec = ParseTree__new_with_words(PHRASE_TO_DECIDE_VALUE_VNT, W);
SParser__add_ilist(spec, p);
*XP = spec; return TRUE;
}
return FALSE;
}
#line 269 "inform7/Chapter 16/Conditions and Phrases.w"
parse_node *SParser__say_adjective(adjectival_phrase *aph, wording W) {
parse_node *spec = ParseTree__new_with_words(PHRASE_TO_DECIDE_VALUE_VNT, W);
parse_node *inv = Invocations__new();
Invocations__set_word_range(inv, W);
Invocations__set_adjectival_phrase(inv, aph);
spec->down = ParseTree__new(INVOCATION_LIST_NT);
spec->down->down = Invocations__add_to_list(spec->down->down, inv);
return spec;
}
#line 283 "inform7/Chapter 16/Conditions and Phrases.w"
parse_node *SParser__say_verb(verb_conjugation *vc, int neg, verb_conjugation *mvc, wording W) {
parse_node *spec = ParseTree__new_with_words(PHRASE_TO_DECIDE_VALUE_VNT, W);
parse_node *inv = Invocations__new();
Invocations__set_word_range(inv, W);
Invocations__set_verb_conjugation(inv, vc, mvc, neg);
spec->down = ParseTree__new(INVOCATION_LIST_NT);
spec->down->down = Invocations__add_to_list(spec->down->down, inv);
return spec;
}
#line 306 "inform7/Chapter 16/Conditions and Phrases.w"
void SParser__add_ilist(parse_node *spec, parse_node *p) {
{
#line 320 "inform7/Chapter 16/Conditions and Phrases.w"
for (; p; p = p->next_alternative) {
phrase *ph = RETRIEVE_POINTER_phrase(
Semantics__Nouns__ExcerptMeanings__data(ParseTree__get_meaning(p)));
parse_node *inv = Phrases__Parser__parse_against(ph, p);
if ((Phrases__TypeData__is_the_primordial_say(&(ph->type_data)) == FALSE) &&
(Rvalues__is_CONSTANT_of_kind(
Invocations__get_token_as_parsed(inv, 0), K_text)))
continue;
if (spec->down == NULL) {
spec->down = ParseTree__new(INVOCATION_LIST_NT);
ParseTree__set_text(spec->down, ParseTree__get_text(spec));
}
spec->down->down = Invocations__add_to_list(spec->down->down, inv);
}
}
#line 307 "inform7/Chapter 16/Conditions and Phrases.w"
;
int len = Invocations__length_of_list(spec->down->down);
if (len >= MAX_INVOCATIONS_PER_PHRASE)
{
#line 343 "inform7/Chapter 16/Conditions and Phrases.w"
spec->down->down->next = NULL; /* truncate to just one */
ParseTree__set_text(spec, ParseTree__get_text(current_sentence));
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"In %1, the phrase being constructed is just too "
"long and complicated, and will need to be simplified. (This "
"sometimes happens with a 'say', or a piece of text, containing "
"many text substitutions in succession: if so, it may be worth "
"defining some more powerful text substitutions - for instance "
"writing 'To say super-duper: ...', giving the gory details, "
"and then using the single substitution '[super-duper]' in the "
"original phrase.");
Problems__issue_problem_end();
}
#line 311 "inform7/Chapter 16/Conditions and Phrases.w"
else if (len > 0)
spec->down->down = Invocations__sort_list(spec->down->down);
}
#line 73 "inform7/Chapter 17/Terms.w"
pcalc_term Calculus__Terms__new_variable(int v) {
pcalc_term pt;
{
#line 97 "inform7/Chapter 17/Terms.w"
pt.variable = -1;
pt.constant = NULL;
pt.function = NULL;
pt.cinder = -1; /* that is, no cinder */
pt.term_checked_as_kind = NULL;
}
#line 74 "inform7/Chapter 17/Terms.w"
;
if ((v < 0) || (v >= 26)) internal_error("bad variable term created");
pt.variable = v;
return pt;
}
pcalc_term Calculus__Terms__new_constant(parse_node *c) {
pcalc_term pt;
{
#line 97 "inform7/Chapter 17/Terms.w"
pt.variable = -1;
pt.constant = NULL;
pt.function = NULL;
pt.cinder = -1; /* that is, no cinder */
pt.term_checked_as_kind = NULL;
}
#line 81 "inform7/Chapter 17/Terms.w"
;
pt.constant = c;
return pt;
}
pcalc_term Calculus__Terms__new_function(binary_predicate *bp, pcalc_term ptof, int t) {
pcalc_term pt;
{
#line 97 "inform7/Chapter 17/Terms.w"
pt.variable = -1;
pt.constant = NULL;
pt.function = NULL;
pt.cinder = -1; /* that is, no cinder */
pt.term_checked_as_kind = NULL;
}
#line 87 "inform7/Chapter 17/Terms.w"
;
pcalc_func *pf = CREATE(pcalc_func);
pf->bp = bp; pf->fn_of = ptof; pf->from_term = t;
pt.function = pf;
return pt;
}
#line 106 "inform7/Chapter 17/Terms.w"
pcalc_term Calculus__Terms__copy(pcalc_term pt) {
if (pt.constant) pt.constant = ParseTree__duplicate(pt.constant);
if (pt.function) pt = Calculus__Terms__new_function(pt.function->bp,
Calculus__Terms__copy(pt.function->fn_of), pt.function->from_term);
return pt;
}
#line 133 "inform7/Chapter 17/Terms.w"
char *pcalc_vars = "xyzabcdefghijklmnopqrstuvw";
#line 140 "inform7/Chapter 17/Terms.w"
parse_node *Calculus__Terms__constant_underlying(pcalc_term *t) {
if (t == NULL) internal_error("null term");
if (t->constant) return t->constant;
if (t->function) return Calculus__Terms__constant_underlying(&(t->function->fn_of));
return NULL;
}
int Calculus__Terms__variable_underlying(pcalc_term *t) {
if (t == NULL) internal_error("null term");
if (t->variable >= 0) return t->variable;
if (t->function) return Calculus__Terms__variable_underlying(&(t->function->fn_of));
return -1;
}
#line 166 "inform7/Chapter 17/Terms.w"
pcalc_term Calculus__Terms__adj_to_noun_conversion(adjective_usage *tr) {
adjectival_phrase *aph = Adjectives__Usages__get_aph(tr);
instance *I = Adjectives__Phrases__has_ENUMERATIVE_meaning(aph);
if (I) return Calculus__Terms__new_constant(Rvalues__from_instance(I));
property *prn = Adjectives__Phrases__has_EORP_meaning(aph, NULL);
if (prn) return Calculus__Terms__new_constant(Rvalues__from_property(prn));
return Calculus__Terms__new_variable(0);
}
#line 178 "inform7/Chapter 17/Terms.w"
adjective_usage *Calculus__Terms__noun_to_adj_conversion(pcalc_term pt) {
kind *K;
adjectival_phrase *aph;
parse_node *spec = pt.constant;
if (ParseTree__is(spec, CONSTANT_VNT) == FALSE) return NULL;
K = ParseTree__get_kind_of_value(spec);
if (Kinds__Behaviour__get_coinciding_property(K) == NULL) return NULL;
if (Kinds__Behaviour__is_an_enumeration(K)) {
instance *I = ParseTree__get_constant_instance(spec);
aph = Instances__get_adjectival_phrase(I);
return Adjectives__Usages__new(aph, TRUE);
}
return NULL;
}
#line 211 "inform7/Chapter 17/Terms.w"
void Calculus__Terms__compile(OUTPUT_STREAM, pcalc_term pt) {
if (logging_to_I6_text) { Calculus__Terms__log(&pt); return; }
if (pt.variable >= 0) {
WRITE("%c", pcalc_vars[pt.variable]);
return;
}
if (pt.constant) {
if (pt.cinder >= 0) {
Calculus__Deferrals__Cinders__compile(OUT, pt.cinder);
} else {
if (ParseTree__is_phrasal(pt.constant))
Dash__check_value(pt.constant, NULL);
Specifications__Compiler__compile(OUT, pt.constant);
}
return;
}
if (pt.function) {
i6_schema *fn;
binary_predicate *bp = (pt.function)->bp;
fn = BinaryPredicates__get_term_as_function_of_other(bp, 0);
if (fn == NULL) fn = BinaryPredicates__get_term_as_function_of_other(bp, 1);
if (fn == NULL) internal_error("Function of non-functional predicate");
Calculus__Schemas__expand(fn, OUT, &(pt.function->fn_of), NULL);
return;
}
internal_error("Broken pcalc term");
}
#line 245 "inform7/Chapter 17/Terms.w"
void Calculus__Terms__log(pcalc_term *pt) {
if (pt == NULL) {
LOG("<null-term>");
} else if (pt->constant) {
parse_node *spec = pt->constant;
if (pt->cinder >= 0) { LOG("const_%d", pt->cinder); return; }
if (Wordings__nonempty(ParseTree__get_text(spec))) { LOG("'$w'", ParseTree__get_text(spec)); return; }
if (ParseTree__is(spec, CONSTANT_VNT)) {
instance *I = Rvalues__to_object_instance(spec);
if (I) { LOG("$O", I); return; }
}
LOG("$P", spec);
} else if (pt->function) {
binary_predicate *bp = pt->function->bp;
i6_schema *fn = BinaryPredicates__get_term_as_function_of_other(bp, 0);
if (fn == NULL) fn = BinaryPredicates__get_term_as_function_of_other(bp, 1);
if (fn == NULL) internal_error("Function of non-functional predicate");
if (logging_to_I6_text) {
Calculus__Schemas__log_applied(fn, &(pt->function->fn_of));
} else {
LOG("{$i:$0}", fn, &(pt->function->fn_of));
}
} else if (pt->variable >= 0) {
int j = pt->variable;
if (j<26) LOG("%c", pcalc_vars[j]); else LOG("<bad-var=%d>", j);
} else {
LOG("<bad-term>");
}
}
#line 75 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__element_get_group(int element) {
if (element <= 0) return 0;
if (element < STRUCTURAL_GROUP) return STRUCTURAL_GROUP;
if (element < PREDICATES_GROUP) return PREDICATES_GROUP;
if (element < OPEN_OPERATORS_GROUP) return OPEN_OPERATORS_GROUP;
if (element < CLOSE_OPERATORS_GROUP) return CLOSE_OPERATORS_GROUP;
return 0;
}
#line 89 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__element_get_match(int element) {
switch (element) {
case NEGATION_OPEN_ATOM: return NEGATION_CLOSE_ATOM;
case NEGATION_CLOSE_ATOM: return NEGATION_OPEN_ATOM;
case DOMAIN_OPEN_ATOM: return DOMAIN_CLOSE_ATOM;
case DOMAIN_CLOSE_ATOM: return DOMAIN_OPEN_ATOM;
default: return 0;
}
}
#line 103 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__new(int element) {
pcalc_prop *prop = CREATE(pcalc_prop);
prop->next = NULL;
prop->element = element;
prop->assert_kind = NULL;
prop->composited = FALSE;
prop->unarticled = FALSE;
prop->arity = 0;
prop->predicate = NULL_GENERAL_POINTER;
return prop;
}
#line 135 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__QUANTIFIER_new(quantifier *quant, int v, int parameter) {
pcalc_prop *prop = Calculus__Atoms__new(QUANTIFIER_ATOM);
prop->arity = 1;
prop->terms[0] = Calculus__Terms__new_variable(v);
prop->predicate = STORE_POINTER_quantifier(quant);
prop->quantification_parameter = parameter;
return prop;
}
#line 147 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_quantifier(pcalc_prop *prop) {
if ((prop) && (prop->element == QUANTIFIER_ATOM)) return TRUE;
return FALSE;
}
quantifier *Calculus__Atoms__get_quantifier(pcalc_prop *prop) {
if ((prop) && (prop->element == QUANTIFIER_ATOM))
return RETRIEVE_POINTER_quantifier(prop->predicate);
return NULL;
}
int Calculus__Atoms__get_quantification_parameter(pcalc_prop *prop) {
if ((prop) && (prop->element == QUANTIFIER_ATOM))
return prop->quantification_parameter;
return 0;
}
int Calculus__Atoms__is_existence_quantifier(pcalc_prop *prop) {
if ((prop) && (prop->element == QUANTIFIER_ATOM) &&
(RETRIEVE_POINTER_quantifier(prop->predicate) == exists_quantifier))
return TRUE;
return FALSE;
}
int Calculus__Atoms__is_nonexistence_quantifier(pcalc_prop *prop) {
if ((prop) && (prop->element == QUANTIFIER_ATOM) &&
(RETRIEVE_POINTER_quantifier(prop->predicate) == not_exists_quantifier))
return TRUE;
return FALSE;
}
int Calculus__Atoms__is_forall_quantifier(pcalc_prop *prop) {
if ((prop) && (prop->element == QUANTIFIER_ATOM) &&
(RETRIEVE_POINTER_quantifier(prop->predicate) == for_all_quantifier))
return TRUE;
return FALSE;
}
int Calculus__Atoms__is_notall_quantifier(pcalc_prop *prop) {
if ((prop) && (prop->element == QUANTIFIER_ATOM) &&
(RETRIEVE_POINTER_quantifier(prop->predicate) == not_for_all_quantifier))
return TRUE;
return FALSE;
}
int Calculus__Atoms__is_for_all_x(pcalc_prop *prop) {
if ((Calculus__Atoms__is_forall_quantifier(prop)) && (prop->terms[0].variable == 0)) return TRUE;
return FALSE;
}
#line 200 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_now_assertable_quantifier(pcalc_prop *prop) {
if (prop->element != QUANTIFIER_ATOM) return FALSE;
return Quantifiers__is_now_assertable(RETRIEVE_POINTER_quantifier(prop->predicate));
}
#line 209 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__EVERYWHERE_new(pcalc_term pt) {
pcalc_prop *prop = Calculus__Atoms__new(EVERYWHERE_ATOM);
prop->arity = 1;
prop->terms[0] = pt;
return prop;
}
#line 219 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__NOWHERE_new(pcalc_term pt) {
pcalc_prop *prop = Calculus__Atoms__new(NOWHERE_ATOM);
prop->arity = 1;
prop->terms[0] = pt;
return prop;
}
#line 229 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__HERE_new(pcalc_term pt) {
pcalc_prop *prop = Calculus__Atoms__new(HERE_ATOM);
prop->arity = 1;
prop->terms[0] = pt;
return prop;
}
#line 239 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__ISAKIND_new(pcalc_term pt, kind *K) {
pcalc_prop *prop = Calculus__Atoms__new(ISAKIND_ATOM);
prop->arity = 1;
prop->terms[0] = pt;
prop->assert_kind = K;
return prop;
}
#line 250 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__ISAVAR_new(pcalc_term pt) {
pcalc_prop *prop = Calculus__Atoms__new(ISAVAR_ATOM);
prop->arity = 1;
prop->terms[0] = pt;
return prop;
}
#line 260 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__ISACONST_new(pcalc_term pt) {
pcalc_prop *prop = Calculus__Atoms__new(ISACONST_ATOM);
prop->arity = 1;
prop->terms[0] = pt;
return prop;
}
#line 282 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__CALLED_new(wording W, pcalc_term pt, kind *K) {
pcalc_prop *prop = Calculus__Atoms__new(CALLED_ATOM);
prop->arity = 1;
prop->terms[0] = pt;
prop->calling_name = W;
prop->assert_kind = K;
return prop;
}
wording Calculus__Atoms__CALLED_get_name(pcalc_prop *prop) {
return prop->calling_name;
}
#line 320 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__KIND_new(kind *K, pcalc_term pt) {
pcalc_prop *prop = Calculus__Atoms__new(KIND_ATOM);
prop->arity = 1;
prop->assert_kind = K;
prop->terms[0] = pt;
return prop;
}
pcalc_prop *Calculus__Atoms__KIND_new_composited(kind *K, pcalc_term pt) {
pcalc_prop *prop = Calculus__Atoms__new(KIND_ATOM);
prop->arity = 1;
prop->assert_kind = K;
prop->terms[0] = pt;
prop->composited = TRUE;
return prop;
}
kind *Calculus__Atoms__get_asserted_kind(pcalc_prop *prop) {
if (prop) return prop->assert_kind;
return NULL;
}
int Calculus__Atoms__is_composited(pcalc_prop *prop) {
if ((prop) && (prop->composited)) return TRUE;
return FALSE;
}
void Calculus__Atoms__set_composited(pcalc_prop *prop, int state) {
if (prop) prop->composited = state;
}
#line 354 "inform7/Chapter 17/Atomic Propositions.w"
int Calculus__Atoms__is_unarticled(pcalc_prop *prop) {
if ((prop) && (prop->unarticled)) return TRUE;
return FALSE;
}
void Calculus__Atoms__set_unarticled(pcalc_prop *prop, int state) {
if (prop) prop->unarticled = state;
}
#line 368 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__unary_PREDICATE_from_aph(adjectival_phrase *aph, int negated) {
pcalc_prop *prop = Calculus__Atoms__new(PREDICATE_ATOM);
prop->arity = 1;
prop->terms[0] = Calculus__Terms__new_variable(0);
prop->predicate = STORE_POINTER_adjective_usage(
Adjectives__Usages__new(aph, (negated)?FALSE:TRUE));
return prop;
}
adjective_usage *Calculus__Atoms__au_from_unary_PREDICATE(pcalc_prop *prop) {
return RETRIEVE_POINTER_adjective_usage(prop->predicate);
}
#line 384 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__binary_PREDICATE_new(binary_predicate *bp,
pcalc_term pt1, pcalc_term pt2) {
pcalc_prop *prop = Calculus__Atoms__new(PREDICATE_ATOM);
prop->arity = 2;
prop->predicate = STORE_POINTER_binary_predicate(bp);
prop->terms[0] = pt1; prop->terms[1] = pt2;
return prop;
}
binary_predicate *Calculus__Atoms__is_binary_predicate(pcalc_prop *prop) {
if (prop == NULL) return NULL;
if (prop->element != PREDICATE_ATOM) return NULL;
if (prop->arity != 2) return NULL;
return RETRIEVE_POINTER_binary_predicate(prop->predicate);
}
int Calculus__Atoms__is_equality_predicate(pcalc_prop *prop) {
binary_predicate *bp = Calculus__Atoms__is_binary_predicate(prop);
if (bp == R_equality) return TRUE;
return FALSE;
}
#line 409 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_prop *Calculus__Atoms__prop_x_is_constant(parse_node *spec) {
return Calculus__Atoms__binary_PREDICATE_new(R_equality,
Calculus__Terms__new_variable(0), Calculus__Terms__new_constant(spec));
}
#line 417 "inform7/Chapter 17/Atomic Propositions.w"
pcalc_term *Calculus__Atoms__is_x_equals(pcalc_prop *prop) {
if (Calculus__Atoms__is_equality_predicate(prop) == FALSE) return NULL;
if (prop->terms[0].variable != 0) return NULL;
return &(prop->terms[1]);
}
#line 426 "inform7/Chapter 17/Atomic Propositions.w"
char *Calculus__Atoms__validate(pcalc_prop *prop) {
int group;
if (prop == NULL) return NULL;
group = Calculus__Atoms__element_get_group(prop->element);
if (group == 0) return "atom of undiscovered element";
if (prop->arity > MAX_ATOM_ARITY) return "atom with overly large arity";
if (prop->arity < 0) return "atom with negative arity";
if (prop->arity == 0) {
if (group == PREDICATES_GROUP) return "predicate without terms";
if (prop->element == QUANTIFIER_ATOM) return "quantifier without variable";
} else {
if ((prop->element != PREDICATE_ATOM) && (prop->arity != 1))
return "unary atom with other than one term";
if ((group == OPEN_OPERATORS_GROUP) || (group == CLOSE_OPERATORS_GROUP))
return "parentheses with terms";
}
if ((prop->element == QUANTIFIER_ATOM) && (prop->terms[0].variable == -1))
return "missing variable in quantification";
return NULL;
}
#line 451 "inform7/Chapter 17/Atomic Propositions.w"
void Calculus__Atoms__log(pcalc_prop *prop) {
if (prop == NULL) { LOG("<null-atom>"); return; }
switch(prop->element) {
case PREDICATE_ATOM:
switch(prop->arity) {
case 1:
{
#line 499 "inform7/Chapter 17/Atomic Propositions.w"
adjective_usage *tr = RETRIEVE_POINTER_adjective_usage(prop->predicate);
if (Adjectives__Usages__get_parity(tr) == FALSE) LOG("not-");
Adjectives__Phrases__log(Adjectives__Usages__get_aph(tr));
}
#line 456 "inform7/Chapter 17/Atomic Propositions.w"
; break;
case 2:
{
#line 506 "inform7/Chapter 17/Atomic Propositions.w"
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(prop->predicate);
if (bp == NULL) LOG("?bad-bp?"); else LOG(BinaryPredicates__get_log_name(bp));
}
#line 457 "inform7/Chapter 17/Atomic Propositions.w"
; break;
default: LOG("?exotic-predicate-arity=%d?", prop->arity); break;
}
break;
case QUANTIFIER_ATOM: {
quantifier *quant = RETRIEVE_POINTER_quantifier(prop->predicate);
Quantifiers__log(quant, prop->quantification_parameter);
LOG(" ");
{
#line 514 "inform7/Chapter 17/Atomic Propositions.w"
int t;
for (t=0; t<prop->arity; t++) {
if (t>0) LOG(", ");
Calculus__Terms__log(&(prop->terms[t]));
}
}
#line 464 "inform7/Chapter 17/Atomic Propositions.w"
;
return;
}
case CALLED_ATOM: {
wording W = Calculus__Atoms__CALLED_get_name(prop);
LOG("called='$w'", W);
if (prop->assert_kind) LOG("($u)", prop->assert_kind);
break;
}
case KIND_ATOM:
if (logging_to_I6_text == FALSE) LOG("kind=");
LOG("$u", prop->assert_kind);
if ((logging_to_I6_text == FALSE) && (prop->composited)) LOG("_c");
if ((logging_to_I6_text == FALSE) && (prop->unarticled)) LOG("_u");
break;
case ISAKIND_ATOM: LOG("is-a-kind"); break;
case ISAVAR_ATOM: LOG("is-a-var"); break;
case ISACONST_ATOM: LOG("is-a-const"); break;
case EVERYWHERE_ATOM: LOG("everywhere"); break;
case NOWHERE_ATOM: LOG("nowhere"); break;
case HERE_ATOM: LOG("here"); break;
case NEGATION_OPEN_ATOM: LOG("NOT["); break;
case NEGATION_CLOSE_ATOM: LOG("NOT]"); break;
case DOMAIN_OPEN_ATOM: LOG("IN["); break;
case DOMAIN_CLOSE_ATOM: LOG("IN]"); break;
default: LOG("?bad-atom?"); break;
}
if (prop->arity > 0) {
LOG("(");
{
#line 514 "inform7/Chapter 17/Atomic Propositions.w"
int t;
for (t=0; t<prop->arity; t++) {
if (t>0) LOG(", ");
Calculus__Terms__log(&(prop->terms[t]));
}
}
#line 492 "inform7/Chapter 17/Atomic Propositions.w"
; LOG(")");
}
}
#line 141 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__implied_conjunction_between(pcalc_prop *p1, pcalc_prop *p2) {
if ((p1 == NULL) || (p2 == NULL)) return FALSE;
if (Calculus__Atoms__element_get_group(p1->element) == OPEN_OPERATORS_GROUP) return FALSE;
if (Calculus__Atoms__element_get_group(p2->element) == CLOSE_OPERATORS_GROUP) return FALSE;
if (p1->element == QUANTIFIER_ATOM) return FALSE;
if (p1->element == DOMAIN_CLOSE_ATOM) return FALSE;
return TRUE;
}
#line 154 "inform7/Chapter 17/Propositions.w"
char *Calculus__Propositions__debugging_log_text_between(pcalc_prop *p1, pcalc_prop *p2) {
if ((p1 == NULL) || (p2 == NULL)) return "";
if (p1->element == QUANTIFIER_ATOM) {
if (p2->element == DOMAIN_OPEN_ATOM) return "";
return ":";
}
if (p1->element == DOMAIN_CLOSE_ATOM) return ":";
if (Calculus__Propositions__implied_conjunction_between(p1, p2)) {
if (logging_to_I6_text) return("&"); /* since |^| in I6 strings means newline */
return ("^");
}
return "";
}
#line 172 "inform7/Chapter 17/Propositions.w"
void Calculus__Propositions__log(pcalc_prop *prop) {
TRAVERSE_VARIABLE(p);
LOG("[ ");
TRAVERSE_PROPOSITION(p, prop) {
char *bridge = Calculus__Propositions__debugging_log_text_between(p_prev, p);
if (bridge[0]) LOG("%s ", bridge);
Calculus__Atoms__log(p);
LOG(" ");
}
LOG("]");
}
#line 234 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__is_syntactically_valid(pcalc_prop *prop) {
TRAVERSE_VARIABLE(p);
int groups_stack[MAX_PROPOSITION_GROUP_NESTING], group_sp = 0;
TRAVERSE_PROPOSITION(p, prop) {
/* (1) each individual atom has to be properly built: */
char *err = Calculus__Atoms__validate(p);
if (err) { LOG("Atom error: %s: $o\n", err, p); return FALSE; }
/* (2) every open bracket must be matched by a close bracket of the same kind: */
if (Calculus__Atoms__element_get_group(p->element) == OPEN_OPERATORS_GROUP) {
if (group_sp >= MAX_PROPOSITION_GROUP_NESTING) {
LOG("Group nesting too deep\n"); return FALSE;
}
groups_stack[group_sp++] = p->element;
}
if (Calculus__Atoms__element_get_group(p->element) == CLOSE_OPERATORS_GROUP) {
if (group_sp <= 0) { LOG("Too many close groups\n"); return FALSE; }
if (Calculus__Atoms__element_get_match(groups_stack[--group_sp]) != p->element) {
LOG("Group open/close doesn't match\n"); return FALSE;
}
}
/* (3) every quantifier except "exists" must be followed by domain brackets, which occur nowhere else: */
if ((Calculus__Atoms__is_quantifier(p_prev)) && (Calculus__Atoms__is_existence_quantifier(p_prev) == FALSE)) {
if (p->element != DOMAIN_OPEN_ATOM) { LOG("Quant without domain\n"); return FALSE; }
} else {
if (p->element == DOMAIN_OPEN_ATOM) { LOG("Domain without quant\n"); return FALSE; }
}
if ((p->next == NULL) &&
(Calculus__Atoms__is_quantifier(p)) && (Calculus__Atoms__is_existence_quantifier(p) == FALSE)) {
LOG("Ends without domain of final quantifier\n"); return FALSE;
}
}
/* (4) a proposition must end with all its brackets closed: */
if (group_sp != 0) { LOG("%d group(s) open\n", group_sp); return FALSE; }
return TRUE;
}
#line 277 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__is_complex(pcalc_prop *prop) {
pcalc_prop *p;
for (p = prop; p; p = p->next) {
if (p->element == QUANTIFIER_ATOM) return TRUE;
if (p->element == NEGATION_OPEN_ATOM) return TRUE;
if (p->element == NEGATION_CLOSE_ATOM) return TRUE;
if (p->element == DOMAIN_OPEN_ATOM) return TRUE;
if (p->element == DOMAIN_CLOSE_ATOM) return TRUE;
if ((p->element == PREDICATE_ATOM) && (p->arity == 2)) {
if (Calculus__Atoms__is_equality_predicate(p) == FALSE) return TRUE;
if (!(((p->terms[0].variable == 0) && (p->terms[1].constant)) ||
((p->terms[1].variable == 0) && (p->terms[0].constant)))) return TRUE;
}
}
return FALSE;
}
#line 299 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__copy(pcalc_prop *original) {
pcalc_prop *first = NULL, *last = NULL, *prop = original;
while (prop) {
pcalc_prop *copied_atom = Calculus__Atoms__new(0);
*copied_atom = *prop;
for (int j=0; j<prop->arity; j++)
copied_atom->terms[j] = Calculus__Terms__copy(prop->terms[j]);
copied_atom->next = NULL;
if (first) last->next = copied_atom;
else first = copied_atom;
last = copied_atom;
prop = prop->next;
}
return first;
}
#line 320 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__concatenate(pcalc_prop *existing_body, pcalc_prop *tail) {
pcalc_prop *end = existing_body;
if (end == NULL) return tail;
int sc = 0;
while (end && (end->next)) {
if (sc++ == 100000) internal_error("malformed proposition");
end = end->next;
}
end->next = tail;
return existing_body;
}
#line 335 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__conjoin(pcalc_prop *existing_body, pcalc_prop *tail) {
Calculus__Variables__renumber_bound(tail, existing_body, -1);
existing_body = Calculus__Propositions__concatenate(existing_body, tail);
return existing_body;
}
#line 346 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__insert_atom(pcalc_prop *prop, pcalc_prop *position,
pcalc_prop *new_atom) {
if (position == NULL) {
new_atom->next = prop;
return new_atom;
} else {
if (prop == NULL) internal_error("inserting atom nowhere");
new_atom->next = position->next;
position->next = new_atom;
return prop;
}
}
#line 362 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__delete_atom(pcalc_prop *prop, pcalc_prop *position) {
if (position == NULL) {
if (prop == NULL) internal_error("deleting atom nowhere");
return prop->next;
} else {
if (position->next == NULL) internal_error("deleting atom off end");
position->next = position->next->next;
return prop;
}
}
#line 380 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__length(pcalc_prop *prop) {
int n = 0;
TRAVERSE_VARIABLE(p);
TRAVERSE_PROPOSITION(p, prop) n++;
return n;
}
#line 408 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__match(pcalc_prop *prop, int c, ...) {
int i, outcome = TRUE;
va_list ap; /* the variable argument list signified by the dots */
va_start(ap, c); /* macro to begin variable argument processing */
for (i = 0; i < c; i++) {
int a = va_arg(ap, int);
pcalc_prop **atom_p = va_arg(ap, pcalc_prop **);
if (atom_p != NULL) *atom_p = prop;
switch (a) {
case ANY_ATOM_HERE: if (prop == NULL) outcome = FALSE; break;
case END_PROP_HERE: if (prop != NULL) outcome = FALSE; break;
default: if (prop == NULL) outcome = FALSE;
else if (prop->element != a) outcome = FALSE;
break;
}
if (prop) prop = prop->next;
}
va_end(ap); /* macro to end variable argument processing */
return outcome;
}
#line 434 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__prop_seek_atom(pcalc_prop *prop, int atom_req, int arity_req) {
TRAVERSE_VARIABLE(p);
TRAVERSE_PROPOSITION(p, prop)
if (((atom_req < 0) || (p->element == atom_req)) &&
((arity_req < 0) || (p->arity == arity_req)))
return p;
return NULL;
}
#line 446 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__contains_binary_predicate(pcalc_prop *prop) {
if (Calculus__Propositions__prop_seek_atom(prop, PREDICATE_ATOM, 2)) return TRUE; return FALSE;
}
int Calculus__Propositions__contains_quantifier(pcalc_prop *prop) {
if (Calculus__Propositions__prop_seek_atom(prop, QUANTIFIER_ATOM, -1)) return TRUE; return FALSE;
}
pcalc_prop *Calculus__Propositions__composited_kind(pcalc_prop *prop) {
pcalc_prop *k_atom = Calculus__Propositions__prop_seek_atom(prop, KIND_ATOM, -1);
if ((k_atom) && (k_atom->composited == FALSE)) k_atom = NULL;
return k_atom;
}
int Calculus__Propositions__contains_nonexistence_quantifier(pcalc_prop *prop) {
while ((prop = Calculus__Propositions__prop_seek_atom(prop, QUANTIFIER_ATOM, 1)) != NULL) {
quantifier *quant = RETRIEVE_POINTER_quantifier(prop->predicate);
if (quant != exists_quantifier) return TRUE;
prop = prop->next;
}
return FALSE;
}
int Calculus__Propositions__contains_callings(pcalc_prop *prop) {
if (Calculus__Propositions__prop_seek_atom(prop, CALLED_ATOM, -1)) return TRUE; return FALSE;
}
#line 477 "inform7/Chapter 17/Propositions.w"
kind *Calculus__Propositions__describes_kind(pcalc_prop *prop) {
pcalc_prop *p = prop;
while ((p = Calculus__Propositions__prop_seek_atom(p, ISAKIND_ATOM, 1)) != NULL) {
if ((Calculus__Terms__variable_underlying(&(p->terms[0])) == 0) &&
(Kinds__Compare__eq(p->assert_kind, K_value))) return p->assert_kind;
p = p->next;
}
p = prop;
while ((p = Calculus__Propositions__prop_seek_atom(p, KIND_ATOM, 1)) != NULL) {
if (Calculus__Terms__variable_underlying(&(p->terms[0])) == 0) return p->assert_kind;
p = p->next;
}
parse_node *val = Calculus__Propositions__describes_value(prop);
if (val) return Specifications__to_kind(val);
return NULL;
}
#line 497 "inform7/Chapter 17/Propositions.w"
parse_node *Calculus__Propositions__describes_value(pcalc_prop *prop) {
pcalc_prop *p; int bl = 0;
for (p = prop; p; p = p->next)
switch (p->element) {
case NEGATION_OPEN_ATOM: bl++; break;
case NEGATION_CLOSE_ATOM: bl--; break;
case DOMAIN_OPEN_ATOM: bl++; break;
case DOMAIN_CLOSE_ATOM: bl--; break;
default:
if (bl == 0) {
if (Calculus__Atoms__is_equality_predicate(p)) {
if ((p->terms[0].variable == 0) && (p->terms[1].constant))
return p->terms[1].constant;
if ((p->terms[1].variable == 0) && (p->terms[0].constant))
return p->terms[0].constant;
}
}
break;
}
return NULL;
}
#line 522 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__contains_adjective(pcalc_prop *prop) {
if (Calculus__Propositions__prop_seek_atom(prop, PREDICATE_ATOM, 1)) return TRUE;
return FALSE;
}
int Calculus__Propositions__count_unary_predicates(pcalc_prop *prop) {
int ac = 0;
pcalc_prop *p = prop;
while ((p = Calculus__Propositions__prop_seek_atom(p, PREDICATE_ATOM, 1)) != NULL) {
if (Calculus__Terms__variable_underlying(&(p->terms[0])) == 0) ac++;
p = p->next;
}
return ac;
}
#line 541 "inform7/Chapter 17/Propositions.w"
pcalc_term Calculus__Propositions__get_first_cited_term(pcalc_prop *prop) {
TRAVERSE_VARIABLE(p);
TRAVERSE_PROPOSITION(p, prop)
if (p->arity > 0)
return p->terms[0];
internal_error("Calculus__Propositions__get_first_cited_term on termless proposition");
return Calculus__Terms__new_variable(0); /* never executed, but needed to prevent |gcc| warnings */
}
#line 557 "inform7/Chapter 17/Propositions.w"
pcalc_term Calculus__Propositions__convert_adj_to_noun(pcalc_prop *prop) {
pcalc_term pct = Calculus__Terms__new_variable(0);
if (prop == NULL) return pct;
if (Calculus__Atoms__is_existence_quantifier(prop)) prop = prop->next;
if (prop == NULL) return pct;
if (prop->next != NULL) return pct;
if ((prop->element == PREDICATE_ATOM) && (prop->arity == 1)) {
adjective_usage *tr = RETRIEVE_POINTER_adjective_usage(prop->predicate);
return Calculus__Terms__adj_to_noun_conversion(tr);
}
if (prop->element == KIND_ATOM) {
kind *K = prop->assert_kind;
property *pname = Kinds__Behaviour__get_coinciding_property(K);
if (pname) return Calculus__Terms__new_constant(Rvalues__from_property(pname));
}
return pct;
}
#line 579 "inform7/Chapter 17/Propositions.w"
adjective_usage *Calculus__Propositions__first_adjective_usage(pcalc_prop *prop, pcalc_prop **ppp) {
prop = Calculus__Propositions__prop_seek_atom(prop, PREDICATE_ATOM, 1);
if (ppp) *ppp = prop;
if (prop == NULL) return NULL;
return Calculus__Atoms__au_from_unary_PREDICATE(prop);
}
adjective_usage *Calculus__Propositions__next_adjective_usage(pcalc_prop **ppp) {
if (ppp == NULL) internal_error("bad ppp");
pcalc_prop *prop = Calculus__Propositions__prop_seek_atom((*ppp)->next, PREDICATE_ATOM, 1);
*ppp = prop;
if (prop == NULL) return NULL;
return Calculus__Atoms__au_from_unary_PREDICATE(prop);
}
#line 604 "inform7/Chapter 17/Propositions.w"
int Calculus__Propositions__is_a_group(pcalc_prop *prop, int governing) {
int match = Calculus__Atoms__element_get_match(governing), level = 0;
if (match == 0) internal_error("Calculus__Propositions__is_a_group called on unmatchable");
TRAVERSE_VARIABLE(p);
if ((prop == NULL) || (prop->element != governing)) return FALSE;
TRAVERSE_PROPOSITION(p, prop) {
if (Calculus__Atoms__element_get_group(p->element) == OPEN_OPERATORS_GROUP) level++;
if (Calculus__Atoms__element_get_group(p->element) == CLOSE_OPERATORS_GROUP) level--;
}
if ((p_prev->element == match) && (level == 0)) return TRUE;
return FALSE;
}
#line 620 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__remove_topmost_group(pcalc_prop *prop) {
TRAVERSE_VARIABLE(p);
if ((prop == NULL) || (Calculus__Propositions__is_a_group(prop, prop->element) == FALSE))
internal_error("tried to remove topmost group which wasn't there");
LOGIF(PREDICATE_CALCULUS_WORKINGS, "ungrouping proposition: $D\n", prop);
prop = prop->next;
TRAVERSE_PROPOSITION(p, prop)
if ((p->next) && (p->next->next == NULL)) { p->next = NULL; break; }
LOGIF(PREDICATE_CALCULUS_WORKINGS, "to ungrouped result: $D\n", prop);
return prop;
}
#line 635 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__unnegate(pcalc_prop *prop) {
if (Calculus__Propositions__is_a_group(prop, NEGATION_OPEN_ATOM))
return Calculus__Propositions__remove_topmost_group(prop);
return NULL;
}
#line 645 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__ungroup_after(pcalc_prop *prop, pcalc_prop *position, pcalc_prop **last) {
TRAVERSE_VARIABLE(p);
pcalc_prop *from;
int opener, closer, level;
LOGIF(PREDICATE_CALCULUS_WORKINGS, "removing frontmost group from proposition: $D\n", prop);
if (position == NULL) from = prop; else from = position->next;
opener = from->element;
closer = Calculus__Atoms__element_get_match(opener);
if (closer == 0) internal_error("tried to remove frontmost group which doesn't open");
from = from->next;
prop = Calculus__Propositions__delete_atom(prop, position); /* remove opening atom */
if (from->element == closer) { /* the special case of an empty group */
prop = Calculus__Propositions__delete_atom(prop, position); /* remove opening atom */
goto Ungrouped;
}
level = 0;
TRAVERSE_PROPOSITION(p, from) {
if (p->element == opener) level++;
if (p->element == closer) level--;
if (level < 0) {
if (last) *last = p_prev;
prop = Calculus__Propositions__delete_atom(prop, p_prev); /* remove closing atom */
goto Ungrouped;
}
}
internal_error("tried to remove frontmost group which doesn't close");
Ungrouped:
LOGIF(PREDICATE_CALCULUS_WORKINGS, "to ungrouped result: $D\n", prop);
return prop;
}
#line 680 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__trim_universal_quantifier(pcalc_prop *prop) {
if ((Calculus__Atoms__is_for_all_x(prop)) &&
(Calculus__Propositions__match(prop, 2, QUANTIFIER_ATOM, NULL, DOMAIN_OPEN_ATOM, NULL))) {
prop = Calculus__Propositions__ungroup_after(prop, prop, NULL);
prop = Calculus__Propositions__delete_atom(prop, NULL);
LOGIF(PREDICATE_CALCULUS_WORKINGS, "Calculus__Propositions__trim_universal_quantifier: $D\n", prop);
}
return prop;
}
#line 693 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__remove_final_close_domain(pcalc_prop *prop, int *move_domain) {
*move_domain = FALSE;
TRAVERSE_VARIABLE(p);
TRAVERSE_PROPOSITION(p, prop)
if ((p->next == NULL) && (p->element == DOMAIN_CLOSE_ATOM)) {
*move_domain = TRUE;
return Calculus__Propositions__delete_atom(prop, p_prev);
}
return prop;
}
#line 708 "inform7/Chapter 17/Propositions.w"
pcalc_prop *Calculus__Propositions__from_spec(parse_node *spec) {
if (spec == NULL) return NULL; /* the null description is universally true */
if (Specifications__is_description(spec))
return Descriptions__to_proposition(spec);
pcalc_prop *prop = Specifications__to_proposition(spec);
if (prop) return prop; /* a propositional form is already made */
{
#line 730 "inform7/Chapter 17/Propositions.w"
instance *I = Rvalues__to_instance(spec);
if (I) {
property *pname = Kinds__Behaviour__get_coinciding_property(Instances__to_kind(I));
if (pname) {
prop = Calculus__Atoms__unary_PREDICATE_from_aph(Instances__get_adjectival_phrase(I), FALSE);
{
#line 762 "inform7/Chapter 17/Propositions.w"
Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_no_problem_reporting());
return prop;
}
#line 735 "inform7/Chapter 17/Propositions.w"
;
}
}
}
#line 717 "inform7/Chapter 17/Propositions.w"
;
{
#line 742 "inform7/Chapter 17/Propositions.w"
if (Rvalues__is_CONSTANT_construction(spec, CON_property)) {
property *prn = Rvalues__to_property(spec);
if (Properties__is_either_or(prn)) {
prop = Calculus__Atoms__unary_PREDICATE_from_aph(
Properties__EitherOr__get_aph(prn), FALSE);
{
#line 762 "inform7/Chapter 17/Propositions.w"
Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_no_problem_reporting());
return prop;
}
#line 747 "inform7/Chapter 17/Propositions.w"
;
}
}
}
#line 718 "inform7/Chapter 17/Propositions.w"
;
{
#line 754 "inform7/Chapter 17/Propositions.w"
prop = Calculus__Atoms__prop_x_is_constant(ParseTree__duplicate(spec));
{
#line 762 "inform7/Chapter 17/Propositions.w"
Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_no_problem_reporting());
return prop;
}
#line 755 "inform7/Chapter 17/Propositions.w"
;
}
#line 719 "inform7/Chapter 17/Propositions.w"
;
}
#line 78 "inform7/Chapter 17/Binding and Substitution.w"
void Calculus__Variables__determine_status(pcalc_prop *prop, int *var_states, int *valid) {
TRAVERSE_VARIABLE(p);
int j, unavailable[26], blevel = 0, dummy;
if (valid == NULL) valid = &dummy;
*valid = TRUE;
for (j=0; j<26; j++) { var_states[j] = UNUSED_VST; unavailable[j] = 0; }
TRAVERSE_PROPOSITION(p, prop) {
if (Calculus__Atoms__element_get_group(p->element) == OPEN_OPERATORS_GROUP) blevel++;
if (Calculus__Atoms__element_get_group(p->element) == CLOSE_OPERATORS_GROUP) {
blevel--;
for (j=0; j<26; j++) if (unavailable[j] > blevel) unavailable[j] = -1;
}
for (j=0; j<p->arity; j++) {
int v = Calculus__Terms__variable_underlying(&(p->terms[j]));
if (v >= 26) internal_error("corrupted variable term");
if (v >= 0) {
if (unavailable[v] == -1) {
*valid = FALSE;
LOG("$o invalid because of %c unavailable\n", p, pcalc_vars[v]);
}
if (p->element == QUANTIFIER_ATOM) {
if (var_states[v] != UNUSED_VST) {
*valid = FALSE;
LOG("$D: $o invalid because of %c Q for F\n", prop, p, pcalc_vars[v]);
}
var_states[v] = BOUND_VST; unavailable[v] = blevel;
} else {
if (var_states[v] == UNUSED_VST) var_states[v] = FREE_VST;
}
}
}
}
}
#line 115 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__is_well_formed(pcalc_prop *prop) {
int status, var_states[26];
if (Calculus__Propositions__is_syntactically_valid(prop) == FALSE) return FALSE;
Calculus__Variables__determine_status(prop, var_states, &status);
if (status == FALSE) { LOG("Variable usage malformed\n"); return FALSE; }
return TRUE;
}
#line 126 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__status(pcalc_prop *prop, int v) {
int var_states[26];
if (v == -1) return UNUSED_VST;
Calculus__Variables__determine_status(prop, var_states, NULL);
return var_states[v];
}
#line 136 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__number_free(pcalc_prop *prop) {
int var_states[26], j, c;
Calculus__Variables__determine_status(prop, var_states, NULL);
for (j=0, c=0; j<26; j++) if (var_states[j] == FREE_VST) c++;
LOGIF(PREDICATE_CALCULUS_WORKINGS, "There %s %d free variable%s in $D\n",
(c==1)?"is":"are", c, (c==1)?"":"s", prop);
return c;
}
#line 149 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__find_unused(pcalc_prop *prop) {
int var_states[26], j;
Calculus__Variables__determine_status(prop, var_states, NULL);
for (j=0; j<26; j++) if (var_states[j] == UNUSED_VST) return j;
return 25; /* the best we can do: it avoids crashes, at least... */
}
#line 167 "inform7/Chapter 17/Binding and Substitution.w"
void Calculus__Variables__vars_map(pcalc_prop *prop, int *renumber_map, pcalc_term *preserving) {
TRAVERSE_VARIABLE(p);
int j;
TRAVERSE_PROPOSITION(p, prop)
for (j=0; j<p->arity; j++) {
pcalc_term *pt = &(p->terms[j]);
Calculus__Variables__term_map(pt, renumber_map);
}
if (preserving) Calculus__Variables__term_map(preserving, renumber_map);
}
void Calculus__Variables__term_map(pcalc_term *pt, int *renumber_map) {
while (pt->function) pt=&(pt->function->fn_of);
int nv = renumber_map[pt->variable];
if ((pt->variable >= 0) && (nv >= 0)) {
if (nv >= 26) internal_error("malformed renumbering map");
pt->variable = nv;
}
}
#line 193 "inform7/Chapter 17/Binding and Substitution.w"
void Calculus__Variables__renumber(pcalc_prop *prop, pcalc_term *preserving) {
TRAVERSE_VARIABLE(p);
int j, k, renumber_map[26];
for (j=0; j<26; j++) renumber_map[j] = -1;
k = 0;
TRAVERSE_PROPOSITION(p, prop)
for (j=0; j<p->arity; j++) {
int v = Calculus__Terms__variable_underlying(&(p->terms[j]));
if ((v >= 0) && (renumber_map[v] == -1)) renumber_map[v] = k++;
}
Calculus__Variables__vars_map(prop, renumber_map, preserving);
}
#line 231 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__renumber_bound(pcalc_prop *prop, pcalc_prop *not_to_overlap, int query) {
int prop_vstates[26], nto_vstates[26], renumber_map[26];
int j, next_unused;
Calculus__Variables__determine_status(prop, prop_vstates, NULL);
Calculus__Variables__determine_status(not_to_overlap, nto_vstates, NULL);
for (j=0, next_unused=0; j<26; j++)
if ((prop_vstates[j] == BOUND_VST) && (nto_vstates[j] != UNUSED_VST)) {
{
#line 253 "inform7/Chapter 17/Binding and Substitution.w"
int k;
for (k=next_unused; (k<26) &&
(!((prop_vstates[k] == UNUSED_VST) && (nto_vstates[k] == UNUSED_VST))); k++) ;
if (k == 26) next_unused = 25; else next_unused = k;
}
#line 239 "inform7/Chapter 17/Binding and Substitution.w"
;
renumber_map[j] = next_unused++;
} else renumber_map[j] = -1;
Calculus__Variables__vars_map(prop, renumber_map, NULL);
if (query == -1) return -1;
if (renumber_map[query] == -1) return query;
return renumber_map[query];
}
#line 274 "inform7/Chapter 17/Binding and Substitution.w"
pcalc_prop *Calculus__Variables__bind_existential(pcalc_prop *prop,
pcalc_term *preserving) {
int var_states[26], j;
Calculus__Variables__renumber(prop, preserving);
Calculus__Variables__determine_status(prop, var_states, NULL);
for (j=25; j>=0; j--)
if (var_states[j] == FREE_VST)
prop = Calculus__Propositions__insert_atom(prop, NULL,
Calculus__Atoms__QUANTIFIER_new(exists_quantifier, j, 0));
return prop;
}
#line 295 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__substitute_v_in_term(pcalc_term *pt, int v, pcalc_term *t) {
if (pt->variable == v) { *pt = *t; return TRUE; }
if (pt->function) return Calculus__Variables__substitute_v_in_term(&(pt->function->fn_of), v, t);
return FALSE;
}
void Calculus__Variables__substitute_nothing_in_term(pcalc_term *pt, pcalc_term *t) {
if ((pt->constant) && (Rvalues__is_nothing_object_constant(pt->constant))) { *pt = *t; return; }
if (pt->function) Calculus__Variables__substitute_nothing_in_term(&(pt->function->fn_of), t);
}
void Calculus__Variables__substitute_term_in_term(pcalc_term *pt, pcalc_term *t) {
if (pt->constant) { *pt = *t; return; }
if (pt->function) Calculus__Variables__substitute_term_in_term(&(pt->function->fn_of), t);
}
#line 331 "inform7/Chapter 17/Binding and Substitution.w"
pcalc_prop *Calculus__Variables__substitute_term(pcalc_prop *prop, int v, pcalc_term t,
int verify_only, int *allowed, int *changed) {
TRAVERSE_VARIABLE(p);
if (verify_only) *allowed = TRUE;
if ((v<0) || (v>=26)) DISALLOW("variable substitution out of range");
if (Calculus__Variables__is_well_formed(prop) == FALSE)
DISALLOW("substituting into malformed prop");
{
#line 371 "inform7/Chapter 17/Binding and Substitution.w"
if ((verify_only == FALSE) && (Calculus__Variables__status(prop, v) == BOUND_VST))
DISALLOW("substituting bound variable");
int vut = Calculus__Terms__variable_underlying(&t);
if (vut >= 0) {
int v_has_been_seen = FALSE;
if (v == vut) DISALLOW("resubstituting same variable");
TRAVERSE_PROPOSITION(p, prop) {
if (v_has_been_seen == FALSE) {
int i;
for (i=0; i<p->arity; i++)
if (Calculus__Terms__variable_underlying(&(p->terms[i])) == v)
v_has_been_seen = TRUE;
}
if ((p->element == QUANTIFIER_ATOM) && (p->terms[0].variable == vut) &&
(v_has_been_seen))
DISALLOW("substituted value may be circular");
}
}
}
#line 339 "inform7/Chapter 17/Binding and Substitution.w"
;
if (verify_only) return prop;
LOGIF(PREDICATE_CALCULUS_WORKINGS, "Substituting %c = $0 in: $D\n", pcalc_vars[v], &t, prop);
TRAVERSE_PROPOSITION(p, prop) {
int i;
for (i=0; i<p->arity; i++)
if (Calculus__Variables__substitute_v_in_term(&(p->terms[i]), v, &t))
*changed = TRUE;
}
if (Calculus__Variables__is_well_formed(prop) == FALSE)
internal_error("substitution made malformed prop");
return prop;
}
#line 400 "inform7/Chapter 17/Binding and Substitution.w"
kind *Calculus__Variables__kind_of_variable_0(pcalc_prop *prop) {
TRAVERSE_VARIABLE(p);
TRAVERSE_PROPOSITION(p, prop)
if ((p->element == KIND_ATOM) && (p->terms[0].variable == 0)) {
kind *K = p->assert_kind;
if (K) return K;
}
return NULL;
}
#line 413 "inform7/Chapter 17/Binding and Substitution.w"
pcalc_prop *Calculus__Variables__substitute_var_0_in(pcalc_prop *prop, parse_node *spec) {
int bogus;
return Calculus__Variables__substitute_term(prop, 0, Calculus__Terms__new_constant(spec), FALSE, NULL, &bogus);
}
#line 421 "inform7/Chapter 17/Binding and Substitution.w"
kind *Calculus__Variables__infer_kind_of_variable_0(pcalc_prop *prop) {
TRAVERSE_VARIABLE(p);
TRAVERSE_PROPOSITION(p, prop) {
if ((p->element == KIND_ATOM) && (p->terms[0].variable == 0)) {
kind *K = p->assert_kind;
if (K) return K;
}
if ((p->element == PREDICATE_ATOM) && (p->arity == 1) && (p->terms[0].variable == 0)) {
adjective_usage *tr = RETRIEVE_POINTER_adjective_usage(p->predicate);
adjectival_phrase *aph = Adjectives__Usages__get_aph(tr);
adjective_meaning *am = Adjectives__Phrases__first_meaning(aph);
kind *K = Adjectives__Meanings__get_domain(am);
if (K) return K;
}
}
return NULL;
}
#line 449 "inform7/Chapter 17/Binding and Substitution.w"
int Calculus__Variables__detect_locals(pcalc_prop *prop, parse_node **example) {
TRAVERSE_VARIABLE(pl);
int i, locals_count = 0;
TRAVERSE_PROPOSITION(pl, prop)
for (i=0; i<pl->arity; i++)
locals_count =
Calculus__Variables__detect_local_in_term(&(pl->terms[i]), locals_count, example);
return locals_count;
}
int Calculus__Variables__detect_local_in_term(pcalc_term *pt, int locals_count, parse_node **example) {
if (pt->function)
locals_count += Calculus__Variables__detect_local_in_term(&(pt->function->fn_of), locals_count, example);
if (pt->constant)
locals_count += Calculus__Variables__detect_local_in_spec(pt->constant, locals_count, example);
return locals_count;
}
int Calculus__Variables__detect_local_in_spec(parse_node *spec, int locals_count, parse_node **example) {
if (spec == NULL) return locals_count;
if (Lvalues__get_storage_form(spec) == LOCAL_VARIABLE_VNT) {
if ((example) && (*example == NULL)) *example = spec;
return ++locals_count;
}
if (Lvalues__get_storage_form(spec) == NONLOCAL_VARIABLE_VNT) {
nonlocal_variable *nlv = ParseTree__get_constant_nonlocal_variable(spec);
if (NonlocalVariables__is_global(nlv) == FALSE) {
if ((example) && (*example == NULL)) *example = spec;
return ++locals_count;
}
}
if (ParseTree__is_phrasal(spec)) {
parse_node *inv;
LOOP_THROUGH_INVOCATION_LIST(inv, spec->down->down) {
parse_node *param;
LOOP_THROUGH_TOKENS_PARSED_IN_INV(inv, param)
locals_count +=
Calculus__Variables__detect_local_in_spec(param, locals_count, example);
}
}
for (parse_node *p = spec->down; p; p = p->next)
locals_count +=
Calculus__Variables__detect_local_in_spec(p, locals_count, example);
return locals_count;
}
#line 18 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__Abstract__to_make_a_kind(kind *K) {
return Calculus__Atoms__ISAKIND_new(Calculus__Terms__new_variable(0), K);
}
pcalc_prop *Calculus__Propositions__Abstract__to_make_a_var(void) {
return Calculus__Atoms__ISAVAR_new(Calculus__Terms__new_variable(0));
}
pcalc_prop *Calculus__Propositions__Abstract__to_make_a_const(void) {
return Calculus__Atoms__ISACONST_new(Calculus__Terms__new_variable(0));
}
pcalc_prop *Calculus__Propositions__Abstract__to_create_something(kind *K, wording W) {
pcalc_prop *prop = Calculus__Atoms__QUANTIFIER_new(exists_quantifier, 0, 0);
if ((K) && (Kinds__Compare__eq(K, K_object) == FALSE))
prop = Calculus__Propositions__concatenate(prop,
Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0)));
if (Wordings__nonempty(W))
prop = Calculus__Propositions__concatenate(prop,
Calculus__Atoms__CALLED_new(W, Calculus__Terms__new_variable(0), K));
return prop;
}
#line 44 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__Abstract__prop_to_set_kind(instance *I, kind *k) {
return Calculus__Atoms__KIND_new(k, Calculus__Terms__new_variable(0));
}
void Calculus__Propositions__Abstract__assert_kind_of_object(instance *I, kind *k) {
Calculus__Propositions__Assert__assert_true_about(Calculus__Propositions__Abstract__prop_to_set_kind(I, k),
Instances__as_subject(I), prevailing_mood);
}
void Calculus__Propositions__Abstract__assert_kind_of_subject(inference_subject *inst, inference_subject *new,
pcalc_prop *subject_to) {
kind *K = InferenceSubjects__domain(new);
pcalc_prop *prop = Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0));
if (subject_to) prop = Calculus__Propositions__concatenate(prop, subject_to);
Calculus__Propositions__Assert__assert_true_about(prop, inst, prevailing_mood);
}
#line 64 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__Abstract__to_set_simple_relation(binary_predicate *bp, instance *I) {
parse_node *spec;
if (I) spec = Rvalues__from_instance(I);
else spec = Rvalues__new_nothing_object_constant();
return Calculus__Atoms__binary_PREDICATE_new(bp,
Calculus__Terms__new_variable(0), Calculus__Terms__new_constant(spec));
}
pcalc_prop *Calculus__Propositions__Abstract__to_set_relation(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0, inference_subject *infs1, parse_node *spec1) {
pcalc_term pt0, pt1;
if (infs0) pt0 = Calculus__Terms__new_constant(InferenceSubjects__as_constant(infs0));
else pt0 = Calculus__Terms__new_constant(spec0);
if (infs1) pt1 = Calculus__Terms__new_constant(InferenceSubjects__as_constant(infs1));
else pt1 = Calculus__Terms__new_constant(spec1);
pcalc_prop *prop = Calculus__Atoms__binary_PREDICATE_new(bp, pt0, pt1);
int dummy;
prop = Calculus__Simplifications__make_kinds_of_value_explicit(prop, &dummy);
return prop;
}
#line 88 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__Abstract__to_provide_property(property *prn) {
return Calculus__Atoms__binary_PREDICATE_new(R_provision,
Calculus__Terms__new_variable(0), Calculus__Terms__new_constant(Rvalues__from_property(prn)));
}
pcalc_prop *Calculus__Propositions__Abstract__to_set_property(property *prn, parse_node *val) {
if (val == NULL) return NULL;
if (Properties__Valued__get_setting_bp(prn) == NULL) internal_error("no BP for this property");
return Calculus__Atoms__binary_PREDICATE_new(Properties__Valued__get_setting_bp(prn),
Calculus__Terms__new_variable(0), Calculus__Terms__new_constant(val));
}
#line 103 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__Abstract__to_put_everywhere(void) {
return Calculus__Atoms__EVERYWHERE_new(Calculus__Terms__new_variable(0));
}
pcalc_prop *Calculus__Propositions__Abstract__to_put_nowhere(void) {
return Calculus__Atoms__NOWHERE_new(Calculus__Terms__new_variable(0));
}
pcalc_prop *Calculus__Propositions__Abstract__to_put_here(void) {
return Calculus__Atoms__HERE_new(Calculus__Terms__new_variable(0));
}
#line 120 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__Abstract__from_property_subtree(property *prn, parse_node *py) {
return Calculus__Propositions__Abstract__to_set_property(prn, Assertions__PropertyKnowledge__property_value_from_property_subtree(prn, py));
}
#line 130 "inform7/Chapter 17/Tree Conversions.w"
pcalc_prop *Calculus__Propositions__Abstract__from_property_list(parse_node *p, kind *K) {
pcalc_prop *prop = NULL;
if (p) {
switch(ParseTree__get_type(p)) {
case AND_NT:
for (p = p->down; p; p = p->next)
prop = Calculus__Propositions__conjoin(prop, Calculus__Propositions__Abstract__from_property_list(p, NULL));
break;
case PROPERTY_LIST_NT:
{
#line 159 "inform7/Chapter 17/Tree Conversions.w"
property *prn = NULL;
wording PW = EMPTY_WORDING, VW = EMPTY_WORDING;
{
#line 216 "inform7/Chapter 17/Tree Conversions.w"
wording W = Articles__remove_the(ParseTree__get_text(p));
if (Wordings__empty(W)) {
Problems__Issue__assertion_problem(_p_(BelievedImpossible),
"this looked to me as if it might be trying to create something "
"which has certain properties",
"and that made no sense on investigation. This sometimes happens "
"if a sentence uses 'to have' oddly?");
return NULL;
}
int name_length = Properties__match_longest(W);
if (name_length < 0) {
name_length = 1;
if (Preform__parse_nt_against_word_range(s_literal_NTM, W, NULL, NULL)) name_length = Wordings__length(W) - 1;
}
PW = Wordings__up_to(W, Wordings__first_wn(W) + name_length - 1);
VW = Wordings__from(W, Wordings__first_wn(W) + name_length);
}
#line 161 "inform7/Chapter 17/Tree Conversions.w"
;
if ((Wordings__nonempty(PW)) && (Preform__parse_nt_against_word_range(property_name_NTM, PW, NULL, NULL))) prn = most_recent_result_p;
if (prn == NULL)
{
#line 236 "inform7/Chapter 17/Tree Conversions.w"
LOG("Failed property list: pname = <$w>; pval = <$w>\n", PW, VW);
Problems__Issue__assertion_problem(_p_(PM_BadPropertyList),
"this looked to me as if it might be trying to create something "
"which has certain properties",
"and that made no sense on investigation. This sometimes happens "
"if a sentence uses 'with' a little too liberally, or to specify "
"a never-declared property. For instance, 'An antique is a kind of "
"thing with an age.' would not be the right way to declare the "
"property 'age' (because it does not tell Inform what kind of "
"value this would be). Instead, try 'An antique is a kind of "
"thing. An antique has a number called age.' It would then be all "
"right to say 'The Louis Quinze chair is an antique with age 241.'");
return NULL;
}
#line 164 "inform7/Chapter 17/Tree Conversions.w"
;
if (Wordings__nonempty(VW)) { /* a value is supplied... */
if (Properties__is_either_or(prn)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__quote_property(3, prn);
Problems__quote_wording(4, VW);
Problems__Issue__handmade_problem(_p_(PM_WithEitherOrValue));
Problems__issue_problem_segment(
"The sentence '%1' seems to be trying to create something which "
"has '%2', where the %3 property is being set equal to %4. But "
"this made no sense to me, because %3 is an either/or property "
"and cannot have a value.");
Problems__issue_problem_end();
return NULL;
}
Preform__parse_nt_against_word_range(nounphrase_as_object_NTM, VW, NULL, NULL);
parse_node *pn = most_recent_result_p;
Assertions__Refiner__refine(pn, FORBID_CREATION);
pcalc_prop *P = Calculus__Propositions__Abstract__from_property_subtree(prn, pn);
prop = Calculus__Propositions__conjoin(prop, P);
} else { /* no value is supplied... */
if (Properties__is_either_or(prn) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__quote_property(3, prn);
Problems__quote_kind(4, Properties__Valued__kind(prn));
Problems__Issue__handmade_problem(_p_(PM_WithValuelessValue));
Problems__issue_problem_segment(
"The sentence '%1' seems to be trying to create something which "
"has '%2', where the %3 property is being set in some way. But "
"this made no sense to me, because %3 is a value property (it "
"needs to be %4) and no value for it was given here.");
Problems__issue_problem_end();
return NULL;
}
prop = Calculus__Propositions__conjoin(prop, Calculus__Propositions__Abstract__from_property_subtree(prn, NULL));
}
}
#line 139 "inform7/Chapter 17/Tree Conversions.w"
;
break;
case ADJECTIVE_NT:
{
#line 258 "inform7/Chapter 17/Tree Conversions.w"
int negate_me = FALSE;
if (ParseTree__int_annotation(p, negated_boolean_ANNOT)) negate_me = TRUE;
if (ParseTree__get_aph(p) == NULL)
internal_error("Bogus adjective at Calculus__Propositions__Abstract__from_property_list");
if (ParseTree__get_creation_proposition(p))
prop = Calculus__Propositions__conjoin(prop, ParseTree__get_creation_proposition(p));
if (negate_me) prop = Calculus__Propositions__conjoin(prop, Calculus__Atoms__new(NEGATION_OPEN_ATOM));
prop = Calculus__Propositions__conjoin(prop, Calculus__Atoms__unary_PREDICATE_from_aph(ParseTree__get_aph(p), FALSE));
if (negate_me) prop = Calculus__Propositions__conjoin(prop, Calculus__Atoms__new(NEGATION_CLOSE_ATOM));
}
#line 142 "inform7/Chapter 17/Tree Conversions.w"
;
break;
default: internal_error_on_node_type(p);
}
}
if ((prop) && (K)) {
prop = Calculus__Propositions__conjoin(
Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0)), prop);
}
return prop;
}
#line 31 "inform7/Chapter 17/Sentence Conversions.w"
int conv_log_depth = 0; /* recursion depth: used only to clarify the debugging log */
pcalc_prop *Calculus__Propositions__FromSentences__S_subtree(int SV_not_SN, wording W, parse_node *A, parse_node *B, pcalc_term *subject_of_sentence, int verb_phrase_negated) {
parse_node *subject_phrase_subtree = NULL, *object_phrase_subtree = NULL;
pcalc_prop *subject_phrase_prop, *object_phrase_prop;
pcalc_term subject_phrase_term, object_phrase_term;
binary_predicate *verb_phrase_relation = NULL;
pcalc_prop *sentence_prop = NULL;
{
#line 62 "inform7/Chapter 17/Sentence Conversions.w"
if (A) Problems__Issue__s_subtree_error_set_position(A);
if (conv_log_depth == 0) LOGIF(PREDICATE_CALCULUS, "-----------\n");
conv_log_depth++;
LOGIF(PREDICATE_CALCULUS, "[%d] Starting fs on: <$w>\n", conv_log_depth, W);
}
#line 41 "inform7/Chapter 17/Sentence Conversions.w"
;
if (A == NULL) {
{
#line 87 "inform7/Chapter 17/Sentence Conversions.w"
if (SV_not_SN == FALSE) internal_error("THERE subtree misplaced");
parse_node *spec = B->down;
sentence_prop = Calculus__Propositions__from_spec(spec);
sentence_prop = Calculus__Variables__bind_existential(sentence_prop, NULL);
}
#line 44 "inform7/Chapter 17/Sentence Conversions.w"
;
} else {
{
#line 103 "inform7/Chapter 17/Sentence Conversions.w"
parse_node *verb_phrase_subtree;
verb_usage *vu; preposition_usage *pu = NULL;
subject_phrase_subtree = A;
if (subject_phrase_subtree == NULL) Problems__Issue__s_subtree_error("SP subtree null");
verb_phrase_subtree = B;
if (verb_phrase_subtree == NULL) Problems__Issue__s_subtree_error("VP subtree null");
if (verb_phrase_subtree->down == NULL) Problems__Issue__s_subtree_error("VP subtree broken");
object_phrase_subtree = verb_phrase_subtree->down;
vu = ParseTree__get_vu(verb_phrase_subtree);
if (vu == NULL) Problems__Issue__s_subtree_error("verb null");
if ((SV_not_SN == FALSE) && (Verbs__get_tense_used(vu) != IS_TENSE))
{
#line 126 "inform7/Chapter 17/Sentence Conversions.w"
SParser__Subtrees__throw_past_problem(FALSE);
}
#line 116 "inform7/Chapter 17/Sentence Conversions.w"
;
pu = ParseTree__get_pu(verb_phrase_subtree);
if (pu) verb_phrase_relation = Prepositions__get_meaning(pu);
else verb_phrase_relation = Verbs__get_meaning(vu);
}
#line 46 "inform7/Chapter 17/Sentence Conversions.w"
;
{
#line 186 "inform7/Chapter 17/Sentence Conversions.w"
kind *subject_K = BinaryPredicates__term_kind(verb_phrase_relation, 0);
if (Kinds__Compare__lt(subject_K, K_object)) subject_K = NULL;
subject_phrase_prop =
Calculus__Propositions__FromSentences__NP_subtree_to_proposition(&subject_phrase_term, subject_phrase_subtree,
subject_K);
kind *object_K = BinaryPredicates__term_kind(verb_phrase_relation, 1);
if (Kinds__Compare__lt(object_K, K_object)) object_K = NULL;
object_phrase_prop =
Calculus__Propositions__FromSentences__NP_subtree_to_proposition(&object_phrase_term, object_phrase_subtree,
object_K);
LOGIF(PREDICATE_CALCULUS, "[%d] subject NP: $0 such that: $D\n",
conv_log_depth, &subject_phrase_term, subject_phrase_prop);
LOGIF(PREDICATE_CALCULUS, "[%d] object NP: $0 such that: $D\n",
conv_log_depth, &object_phrase_term, object_phrase_prop);
}
#line 47 "inform7/Chapter 17/Sentence Conversions.w"
;
{
#line 226 "inform7/Chapter 17/Sentence Conversions.w"
if (SV_not_SN) subject_phrase_prop = Calculus__Variables__bind_existential(subject_phrase_prop, &subject_phrase_term);
object_phrase_prop = Calculus__Variables__bind_existential(object_phrase_prop, &object_phrase_term);
}
#line 48 "inform7/Chapter 17/Sentence Conversions.w"
;
{
#line 319 "inform7/Chapter 17/Sentence Conversions.w"
int use_case_2 = FALSE;
if (SV_not_SN == FALSE)
subject_phrase_prop = Calculus__Propositions__remove_final_close_domain(subject_phrase_prop, &use_case_2);
{
#line 352 "inform7/Chapter 17/Sentence Conversions.w"
pcalc_prop *k_atom = Calculus__Propositions__composited_kind(object_phrase_prop);
if ((k_atom) && (Kinds__Compare__eq(k_atom->assert_kind, K_room)) &&
(verb_phrase_relation == R_equality) && (room_containment_predicate)) {
Calculus__Atoms__set_composited(k_atom, FALSE);
verb_phrase_relation = BinaryPredicates__get_reversal(room_containment_predicate);
LOGIF(PREDICATE_CALCULUS, "[%d] Decompositing object: $D\n",
conv_log_depth, object_phrase_prop);
}
}
#line 323 "inform7/Chapter 17/Sentence Conversions.w"
;
LOGIF(PREDICATE_CALCULUS, "[%d] Before renumbering of OP: t = $0, phi = $D\n", conv_log_depth, &object_phrase_term, object_phrase_prop);
object_phrase_term.variable =
Calculus__Variables__renumber_bound(object_phrase_prop, subject_phrase_prop, object_phrase_term.variable);
if (object_phrase_term.variable >= 26) internal_error("bad OP renumbering");
LOGIF(PREDICATE_CALCULUS, "[%d] After renumbering of OP: t = $0, phi = $D\n", conv_log_depth, &object_phrase_term, object_phrase_prop);
sentence_prop = subject_phrase_prop;
if (verb_phrase_negated)
sentence_prop = Calculus__Propositions__concatenate(sentence_prop, Calculus__Atoms__new(NEGATION_OPEN_ATOM));
sentence_prop = Calculus__Propositions__concatenate(sentence_prop, object_phrase_prop);
sentence_prop = Calculus__Propositions__concatenate(sentence_prop,
Calculus__Atoms__binary_PREDICATE_new(verb_phrase_relation, subject_phrase_term, object_phrase_term));
if (verb_phrase_negated)
sentence_prop = Calculus__Propositions__concatenate(sentence_prop, Calculus__Atoms__new(NEGATION_CLOSE_ATOM));
if (use_case_2)
sentence_prop = Calculus__Propositions__concatenate(sentence_prop, Calculus__Atoms__new(DOMAIN_CLOSE_ATOM));
LOGIF(PREDICATE_CALCULUS, "[%d] Initial meaning: $D\n", conv_log_depth, sentence_prop);
}
#line 49 "inform7/Chapter 17/Sentence Conversions.w"
;
}
{
#line 405 "inform7/Chapter 17/Sentence Conversions.w"
if (Calculus__Variables__is_well_formed(sentence_prop) == FALSE) {
LOG("Failed before simplification: $D", sentence_prop);
internal_error("tried to simplify proposition which is not well-formed");
}
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__nothing_constant);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__use_listed_in);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__negated_determiners_nonex);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__negated_satisfiable);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__make_kinds_of_value_explicit);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__redundant_kinds);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__turn_right_way_round);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__region_containment);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__everywhere_and_nowhere);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__reduce_predicates);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__eliminate_redundant_variables);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__not_related_to_something);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__convert_gerunds);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__eliminate_to_have);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__is_all_rooms);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__redundant_kinds);
Calculus__Variables__renumber(sentence_prop, NULL); /* just for the sake of tidiness */
}
#line 52 "inform7/Chapter 17/Sentence Conversions.w"
;
{
#line 70 "inform7/Chapter 17/Sentence Conversions.w"
LOGIF(PREDICATE_CALCULUS, "[%d] fs: $w --> $D\n",
conv_log_depth, W, sentence_prop);
conv_log_depth--;
}
#line 53 "inform7/Chapter 17/Sentence Conversions.w"
;
if (subject_of_sentence) *subject_of_sentence = subject_phrase_term;
return sentence_prop;
}
#line 433 "inform7/Chapter 17/Sentence Conversions.w"
pcalc_prop *Calculus__Propositions__FromSentences__simplify(pcalc_prop *sentence_prop) {
int conv_log_depth = 1;
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__nothing_constant);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__use_listed_in);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__negated_determiners_nonex);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__negated_satisfiable);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__make_kinds_of_value_explicit);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__redundant_kinds);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__turn_right_way_round);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__region_containment);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__everywhere_and_nowhere);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__reduce_predicates);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__eliminate_redundant_variables);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__not_related_to_something);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__convert_gerunds);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__eliminate_to_have);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__is_all_rooms);
APPLY_SIMPLIFICATION(sentence_prop, Calculus__Simplifications__redundant_kinds);
Calculus__Variables__renumber(sentence_prop, NULL); /* just for the sake of tidiness */
return sentence_prop;
}
#line 472 "inform7/Chapter 17/Sentence Conversions.w"
pcalc_prop *Calculus__Propositions__FromSentences__NP_subtree_to_proposition(pcalc_term *subject_of_NP, parse_node *p,
kind *K) {
pcalc_prop *NP_prop = NULL; wording W;
{
#line 498 "inform7/Chapter 17/Sentence Conversions.w"
W = ParseTree__get_text(p);
conv_log_depth++;
LOGIF(PREDICATE_CALCULUS, "[%d] Starting Calculus__Propositions__FromSentences__NP_subtree_to_proposition on: <$w>\n",
conv_log_depth, W);
}
#line 475 "inform7/Chapter 17/Sentence Conversions.w"
;
pcalc_term *st = ParseTree__get_subject_term(p);
if (st) {
*subject_of_NP = *st;
NP_prop = Calculus__Propositions__copy(Specifications__to_proposition(p));
} else {
if (Specifications__is_description_like(p))
{
#line 558 "inform7/Chapter 17/Sentence Conversions.w"
parse_node *spec = p;
NP_prop = Calculus__Propositions__copy(Calculus__Propositions__from_spec(spec));
if (Calculus__Propositions__match(NP_prop, 2, PREDICATE_ATOM, NULL, END_PROP_HERE, NULL)) {
pcalc_term *pt = Calculus__Atoms__is_x_equals(NP_prop);
if (pt) { *subject_of_NP = *pt; NP_prop = NULL; }
}
if ((Calculus__Propositions__match(NP_prop, 2, KIND_ATOM, NULL, END_PROP_HERE, NULL)) &&
(Preform__parse_nt_against_word_range(k_formal_kind_variable_singular_NTM, W, NULL, NULL))) {
Calculus__Atoms__set_unarticled(NP_prop, TRUE);
}
if (NP_prop) *subject_of_NP = Calculus__Propositions__get_first_cited_term(NP_prop);
}
#line 482 "inform7/Chapter 17/Sentence Conversions.w"
else if (ParseTree__get_type(p) == UNKNOWN_VNT)
{
#line 588 "inform7/Chapter 17/Sentence Conversions.w"
*subject_of_NP = Calculus__Terms__new_constant(Rvalues__new_self_object_constant());
}
#line 483 "inform7/Chapter 17/Sentence Conversions.w"
else
{
#line 535 "inform7/Chapter 17/Sentence Conversions.w"
parse_node *spec = p;
*subject_of_NP = Calculus__Terms__new_constant(spec);
if (Rvalues__is_CONSTANT_construction(spec, CON_property)) {
property *prn = Rvalues__to_property(spec);
if (Properties__is_either_or(prn)) {
*subject_of_NP = Calculus__Terms__new_variable(0);
NP_prop = Calculus__Atoms__unary_PREDICATE_from_aph(Properties__EitherOr__get_aph(prn), FALSE);
} else if (Properties__Valued__coincides_with_kind(prn)) {
*subject_of_NP = Calculus__Terms__new_variable(0);
kind *K = Properties__Valued__kind(prn);
NP_prop = Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0));
}
}
}
#line 484 "inform7/Chapter 17/Sentence Conversions.w"
;
}
{
#line 628 "inform7/Chapter 17/Sentence Conversions.w"
if (((Rvalues__is_CONSTANT_construction(p, CON_property)) &&
(ParseTree__int_annotation(p, property_name_used_as_noun_ANNOT))) || (K)) {
pcalc_term pct = Calculus__Propositions__convert_adj_to_noun(NP_prop);
if (pct.constant) { *subject_of_NP = pct; NP_prop = NULL; }
}
}
#line 487 "inform7/Chapter 17/Sentence Conversions.w"
;
{
#line 646 "inform7/Chapter 17/Sentence Conversions.w"
if ((subject_of_NP->constant) && (NP_prop)) {
int y = Calculus__Variables__find_unused(NP_prop);
LOGIF(PREDICATE_CALCULUS,
"[%d] Rewriting qualified constant t = $0 (new var %d)\n", conv_log_depth, subject_of_NP, y);
NP_prop = Calculus__Propositions__concatenate(
Calculus__Atoms__binary_PREDICATE_new(R_equality, *subject_of_NP, Calculus__Terms__new_variable(y)),
NP_prop);
*subject_of_NP = Calculus__Terms__new_variable(y);
NP_prop = Calculus__Variables__bind_existential(NP_prop, subject_of_NP);
LOGIF(PREDICATE_CALCULUS,
"[%d] Rewriting qualified constant: <$w> --> t = $0, phi = $D\n",
conv_log_depth, W, subject_of_NP, NP_prop);
}
}
#line 488 "inform7/Chapter 17/Sentence Conversions.w"
;
{
#line 668 "inform7/Chapter 17/Sentence Conversions.w"
int i, nq = 0;
TRAVERSE_VARIABLE(p);
TRAVERSE_PROPOSITION(p, NP_prop)
switch (p->element) {
case DOMAIN_OPEN_ATOM: nq++; break;
case DOMAIN_CLOSE_ATOM: nq--; break;
}
if (nq < 0) internal_error("malformed proposition with too many domain ends");
for (i=1; i<=nq; i++)
NP_prop = Calculus__Propositions__concatenate(NP_prop, Calculus__Atoms__new(DOMAIN_CLOSE_ATOM));
}
#line 489 "inform7/Chapter 17/Sentence Conversions.w"
;
{
#line 506 "inform7/Chapter 17/Sentence Conversions.w"
if (Calculus__Variables__is_well_formed(NP_prop) == FALSE) internal_error("malformed NP proposition");
int NF = Calculus__Variables__number_free(NP_prop);
if (NF >= 2) internal_error("two or more free variables from NP");
if (subject_of_NP->constant) {
if (NP_prop) internal_error("constant plus substantive prop from NP");
} else if (NF == 1) {
int v = Calculus__Terms__variable_underlying(subject_of_NP);
if (Calculus__Variables__status(NP_prop, v) != FREE_VST)
internal_error("free variable from NP but not the preferred term");
}
LOGIF(PREDICATE_CALCULUS, "[%d] Calculus__Propositions__FromSentences__NP_subtree_to_proposition: $w --> t = $0, phi = $D\n",
conv_log_depth, W, subject_of_NP, NP_prop);
conv_log_depth--;
}
#line 491 "inform7/Chapter 17/Sentence Conversions.w"
;
return NP_prop;
}
#line 48 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__nothing_constant(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
*changed = FALSE;
TRAVERSE_PROPOSITION(pl, prop)
if ((Calculus__Atoms__is_binary_predicate(pl)) && (Calculus__Atoms__is_equality_predicate(pl) == FALSE)) {
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(pl->predicate);
int i;
for (i=0; i<2; i++) {
if (Rvalues__is_nothing_object_constant(Calculus__Terms__constant_underlying(&(pl->terms[i])))) {
{
#line 105 "inform7/Chapter 17/Simplifications.w"
int nv = Calculus__Variables__find_unused(prop);
pcalc_term new_var = Calculus__Terms__new_variable(nv);
Calculus__Variables__substitute_nothing_in_term(&(pl->terms[i]), &new_var);
pcalc_prop *position = NULL; /* at the front if |nothing| is the SP... */
if (i == 1) position = pl_prev; /* ...but up close to the predicate if it's the OP */
/* insert four atoms, in reverse order, at this position: */
prop = Calculus__Propositions__insert_atom(prop, position, Calculus__Atoms__new(DOMAIN_CLOSE_ATOM));
if (BinaryPredicates__term_kind(bp, i))
prop = Calculus__Propositions__insert_atom(prop, position,
Calculus__Atoms__KIND_new(BinaryPredicates__term_kind(bp, i), new_var));
prop = Calculus__Propositions__insert_atom(prop, position, Calculus__Atoms__new(DOMAIN_OPEN_ATOM));
prop = Calculus__Propositions__insert_atom(prop, position, Calculus__Atoms__QUANTIFIER_new(not_exists_quantifier, nv, 0));
}
#line 58 "inform7/Chapter 17/Simplifications.w"
;
PROPOSITION_EDITED(pl, prop);
break;
}
}
}
return prop;
}
#line 163 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__use_listed_in(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
*changed = FALSE;
TRAVERSE_PROPOSITION(pl, prop) {
int j;
for (j=0; j<pl->arity; j++) {
parse_node *spec = Calculus__Terms__constant_underlying(&(pl->terms[j]));
if ((spec) && (Lvalues__get_storage_form(spec) == TABLE_ENTRY_VNT) &&
(ParseTree__no_children(spec) == 2)) {
parse_node *col = spec->down;
parse_node *tab = spec->down->next;
table_column *tc = Rvalues__to_table_column(col);
kind *K = Tables__Columns__get_kind(tc);
if (Kinds__Compare__eq(K, K_understanding)) K = K_snippet;
int nv = Calculus__Variables__find_unused(prop);
pcalc_term nv_term = Calculus__Terms__new_variable(nv);
prop = Calculus__Propositions__insert_atom(prop, pl_prev,
Calculus__Atoms__binary_PREDICATE_new(Tables__Columns__get_listed_in_predicate(tc),
nv_term, Calculus__Terms__new_constant(tab)));
pcalc_prop *new_KIND = Calculus__Atoms__KIND_new(K, nv_term);
new_KIND->predicate =
STORE_POINTER_binary_predicate(Tables__Columns__get_listed_in_predicate(tc));
prop = Calculus__Propositions__insert_atom(prop, pl_prev, new_KIND);
prop = Calculus__Propositions__insert_atom(prop, pl_prev,
Calculus__Atoms__QUANTIFIER_new(exists_quantifier, nv, 0));
Calculus__Variables__substitute_term_in_term(&(pl->terms[j]), &nv_term);
LocalVariables__add_table_lookup();
PROPOSITION_EDITED(pl, prop);
}
}
}
return prop;
}
#line 216 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__negated_determiners_nonex(pcalc_prop *prop, int *changed) {
return Calculus__Simplifications__negated_determiners(prop, changed, FALSE);
}
pcalc_prop *Calculus__Simplifications__negated_determiners(pcalc_prop *prop, int *changed,
int negate_existence_too) {
TRAVERSE_VARIABLE(pl);
*changed = FALSE;
TRAVERSE_PROPOSITION(pl, prop) {
pcalc_prop *quant_atom;
if (Calculus__Propositions__match(pl, 2,
NEGATION_OPEN_ATOM, NULL, QUANTIFIER_ATOM, &quant_atom)) {
if ((negate_existence_too) ||
((Calculus__Atoms__is_existence_quantifier(quant_atom) == FALSE))) {
prop = Calculus__Simplifications__prop_ungroup_and_negate_determiner(prop, pl_prev, TRUE);
PROPOSITION_EDITED(pl, prop);
}
}
}
return prop;
}
#line 261 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__prop_ungroup_and_negate_determiner(pcalc_prop *prop, pcalc_prop *after,
int add_domain_brackets) {
pcalc_prop *quant_atom, *last;
int fnd;
if (after == NULL)
fnd = Calculus__Propositions__match(prop, 2,
NEGATION_OPEN_ATOM, NULL, QUANTIFIER_ATOM, &quant_atom);
else
fnd = Calculus__Propositions__match(after, 3, ANY_ATOM_HERE, NULL,
NEGATION_OPEN_ATOM, NULL, QUANTIFIER_ATOM, &quant_atom);
if (fnd) {
quantifier *quant = RETRIEVE_POINTER_quantifier(quant_atom->predicate);
quantifier *antiquant = Quantifiers__get_negation(quant);
quant_atom->predicate = STORE_POINTER_quantifier(antiquant);
prop = Calculus__Propositions__ungroup_after(prop, after, &last); /* remove negation group brackets */
if ((quant == exists_quantifier) && (add_domain_brackets)) {
prop = Calculus__Propositions__insert_atom(prop, quant_atom, Calculus__Atoms__new(DOMAIN_OPEN_ATOM));
prop = Calculus__Propositions__insert_atom(prop, last, Calculus__Atoms__new(DOMAIN_CLOSE_ATOM));
}
if (antiquant == exists_quantifier) {
prop = Calculus__Propositions__ungroup_after(prop, quant_atom, NULL); /* remove domain group brackets */
}
LOGIF(PREDICATE_CALCULUS_WORKINGS, "Calculus__Simplifications__prop_ungroup_and_negate_determiner: $D\n", prop);
} else internal_error("not a negate-group-determiner");
return prop;
}
#line 303 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__negated_satisfiable(pcalc_prop *prop, int *changed) {
pcalc_prop *quant_atom, *predicate_atom, *kind_atom;
*changed = FALSE;
if ((Calculus__Propositions__match(prop, 6,
NEGATION_OPEN_ATOM, NULL,
QUANTIFIER_ATOM, &quant_atom,
KIND_ATOM, &kind_atom,
PREDICATE_ATOM, &predicate_atom,
NEGATION_CLOSE_ATOM, NULL,
END_PROP_HERE, NULL)) &&
(Calculus__Atoms__is_existence_quantifier(quant_atom)) &&
(Calculus__Atoms__is_equality_predicate(predicate_atom) == FALSE) &&
(kind_atom->terms[0].variable == quant_atom->terms[0].variable)) {
prop = Calculus__Simplifications__prop_ungroup_and_negate_determiner(prop, NULL, FALSE);
prop = Calculus__Propositions__insert_atom(prop, quant_atom, Calculus__Atoms__new(DOMAIN_OPEN_ATOM));
prop = Calculus__Propositions__insert_atom(prop, kind_atom, Calculus__Atoms__new(DOMAIN_CLOSE_ATOM));
*changed = TRUE;
}
return prop;
}
#line 353 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__make_kinds_of_value_explicit(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, prop)
if (Calculus__Atoms__is_binary_predicate(pl)) {
int i;
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(pl->predicate);
for (i=1; i>=0; i--) {
int v = pl->terms[i].variable;
if (v >= 0) {
kind *K = BinaryPredicates__term_kind(bp, i);
if (K) {
pcalc_prop *new_KIND = Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(v));
new_KIND->predicate = STORE_POINTER_binary_predicate(bp);
prop = Calculus__Propositions__insert_atom(prop, pl_prev, new_KIND);
}
*changed = TRUE;
}
}
}
return prop;
}
#line 383 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__redundant_kinds(pcalc_prop *prop, int *changed) {
int c1 = FALSE, c2 = FALSE;
prop = Calculus__Simplifications__simp_redundant_kinds_dash(prop, prop, 1, &c1);
prop = Calculus__Simplifications__simp_redundant_kinds_dash(prop, prop, 1, &c2);
if ((c1) || (c2)) *changed = TRUE; else *changed = FALSE;
return prop;
}
#line 403 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__simp_redundant_kinds_dash(pcalc_prop *prop, pcalc_prop *start_group,
int start_level, int *changed) {
pcalc_prop *optimal_kind_placings_domain[26], *optimal_kind_placings_statement[26];
{
#line 421 "inform7/Chapter 17/Simplifications.w"
TRAVERSE_VARIABLE(pl);
int blevel = start_level;
TRAVERSE_PROPOSITION(pl, start_group) {
if (Calculus__Atoms__element_get_group(pl->element) == OPEN_OPERATORS_GROUP) {
blevel++;
if (blevel == 2) prop = Calculus__Simplifications__simp_redundant_kinds_dash(prop, pl, 0, changed);
}
if (Calculus__Atoms__element_get_group(pl->element) == CLOSE_OPERATORS_GROUP) blevel--;
if (blevel == 0) break;
}
}
#line 407 "inform7/Chapter 17/Simplifications.w"
;
{
#line 466 "inform7/Chapter 17/Simplifications.w"
TRAVERSE_VARIABLE(pl);
int bvsp = 0, bound_vars_stack[26];
int blevel = start_level, j;
for (j=0; j<26; j++) {
optimal_kind_placings_domain[j] = (start_level == 1)?NULL:start_group;
optimal_kind_placings_statement[j] = optimal_kind_placings_domain[j];
}
TRAVERSE_PROPOSITION(pl, start_group) {
if (Calculus__Atoms__element_get_group(pl->element) == OPEN_OPERATORS_GROUP) blevel++;
if (Calculus__Atoms__element_get_group(pl->element) == CLOSE_OPERATORS_GROUP) blevel--;
if (blevel == 0) break;
pcalc_prop *dom;
if (Calculus__Propositions__match(pl, 2,
QUANTIFIER_ATOM, NULL, DOMAIN_OPEN_ATOM, &dom)) {
if ((Calculus__Atoms__is_existence_quantifier(pl)) ||
(Calculus__Atoms__is_nonexistence_quantifier(pl)))
bound_vars_stack[bvsp++] = -1;
else
bound_vars_stack[bvsp++] = pl->terms[0].variable;
optimal_kind_placings_domain[pl->terms[0].variable] = dom;
optimal_kind_placings_statement[pl->terms[0].variable] = dom;
} else if (Calculus__Atoms__is_existence_quantifier(pl)) {
optimal_kind_placings_domain[pl->terms[0].variable] = pl;
optimal_kind_placings_statement[pl->terms[0].variable] = pl;
}
if (pl->element == DOMAIN_CLOSE_ATOM) {
int v = bound_vars_stack[--bvsp];
if (v >= 0) optimal_kind_placings_statement[v] = pl;
}
}
}
#line 408 "inform7/Chapter 17/Simplifications.w"
;
{
#line 533 "inform7/Chapter 17/Simplifications.w"
TRAVERSE_VARIABLE(pl);
int domain_passed[26], j;
int blevel = start_level;
for (j=0; j<26; j++) domain_passed[j] = FALSE;
TRAVERSE_PROPOSITION(pl, start_group) {
for (j=0; j<26; j++)
if (pl == optimal_kind_placings_statement[j])
domain_passed[j] = TRUE;
if (Calculus__Atoms__element_get_group(pl->element) == OPEN_OPERATORS_GROUP) blevel++;
if (Calculus__Atoms__element_get_group(pl->element) == CLOSE_OPERATORS_GROUP) blevel--;
if (blevel == 1) {
if (pl->element == KIND_ATOM) {
kind *early_kind = pl->assert_kind;
int v = pl->terms[0].variable;
if ((v >= 0) && (early_kind)) {
{
#line 569 "inform7/Chapter 17/Simplifications.w"
TRAVERSE_VARIABLE(gpl);
int glevel = 1;
TRAVERSE_PROPOSITION(gpl, pl) {
if (Calculus__Atoms__element_get_group(gpl->element) == OPEN_OPERATORS_GROUP) glevel++;
if (gpl->element == DOMAIN_CLOSE_ATOM) {
if (glevel > 1) glevel--;
} else if (Calculus__Atoms__element_get_group(gpl->element) == CLOSE_OPERATORS_GROUP) glevel--;
if (glevel == 0) break;
if ((gpl != pl) && (gpl->element == KIND_ATOM) && (v == gpl->terms[0].variable)) {
/* i.e., |gpl| now points to a different kind atom on the same variable */
kind *later_kind = gpl->assert_kind;
if ((later_kind) && (Kinds__Compare__le(early_kind, later_kind))) {
prop = Calculus__Propositions__delete_atom(prop, gpl_prev);
PROPOSITION_EDITED_REPEATING_CURRENT(gpl, prop);
}
}
}
}
#line 550 "inform7/Chapter 17/Simplifications.w"
;
{
#line 590 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *best_place = optimal_kind_placings_domain[v];
if (domain_passed[v]) best_place = optimal_kind_placings_statement[v];
if (pl_prev != best_place) {
int state = Calculus__Atoms__is_unarticled(pl_prev);
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* that is, delete the current $K(v)$ */
pcalc_prop *new_K = Calculus__Atoms__KIND_new(early_kind,
Calculus__Terms__new_variable(v));
Calculus__Atoms__set_unarticled(new_K, state);
prop = Calculus__Propositions__insert_atom(prop, best_place, new_K); /* insert a new one */
PROPOSITION_EDITED_REPEATING_CURRENT(pl, prop);
}
}
#line 551 "inform7/Chapter 17/Simplifications.w"
;
}
}
}
if (blevel == 0) break;
}
}
#line 409 "inform7/Chapter 17/Simplifications.w"
;
{
#line 635 "inform7/Chapter 17/Simplifications.w"
TRAVERSE_VARIABLE(pl);
int blevel = start_level;
TRAVERSE_PROPOSITION(pl, start_group) {
if (Calculus__Atoms__element_get_group(pl->element) == OPEN_OPERATORS_GROUP) blevel++;
if (Calculus__Atoms__element_get_group(pl->element) == CLOSE_OPERATORS_GROUP) blevel--;
if (blevel == 1) {
if (pl->element == KIND_ATOM) {
kind *early_kind = pl->assert_kind;
parse_node *spec = pl->terms[0].constant;
if (ParseTree__is_rvalue(spec)) {
kind *K = Rvalues__to_kind(spec);
if ((K) && (Kinds__Compare__lt(early_kind, K_object) == FALSE) &&
(Kinds__Compare__le(early_kind, K))) {
prop = Calculus__Propositions__delete_atom(prop, pl_prev);
PROPOSITION_EDITED_REPEATING_CURRENT(pl, prop);
}
}
}
}
}
}
#line 410 "inform7/Chapter 17/Simplifications.w"
;
return prop;
}
#line 674 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__turn_right_way_round(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
*changed = FALSE;
TRAVERSE_PROPOSITION(pl, prop) {
binary_predicate *bp = Calculus__Atoms__is_binary_predicate(pl);
if ((bp) && (BinaryPredicates__is_the_wrong_way_round(bp))) {
pcalc_term pt = pl->terms[0];
pl->terms[0] = pl->terms[1];
pl->terms[1] = pt;
pl->predicate = STORE_POINTER_binary_predicate(BinaryPredicates__get_reversal(bp));
PROPOSITION_EDITED(pl, prop);
}
}
return prop;
}
#line 714 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__region_containment(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
*changed = FALSE;
TRAVERSE_PROPOSITION(pl, prop) {
binary_predicate *bp = Calculus__Atoms__is_binary_predicate(pl);
if (bp == R_containment) {
int j;
for (j=0; j<2; j++) {
int regionality = FALSE, backdropping = FALSE;
if (pl->terms[j].constant) {
kind *KR = Specifications__to_kind(pl->terms[j].constant);
if (Kinds__Compare__le(KR, K_region)) {
regionality = TRUE;
LOG("Regional: $T == $u\n", pl->terms[j].constant, KR);
}
}
if (pl->terms[1-j].constant) {
kind *KB = Specifications__to_kind(pl->terms[1-j].constant);
if (Kinds__Compare__le(KB, K_backdrop)) backdropping = TRUE;
}
if ((regionality) && (!backdropping)) {
pl->predicate = STORE_POINTER_binary_predicate(R_regional_containment);
PROPOSITION_EDITED(pl, prop);
}
}
}
}
return prop;
}
#line 772 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__reduce_predicates(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
*changed = FALSE;
TRAVERSE_PROPOSITION(pl, prop) {
binary_predicate *bp = Calculus__Atoms__is_binary_predicate(pl);
if (bp) {
int j;
for (j=0; j<2; j++)
if ((BinaryPredicates__get_term_as_function_of_other(bp, j)) &&
(BinaryPredicates__allows_function_simplification(bp))) {
pl->terms[1-j] = Calculus__Terms__new_function(bp, pl->terms[1-j], 1-j);
pl->predicate = STORE_POINTER_binary_predicate(R_equality);
PROPOSITION_EDITED(pl, prop);
}
}
}
return prop;
}
#line 804 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__eliminate_redundant_variables(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
int level, binding_status[26], binding_level[26], binding_sequence[26];
pcalc_prop *position_of_binding[26];
*changed = FALSE;
EliminateVariables:
{
#line 855 "inform7/Chapter 17/Simplifications.w"
int j, c = 0, level = 0;
for (j=0; j<26; j++) {
binding_status[j] = NOT_BOUND_AT_ALL;
binding_level[j] = 0; binding_sequence[j] = 0; position_of_binding[j] = NULL;
}
TRAVERSE_PROPOSITION(pl, prop) {
if (Calculus__Atoms__element_get_group(pl->element) == OPEN_OPERATORS_GROUP) level++;
if (Calculus__Atoms__element_get_group(pl->element) == CLOSE_OPERATORS_GROUP) level--;
if (Calculus__Atoms__is_quantifier(pl)) {
int v = pl->terms[0].variable;
if (Calculus__Atoms__is_existence_quantifier(pl)) binding_status[v] = BOUND_BY_EXISTS;
else binding_status[v] = BOUND_BY_SOMETHING_ELSE;
binding_level[v] = level;
binding_sequence[v] = c;
position_of_binding[v] = pl_prev;
}
c++;
}
}
#line 812 "inform7/Chapter 17/Simplifications.w"
;
level = 0;
TRAVERSE_PROPOSITION(pl, prop) {
if (Calculus__Atoms__element_get_group(pl->element) == OPEN_OPERATORS_GROUP) level++;
if (Calculus__Atoms__element_get_group(pl->element) == CLOSE_OPERATORS_GROUP) level--;
if (Calculus__Atoms__is_equality_predicate(pl)) {
int j;
for (j=1; j>=0; j--) {
int var_to_sub = pl->terms[j].variable;
int var_in_other_term = Calculus__Terms__variable_underlying(&(pl->terms[1-j]));
int var_is_redundant = FALSE, value_can_be_subbed = FALSE;
{
#line 902 "inform7/Chapter 17/Simplifications.w"
if ((var_to_sub >= 0)
&& (binding_status[var_to_sub] == BOUND_BY_EXISTS)
&& (binding_level[var_to_sub] == level))
var_is_redundant = TRUE;
if ((var_in_other_term < 0)
|| (binding_status[var_in_other_term] == NOT_BOUND_AT_ALL)
|| (binding_sequence[var_in_other_term] < binding_sequence[var_to_sub]))
value_can_be_subbed = TRUE;
}
#line 823 "inform7/Chapter 17/Simplifications.w"
;
if ((var_is_redundant) && (value_can_be_subbed)) {
int permitted;
Calculus__Variables__substitute_term(prop, var_to_sub, pl->terms[1-j],
TRUE, &permitted, changed);
if (permitted) {
LOGIF(PREDICATE_CALCULUS_WORKINGS, "Substituting %c <-- $0\n",
pcalc_vars[var_to_sub], &(pl->terms[1-j]));
/* first delete the ${\it is}(v, t)$ predicate */
prop = Calculus__Propositions__delete_atom(prop, pl_prev);
/* then unbind the variable, by deleting its $\exists v$ quantifier */
prop = Calculus__Propositions__delete_atom(prop, position_of_binding[var_to_sub]);
LOGIF(PREDICATE_CALCULUS_WORKINGS, "After deletion: $D\n", prop);
binding_status[var_to_sub] = NOT_BOUND_AT_ALL;
/* then substitute for all other occurrences of $v$ */
prop = Calculus__Variables__substitute_term(prop, var_to_sub, pl->terms[1-j],
FALSE, NULL, changed);
*changed = TRUE;
/* since the proposition is now shorter by 2 atoms, this loop terminates */
goto EliminateVariables;
}
}
}
}
}
Calculus__Variables__renumber(prop, NULL); /* for the sake of tidiness */
return prop;
}
#line 936 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__not_related_to_something(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
*changed = FALSE;
TRAVERSE_PROPOSITION(pl, prop) {
pcalc_prop *kind_atom;
if (Calculus__Propositions__match(pl, 3,
NEGATION_OPEN_ATOM, NULL,
KIND_ATOM, &kind_atom,
NEGATION_CLOSE_ATOM, NULL)) {
kind *K = kind_atom->assert_kind;
if (Kinds__Compare__lt(K, K_object)) {
binary_predicate *bp = NULL;
pcalc_term KIND_term = kind_atom->terms[0];
if (KIND_term.function) bp = KIND_term.function->bp;
if ((bp) && (Kinds__Compare__eq(K, BinaryPredicates__term_kind(bp, 1)))) {
parse_node *new_nothing =
Lvalues__new_actual_NONLOCAL_VARIABLE(i6_nothing_VAR);
prop = Calculus__Propositions__ungroup_after(prop, pl_prev, NULL); /* remove negation grouping */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |KIND_ATOM| */
/* now insert equality predicate: */
prop = Calculus__Propositions__insert_atom(prop, pl_prev,
Calculus__Atoms__binary_PREDICATE_new(R_equality,
KIND_term, Calculus__Terms__new_constant(new_nothing)));
PROPOSITION_EDITED(pl, prop);
}
}
}
}
return prop;
}
#line 983 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__convert_gerunds(pcalc_prop *prop, int *changed) {
*changed = FALSE;
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, prop)
if ((pl->element == PREDICATE_ATOM) && (pl->arity == 2))
for (int i=0; i<2; i++)
if (Conditions__is_TEST_ACTION(pl->terms[i].constant))
pl->terms[i].constant = Conditions__action_tested(pl->terms[i].constant);
return prop;
}
#line 1020 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__eliminate_to_have(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
*changed = FALSE;
TRAVERSE_PROPOSITION(pl, prop) {
if (Calculus__Atoms__is_equality_predicate(pl)) {
int i;
for (i=0; i<2; i++)
if ((pl->terms[i].function) &&
(pl->terms[i].function->bp == a_has_b_predicate) &&
(pl->terms[i].function->fn_of.constant) && (pl->terms[1-i].constant)) {
parse_node *spec = pl->terms[i].function->fn_of.constant;
if (Rvalues__is_CONSTANT_construction(spec, CON_property))
{
#line 1047 "inform7/Chapter 17/Simplifications.w"
property *prn = Rvalues__to_property(spec);
parse_node *po_spec =
Lvalues__new_PROPERTY_VALUE(spec, pl->terms[1-i].constant);
ParseTree__set_text(po_spec, prn->name);
int no_substitutions_made;
prop = Calculus__Simplifications__prop_substitute_prop_cons(prop, prn, po_spec, &no_substitutions_made, pl);
if (no_substitutions_made > 0) {
prop = Calculus__Propositions__delete_atom(prop, pl_prev);
PROPOSITION_EDITED_REPEATING_CURRENT(pl, prop);
}
}
#line 1034 "inform7/Chapter 17/Simplifications.w"
;
}
}
}
return prop;
}
#line 1065 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__prop_substitute_prop_cons(pcalc_prop *prop, property *prn,
parse_node *po_spec, int *count, pcalc_prop *not_this) {
TRAVERSE_VARIABLE(pl);
int j, c = 0;
TRAVERSE_PROPOSITION(pl, prop)
if (pl != not_this)
for (j=0; j<pl->arity; j++) {
pcalc_term *pt = &(pl->terms[j]);
while (pt->function) pt = &(pt->function->fn_of);
if (pt->constant == NULL) continue;
if (Rvalues__is_CONSTANT_construction(pt->constant, CON_property)) {
property *tprn;
tprn = Rvalues__to_property(pt->constant);
if (tprn == prn) {
pt->constant = po_spec;
c++;
}
}
}
*count = c;
return prop;
}
#line 1112 "inform7/Chapter 17/Simplifications.w"
pcalc_prop *Calculus__Simplifications__is_all_rooms(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
*changed = FALSE;
return prop;
TRAVERSE_PROPOSITION(pl, prop) {
pcalc_prop *q_atom, *k_atom, *bp_atom;
if ((Calculus__Propositions__match(pl, 6,
QUANTIFIER_ATOM, &q_atom,
DOMAIN_OPEN_ATOM, NULL,
KIND_ATOM, &k_atom,
DOMAIN_CLOSE_ATOM, NULL,
PREDICATE_ATOM, &bp_atom,
END_PROP_HERE, NULL)) &&
((Calculus__Atoms__is_forall_quantifier(q_atom)) || (Calculus__Atoms__is_notall_quantifier(q_atom))) &&
(Kinds__Compare__eq(k_atom->assert_kind, K_room)) &&
(bp_atom->arity == 2) &&
(RETRIEVE_POINTER_binary_predicate(bp_atom->predicate) == R_equality)) {
int j, v = k_atom->terms[0].variable;
for (j=0; j<2; j++) {
if ((bp_atom->terms[1-j].variable == v) && (v >= 0)) {
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |QUANTIFIER_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |DOMAIN_OPEN_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |KIND_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |DOMAIN_CLOSE_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |PREDICATE_ATOM| */
if (Calculus__Atoms__is_notall_quantifier(q_atom))
prop = Calculus__Propositions__insert_atom(prop, pl_prev, Calculus__Atoms__new(NEGATION_CLOSE_ATOM));
prop = Calculus__Propositions__insert_atom(prop, pl_prev,
Calculus__Atoms__EVERYWHERE_new(bp_atom->terms[j]));
if (Calculus__Atoms__is_notall_quantifier(q_atom))
prop = Calculus__Propositions__insert_atom(prop, pl_prev, Calculus__Atoms__new(NEGATION_OPEN_ATOM));
PROPOSITION_EDITED(pl, prop);
break;
}
}
}
if ((Calculus__Propositions__match(pl, 6,
QUANTIFIER_ATOM, &q_atom,
DOMAIN_OPEN_ATOM, NULL,
KIND_ATOM, &k_atom,
DOMAIN_CLOSE_ATOM, NULL,
PREDICATE_ATOM, &bp_atom,
END_PROP_HERE, NULL)) &&
(Calculus__Atoms__is_nonexistence_quantifier(q_atom)) &&
(Kinds__Compare__eq(k_atom->assert_kind, K_room)) &&
(Calculus__Atoms__is_composited(k_atom)) &&
(bp_atom->arity == 2) &&
(RETRIEVE_POINTER_binary_predicate(bp_atom->predicate) == R_equality)) {
int j, v = k_atom->terms[0].variable;
for (j=0; j<2; j++) {
if ((bp_atom->terms[1-j].variable == v) && (v >= 0)) {
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |QUANTIFIER_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |DOMAIN_OPEN_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |KIND_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |DOMAIN_CLOSE_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |PREDICATE_ATOM| */
prop = Calculus__Propositions__insert_atom(prop, pl_prev,
Calculus__Atoms__NOWHERE_new(bp_atom->terms[j]));
PROPOSITION_EDITED(pl, prop);
break;
}
}
}
}
return prop;
}
pcalc_prop *Calculus__Simplifications__everywhere_and_nowhere(pcalc_prop *prop, int *changed) {
TRAVERSE_VARIABLE(pl);
*changed = FALSE;
TRAVERSE_PROPOSITION(pl, prop) {
pcalc_prop *q_atom, *k_atom, *bp_atom;
if ((Calculus__Propositions__match(pl, 6,
QUANTIFIER_ATOM, &q_atom,
DOMAIN_OPEN_ATOM, NULL,
KIND_ATOM, &k_atom,
DOMAIN_CLOSE_ATOM, NULL,
PREDICATE_ATOM, &bp_atom,
END_PROP_HERE, NULL)) &&
((Calculus__Atoms__is_forall_quantifier(q_atom)) ||
(Calculus__Atoms__is_notall_quantifier(q_atom)) ||
(Calculus__Atoms__is_nonexistence_quantifier(q_atom))) &&
(Kinds__Compare__eq(k_atom->assert_kind, K_room)) &&
(bp_atom->arity == 2)) {
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(bp_atom->predicate);
if (((Calculus__Atoms__is_nonexistence_quantifier(q_atom) == FALSE) && (bp == R_containment)) ||
(bp == room_containment_predicate)) {
int j, v = k_atom->terms[0].variable;
for (j=0; j<2; j++) {
if ((bp_atom->terms[1-j].variable == v) && (v >= 0)) {
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |QUANTIFIER_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |DOMAIN_OPEN_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |KIND_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |DOMAIN_CLOSE_ATOM| */
prop = Calculus__Propositions__delete_atom(prop, pl_prev); /* remove |PREDICATE_ATOM| */
if (Calculus__Atoms__is_notall_quantifier(q_atom))
prop = Calculus__Propositions__insert_atom(prop, pl_prev, Calculus__Atoms__new(NEGATION_CLOSE_ATOM));
pcalc_prop *new_atom;
if (Calculus__Atoms__is_nonexistence_quantifier(q_atom))
new_atom = Calculus__Atoms__NOWHERE_new(bp_atom->terms[j]);
else
new_atom = Calculus__Atoms__EVERYWHERE_new(bp_atom->terms[j]);
prop = Calculus__Propositions__insert_atom(prop, pl_prev, new_atom);
if (Calculus__Atoms__is_notall_quantifier(q_atom))
prop = Calculus__Propositions__insert_atom(prop, pl_prev, Calculus__Atoms__new(NEGATION_OPEN_ATOM));
PROPOSITION_EDITED(pl, prop);
break;
}
}
}
}
}
return prop;
}
#line 49 "inform7/Chapter 17/Type Check Propositions.w"
tc_problem_kit Calculus__Propositions__Checker__tc_no_problem_reporting(void) {
tc_problem_kit tck;
tck.issue_error = FALSE; tck.ew_text = EMPTY_WORDING; tck.intention = "be silent checking";
tck.log_to_I6_text = FALSE; tck.flag_problem = FALSE; return tck;
}
tc_problem_kit Calculus__Propositions__Checker__tc_problem_reporting(wording W, char *intent) {
tc_problem_kit tck = Calculus__Propositions__Checker__tc_no_problem_reporting();
tck.issue_error = TRUE; tck.ew_text = W; tck.intention = intent;
return tck;
}
#line 65 "inform7/Chapter 17/Type Check Propositions.w"
tc_problem_kit Calculus__Propositions__Checker__tc_problem_logging(void) {
tc_problem_kit tck = Calculus__Propositions__Checker__tc_no_problem_reporting();
tck.intention = "be internal testing"; tck.log_to_I6_text = TRUE; return tck;
}
#line 80 "inform7/Chapter 17/Type Check Propositions.w"
int Calculus__Propositions__Checker__type_check(pcalc_prop *prop, tc_problem_kit tck_s) {
TRAVERSE_VARIABLE(pl);
variable_type_assignment vta;
tc_problem_kit *tck = &tck_s;
LOGIF(MATCHING, "Type-checking proposition: $D\n", prop);
int j;
if (prop == NULL) return ALWAYS_MATCH;
if (Calculus__Variables__is_well_formed(prop) == FALSE)
internal_error("type-checking malformed proposition");
{
#line 141 "inform7/Chapter 17/Type Check Propositions.w"
TRAVERSE_PROPOSITION(pl, prop) {
int j;
for (j=0; j<pl->arity; j++) {
parse_node *spec = Calculus__Terms__constant_underlying(&(pl->terms[j]));
if (spec) {
int rv = NEVER_MATCH;
if (!(ParseTree__is(spec, UNKNOWN_VNT))) {
if (tck->issue_error) rv = Dash__check_value(spec, NULL);
else rv = Dash__check_value_silently(spec, NULL);
}
if (rv == NEVER_MATCH)
{
#line 237 "inform7/Chapter 17/Type Check Propositions.w"
if (problem_count == 0) {
if (tck->log_to_I6_text) LOG("Atom $o contains failed constant\n", pl);
if (tck->issue_error == FALSE) return NEVER_MATCH;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(spec));
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"The sentence %1 seems to contain a value '%2' which I can't make "
"any sense of.");
Problems__issue_problem_end();
LOG("Stare at this, then: $P\n", spec);
}
return NEVER_MATCH;
}
#line 151 "inform7/Chapter 17/Type Check Propositions.w"
;
}
}
}
}
#line 92 "inform7/Chapter 17/Type Check Propositions.w"
;
for (j=0; j<26; j++) vta.assigned_kinds[j] = NULL;
{
#line 169 "inform7/Chapter 17/Type Check Propositions.w"
TRAVERSE_PROPOSITION(pl, prop)
if (pl->element == KIND_ATOM) {
int v = pl->terms[0].variable;
if (v >= 0) {
kind *new_kind = pl->assert_kind;
if (Kinds__Compare__le(new_kind, K_object)) new_kind = K_object;
kind *old_kind = vta.assigned_kinds[v];
if (old_kind) {
if (Kinds__Compare__compatible(old_kind, new_kind) == NEVER_MATCH) {
if (tck->log_to_I6_text)
LOG("%c is both $u and $u\n", pcalc_vars[v], old_kind, new_kind);
Calculus__Propositions__Checker__issue_kind_typecheck_error(old_kind, new_kind, tck, pl);
return NEVER_MATCH;
}
if (Kinds__Behaviour__definite(new_kind) == FALSE) new_kind = old_kind;
}
vta.assigned_kinds[v] = new_kind;
}
}
}
#line 95 "inform7/Chapter 17/Type Check Propositions.w"
;
{
#line 194 "inform7/Chapter 17/Type Check Propositions.w"
TRAVERSE_PROPOSITION(pl, prop)
if ((pl->element == KIND_ATOM) && (pl->unarticled)) {
if (tck->log_to_I6_text)
LOG("Rejecting as unarticled\n");
if (tck->issue_error == FALSE) return NEVER_MATCH;
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_BareKindVariable));
Problems__issue_problem_segment(
"The sentence %1 seems to use a kind variable by its letter "
"alone in the context of a noun, which Inform doesn't allow. "
"It's fine to say 'if the noun is a K', for example, but "
"not 'if K is number'. By putting 'a' or 'an' in front of the "
"kind variable, you make clear that I'm supposed to perform "
"matching against a description.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
}
#line 96 "inform7/Chapter 17/Type Check Propositions.w"
;
{
#line 228 "inform7/Chapter 17/Type Check Propositions.w"
int j;
for (j=0; j<26; j++)
if (vta.assigned_kinds[j] == NULL)
vta.assigned_kinds[j] = K_object;
}
#line 97 "inform7/Chapter 17/Type Check Propositions.w"
;
TRAVERSE_PROPOSITION(pl, prop) {
for (j=0; j<pl->arity; j++) Calculus__Propositions__Checker__kind_of_term(&(pl->terms[j]), &vta, tck);
if (tck->flag_problem) return NEVER_MATCH;
if (pl->element == KIND_ATOM)
{
#line 265 "inform7/Chapter 17/Type Check Propositions.w"
kind *need_to_find = pl->assert_kind;
if (Kinds__Compare__le(need_to_find, K_object)) need_to_find = K_object;
kind *actually_find = Calculus__Propositions__Checker__kind_of_term(&(pl->terms[0]), &vta, tck);
if (Kinds__Compare__compatible(actually_find, need_to_find) == NEVER_MATCH) {
if (tck->log_to_I6_text)
LOG("Term $0 is $u not $u\n", &(pl->terms[0]), actually_find, need_to_find);
Calculus__Propositions__Checker__issue_kind_typecheck_error(actually_find, need_to_find, tck, pl);
return NEVER_MATCH;
}
}
#line 103 "inform7/Chapter 17/Type Check Propositions.w"
;
if ((pl->element == PREDICATE_ATOM) && (pl->arity == 2))
{
#line 294 "inform7/Chapter 17/Type Check Propositions.w"
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(pl->predicate);
if (BinaryPredicates__is_the_wrong_way_round(bp)) internal_error("BP wrong way round");
if (Calculus__Propositions__Checker__type_check_binary_predicate(pl, &vta, tck) == NEVER_MATCH) {
if (bp == R_equality) {
adjective_usage *alt = Calculus__Terms__noun_to_adj_conversion(pl->terms[1]);
if (alt) {
pcalc_prop test_unary = *pl;
test_unary.arity = 1;
test_unary.predicate = STORE_POINTER_adjective_usage(alt);
if (Calculus__Propositions__Checker__type_check_unary_predicate(&test_unary, &vta, tck) == NEVER_MATCH)
{
#line 314 "inform7/Chapter 17/Type Check Propositions.w"
if (tck->log_to_I6_text) LOG("BP $o cannot be applied\n", pl);
return NEVER_MATCH;
}
#line 304 "inform7/Chapter 17/Type Check Propositions.w"
;
pl->arity = 1;
pl->predicate = STORE_POINTER_adjective_usage(alt);
} else
{
#line 314 "inform7/Chapter 17/Type Check Propositions.w"
if (tck->log_to_I6_text) LOG("BP $o cannot be applied\n", pl);
return NEVER_MATCH;
}
#line 307 "inform7/Chapter 17/Type Check Propositions.w"
;
} else
{
#line 314 "inform7/Chapter 17/Type Check Propositions.w"
if (tck->log_to_I6_text) LOG("BP $o cannot be applied\n", pl);
return NEVER_MATCH;
}
#line 308 "inform7/Chapter 17/Type Check Propositions.w"
;
}
}
#line 105 "inform7/Chapter 17/Type Check Propositions.w"
;
if ((pl->element == PREDICATE_ATOM) && (pl->arity == 1))
{
#line 278 "inform7/Chapter 17/Type Check Propositions.w"
if (Calculus__Propositions__Checker__type_check_unary_predicate(pl, &vta, tck) == NEVER_MATCH) {
if (tck->log_to_I6_text) LOG("Adjective $o cannot be applied\n", pl);
return NEVER_MATCH;
}
}
#line 107 "inform7/Chapter 17/Type Check Propositions.w"
;
if (pl->element == EVERYWHERE_ATOM)
{
#line 327 "inform7/Chapter 17/Type Check Propositions.w"
kind *actually_find = Calculus__Propositions__Checker__kind_of_term(&(pl->terms[0]), &vta, tck);
if (Kinds__Compare__compatible(actually_find, K_object) == NEVER_MATCH) {
if (tck->log_to_I6_text)
LOG("Term $0 is $u not an object\n", &(pl->terms[0]), actually_find);
Problems__quote_kind(4, actually_find);
Problems__Issue__tcp_problem(_p_(PM_EverywhereMisapplied), tck,
"that seems to say that a value - specifically, %4 - is everywhere. "
"To Inform, everywhere means 'in every room', and only objects "
"can be everywhere - in fact not even all of those, as it's a "
"privilege reserved for backdrops. (For instance, 'The sky is a "
"backdrop. The sky is everywhere.' is allowed.)");
return NEVER_MATCH;
}
}
#line 109 "inform7/Chapter 17/Type Check Propositions.w"
;
if (pl->element == NOWHERE_ATOM)
{
#line 344 "inform7/Chapter 17/Type Check Propositions.w"
kind *actually_find = Calculus__Propositions__Checker__kind_of_term(&(pl->terms[0]), &vta, tck);
if (Kinds__Compare__compatible(actually_find, K_object) == NEVER_MATCH) {
if (tck->log_to_I6_text)
LOG("Term $0 is $u not an object\n", &(pl->terms[0]), actually_find);
Problems__quote_kind(4, actually_find);
Problems__Issue__tcp_problem(_p_(PM_NowhereMisapplied), tck,
"that seems to say that a value - specifically, %4 - is nowhere. "
"To Inform, nowhere means 'in no room', and only things can be "
"nowhere. (For instance, 'Godot is nowhere.' is allowed - it means "
"Godot exists, but is not initially part of the drama.)");
return NEVER_MATCH;
}
}
#line 111 "inform7/Chapter 17/Type Check Propositions.w"
;
if (pl->element == ISAKIND_ATOM)
{
#line 320 "inform7/Chapter 17/Type Check Propositions.w"
kind *actually_find = Calculus__Propositions__Checker__kind_of_term(&(pl->terms[0]), &vta, tck);
if (Kinds__Compare__compatible(actually_find, K_object) == NEVER_MATCH)
internal_error("ISAKIND atom misapplied");
}
#line 113 "inform7/Chapter 17/Type Check Propositions.w"
;
if (pl->element == HERE_ATOM)
{
#line 361 "inform7/Chapter 17/Type Check Propositions.w"
kind *actually_find = Calculus__Propositions__Checker__kind_of_term(&(pl->terms[0]), &vta, tck);
if (Kinds__Compare__compatible(actually_find, K_object) == NEVER_MATCH) {
if (tck->log_to_I6_text)
LOG("Term $0 is $u not an object\n", &(pl->terms[0]), actually_find);
Problems__quote_kind(4, actually_find);
Problems__Issue__tcp_problem(_p_(BelievedImpossible), tck,
"that seems to say that a value - specifically, %4 - is here. "
"To Inform, here means 'in the room we're talking about', so only "
"objects can be 'here'.");
return NEVER_MATCH;
}
}
#line 115 "inform7/Chapter 17/Type Check Propositions.w"
;
}
if (tck->log_to_I6_text)
{
#line 378 "inform7/Chapter 17/Type Check Propositions.w"
int j, var_states[26], c=0;
Calculus__Variables__determine_status(prop, var_states, NULL);
for (j=0; j<26; j++)
if (var_states[j] != UNUSED_VST) {
LOG("%c%s - $u. ", pcalc_vars[j],
(var_states[j] == FREE_VST)?" (free)":"",
vta.assigned_kinds[j]); c++;
}
if (c>0) LOG("\n");
}
#line 118 "inform7/Chapter 17/Type Check Propositions.w"
;
return ALWAYS_MATCH;
}
#line 395 "inform7/Chapter 17/Type Check Propositions.w"
kind *Calculus__Propositions__Checker__kind_of_term(pcalc_term *pt, variable_type_assignment *vta,
tc_problem_kit *tck) {
kind *K = Calculus__Propositions__Checker__kind_of_term_inner(pt, vta, tck);
pt->term_checked_as_kind = K;
if (K == NULL) { LOGIF(MATCHING, "No kind for term $0 = $T\n", pt, pt->constant); tck->flag_problem = TRUE; }
return K;
}
#line 410 "inform7/Chapter 17/Type Check Propositions.w"
kind *Calculus__Propositions__Checker__kind_of_term_inner(pcalc_term *pt, variable_type_assignment *vta,
tc_problem_kit *tck) {
if (pt->constant) return Specifications__to_kind(pt->constant);
if (pt->variable >= 0) return vta->assigned_kinds[pt->variable];
if (pt->function) {
binary_predicate *bp = pt->function->bp;
kind *kind_found = Calculus__Propositions__Checker__kind_of_term(&(pt->function->fn_of), vta, tck);
kind *kind_from = Calculus__Propositions__Checker__approximate_argument_kind(bp, pt->function->from_term);
kind *kind_to = Calculus__Propositions__Checker__approximate_argument_kind(bp, 1 - pt->function->from_term);
if ((kind_from) && (Kinds__Compare__compatible(kind_found, kind_from) == NEVER_MATCH)) {
if (tck->log_to_I6_text)
LOG("Term $0 applies function to $u not $u\n", pt, kind_found, kind_from);
Calculus__Propositions__Checker__issue_bp_typecheck_error(bp, kind_found, kind_to, tck);
kind_found = kind_from; /* the better to recover */
}
if (kind_to) return kind_to;
return kind_found;
}
return NULL;
}
#line 441 "inform7/Chapter 17/Type Check Propositions.w"
kind *Calculus__Propositions__Checker__approximate_argument_kind(binary_predicate *bp, int i) {
kind *K = BinaryPredicates__term_kind(bp, i);
if (K == NULL) return K_object;
return Kinds__weaken(K);
}
#line 453 "inform7/Chapter 17/Type Check Propositions.w"
int Calculus__Propositions__Checker__type_check_unary_predicate(pcalc_prop *pl, variable_type_assignment *vta,
tc_problem_kit *tck) {
adjective_usage *tr = RETRIEVE_POINTER_adjective_usage(pl->predicate);
adjectival_phrase *aph = Adjectives__Usages__get_aph(tr);
kind *K = Calculus__Propositions__Checker__kind_of_term(&(pl->terms[0]), vta, tck);
if ((aph) && (Adjectives__Phrases__applicable_to(aph, K) == FALSE)) {
wording W = Adjectives__Phrases__get_text(aph, FALSE);
if (tck->log_to_I6_text)
LOG("Adjective '$w' undefined on $u\n", W, K);
Problems__quote_wording(4, W);
Problems__quote_kind(5, K);
Problems__Issue__tcp_problem(_p_(PM_AdjectiveMisapplied), tck,
"that seems to involve applying the adjective '%4' to %5 - and I "
"have no definition of it which would apply in that situation. "
"(Try looking it up in the Lexicon part of the Phrasebook index "
"to see what definition(s) '%4' has.)");
return NEVER_MATCH;
}
return ALWAYS_MATCH;
}
#line 482 "inform7/Chapter 17/Type Check Propositions.w"
int Calculus__Propositions__Checker__type_check_binary_predicate(pcalc_prop *pl, variable_type_assignment *vta,
tc_problem_kit *tck) {
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(pl->predicate);
kind *kinds_of_terms[2], *kinds_required[2];
{
#line 549 "inform7/Chapter 17/Type Check Propositions.w"
for (int i=0; i<2; i++)
kinds_of_terms[i] =
Calculus__Propositions__Checker__kind_of_term(&(pl->terms[i]), vta, tck);
}
#line 487 "inform7/Chapter 17/Type Check Propositions.w"
;
if (bp == R_universal)
{
#line 556 "inform7/Chapter 17/Type Check Propositions.w"
if (Kinds__get_construct(kinds_of_terms[0]) != CON_relation) {
Problems__quote_kind(4, kinds_of_terms[0]);
Problems__Issue__tcp_problem(_p_(PM_BadUniversal1), tck,
"that asks whether something relates something, and in Inform 'to relate' "
"means that a particular relation applies between two things. Here, though, "
"we have %4 rather than the name of a relation.");
return NEVER_MATCH;
}
if (Kinds__get_construct(kinds_of_terms[1]) != CON_combination) {
Problems__quote_kind(4, kinds_of_terms[1]);
Problems__Issue__tcp_problem(_p_(BelievedImpossible), tck,
"that asks whether something relates something, and in Inform 'to relate' "
"means that a particular relation applies between two things. Here, though, "
"we have %4 rather than the combination of the two things.");
return NEVER_MATCH;
}
parse_node *left = pl->terms[0].constant;
if (ParseTree__is(left, CONSTANT_VNT)) {
bp = Rvalues__to_binary_predicate(left);
kind *cleft = NULL, *cright = NULL;
Kinds__binary_construction_material(kinds_of_terms[1], &cleft, &cright);
kinds_of_terms[0] = cleft;
kinds_of_terms[1] = cright;
}
}
#line 488 "inform7/Chapter 17/Type Check Propositions.w"
;
{
#line 538 "inform7/Chapter 17/Type Check Propositions.w"
for (int i=0; i<2; i++) {
kind *K = Kinds__weaken(BinaryPredicates__term_kind(bp, i));
if (K == NULL) K = K_object;
kinds_required[i] = K;
}
}
#line 489 "inform7/Chapter 17/Type Check Propositions.w"
;
int result = BinaryPredicates__typecheck(bp, kinds_of_terms, kinds_required, tck);
if (result == NEVER_MATCH_SAYING_WHY_NOT) {
kind *kinds_dereferencing_properties[2];
LOG("0 = $u. 1 = $u\n", kinds_of_terms[0], kinds_of_terms[1]);
kinds_dereferencing_properties[0] = Kinds__dereference_properties(kinds_of_terms[0]);
kinds_dereferencing_properties[1] = kinds_of_terms[1];
int r2 = BinaryPredicates__typecheck(bp, kinds_dereferencing_properties, kinds_required, tck);
if ((r2 == ALWAYS_MATCH) || (r2 == SOMETIMES_MATCH)) {
result = r2;
}
}
if (result != DECLINE_TO_MATCH) {
if (result == NEVER_MATCH_SAYING_WHY_NOT) {
if (tck->issue_error == FALSE) return NEVER_MATCH;
if (pl->terms[0].function)
Calculus__Propositions__Checker__issue_bp_typecheck_error(pl->terms[0].function->bp,
Calculus__Propositions__Checker__kind_of_term(&(pl->terms[0].function->fn_of), vta, tck),
kinds_of_terms[1], tck);
else if (pl->terms[1].function)
Calculus__Propositions__Checker__issue_bp_typecheck_error(pl->terms[1].function->bp,
kinds_of_terms[0],
Calculus__Propositions__Checker__kind_of_term(&(pl->terms[1].function->fn_of), vta, tck),
tck);
else {
LOG("($u, $u) failed in $2\n", kinds_of_terms[0], kinds_of_terms[1], bp);
Problems__quote_kind(4, kinds_of_terms[0]);
Problems__quote_kind(5, kinds_of_terms[1]);
Problems__Issue__tcp_problem(_p_(PM_ComparisonFailed), tck,
"that would mean comparing two kinds of value which cannot mix - "
"%4 and %5 - so this must be incorrect.");
}
return NEVER_MATCH;
}
return result;
}
{
#line 586 "inform7/Chapter 17/Type Check Propositions.w"
int i;
for (i=0; i<2; i++)
if (kinds_required[i])
if (Kinds__Compare__compatible(kinds_of_terms[i], kinds_required[i]) == NEVER_MATCH) {
if (tck->log_to_I6_text)
LOG("Term %d is $u not $u\n",
i, kinds_of_terms[i], kinds_required[i]);
Calculus__Propositions__Checker__issue_bp_typecheck_error(bp,
kinds_of_terms[0], kinds_of_terms[1], tck);
return NEVER_MATCH;
}
}
#line 528 "inform7/Chapter 17/Type Check Propositions.w"
;
return ALWAYS_MATCH;
}
#line 601 "inform7/Chapter 17/Type Check Propositions.w"
void Calculus__Propositions__Checker__issue_bp_typecheck_error(binary_predicate *bp,
kind *t0, kind *t1, tc_problem_kit *tck) {
Problems__quote_kind(4, t0);
Problems__quote_kind(5, t1);
Problems__quote_relation(6, bp);
Problems__Issue__tcp_problem(_p_(PM_TypeCheckBP2), tck,
"that would mean applying %6 to kinds of value which do not "
"fit - %4 and %5 - so this must be incorrect.");
}
void Calculus__Propositions__Checker__issue_kind_typecheck_error(kind *actually_find,
kind *need_to_find, tc_problem_kit *tck, pcalc_prop *ka) {
binary_predicate *bp = NULL;
if ((ka) && (GENERAL_POINTER_IS_NULL(ka->predicate) == FALSE))
bp = RETRIEVE_POINTER_binary_predicate(ka->predicate);
Problems__quote_kind(4, actually_find);
Problems__quote_kind(5, need_to_find);
if (bp) {
Problems__quote_relation(6, bp);
Problems__Issue__tcp_problem(_p_(PM_TypeCheckBP2a), tck,
"that doesn't work because you use %6 with %4 instead of %5.");
} else {
Problems__Issue__tcp_problem(_p_(PM_TypeCheckKind), tck,
"%4 cannot be %5, so this must be incorrect.");
}
}
#line 20 "inform7/Chapter 18/The Equality Relation.w"
void Calculus__Equality__REL_create_initial_stock(void) {
R_equality = BinaryPredicates__make_equality();
BinaryPredicates__set_index_details(R_equality, "value", "value");
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(MISCELLANEOUS_MC,
Preform__Nonparsing__merge(relation_name_formal_NTM, 0,
Preform__Nonparsing__wording(relation_names_NTM, EQUALITY_RELATION_NAME)),
Rvalues__from_binary_predicate(R_equality));
}
#line 33 "inform7/Chapter 18/The Equality Relation.w"
void Calculus__Equality__REL_create_second_stock(void) {
}
#line 41 "inform7/Chapter 18/The Equality Relation.w"
int Calculus__Equality__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
LOGIF(MATCHING, "Typecheck $u '==' $u\n", kinds_of_terms[0], kinds_of_terms[1]);
if ((Kinds__Compare__eq(kinds_of_terms[0], K_understanding)) &&
(Kinds__Compare__eq(kinds_of_terms[1], K_text))) {
LOGIF(MATCHING, "No!\n");
Problems__Issue__tcp_problem(_p_(PM_TextIsNotTopic), tck,
"though they look the same, because both are written in double "
"quotes, text values can't in fact be used as topics, so it's "
"impossible to store this piece of text in that location.");
return NEVER_MATCH;
}
if (Plugins__Call__typecheck_equality(kinds_of_terms[0], kinds_of_terms[1]))
return ALWAYS_MATCH;
if ((Kinds__Compare__le(kinds_of_terms[0], K_object)) &&
(Kinds__Behaviour__name_can_coincide_with_property(kinds_of_terms[1])))
{
#line 78 "inform7/Chapter 18/The Equality Relation.w"
property *prn = Kinds__Behaviour__get_coinciding_property(kinds_of_terms[1]);
if (prn == NULL) {
if (tck->log_to_I6_text)
LOG("Comparison of object with $u value\n", kinds_of_terms[1]);
Problems__quote_kind(4, kinds_of_terms[1]);
Problems__Issue__tcp_problem(_p_(PM_NonPropertyCompared), tck,
"taken literally that says that an object is the same as a "
"value. Maybe you intended to say that the object "
"has a property - but right now %4 is not yet a property; if you "
"want to use it as one, you'll need to say so. (You can turn a "
"kind of value - say, 'colour' - into a property by writing - "
"say - 'A thing has a colour.')");
return NEVER_MATCH;
}
}
#line 59 "inform7/Chapter 18/The Equality Relation.w"
else if ((Kinds__Compare__eq(kinds_of_terms[1], K_understanding)) &&
(Kinds__Compare__eq(kinds_of_terms[0], K_snippet)))
return ALWAYS_MATCH;
else if ((Kinds__Compare__eq(kinds_of_terms[0], K_understanding)) &&
(Kinds__Compare__eq(kinds_of_terms[1], K_snippet)))
return ALWAYS_MATCH;
else if ((Kinds__Compare__eq(kinds_of_terms[1], K_text)) &&
(Kinds__Compare__eq(kinds_of_terms[0], K_response)))
return ALWAYS_MATCH;
else
{
#line 99 "inform7/Chapter 18/The Equality Relation.w"
if (Calculus__Equality__both_terms_of_same_construction(kinds_of_terms[0], kinds_of_terms[1], CON_rule))
return ALWAYS_MATCH;
if (Calculus__Equality__both_terms_of_same_construction(kinds_of_terms[0], kinds_of_terms[1], CON_rulebook))
return ALWAYS_MATCH;
if (Calculus__Equality__both_terms_of_same_construction(kinds_of_terms[0], kinds_of_terms[1], CON_activity))
return ALWAYS_MATCH;
if ((Kinds__Compare__compatible(kinds_of_terms[0], kinds_of_terms[1]) == NEVER_MATCH) &&
(Kinds__Compare__compatible(kinds_of_terms[1], kinds_of_terms[0]) == NEVER_MATCH)) {
if (tck->log_to_I6_text)
LOG("Unable to compare $u with $u\n", kinds_of_terms[0], kinds_of_terms[1]);
return NEVER_MATCH_SAYING_WHY_NOT;
}
}
#line 70 "inform7/Chapter 18/The Equality Relation.w"
;
return ALWAYS_MATCH;
}
#line 115 "inform7/Chapter 18/The Equality Relation.w"
int Calculus__Equality__both_terms_of_same_construction(kind *k0, kind *k1, kind_constructor *cons) {
if ((Kinds__get_construct(k0) == cons) && (Kinds__get_construct(k1) == cons))
return TRUE;
return FALSE;
}
#line 126 "inform7/Chapter 18/The Equality Relation.w"
int Calculus__Equality__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
if (Lvalues__is_actual_NONLOCAL_VARIABLE(spec0)) {
nonlocal_variable *q = ParseTree__get_constant_nonlocal_variable(spec0);
int allowed = TRUE;
if ((prevailing_mood != UNKNOWN_CE) && (prevailing_mood != LIKELY_CE))
allowed = FALSE;
if ((NonlocalVariables__is_constant(q)) && (prevailing_mood == CERTAIN_CE))
allowed = TRUE;
if (allowed == FALSE)
Problems__Issue__sentence_problem(_p_(PM_CantQualifyVariableValues),
"a variable can only be given its value straightforwardly or "
"qualified by 'usually'",
"not with 'always', 'seldom' or 'never'.");
else World__Inferences__draw_property(
NonlocalVariables__get_knowledge(q), P_variable_initial_value, spec1);
return TRUE;
}
return FALSE;
}
#line 180 "inform7/Chapter 18/The Equality Relation.w"
int Calculus__Equality__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) {
kind *st[2];
st[0] = Calculus__Deferrals__Cinders__kind_of_value_of_term(asch->pt0);
st[1] = Calculus__Deferrals__Cinders__kind_of_value_of_term(asch->pt1);
if ((Kinds__Compare__le(st[0], K_object)) &&
(Kinds__Behaviour__name_can_coincide_with_property(st[1])) && (Kinds__Behaviour__get_coinciding_property(st[1])))
{
#line 242 "inform7/Chapter 18/The Equality Relation.w"
property *prn = Kinds__Behaviour__get_coinciding_property(st[1]);
switch (task) {
case TEST_ATOM_TASK:
Calculus__Schemas__modify(asch->schema, "*1.%s == *2", Properties__get_translation(prn));
return TRUE;
case NOW_ATOM_FALSE_TASK:
break;
case NOW_ATOM_TRUE_TASK:
Calculus__Schemas__modify(asch->schema, "*1.%s = *2", Properties__get_translation(prn));
return TRUE;
}
return FALSE;
}
#line 187 "inform7/Chapter 18/The Equality Relation.w"
;
if ((Kinds__Compare__eq(st[0], K_response)) && (Kinds__Compare__eq(st[1], K_text)))
{
#line 258 "inform7/Chapter 18/The Equality Relation.w"
switch (task) {
case TEST_ATOM_TASK:
Problems__Issue__sentence_problem(_p_(PM_ResponseComparisonUnsafe),
"for complicated internal reasons this comparison isn't safe to perform",
"and might give you a falsely negative result. To avoid what might "
"be misleading, you aren't allowed to compare a response to text.");
break;
case NOW_ATOM_FALSE_TASK:
break;
case NOW_ATOM_TRUE_TASK:
Calculus__Schemas__modify(asch->schema, "BlkValueCopy(ResponseTexts-->((*1)-1), *^2)");
return TRUE;
}
return FALSE;
}
#line 190 "inform7/Chapter 18/The Equality Relation.w"
;
switch (task) {
case TEST_ATOM_TASK:
if ((st[0]) && (st[1]))
Calculus__Schemas__modify(asch->schema, "%s",
Kinds__Behaviour__interpret_test_equality(st[0], st[1]));
else if (problem_count == 0) {
LOG("$0 and $0; $u and $u\n", &(asch->pt0), &(asch->pt1), st[0], st[1]);
Problems__Issue__sentence_problem(_p_(PM_CantCompareValues),
"that would involve comparing things which don't mean "
"anything to me",
"so I'm lost.");
}
return TRUE;
case NOW_ATOM_FALSE_TASK:
break;
case NOW_ATOM_TRUE_TASK: {
node_type_t storage_class = Lvalues__get_storage_form(asch->pt0.constant);
if ((storage_class == UNKNOWN_VNT) &&
(Kinds__get_construct(st[0]) == CON_property))
storage_class = PROPERTY_VALUE_VNT;
if (Plugins__Call__forbid_setting(asch->pt1.term_checked_as_kind)) {
asch->schema = NULL;
return TRUE;
}
{
#line 291 "inform7/Chapter 18/The Equality Relation.w"
if (Kinds__Compare__compatible(st[1], st[0]) == NEVER_MATCH) {
kind *dst[2];
dst[0] = Kinds__dereference_properties(st[0]);
dst[1] = Kinds__dereference_properties(st[1]);
if (Kinds__Compare__compatible(dst[1], dst[0]) == NEVER_MATCH) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, st[1]);
Problems__quote_kind(3, st[0]);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"In the line %1, you seem to be asking me to put %2 into %3, "
"which can't safely be done.");
Problems__issue_problem_end();
asch->schema = NULL;
return TRUE;
}
}
}
#line 216 "inform7/Chapter 18/The Equality Relation.w"
;
if (storage_class == UNKNOWN_VNT) {
{
#line 313 "inform7/Chapter 18/The Equality Relation.w"
if (Rvalues__to_instance(asch->pt0.constant)) {
if (Kinds__Compare__le(Specifications__to_kind(asch->pt0.constant), K_object))
Problems__Issue__sentence_problem(_p_(PM_CantEquateValues),
"equality is not something I can change",
"so either those are already the same or are different, and I "
"can't alter matters.");
else
Problems__Issue__sentence_problem(_p_(PM_CantChangeNamedConstant),
"I can't change that",
"because it is a name for a constant value. Some named values, "
"like 'the score', can be changed, because they were defined "
"as values that vary. But others are fixed. If we write 'The "
"oak tree can be sturdy, lightning-struck or leaning.', for "
"instance, then 'sturdy' is a name for a value which is fixed, "
"just as the number '7' is fixed.");
}
}
#line 218 "inform7/Chapter 18/The Equality Relation.w"
asch->schema = NULL;
} else {
{
#line 276 "inform7/Chapter 18/The Equality Relation.w"
nonlocal_variable *nlv =
Lvalues__get_nonlocal_variable_if_any(asch->pt0.constant);
if ((nlv) && (NonlocalVariables__must_be_constant(nlv))) {
asch->schema = NULL;
return TRUE;
}
char *exotica = NonlocalVariables__get_write_schema(nlv);
if (exotica) {
Calculus__Schemas__modify(asch->schema, "%s", exotica);
return TRUE;
}
}
#line 221 "inform7/Chapter 18/The Equality Relation.w"
;
Calculus__Schemas__modify(asch->schema, "%s",
Kinds__Behaviour__interpret_store(storage_class, st[0], st[1], 0));
{
#line 333 "inform7/Chapter 18/The Equality Relation.w"
if ((Kinds__Compare__compatible(st[1], st[0]) == SOMETIMES_MATCH) &&
(Kinds__Compare__lt(st[0], K_object))) {
TEMPORARY_STREAM;
WRITE_TO(TEMP,
"; if (~~(*1 ofclass %s)) RunTimeProblem(RTP_WRONGASSIGNEDKIND, *1, \"*?\", \"",
Kinds__Behaviour__I6_classname(st[0]));
Kinds__Textual__write(TEMP, st[0]);
WRITE_TO(TEMP, "\");");
Calculus__Schemas__append(asch->schema, "%s", STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
}
#line 224 "inform7/Chapter 18/The Equality Relation.w"
;
}
return TRUE;
}
}
return FALSE;
}
#line 348 "inform7/Chapter 18/The Equality Relation.w"
int Calculus__Equality__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 32 "inform7/Chapter 18/Quasinumeric Relations.w"
void Calculus__QuasinumericRelations__REL_create_initial_stock(void) {
bp_term_details number_term = BinaryPredicates__new_term(Kinds__Behaviour__as_subject(K_number));
R_numerically_greater_than =
BinaryPredicates__make_pair(QUASINUMERIC_KBP,
number_term, number_term,
"greater-than", NULL, NULL, NULL, Calculus__Schemas__new("*1 > *2"),
Preform__Nonparsing__wording(relation_names_NTM, GT_RELATION_NAME));
R_numerically_less_than =
BinaryPredicates__make_pair(QUASINUMERIC_KBP,
number_term, number_term,
"less-than", NULL, NULL, NULL, Calculus__Schemas__new("*1 < *2"),
Preform__Nonparsing__wording(relation_names_NTM, LT_RELATION_NAME));
R_numerically_greater_than_or_equal_to =
BinaryPredicates__make_pair(QUASINUMERIC_KBP,
number_term, number_term,
"at-least", NULL, NULL, NULL, Calculus__Schemas__new("*1 >= *2"),
Preform__Nonparsing__wording(relation_names_NTM, GE_RELATION_NAME));
R_numerically_less_than_or_equal_to =
BinaryPredicates__make_pair(QUASINUMERIC_KBP,
number_term, number_term,
"at-most", NULL, NULL, NULL, Calculus__Schemas__new("*1 <= *2"),
Preform__Nonparsing__wording(relation_names_NTM, LE_RELATION_NAME));
BinaryPredicates__set_index_details(R_numerically_greater_than,
"arithmetic value", "arithmetic value");
BinaryPredicates__set_index_details(R_numerically_less_than,
"arithmetic value", "arithmetic value");
BinaryPredicates__set_index_details(R_numerically_greater_than_or_equal_to,
"arithmetic value", "arithmetic value");
BinaryPredicates__set_index_details(R_numerically_less_than_or_equal_to,
"arithmetic value", "arithmetic value");
}
#line 68 "inform7/Chapter 18/Quasinumeric Relations.w"
void Calculus__QuasinumericRelations__REL_create_second_stock(void) {
}
#line 74 "inform7/Chapter 18/Quasinumeric Relations.w"
int Calculus__QuasinumericRelations__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
if ((Kinds__Compare__compatible(kinds_of_terms[0], kinds_of_terms[1]) == NEVER_MATCH) &&
(Kinds__Compare__compatible(kinds_of_terms[1], kinds_of_terms[0]) == NEVER_MATCH)) {
if (tck->log_to_I6_text)
LOG("Unable to apply inequality of $u and $u\n", kinds_of_terms[0], kinds_of_terms[1]);
Problems__quote_kind(4, kinds_of_terms[0]);
Problems__quote_kind(5, kinds_of_terms[1]);
Problems__Issue__tcp_problem(_p_(PM_InequalityFailed), tck,
"that would mean comparing two kinds of value which cannot mix - "
"%4 and %5 - so this must be incorrect.");
return NEVER_MATCH;
}
return ALWAYS_MATCH;
}
#line 94 "inform7/Chapter 18/Quasinumeric Relations.w"
int Calculus__QuasinumericRelations__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
return FALSE;
}
#line 106 "inform7/Chapter 18/Quasinumeric Relations.w"
int Calculus__QuasinumericRelations__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) {
kind *st[2];
st[0] = Calculus__Deferrals__Cinders__kind_of_value_of_term(asch->pt0);
st[1] = Calculus__Deferrals__Cinders__kind_of_value_of_term(asch->pt1);
switch (task) {
case TEST_ATOM_TASK:
if ((st[0]) && (st[1])) {
char *cr = "";
int promote_left = FALSE, promote_right = FALSE;
if ((Kinds__FloatingPoint__uses_floating_point(st[0])) ||
(Kinds__FloatingPoint__uses_floating_point(st[1]))) {
if (Kinds__FloatingPoint__uses_floating_point(st[0]) == FALSE)
promote_left = TRUE;
if (Kinds__FloatingPoint__uses_floating_point(st[1]) == FALSE)
promote_right = TRUE;
cr = Kinds__Behaviour__get_comparison_routine(K_real_number);
} else
cr = Kinds__Behaviour__get_comparison_routine(st[0]);
if ((cr[0] == 0) || (strcmp(cr, "signed") == 0)) return FALSE;
if (promote_left) {
if (bp == R_numerically_greater_than)
Calculus__Schemas__modify(asch->schema, "*_2(NUMBER_TY_to_REAL_NUMBER_TY(*1), *2) > 0");
if (bp == R_numerically_less_than)
Calculus__Schemas__modify(asch->schema, "*_2(NUMBER_TY_to_REAL_NUMBER_TY(*1), *2) < 0");
if (bp == R_numerically_greater_than_or_equal_to)
Calculus__Schemas__modify(asch->schema, "*_2(NUMBER_TY_to_REAL_NUMBER_TY(*1), *2) >= 0");
if (bp == R_numerically_less_than_or_equal_to)
Calculus__Schemas__modify(asch->schema, "*_2(NUMBER_TY_to_REAL_NUMBER_TY(*1), *2) <= 0");
} else if (promote_right) {
if (bp == R_numerically_greater_than)
Calculus__Schemas__modify(asch->schema, "*_1(*1, NUMBER_TY_to_REAL_NUMBER_TY(*2)) > 0");
if (bp == R_numerically_less_than)
Calculus__Schemas__modify(asch->schema, "*_1(*1, NUMBER_TY_to_REAL_NUMBER_TY(*2)) < 0");
if (bp == R_numerically_greater_than_or_equal_to)
Calculus__Schemas__modify(asch->schema, "*_1(*1, NUMBER_TY_to_REAL_NUMBER_TY(*2)) >= 0");
if (bp == R_numerically_less_than_or_equal_to)
Calculus__Schemas__modify(asch->schema, "*_1(*1, NUMBER_TY_to_REAL_NUMBER_TY(*2)) <= 0");
} else {
if (bp == R_numerically_greater_than)
Calculus__Schemas__modify(asch->schema, "*_1(*1, *2) > 0");
if (bp == R_numerically_less_than)
Calculus__Schemas__modify(asch->schema, "*_1(*1, *2) < 0");
if (bp == R_numerically_greater_than_or_equal_to)
Calculus__Schemas__modify(asch->schema, "*_1(*1, *2) >= 0");
if (bp == R_numerically_less_than_or_equal_to)
Calculus__Schemas__modify(asch->schema, "*_1(*1, *2) <= 0");
}
} else if (problem_count == 0) {
LOG("$0 and $0; $u and $u\n", &(asch->pt0), &(asch->pt1), st[0], st[1]);
internal_error("null kind in equality test");
}
return TRUE;
}
return FALSE;
}
#line 166 "inform7/Chapter 18/Quasinumeric Relations.w"
int Calculus__QuasinumericRelations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 88 "inform7/Chapter 18/Assert Propositions.w"
void Calculus__Propositions__Assert__assert_true(pcalc_prop *prop, int certitude) {
Calculus__Propositions__Assert__prop_true_in_world_model_inner(prop, NULL, certitude);
}
void Calculus__Propositions__Assert__assert_true_about(pcalc_prop *prop, inference_subject *infs,
int certitude) {
Calculus__Propositions__Assert__prop_true_in_world_model_inner(prop, infs, certitude);
}
#line 103 "inform7/Chapter 18/Assert Propositions.w"
inference_subject **current_interpretation_as_infs = NULL; /* must point to a 26-element array */
parse_node **current_interpretation_as_spec = NULL; /* must point to a 26-element array */
#line 109 "inform7/Chapter 18/Assert Propositions.w"
parse_node *last_couldnt_assert_at = NULL;
#line 117 "inform7/Chapter 18/Assert Propositions.w"
void Calculus__Propositions__Assert__prop_true_in_world_model_inner(pcalc_prop *prop, inference_subject *subject,
int certainty) {
inference_subject **saved_interpretation_as_infs = current_interpretation_as_infs;
parse_node **saved_interpretation_as_spec = current_interpretation_as_spec;
int saved_prevailing_mood = prevailing_mood;
if (certainty != UNKNOWN_CE) prevailing_mood = certainty;
inference_subject *ciawo[26]; parse_node *ciats[26];
{
#line 142 "inform7/Chapter 18/Assert Propositions.w"
int k;
for (k=0; k<26; k++) { ciawo[k] = NULL; ciats[k] = NULL; }
ciawo[0] = subject; ciats[0] = NULL;
current_interpretation_as_infs = ciawo; current_interpretation_as_spec = ciats;
}
#line 125 "inform7/Chapter 18/Assert Propositions.w"
;
ptim_recursion_depth++;
Calculus__Propositions__Assert__prop_true_in_model(prop);
ptim_recursion_depth--;
prevailing_mood = saved_prevailing_mood;
current_interpretation_as_infs = saved_interpretation_as_infs;
current_interpretation_as_spec = saved_interpretation_as_spec;
}
#line 166 "inform7/Chapter 18/Assert Propositions.w"
void Calculus__Propositions__Assert__prop_true_in_model(pcalc_prop *prop) {
if (prop == NULL) return;
{
#line 202 "inform7/Chapter 18/Assert Propositions.w"
int i;
LOGIF(ASSERTIONS, "::");
switch(prevailing_mood) {
case IMPOSSIBLE_CE: LOGIF(ASSERTIONS, " (impossible)"); break;
case UNLIKELY_CE: LOGIF(ASSERTIONS, " (unlikely)"); break;
case UNKNOWN_CE: LOGIF(ASSERTIONS, " (no certainty)"); break;
case LIKELY_CE: LOGIF(ASSERTIONS, " (likely)"); break;
case INITIALLY_CE: LOGIF(ASSERTIONS, " (initially)"); break;
case CERTAIN_CE: break;
default: LOG(" (unknown certainty)"); break;
}
for (i=0; i<26; i++) {
if (current_interpretation_as_infs[i]) {
LOGIF(ASSERTIONS, " %c = $j", pcalc_vars[i], current_interpretation_as_infs[i]);
} else if (current_interpretation_as_spec[i]) {
LOGIF(ASSERTIONS, " %c = $P", pcalc_vars[i], current_interpretation_as_spec[i]);
}
}
LOGIF(ASSERTIONS, " $D\n", prop);
}
#line 168 "inform7/Chapter 18/Assert Propositions.w"
;
if (Calculus__Propositions__contains_nonexistence_quantifier(prop))
{
#line 228 "inform7/Chapter 18/Assert Propositions.w"
Problems__Issue__sentence_problem(_p_(PM_CantAssertQuantifier),
"the relationship you describe is not exact enough",
"so that I cannot be sure of the initial situation. A specific "
"relationship would be something like 'the box is a container in "
"the Attic', rather than 'the box is a container in a room which "
"is dark' (fine, but which dark room? You must say).");
return;
}
#line 170 "inform7/Chapter 18/Assert Propositions.w"
;
{
#line 242 "inform7/Chapter 18/Assert Propositions.w"
wording W = EMPTY_WORDING;
if (current_sentence) W = ParseTree__get_text(current_sentence);
if (Calculus__Propositions__Checker__type_check(prop,
Calculus__Propositions__Checker__tc_problem_reporting(W, "be asserting something"))
!= ALWAYS_MATCH)
return;
}
#line 171 "inform7/Chapter 18/Assert Propositions.w"
;
{
#line 261 "inform7/Chapter 18/Assert Propositions.w"
int i, valid = TRUE, var_states[26];
Calculus__Variables__determine_status(prop, var_states, &valid);
if (valid == FALSE) internal_error("tried to assert malformed proposition");
for (i=0; i<26; i++) {
int set = FALSE;
if (current_interpretation_as_spec[i]) set = TRUE;
if (current_interpretation_as_infs[i]) {
if (current_interpretation_as_spec[i]) current_interpretation_as_infs[i] = NULL;
set = TRUE;
}
if ((var_states[i] == UNUSED_VST) && (set))
internal_error("tried to set an unused variable");
if ((var_states[i] == BOUND_VST) && (set))
internal_error("tried to set a bound variable");
if ((var_states[i] == FREE_VST) && (set == FALSE))
internal_error("failed to set a free variable");
}
}
#line 172 "inform7/Chapter 18/Assert Propositions.w"
;
TRAVERSE_VARIABLE(pl);
int now_negated = FALSE;
TRAVERSE_PROPOSITION(pl, prop) {
switch(pl->element) {
case NEGATION_OPEN_ATOM: case NEGATION_CLOSE_ATOM:
now_negated = (now_negated)?FALSE:TRUE; break;
case QUANTIFIER_ATOM:
{
#line 285 "inform7/Chapter 18/Assert Propositions.w"
int v = pl->terms[0].variable; if (v == -1) internal_error("bad QUANTIFIER atom");
if (now_negated) internal_error("tried to negate existence");
wording NW = EMPTY_WORDING;
int is_a_var = FALSE, is_a_const = FALSE, is_a_kind = FALSE;
kind *K = NULL;
{
#line 301 "inform7/Chapter 18/Assert Propositions.w"
TRAVERSE_VARIABLE(lookahead);
TRAVERSE_PROPOSITION(lookahead, pl)
if ((lookahead->arity == 1) && (lookahead->terms[0].variable == v)) {
switch(lookahead->element) {
case KIND_ATOM: K = lookahead->assert_kind; break;
case CALLED_ATOM: NW = Calculus__Atoms__CALLED_get_name(lookahead); break;
case ISAKIND_ATOM: is_a_kind = TRUE; K = lookahead->assert_kind; break;
case ISAVAR_ATOM: is_a_var = TRUE; break;
case ISACONST_ATOM: is_a_const = TRUE; break;
}
}
}
#line 292 "inform7/Chapter 18/Assert Propositions.w"
;
{
#line 316 "inform7/Chapter 18/Assert Propositions.w"
if (is_a_kind) {
K = Kinds__new_base(NW, K);
current_interpretation_as_infs[v] = Kinds__Behaviour__as_subject(K);
current_interpretation_as_spec[v] = Specifications__from_kind(K);
} else if ((is_a_var) || (is_a_const)) {
if (K == NULL) K = K_object;
nonlocal_variable *q = NonlocalVariables__new_global(NW, K);
current_interpretation_as_infs[v] = NULL;
current_interpretation_as_spec[v] = Lvalues__new_actual_NONLOCAL_VARIABLE(q);
if (is_a_const) NonlocalVariables__make_constant(q, FALSE);
} else {
instance *nc = Instances__new(NW, K);
current_interpretation_as_infs[v] = Instances__as_subject(nc);
if ((K == NULL) || (Kinds__Compare__le(K, K_object)))
current_interpretation_as_spec[v] = Rvalues__from_instance(nc);
else
current_interpretation_as_spec[v] = Rvalues__from_instance(nc);
}
}
#line 293 "inform7/Chapter 18/Assert Propositions.w"
;
{
#line 339 "inform7/Chapter 18/Assert Propositions.w"
if (current_interpretation_as_spec[v]) {
LOGIF(ASSERTIONS, ":: %c <-- $P\n", pcalc_vars[v], current_interpretation_as_spec[v]);
} else if (current_interpretation_as_infs[v]) {
LOGIF(ASSERTIONS, ":: %c <-- $j\n", pcalc_vars[v], current_interpretation_as_infs[v]);
}
}
#line 294 "inform7/Chapter 18/Assert Propositions.w"
;
}
#line 180 "inform7/Chapter 18/Assert Propositions.w"
; break;
case KIND_ATOM:
{
#line 355 "inform7/Chapter 18/Assert Propositions.w"
if (now_negated) {
Problems__Issue__sentence_problem(_p_(PM_CantAssertNonKind),
"that seems to say what kind something doesn't have",
"which is too vague. You must say what kind it does have.");
return;
}
inference_subject *subj = Calculus__Propositions__Assert__subject_of_term(pl->terms[0]);
instance *ox = InferenceSubjects__as_object_instance(subj);
if (ox) Instances__set_kind(ox, pl->assert_kind);
else {
kind *K = InferenceSubjects__as_kind(subj);
if (K) Kinds__Compare__make_subkind(K, pl->assert_kind);
}
}
#line 181 "inform7/Chapter 18/Assert Propositions.w"
; break;
case PREDICATE_ATOM:
switch (pl->arity) {
case 1:
{
#line 438 "inform7/Chapter 18/Assert Propositions.w"
adjective_usage *tr = RETRIEVE_POINTER_adjective_usage(pl->predicate);
adjectival_phrase *aph = Adjectives__Usages__get_aph(tr);
int parity = (now_negated)?FALSE:TRUE, found;
if (Adjectives__Usages__get_parity(tr) == FALSE) parity = (parity)?FALSE:TRUE;
inference_subject *ox = Calculus__Propositions__Assert__subject_of_term(pl->terms[0]);
parse_node *ots = Calculus__Propositions__Assert__spec_of_term(pl->terms[0]);
kind *domain_of_definition = InferenceSubjects__domain(ox);
if (domain_of_definition == NULL) {
instance *inst = InferenceSubjects__as_object_instance(ox);
if (inst) domain_of_definition = Instances__to_kind(inst);
}
inference_subject *try = ox;
while ((domain_of_definition == NULL) && (try)) {
domain_of_definition = InferenceSubjects__domain(try);
try = InferenceSubjects__narrowest_broader_subject(try);
}
if (domain_of_definition == NULL)
domain_of_definition = ParseTree__get_kind_of_value(ots);
if (ox) found = Adjectives__Phrases__assert(aph, domain_of_definition, ox, NULL, parity);
else found = Adjectives__Phrases__assert(aph, domain_of_definition, NULL, ots, parity);
if (found == FALSE) {
if (last_couldnt_assert_at != current_sentence) {
wording W = Adjectives__Phrases__get_text(aph, FALSE);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_CantAssertAdjective));
if (parity == FALSE) Problems__issue_problem_segment(
"In the sentence %1, you ask me to arrange for something not to be "
"'%2' at the start of play. This is only possible when an adjective "
"talks about an either/or property, like 'open'/'closed' - if there "
"are three or more possibilities then it's ambiguous. Even if there "
"are only two possibilities, I can't always fix them just on your "
"request - 'visible'/'invisible', for instance, is something I can "
"test during play at any time, but not something I can arrange at "
"the start.");
else Problems__issue_problem_segment(
"In the sentence %1, you ask me to arrange for something to be '%2' "
"at the start of play. There are some adjectives ('open' or 'dark', "
"for instance) which I can fix, but others are just too vague. For "
"example, saying 'Peter is visible.' isn't allowed, because it "
"doesn't tell me where Peter is. Like 'visible', being '%2' is "
"something I can test during play at any time, but not something "
"I can arrange at the start.");
Problems__issue_problem_end();
last_couldnt_assert_at = current_sentence;
}
}
}
#line 184 "inform7/Chapter 18/Assert Propositions.w"
; break;
case 2:
{
#line 507 "inform7/Chapter 18/Assert Propositions.w"
if (now_negated) {
Problems__Issue__sentence_problem(_p_(PM_CantAssertNegatedRelations),
"that seems to make a negative statement about a relationship",
"which is too vague. You must make positive assertions.");
return;
}
binary_predicate *bp;
pcalc_term pt0, pt1;
{
#line 563 "inform7/Chapter 18/Assert Propositions.w"
bp = RETRIEVE_POINTER_binary_predicate(pl->predicate);
pt0 = pl->terms[0]; pt1 = pl->terms[1];
if (bp == R_equality) {
pcalc_func *the_fn = pt0.function; int side = 1;
if (the_fn == NULL) { the_fn = pt1.function; side = 0; }
if (the_fn) {
if ((pl->terms[side].function) || (the_fn->fn_of.function)) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"that is too complicated an assertion",
"and cannot be declared as part of the initial situation. (It "
"does make sense, and could be tested with 'if' - it's just "
"too difficult to get right as an instruction about the starting "
"situation.");
return;
}
bp = the_fn->bp; pt0 = pl->terms[side]; pt1 = the_fn->fn_of;
}
}
}
#line 517 "inform7/Chapter 18/Assert Propositions.w"
;
parse_node *spec0 = Calculus__Propositions__Assert__spec_of_term(pt0), *spec1 = Calculus__Propositions__Assert__spec_of_term(pt1);
inference_subject *subj0 = Calculus__Propositions__Assert__subject_of_term(pt0), *subj1 = Calculus__Propositions__Assert__subject_of_term(pt1);
if ((subj0) && (spec0 == NULL)) spec0 = InferenceSubjects__as_constant(subj0);
if ((subj1) && (spec1 == NULL)) spec1 = InferenceSubjects__as_constant(subj1);
if (bp != R_regional_containment) {
kind *K0 = BinaryPredicates__term_kind(bp, 0);
kind *K1 = BinaryPredicates__term_kind(bp, 1);
if (Kinds__Compare__lt(K0, K_object)) Calculus__Propositions__Assert__cautiously_set_kind(subj0, K0);
if (Kinds__Compare__lt(K1, K_object)) Calculus__Propositions__Assert__cautiously_set_kind(subj1, K1);
}
if (BinaryPredicates__assert(bp, subj0, spec0, subj1, spec1) == FALSE)
{
#line 537 "inform7/Chapter 18/Assert Propositions.w"
LOG("$2 on ($j, $P; $j, $P)\n", bp, subj0, spec0, subj1, spec1);
if ((Rvalues__is_nothing_object_constant(spec0)) ||
(Rvalues__is_nothing_object_constant(spec1)))
Problems__Issue__sentence_problem(_p_(PM_RelationFailedOnNothing),
"that is an assertion which involves 'nothing'",
"which looks as if it might be trying to give me negative rather "
"than positive information. There's no need to tell me something "
"like 'Nothing is in the box.': just don't put anything in the box, "
"and then nothing will be in it.");
else
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"that is an assertion I can't puzzle out",
"which seems to involve placing two things in some sort of "
"relationship, but if so then I can't make it work. Perhaps the "
"sentence is too complicatedly phrased, and could be broken up "
"into two or more sentences?");
}
#line 532 "inform7/Chapter 18/Assert Propositions.w"
;
}
#line 185 "inform7/Chapter 18/Assert Propositions.w"
; break;
}
break;
case HERE_ATOM:
{
#line 413 "inform7/Chapter 18/Assert Propositions.w"
inference_subject *subj = Calculus__Propositions__Assert__subject_of_term(pl->terms[0]);
instance *ox = InferenceSubjects__as_object_instance(subj);
if (now_negated) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"that seems to say that something isn't here",
"which is too vague. You must say where it is.");
return;
}
if (ox == NULL) {
Problems__Issue__sentence_problem(_p_(PM_NonInstanceHere),
"that seems to say that something generic is 'here'",
"which would give it a physical location. (It would be like saying "
"'A number is here' - well, numbers are everywhere and nowhere.)");
return;
}
PL__Spatial__infer_presence_here(ox);
}
#line 188 "inform7/Chapter 18/Assert Propositions.w"
; break;
case EVERYWHERE_ATOM:
{
#line 378 "inform7/Chapter 18/Assert Propositions.w"
inference_subject *subj = Calculus__Propositions__Assert__subject_of_term(pl->terms[0]);
instance *ox = InferenceSubjects__as_object_instance(subj);
if (now_negated) {
Problems__Issue__sentence_problem(_p_(PM_CantAssertNegatedEverywhere),
"that seems to say that something isn't everywhere",
"which is too vague. You must say where it is.");
return;
}
PL__Backdrops__infer_presence_everywhere(ox);
}
#line 189 "inform7/Chapter 18/Assert Propositions.w"
; break;
case NOWHERE_ATOM:
{
#line 391 "inform7/Chapter 18/Assert Propositions.w"
inference_subject *subj = Calculus__Propositions__Assert__subject_of_term(pl->terms[0]);
instance *ox = InferenceSubjects__as_object_instance(subj);
if (now_negated) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"that seems to say that something isn't nowhere",
"which is too vague. You must say where it is.");
return;
}
if (ox == NULL) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"that seems to say that something generic is 'nowhere'",
"which suggests it could some day have a physical location.");
return;
}
PL__Spatial__infer_presence_nowhere(ox);
}
#line 190 "inform7/Chapter 18/Assert Propositions.w"
; break;
case ISAKIND_ATOM: case ISAVAR_ATOM: case ISACONST_ATOM:
if (now_negated) internal_error("ISA... atoms cannot be negated");
break;
}
}
}
#line 598 "inform7/Chapter 18/Assert Propositions.w"
void Calculus__Propositions__Assert__cautiously_set_kind(inference_subject *inst, kind *k) {
if ((inst == NULL) || (k == NULL)) return;
if (Kinds__Compare__eq(k, K_thing)) return;
instance *instance_wo = InferenceSubjects__as_object_instance(inst);
if (instance_wo == NULL) return;
Instances__set_kind(instance_wo, k);
}
#line 620 "inform7/Chapter 18/Assert Propositions.w"
parse_node *Calculus__Propositions__Assert__spec_of_term(pcalc_term pt) {
if (pt.function) return NULL;
if (pt.variable >= 0) return current_interpretation_as_spec[pt.variable];
return pt.constant;
}
#line 640 "inform7/Chapter 18/Assert Propositions.w"
inference_subject *Calculus__Propositions__Assert__subject_of_term(pcalc_term pt) {
if (pt.function) return NULL;
if (pt.variable >= 0) return current_interpretation_as_infs[pt.variable];
parse_node *spec = pt.constant;
if (ParseTree__is(spec, CONSTANT_VNT))
return InferenceSubjects__from_specification(spec);
if (Specifications__is_description(spec)) {
if (Descriptions__to_instance(spec))
return Instances__as_subject(Descriptions__to_instance(spec));
if (Specifications__to_kind(spec))
return Kinds__Behaviour__as_subject(Specifications__to_kind(spec));
}
if (ParseTree__is(spec, NONLOCAL_VARIABLE_VNT)) {
inference_subject *diversion =
NonlocalVariables__get_alias(ParseTree__get_constant_nonlocal_variable(spec));
if (diversion) return diversion;
}
return NULL;
}
#line 671 "inform7/Chapter 18/Assert Propositions.w"
int Calculus__Propositions__Assert__testable_at_compile_time(pcalc_prop *prop) {
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, prop) {
switch(pl->element) {
case KIND_ATOM: break;
case PREDICATE_ATOM:
switch (pl->arity) {
case 1:
{
#line 691 "inform7/Chapter 18/Assert Propositions.w"
adjective_usage *ale = RETRIEVE_POINTER_adjective_usage(pl->predicate);
adjectival_phrase *aph = Adjectives__Usages__get_aph(ale);
property *prn = Adjectives__Phrases__has_EORP_meaning(aph, NULL);
if (prn == NULL) return FALSE;
}
#line 678 "inform7/Chapter 18/Assert Propositions.w"
; break;
case 2: return FALSE;
}
break;
default: return FALSE;
}
}
return TRUE;
}
#line 699 "inform7/Chapter 18/Assert Propositions.w"
int Calculus__Propositions__Assert__test_at_compile_time(pcalc_prop *prop, inference_subject *about) {
if (Calculus__Propositions__Assert__testable_at_compile_time(prop) == FALSE) return NOT_APPLICABLE;
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, prop) {
switch(pl->element) {
case KIND_ATOM:
{
#line 718 "inform7/Chapter 18/Assert Propositions.w"
;
}
#line 704 "inform7/Chapter 18/Assert Propositions.w"
; break;
case PREDICATE_ATOM:
switch (pl->arity) {
case 1:
{
#line 723 "inform7/Chapter 18/Assert Propositions.w"
adjective_usage *ale = RETRIEVE_POINTER_adjective_usage(pl->predicate);
adjectival_phrase *aph = Adjectives__Usages__get_aph(ale);
int sense = Adjectives__Usages__get_parity(ale);
property *prn = Adjectives__Phrases__has_EORP_meaning(aph, NULL);
if (prn) {
possession_marker *adj = Properties__get_possession_marker(prn);
if (sense) {
if (adj->possessed == FALSE) return FALSE;
} else {
if (adj->possessed == TRUE) return FALSE;
}
}
}
#line 707 "inform7/Chapter 18/Assert Propositions.w"
; break;
}
break;
}
}
return TRUE;
}
#line 75 "inform7/Chapter 18/I6 Schemas.w"
i6_schema *Calculus__Schemas__new(char *fmt, ...) {
va_list ap; /* the variable argument list signified by the dots */
char temp[MAX_I6_SCHEMA_ATTEMPT];
{
#line 116 "inform7/Chapter 18/I6 Schemas.w"
int tn = 0;
char *p;
va_start(ap, fmt); /* macro to begin variable argument processing */
for (p = fmt; *p; p++) {
switch (*p) {
case '%':
{
#line 131 "inform7/Chapter 18/I6 Schemas.w"
p++;
switch (*p) {
case 'd': sprintf(temp+tn, "%d", va_arg(ap, int)); break;
case 'k':
{
#line 146 "inform7/Chapter 18/I6 Schemas.w"
kind *K = va_arg(ap, kind *);
TEMPORARY_STREAM;
Kinds__RunTime__compile_weak_id(TEMP, K);
strcpy(temp+tn, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 134 "inform7/Chapter 18/I6 Schemas.w"
; break;
case 's': sprintf(temp+tn, "%s", va_arg(ap, char *)); break;
case '%': temp[tn] = '%'; temp[tn+1] = 0; break;
default:
fprintf(stderr, "*** Bad schema format: <%s> ***\n", fmt);
internal_error("Unknown % string escape in schema format");
}
tn = Platform__strlen(temp);
}
#line 121 "inform7/Chapter 18/I6 Schemas.w"
; break;
default: temp[tn++] = *p; break;
}
}
temp[tn] = 0;
}
#line 78 "inform7/Chapter 18/I6 Schemas.w"
;
va_end(ap); /* macro to end variable argument processing */
i6_schema *sch = CREATE(i6_schema);
if (Platform__strlen(temp) >= MAX_I6_SCHEMA_LENGTH)
Calculus__Schemas__overrun(temp);
strcpy(sch->prototype, temp);
return sch;
}
#line 90 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__modify(i6_schema *sch, char *fmt, ...) {
va_list ap; /* the variable argument list signified by the dots */
char temp[MAX_I6_SCHEMA_ATTEMPT];
{
#line 116 "inform7/Chapter 18/I6 Schemas.w"
int tn = 0;
char *p;
va_start(ap, fmt); /* macro to begin variable argument processing */
for (p = fmt; *p; p++) {
switch (*p) {
case '%':
{
#line 131 "inform7/Chapter 18/I6 Schemas.w"
p++;
switch (*p) {
case 'd': sprintf(temp+tn, "%d", va_arg(ap, int)); break;
case 'k':
{
#line 146 "inform7/Chapter 18/I6 Schemas.w"
kind *K = va_arg(ap, kind *);
TEMPORARY_STREAM;
Kinds__RunTime__compile_weak_id(TEMP, K);
strcpy(temp+tn, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 134 "inform7/Chapter 18/I6 Schemas.w"
; break;
case 's': sprintf(temp+tn, "%s", va_arg(ap, char *)); break;
case '%': temp[tn] = '%'; temp[tn+1] = 0; break;
default:
fprintf(stderr, "*** Bad schema format: <%s> ***\n", fmt);
internal_error("Unknown % string escape in schema format");
}
tn = Platform__strlen(temp);
}
#line 121 "inform7/Chapter 18/I6 Schemas.w"
; break;
default: temp[tn++] = *p; break;
}
}
temp[tn] = 0;
}
#line 93 "inform7/Chapter 18/I6 Schemas.w"
;
va_end(ap); /* macro to end variable argument processing */
if (Platform__strlen(temp) >= MAX_I6_SCHEMA_LENGTH)
Calculus__Schemas__overrun(temp);
strcpy(sch->prototype, temp);
}
#line 103 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__append(i6_schema *sch, char *fmt, ...) {
va_list ap; /* the variable argument list signified by the dots */
char temp[MAX_I6_SCHEMA_ATTEMPT];
{
#line 116 "inform7/Chapter 18/I6 Schemas.w"
int tn = 0;
char *p;
va_start(ap, fmt); /* macro to begin variable argument processing */
for (p = fmt; *p; p++) {
switch (*p) {
case '%':
{
#line 131 "inform7/Chapter 18/I6 Schemas.w"
p++;
switch (*p) {
case 'd': sprintf(temp+tn, "%d", va_arg(ap, int)); break;
case 'k':
{
#line 146 "inform7/Chapter 18/I6 Schemas.w"
kind *K = va_arg(ap, kind *);
TEMPORARY_STREAM;
Kinds__RunTime__compile_weak_id(TEMP, K);
strcpy(temp+tn, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
#line 134 "inform7/Chapter 18/I6 Schemas.w"
; break;
case 's': sprintf(temp+tn, "%s", va_arg(ap, char *)); break;
case '%': temp[tn] = '%'; temp[tn+1] = 0; break;
default:
fprintf(stderr, "*** Bad schema format: <%s> ***\n", fmt);
internal_error("Unknown % string escape in schema format");
}
tn = Platform__strlen(temp);
}
#line 121 "inform7/Chapter 18/I6 Schemas.w"
; break;
default: temp[tn++] = *p; break;
}
}
temp[tn] = 0;
}
#line 106 "inform7/Chapter 18/I6 Schemas.w"
;
va_end(ap); /* macro to end variable argument processing */
if (Platform__strlen(temp) >= MAX_I6_SCHEMA_LENGTH)
Calculus__Schemas__overrun(temp);
strcpy(sch->prototype + Platform__strlen(sch->prototype), temp);
}
#line 155 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__overrun(char *temp) {
Problems__Issue__sentence_problem(_p_(PM_I6SchemaTooLong),
"this seems to involve an Inform 6 definition which is too long",
"which is probably because you wrote too much I6, but might just "
"result from using a very large number of words to describe something "
"in your source text. (Sorry to be so vague.)");
temp[MAX_I6_SCHEMA_LENGTH-2] = 0;
}
#line 168 "inform7/Chapter 18/I6 Schemas.w"
int Calculus__Schemas__empty(i6_schema *sch) {
if (sch == NULL) return TRUE;
if (sch->prototype[0] == 0) return TRUE;
return FALSE;
}
#line 179 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__expand(i6_schema *sch, OUTPUT_STREAM, pcalc_term *pt1, pcalc_term *pt2) {
text_stream *save_dl = dl;
if (OUT == NULL) return;
TEMPORARY_STREAM;
if (OUT == dl) dl = TEMP;
Calculus__Schemas__sch_expand_inner(sch, TEMP, pt1, NULL, pt2, NULL);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
dl = save_dl;
}
#line 193 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__expand_textual(i6_schema *sch, OUTPUT_STREAM, char *str1, char *str2) {
text_stream *save_dl = dl;
if (OUT == NULL) return;
TEMPORARY_STREAM;
if (OUT == dl) dl = TEMP;
Calculus__Schemas__sch_expand_inner(sch, TEMP, NULL, str1, NULL, str2);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
dl = save_dl;
}
#line 207 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__sch_expand_inner(i6_schema *sch, OUTPUT_STREAM,
pcalc_term *pt1, char *str1, pcalc_term *pt2, char *str2) {
STREAM_MUST_BE_IN_MEMORY(OUT);
if (sch == NULL) internal_error("Expanded null I6 schema");
Calculus__Schemas__sch_type_parameter(pt1);
Calculus__Schemas__sch_type_parameter(pt2);
char *schematic_text = sch->prototype;
int cmode = 0, i = 0;
if ((schematic_text[0] == '*') && (schematic_text[1] == '=') &&
(schematic_text[2] == '-')) {
cmode = DEREFERENCE_POINTERS_CMODE; i = 3;
}
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(cmode);
for (; schematic_text[i]; i++) {
if (schematic_text[i] == '*') {
{
#line 237 "inform7/Chapter 18/I6 Schemas.w"
BEGIN_COMPILATION_MODE;
int give_kind_id = FALSE, give_comparison_routine = FALSE,
dereference_property = FALSE, adopt_local_stack_frame = FALSE,
cast_to_kind_of_other_term = FALSE, by_reference = FALSE;
if ((schematic_text[i+2]) && (isdigit(schematic_text[i+2]))) {
switch (schematic_text[i+1]) {
case '!': COMPILATION_MODE_ENTER(PERMIT_LOCALS_IN_TEXT_CMODE); i++; break;
case '#': give_kind_id = TRUE; i++; break;
case '_': give_comparison_routine = TRUE; i++; break;
case '+': dereference_property = TRUE; i++; break;
case '?': adopt_local_stack_frame = TRUE; i++; break;
case '<': cast_to_kind_of_other_term = TRUE; i++; break;
case '^': adopt_local_stack_frame = TRUE; by_reference = TRUE; i++; break;
case '>': by_reference = TRUE; i++; break;
}
}
switch(schematic_text[++i]) {
case '?': if (current_sentence)
Wordings__to_stream_raw_within_i6_literal(OUT, ParseTree__get_text(current_sentence));
break;
case '&':
if ((pt1) && (pt2)) {
kind *reln_K = pt1->term_checked_as_kind;
kind *comb_K = pt2->term_checked_as_kind;
if ((Kinds__get_construct(reln_K) == CON_relation) &&
(Kinds__get_construct(comb_K) == CON_combination)) {
kind *req_A = NULL, *req_B = NULL, *found_A = NULL, *found_B = NULL;
Kinds__binary_construction_material(reln_K, &req_A, &req_B);
Kinds__binary_construction_material(comb_K, &found_A, &found_B);
LOG("($u, $u) vs ($u, $u)\n", req_A, req_B, found_A, found_B);
parse_node *spec_A = NULL, *spec_B = NULL;
Rvalues__to_pair(pt2->constant, &spec_A, &spec_B);
if (!((Kinds__Behaviour__uses_pointer_values(req_A)) && (Kinds__Behaviour__definite(req_A))))
req_A = NULL;
if (!((Kinds__Behaviour__uses_pointer_values(req_B)) && (Kinds__Behaviour__definite(req_B))))
req_B = NULL;
Specifications__Compiler__compile_to_kind(OUT, spec_A, req_A);
WRITE(", ");
Specifications__Compiler__compile_to_kind(OUT, spec_B, req_B);
break;
}
}
Calculus__Schemas__sch_expand_parameter(OUT, pt2, str2,
give_kind_id, give_comparison_routine, dereference_property, NULL, FALSE);
break;
case '-': STREAM_BACKSPACE(OUT); break;
case '1': {
kind *K = NULL;
if (cast_to_kind_of_other_term) K = pt2->term_checked_as_kind;
Calculus__Schemas__sch_expand_parameter(OUT, pt1, str1, give_kind_id,
give_comparison_routine, dereference_property, K, by_reference);
break;
}
case '2': {
rule *R = adopted_rule_for_compilation;
int M = adopted_marker_for_compilation;
if ((adopt_local_stack_frame) &&
(Rvalues__is_CONSTANT_of_kind(pt1->constant, K_response))) {
adopted_rule_for_compilation =
Rvalues__to_rule(pt1->constant);
adopted_marker_for_compilation =
Strings__get_marker_from_response_spec(pt1->constant);
}
kind *K = NULL;
if (cast_to_kind_of_other_term) K = pt1->term_checked_as_kind;
Calculus__Schemas__sch_expand_parameter(OUT, pt2, str2,
give_kind_id, give_comparison_routine, dereference_property, K, by_reference);
adopted_rule_for_compilation = R;
adopted_marker_for_compilation = M;
break;
}
case '3': case '4': case '5': case '6': case '7': case '8': case '9': break;
case '#':
if (schematic_text[++i] == '#') internal_error("can't expand *## in schema");
else internal_error("schema syntax error");
break;
case '*': WRITE("*"); break;
default: internal_error("schema syntax error");
}
END_COMPILATION_MODE;
}
#line 225 "inform7/Chapter 18/I6 Schemas.w"
;
continue;
}
WRITE("%c", schematic_text[i]);
}
END_COMPILATION_MODE;
}
#line 321 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__sch_expand_parameter(OUTPUT_STREAM, pcalc_term *pt, char *str, int give_kind_id,
int give_comparison_routine, int dereference_property, kind *cast_to,
int by_reference) {
if (give_kind_id) {
if (pt) Kinds__RunTime__compile_weak_id(OUT, pt->term_checked_as_kind);
} else if (give_comparison_routine) {
if (pt) {
char *cr = Kinds__Behaviour__get_comparison_routine(pt->term_checked_as_kind);
if ((cr == NULL) || (cr[0] == 0)) WRITE("SignedCompare");
else WRITE("%s", cr);
} else WRITE("SignedCompare");
} else {
if (str) WRITE("%s", str);
else if (by_reference) {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
pcalc_term cpt = *pt;
Calculus__Terms__compile(OUT, cpt);
END_COMPILATION_MODE;
} else {
int casting = Kinds__Behaviour__cast_call(OUT, pt->term_checked_as_kind, cast_to);
pcalc_term cpt = *pt;
if ((dereference_property) &&
(ParseTree__is(cpt.constant, CONSTANT_VNT))) {
kind *K = Specifications__to_kind(cpt.constant);
if (Kinds__get_construct(K) == CON_property) {
cpt = Calculus__Terms__new_constant(
Lvalues__new_PROPERTY_VALUE(
ParseTree__duplicate(cpt.constant),
Rvalues__new_self_object_constant()));
}
}
Calculus__Terms__compile(OUT, cpt);
if (casting) WRITE(")");
}
}
}
#line 363 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__sch_type_parameter(pcalc_term *pt) {
if ((pt) && (pt->constant) && (pt->term_checked_as_kind == NULL))
pt->term_checked_as_kind = Specifications__to_kind(pt->constant);
}
#line 371 "inform7/Chapter 18/I6 Schemas.w"
void Calculus__Schemas__log(i6_schema *sch) {
if (sch == NULL) LOG("<null schema>");
else LOG("<schema: %s>", sch->prototype);
}
void Calculus__Schemas__log_applied(i6_schema *sch, pcalc_term *pt1) {
if (sch == NULL) { LOG("<null schema>"); return; }
Calculus__Schemas__expand(sch, dl, pt1, NULL);
}
#line 56 "inform7/Chapter 18/Compile Atoms.w"
void Calculus__Atoms__Compile__compile(OUTPUT_STREAM, int task, pcalc_prop *pl, int with_semicolon) {
i6_schema sch;
annotated_i6_schema asch;
switch (task) {
case TEST_ATOM_TASK: LOGIF(PREDICATE_CALCULUS_WORKINGS, "Compiling condition: $o\n", pl); break;
case NOW_ATOM_TRUE_TASK: LOGIF(PREDICATE_CALCULUS_WORKINGS, "Compiling 'now': $o\n", pl); break;
case NOW_ATOM_FALSE_TASK: LOGIF(PREDICATE_CALCULUS_WORKINGS, "Compiling 'now' false: $o\n", pl); break;
default: internal_error("unknown compile task");
}
{
#line 74 "inform7/Chapter 18/Compile Atoms.w"
asch = Calculus__Atoms__Compile__i6_schema_of_atom(&sch, pl, task);
if (asch.schema == NULL) {
if (problem_count == 0)
{
#line 85 "inform7/Chapter 18/Compile Atoms.w"
LOG("Failed on task: $o\n", pl);
if (task == TEST_ATOM_TASK)
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"this is not a condition I am able to test",
"or at any rate not during play.");
else
Problems__Issue__sentence_problem(_p_(PM_CantForceRelation),
"this is not something I can make true with 'now'",
"because it is too vague about the underlying cause which would "
"need to be arranged.");
}
#line 77 "inform7/Chapter 18/Compile Atoms.w"
;
return;
}
{
#line 99 "inform7/Chapter 18/Compile Atoms.w"
if ((asch.involves_action_variables) &&
(Frames__used_for_past_tense()) &&
(suppress_C14ActionVarsPastTense == FALSE)) {
if (problem_count == 0)
Problems__Issue__sentence_problem(_p_(PM_ActionVarsPastTense),
"it is misleading to talk about the noun, the second noun "
"or the person asked to do something in past tenses",
"because in the past, those were different things and "
"people, or may have been nothing at all. Writing "
"'if the noun has been unlocked' tends not to do what we "
"might hope because the value of 'noun' changes every turn. "
"So such conditions are not allowed, although to get around "
"this we can instead write 'if we have unlocked the noun', "
"which uses a special mechanism to remember everything which "
"has happened to every object.");
return;
}
}
#line 80 "inform7/Chapter 18/Compile Atoms.w"
;
}
#line 67 "inform7/Chapter 18/Compile Atoms.w"
;
{
#line 123 "inform7/Chapter 18/Compile Atoms.w"
if (task == TEST_ATOM_TASK) {
WRITE("(");
if (asch.negate_schema) WRITE("~~(");
}
Calculus__Schemas__expand(asch.schema, OUT, &(asch.pt0), &(asch.pt1));
if (task == TEST_ATOM_TASK) {
if (asch.negate_schema) WRITE(")");
WRITE(")");
} else {
if (with_semicolon) WRITE(";");
}
}
#line 68 "inform7/Chapter 18/Compile Atoms.w"
;
}
#line 140 "inform7/Chapter 18/Compile Atoms.w"
annotated_i6_schema Calculus__Atoms__Compile__i6_schema_of_atom(i6_schema *sch, pcalc_prop *pl, int task) {
annotated_i6_schema asch;
Calculus__Schemas__modify(sch, " "); /* a non-NULL return in case problems occur */
asch.schema = sch;
asch.negate_schema = FALSE;
asch.pt0 = pl->terms[0]; asch.pt1 = pl->terms[1];
asch.involves_action_variables = Calculus__Atoms__Compile__atom_involves_action_variables(pl);
switch(pl->element) {
case CALLED_ATOM:
{
#line 179 "inform7/Chapter 18/Compile Atoms.w"
switch(task) {
case TEST_ATOM_TASK: {
wording W = Calculus__Atoms__CALLED_get_name(pl);
Calculus__Schemas__modify(sch, "%s=(*1), true",
LocalVariables__lvalue(
LocalVariables__ensure_called_local(W, pl->assert_kind)));
return asch;
}
default: asch.schema = NULL; return asch;
}
}
#line 150 "inform7/Chapter 18/Compile Atoms.w"
;
case KIND_ATOM:
{
#line 199 "inform7/Chapter 18/Compile Atoms.w"
switch(task) {
case TEST_ATOM_TASK:
if (Kinds__Compare__lt(pl->assert_kind, K_object))
Calculus__Schemas__modify(sch, "*1 ofclass %s",
Kinds__Behaviour__I6_classname(pl->assert_kind));
else {
if ((Kinds__get_construct(pl->assert_kind) == CON_list_of) && (problem_count == 0)) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, pl->assert_kind);
Problems__Issue__handmade_problem(_p_(PM_CantCheckListContents));
Problems__issue_problem_segment(
"In %1, you use a list which might or might not match a "
"definition requiring %2. But there's no efficient way to "
"tell during play whether the list actually contains that, "
"without laboriously checking every entry. Because "
"in general this would be a bad idea, this usage is "
"not allowed.");
Problems__issue_problem_end();
}
Calculus__Schemas__modify(sch, "true");
}
return asch;
case NOW_ATOM_TRUE_TASK:
case NOW_ATOM_FALSE_TASK:
if (suppress_C14CantChangeKind == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_CantChangeKind),
"the kind of something is fixed",
"and cannot be changed during play with a 'now'.");
asch.schema = NULL;
} else Calculus__Schemas__modify(sch, " ");
return asch;
}
}
#line 151 "inform7/Chapter 18/Compile Atoms.w"
;
case EVERYWHERE_ATOM:
{
#line 237 "inform7/Chapter 18/Compile Atoms.w"
switch(task) {
case TEST_ATOM_TASK:
Calculus__Schemas__modify(sch, "BackdropEverywhere(*1)");
return asch;
case NOW_ATOM_TRUE_TASK:
Calculus__Schemas__modify(sch, "MoveObject(*1, FoundEverywhere); MoveFloatingObjects();");
return asch;
case NOW_ATOM_FALSE_TASK:
Problems__Issue__sentence_problem(_p_(PM_CantChangeEverywhere),
"not being 'everywhere' is not something which can be changed "
"during play using 'now'",
"because it's not exact enough about what needs to be done.");
asch.schema = NULL; return asch;
}
}
#line 152 "inform7/Chapter 18/Compile Atoms.w"
;
case NOWHERE_ATOM:
{
#line 255 "inform7/Chapter 18/Compile Atoms.w"
switch(task) {
case TEST_ATOM_TASK:
Calculus__Schemas__modify(sch, "LocationOf(*1) == nothing");
return asch;
case NOW_ATOM_TRUE_TASK:
Calculus__Schemas__modify(sch, "RemoveFromPlay(*1);");
return asch;
case NOW_ATOM_FALSE_TASK:
Calculus__Schemas__modify(sch, "MoveObject(*1, real_location, 1, false);");
return asch;
}
}
#line 153 "inform7/Chapter 18/Compile Atoms.w"
;
case HERE_ATOM:
{
#line 271 "inform7/Chapter 18/Compile Atoms.w"
switch(task) {
case TEST_ATOM_TASK:
Calculus__Schemas__modify(sch, "LocationOf(*1) == location");
return asch;
case NOW_ATOM_TRUE_TASK:
case NOW_ATOM_FALSE_TASK:
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"being 'here' is not something which can be changed during play",
"so it cannot be brought about or cancelled out with 'now'.");
asch.schema = NULL; return asch;
}
}
#line 154 "inform7/Chapter 18/Compile Atoms.w"
;
case PREDICATE_ATOM:
switch(pl->arity) {
case 1:
{
#line 287 "inform7/Chapter 18/Compile Atoms.w"
int atask = 0; /* redundant assignment to appease |gcc -O2| */
adjective_usage *tr = RETRIEVE_POINTER_adjective_usage(pl->predicate);
adjectival_phrase *aph = Adjectives__Usages__get_aph(tr);
if (Adjectives__Usages__get_parity(tr) == FALSE) asch.negate_schema = TRUE;
if ((pl->terms[0].constant) && (pl->terms[0].term_checked_as_kind == NULL))
pl->terms[0].term_checked_as_kind = Specifications__to_kind(pl->terms[0].constant);
switch(task) {
case TEST_ATOM_TASK: atask = TEST_ADJECTIVE_TASK; break;
case NOW_ATOM_TRUE_TASK: atask = NOW_ADJECTIVE_TRUE_TASK; break;
case NOW_ATOM_FALSE_TASK: atask = NOW_ADJECTIVE_FALSE_TASK; break;
}
LOGIF(PREDICATE_CALCULUS_WORKINGS, "Unary predicate: $o, on: $u\n", pl, pl->terms[0].term_checked_as_kind);
asch.schema = Adjectives__Meanings__get_i6_schema(aph, pl->terms[0].term_checked_as_kind, atask);
return asch;
}
#line 157 "inform7/Chapter 18/Compile Atoms.w"
;
case 2:
{
#line 309 "inform7/Chapter 18/Compile Atoms.w"
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(pl->predicate);
binary_predicate *bp_to_assert = NULL;
{
#line 321 "inform7/Chapter 18/Compile Atoms.w"
if ((task != TEST_ATOM_TASK) && (bp == R_equality)) {
if (pl->terms[0].function) {
bp_to_assert = pl->terms[0].function->bp;
asch.pt0 = pl->terms[0].function->fn_of;
} else if (pl->terms[1].function) {
bp_to_assert = pl->terms[1].function->bp;
asch.pt1 = pl->terms[1].function->fn_of;
}
if (bp_to_assert == R_equality)
internal_error("contraction of predicate applied to equality");
}
if (bp_to_assert == NULL) bp_to_assert = bp;
}
#line 312 "inform7/Chapter 18/Compile Atoms.w"
;
asch.schema = BinaryPredicates__get_i6_schema(task, bp_to_assert, &asch);
return asch;
}
#line 158 "inform7/Chapter 18/Compile Atoms.w"
;
}
}
asch.schema = NULL; /* signal that the atom cannot be compiled simply */
return asch;
}
#line 337 "inform7/Chapter 18/Compile Atoms.w"
int Calculus__Atoms__Compile__atom_involves_action_variables(pcalc_prop *pl) {
int i;
for (i=0; i<pl->arity; i++) {
parse_node *operand = Calculus__Terms__constant_underlying(&(pl->terms[i]));
if (PL__Actions__Patterns__is_an_action_variable(operand)) return TRUE;
}
return FALSE;
}
#line 349 "inform7/Chapter 18/Compile Atoms.w"
annotated_i6_schema Calculus__Atoms__Compile__blank_asch(void) {
annotated_i6_schema asch;
asch.schema = Calculus__Schemas__new(" ");
asch.negate_schema = FALSE;
asch.pt0 = Calculus__Terms__new_variable(0);
asch.pt1 = Calculus__Terms__new_variable(0);
asch.involves_action_variables = FALSE;
return asch;
}
#line 50 "inform7/Chapter 18/Deciding to Defer.w"
int no_further_deferrals = FALSE;
void Calculus__Deferrals__allow_no_further_deferrals(void) {
no_further_deferrals = TRUE;
}
#line 59 "inform7/Chapter 18/Deciding to Defer.w"
pcalc_prop_deferral *Calculus__Deferrals__new_deferred_proposition(pcalc_prop *prop, int reason) {
pcalc_prop_deferral *pdef = CREATE(pcalc_prop_deferral);
pdef->proposition_to_defer = prop;
pdef->reason = reason;
pdef->deferred_from = current_sentence;
pdef->rtp_constant_needed = FALSE;
if (no_further_deferrals) internal_error("Too late now to defer propositions");
return pdef;
}
#line 74 "inform7/Chapter 18/Deciding to Defer.w"
pcalc_prop *cache_loop_proposition = NULL;
pcalc_prop_deferral *cache_loop_pdef = NULL;
pcalc_prop_deferral *Calculus__Deferrals__defer_loop_domain(pcalc_prop *prop) {
pcalc_prop_deferral *pdef;
if (prop == cache_loop_proposition) return cache_loop_pdef;
pdef = Calculus__Deferrals__new_deferred_proposition(prop, LOOP_DOMAIN_DEFER);
cache_loop_proposition = prop;
cache_loop_pdef = pdef;
return pdef;
}
#line 91 "inform7/Chapter 18/Deciding to Defer.w"
int Calculus__Deferrals__compile_deferred_description_test(parse_node *spec) {
pcalc_prop *prop = Specifications__to_proposition(spec);
if (Calculus__Propositions__contains_callings(prop)) {
Problems__Issue__sentence_problem(_p_(PM_CantCallDeferredDescs),
"'called' can't be used when testing a description",
"since it would make a name for something which existed only "
"so temporarily that it couldn't be used anywhere else.");
return 0;
} else {
pcalc_prop_deferral *pdef = Calculus__Deferrals__new_deferred_proposition(prop, CONDITION_DEFER);
return pdef->allocation_id;
}
}
#line 115 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_test_of_proposition(OUTPUT_STREAM,
parse_node *substitution, pcalc_prop *prop) {
LOGIF(PREDICATE_CALCULUS_WORKINGS, "Compiling as test: $D\n", prop);
prop = Calculus__Propositions__copy(prop);
WRITE("(");
if (prop == NULL) {
WRITE("true");
} else if (Calculus__Propositions__contains_quantifier(prop)) {
{
#line 152 "inform7/Chapter 18/Deciding to Defer.w"
pcalc_prop_deferral *pdef;
LocalVariables__begin_condition(OUT);
{
#line 164 "inform7/Chapter 18/Deciding to Defer.w"
if (Calculus__Propositions__is_a_group(prop, NEGATION_OPEN_ATOM)) {
prop = Calculus__Propositions__remove_topmost_group(prop);
WRITE("~~");
}
}
#line 154 "inform7/Chapter 18/Deciding to Defer.w"
;
pdef = Calculus__Deferrals__new_deferred_proposition(prop, CONDITION_DEFER);
{
#line 194 "inform7/Chapter 18/Deciding to Defer.w"
WRITE("Prop_%d(", pdef->allocation_id);
int cinder_count = Calculus__Deferrals__Cinders__find(OUT, prop, pdef);
if (substitution) {
if (cinder_count > 0) WRITE(",");
Specifications__Compiler__compile(OUT, substitution);
}
WRITE(")");
}
#line 156 "inform7/Chapter 18/Deciding to Defer.w"
;
Calculus__Deferrals__retrieve_callings(OUT, prop, TRUE);
LocalVariables__end_condition(OUT);
}
#line 125 "inform7/Chapter 18/Deciding to Defer.w"
;
} else {
if (substitution) Calculus__Variables__substitute_var_0_in(prop, substitution);
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, prop) {
if (Calculus__Propositions__implied_conjunction_between(pl_prev, pl)) WRITE(" && ");
switch(pl->element) {
case NEGATION_OPEN_ATOM: WRITE("(~~("); break;
case NEGATION_CLOSE_ATOM:
if (pl_prev->element == NEGATION_OPEN_ATOM) WRITE("true");
WRITE("))"); break;
default: Calculus__Atoms__Compile__compile(OUT, TEST_ATOM_TASK, pl, TRUE); break;
}
}
}
WRITE(")");
}
#line 229 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__retrieve_callings(OUTPUT_STREAM, pcalc_prop *prop, int condition_context) {
int calling_count=0;
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, prop) {
switch(pl->element) {
case CALLED_ATOM: {
local_variable *local;
{
#line 265 "inform7/Chapter 18/Deciding to Defer.w"
wording W = Calculus__Atoms__CALLED_get_name(pl);
local = LocalVariables__ensure_called_local(W, pl->assert_kind);
}
#line 236 "inform7/Chapter 18/Deciding to Defer.w"
;
if ((condition_context) && (calling_count == 0)) WRITE(" && (");
if ((condition_context == FALSE) || (calling_count > 0)) WRITE(", ");
WRITE("%s=deferred_calling_list-->%d",
LocalVariables__lvalue(local), calling_count++);
if (condition_context) LocalVariables__add_calling_to_condition(local);
break;
}
}
}
if (calling_count > 0) {
if (condition_context) WRITE(", true)");
else WRITE(", deferred_calling_list-->26");
}
}
#line 255 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__prepare_to_retrieve_callings(OUTPUT_STREAM, pcalc_prop *prop, int condition_context) {
if ((condition_context == FALSE) && (Calculus__Propositions__contains_callings(prop))) {
WRITE("deferred_calling_list-->26 = ");
}
}
#line 272 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_test_if_var_matches_description(OUTPUT_STREAM,
parse_node *var, parse_node *matches) {
if (matches == NULL) internal_error("VMD against null description");
if (var == NULL) internal_error("VMD on null variable");
if ((Lvalues__get_storage_form(var) != NONLOCAL_VARIABLE_VNT) &&
(Lvalues__get_storage_form(var) != LOCAL_VARIABLE_VNT))
internal_error("VMD on non-variable");
LOG_INDENT;
pcalc_prop *prop = Calculus__Propositions__from_spec(matches);
kind *K = Specifications__to_kind(var);
prop = Calculus__Propositions__concatenate(
Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0)), prop);
LOGIF(DESCRIPTION_COMPILATION, "[VMD: $P ($u) matches $D]\n", var, K, prop);
if (Calculus__Propositions__Checker__type_check(prop,
Calculus__Propositions__Checker__tc_no_problem_reporting()) == NEVER_MATCH) {
WRITE("(false)");
} else {
Calculus__Deferrals__compile_test_of_proposition(OUT, var, prop);
}
LOG_OUTDENT;
}
#line 317 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_now_proposition(OUTPUT_STREAM, pcalc_prop *prop,
int with_semicolon) {
int quantifier_count = 0;
LOGIF(PREDICATE_CALCULUS_WORKINGS, "Compiling as 'now': $D\n", prop);
{
#line 353 "inform7/Chapter 18/Deciding to Defer.w"
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, prop) {
switch(pl->element) {
case QUANTIFIER_ATOM:
if (Calculus__Atoms__is_existence_quantifier(pl)) {
Problems__Issue__sentence_problem(_p_(PM_CantForceExistence),
"this is not explicit enough",
"and should set out definite relationships between specific "
"things, like 'now the cat is in the bag', not something "
"more elusive like 'now the cat is carried by a woman.' "
"(Which woman? That's the trouble.)");
return;
}
if (Calculus__Atoms__is_now_assertable_quantifier(pl) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_CantForceGeneralised),
"this can't be made true with 'now'",
"because it is too vague about what it applies to. It's fine "
"to say 'now all the doors are open' or 'now none of the doors "
"is open', because that clearly tells me which doors are "
"affected; but if you write 'now six of the doors are open' "
"or 'now almost all the doors are open', what am I to do?");
return;
}
quantifier_count++;
break;
case CALLED_ATOM:
Problems__Issue__sentence_problem(_p_(PM_CantForceCalling),
"a 'now' is not allowed to call names",
"and it wouldn't really make sense to do so anyway. 'if "
"a person (called the victim) is in the Trap Room' makes "
"sense, because it gives a name - 'victim' - to someone "
"whose identity we don't know. But 'now a person (called "
"the victim) is in the Trap Room' won't be allowed, "
"because 'now' can only talk about people or things whose "
"identities we do know.");
return;
}
}
}
#line 323 "inform7/Chapter 18/Deciding to Defer.w"
;
if (quantifier_count > 0) {
pcalc_prop_deferral *pdef = Calculus__Deferrals__new_deferred_proposition(prop, NOW_ASSERTION_DEFER);
WRITE("Prop_%d(", pdef->allocation_id);
Calculus__Deferrals__Cinders__find(OUT, prop, pdef);
WRITE(");");
} else {
int parity = TRUE;
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, prop) {
switch (pl->element) {
case NEGATION_OPEN_ATOM: case NEGATION_CLOSE_ATOM:
parity = (parity)?FALSE:TRUE;
break;
default:
Calculus__Atoms__Compile__compile(OUT,
(parity)?NOW_ATOM_TRUE_TASK:NOW_ATOM_FALSE_TASK, pl, with_semicolon);
break;
}
}
}
}
#line 417 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_multiple_use_proposition(OUTPUT_STREAM,
parse_node *spec, kind *K) {
int negate = FALSE;
quantifier *q = Descriptions__get_quantifier(spec);
if (q == not_exists_quantifier) negate = TRUE;
else if ((q) && (q != for_all_quantifier)) {
Problems__quote_source(1, current_sentence);
Problems__quote_spec(2, spec);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"In %1 you wrote the description '%2' in the context of a value, "
"but descriptions used that way are not allowed to talk about "
"quantities. For example, it's okay to write 'an even number' "
"as a description value, but not 'three numbers' or 'most numbers'.");
Problems__issue_problem_end();
}
pcalc_prop *prop = Calculus__Propositions__from_spec(spec);
if (negate) {
prop = Calculus__Propositions__concatenate(Calculus__Atoms__new(NEGATION_OPEN_ATOM), prop);
prop = Calculus__Propositions__concatenate(prop, Calculus__Atoms__new(NEGATION_CLOSE_ATOM));
}
prop = Calculus__Propositions__concatenate(
Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0)), prop);
if (Calculus__Propositions__Checker__type_check(prop,
Calculus__Propositions__Checker__tc_no_problem_reporting()) == NEVER_MATCH) return;
parse_node *example = NULL;
if (Calculus__Variables__detect_locals(prop, &example) > 0) {
LOG("Offending proposition: $D\n", prop);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(example));
Problems__Issue__handmade_problem(_p_(PM_LocalInDescription));
Problems__issue_problem_segment(
"You wrote %1, but descriptions used as values are not allowed to "
"contain references to temporary values (defined by 'let', or by loops, "
"or existing only in certain rulebooks or actions, say) - unfortunately "
"'%2' is just such a temporary value. The problem is that it may well "
"not exist any more when the description needs to be used, in another "
"time and another place.");
Problems__issue_problem_end();
} else {
pcalc_prop_deferral *pdef = Calculus__Deferrals__new_deferred_proposition(prop, MULTIPURPOSE_DEFER);
WRITE("Prop_%d", pdef->allocation_id);
}
}
#line 487 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_number_of_S(OUTPUT_STREAM, parse_node *spec) {
if (Calculus__Deferrals__spec_is_variable_of_kind_description(spec)) {
WRITE("(");
Specifications__Compiler__compile(OUT, spec);
WRITE(")(%d)", NUMBER_OF_DUSAGE);
} else {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec);
Calculus__Deferrals__prop_verify_descriptive(prop, "a number of things matching a description", spec);
Calculus__Deferrals__compile_call_to_deferred_desc(OUT, prop, NUMBER_OF_DEFER, NULL_GENERAL_POINTER, NULL);
}
}
#line 502 "inform7/Chapter 18/Deciding to Defer.w"
int Calculus__Deferrals__spec_is_variable_of_kind_description(parse_node *spec) {
if ((ParseTree__is_lvalue(spec)) &&
(Kinds__get_construct(Specifications__to_kind(spec)) == CON_description))
return TRUE;
return FALSE;
}
void Calculus__Deferrals__compile_call_to_deferred_desc(OUTPUT_STREAM, pcalc_prop *prop,
int reason, general_pointer data, kind *K) {
pcalc_prop_deferral *pdef = Calculus__Deferrals__new_deferred_proposition(prop, reason);
pdef->defn_ref = data;
WRITE("(");
Calculus__Deferrals__prepare_to_retrieve_callings(OUT, prop, FALSE);
WRITE("Prop_%d(", pdef->allocation_id);
int nc = Calculus__Deferrals__Cinders__find(OUT, prop, pdef);
if (K) {
if (nc > 0) WRITE(",");
Frames__compile_allocation(OUT, K);
WRITE(",");
Kinds__RunTime__compile_strong_id(OUT, Kinds__unary_construction_material(K));
}
WRITE(")");
Calculus__Deferrals__retrieve_callings(OUT, prop, FALSE);
WRITE(")");
}
#line 531 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_list_of_S(OUTPUT_STREAM, parse_node *spec, kind *K) {
if (Calculus__Deferrals__spec_is_variable_of_kind_description(spec)) {
WRITE("(LIST_OF_TY_Desc(");
Frames__compile_allocation(OUT, K);
WRITE(",");
Specifications__Compiler__compile(OUT, spec);
WRITE(",");
Kinds__RunTime__compile_strong_id(OUT, Kinds__unary_construction_material(K));
WRITE("))");
} else {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec);
Calculus__Deferrals__prop_verify_descriptive(prop, "a list of things matching a description", spec);
Calculus__Deferrals__compile_call_to_deferred_desc(OUT, prop, LIST_OF_DEFER, NULL_GENERAL_POINTER, K);
}
}
#line 550 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_random_of_S(OUTPUT_STREAM, parse_node *spec) {
if (Rvalues__is_CONSTANT_construction(spec, CON_description)) {
kind *K = ParseTree__get_kind_of_value(spec);
K = Kinds__unary_construction_material(K);
if ((K) && (Kinds__Behaviour__is_an_enumeration(K)) &&
(Specifications__to_proposition(spec) == NULL) &&
(Kinds__Compare__lt(Specifications__to_kind(spec),
K_object) == FALSE) &&
(Descriptions__to_instance(spec) == NULL) &&
(Descriptions__number_of_adjectives_applied_to(spec) == 0)) {
WRITE("R_%s()", Kinds__Behaviour__get_name_of_printing_rule(K));
return;
}
}
if (Calculus__Deferrals__spec_is_variable_of_kind_description(spec)) {
WRITE("(");
Specifications__Compiler__compile(OUT, spec);
WRITE(")(%d)", RANDOM_OF_DUSAGE);
} else {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec);
Calculus__Deferrals__prop_verify_descriptive(prop, "a random thing matching a description", spec);
kind *K = Calculus__Propositions__describes_kind(prop);
if ((K) && (Kinds__Behaviour__compile_domain_possible(K) == FALSE))
Problems__Issue__sentence_problem(_p_(PM_RandomImpossible),
"this asks to find a random choice from a range which is too "
"large or impractical",
"so can't be done. For instance, 'a random person' is fine - "
"it's clear exactly who all the people are, and the supply is "
"limited - but not 'a random text'.");
else
Calculus__Deferrals__compile_call_to_deferred_desc(OUT, prop, RANDOM_OF_DEFER, NULL_GENERAL_POINTER, NULL);
}
}
#line 587 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_total_of_S(OUTPUT_STREAM, property *prn, parse_node *spec) {
if (prn == NULL) internal_error("total of on non-property");
if (Calculus__Deferrals__spec_is_variable_of_kind_description(spec)) {
WRITE("(property_to_be_totalled=%s,(", Properties__get_translation(prn));
Specifications__Compiler__compile(OUT, spec);
WRITE(")(%d))", TOTAL_DUSAGE);
} else {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec);
Calculus__Deferrals__prop_verify_descriptive(prop,
"a total property value for things matching a description", spec);
Calculus__Deferrals__compile_call_to_deferred_desc(OUT, prop, TOTAL_DEFER,
STORE_POINTER_property(prn), NULL);
}
}
#line 606 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_substitution_test(OUTPUT_STREAM, parse_node *in,
parse_node *spec) {
if (Calculus__Deferrals__spec_is_variable_of_kind_description(spec)) {
WRITE("(");
Specifications__Compiler__compile(OUT, spec);
WRITE(")(%d,", CONDITION_DUSAGE);
Specifications__Compiler__compile(OUT, in);
WRITE(")");
} else {
Calculus__Deferrals__compile_test_of_proposition(OUT,
in, Calculus__Propositions__from_spec(spec));
}
}
#line 623 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_substitution_now(OUTPUT_STREAM, parse_node *in,
parse_node *spec) {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec);
Calculus__Variables__substitute_var_0_in(prop, in);
Calculus__Propositions__Checker__type_check(prop,
Calculus__Propositions__Checker__tc_no_problem_reporting());
int save_cck = suppress_C14CantChangeKind;
suppress_C14CantChangeKind = TRUE;
Calculus__Deferrals__compile_now_proposition(OUT, prop, TRUE);
suppress_C14CantChangeKind = save_cck;
}
#line 643 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_extremal_of_S(OUTPUT_STREAM, parse_node *spec,
property *prn, int sign) {
if (prn == NULL) internal_error("extremal of on non-property");
if (Calculus__Deferrals__spec_is_variable_of_kind_description(spec)) {
WRITE("(property_to_be_totalled=%s,property_loop_sign=%d,(",
Properties__get_translation(prn), sign);
Specifications__Compiler__compile(OUT, spec);
WRITE(")(%d))", EXTREMAL_DUSAGE);
} else {
measurement_definition *mdef_found = Properties__Measurement__retrieve(prn, sign);
if (mdef_found) {
pcalc_prop *prop = Calculus__Propositions__from_spec(spec);
Calculus__Deferrals__prop_verify_descriptive(prop,
"an extreme case of something matching a description", spec);
Calculus__Deferrals__compile_call_to_deferred_desc(OUT, prop, EXTREMAL_DEFER,
STORE_POINTER_measurement_definition(mdef_found), NULL);
}
}
}
#line 692 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_repeat_through_domain_S(OUTPUT_STREAM, parse_node *spec,
local_variable *v1) {
kind *DK = Specifications__to_kind(spec);
if (Kinds__get_construct(DK) != CON_description)
internal_error("repeat through non-description");
kind *K = Kinds__unary_construction_material(DK);
local_variable *v2 = LocalVariables__new(EMPTY_WORDING, K);
Frames__Blocks__set_scope_to_block_about_to_open(v1);
Frames__Blocks__set_scope_to_block_about_to_open(v2);
char val_var[32], aux_var[32];
sprintf(val_var, "%s", LocalVariables__lvalue(v1));
sprintf(aux_var, "%s", LocalVariables__lvalue(v2));
if (Kinds__Compare__le(K, K_object)) {
pcalc_prop *domain_prop = NULL; int use_as_is = FALSE;
if (Calculus__Deferrals__spec_is_variable_of_kind_description(spec)) use_as_is = TRUE;
else {
domain_prop = Calculus__Propositions__from_spec(spec);
if (Calculus__Propositions__contains_callings(domain_prop))
Problems__Issue__sentence_problem(_p_(PM_CalledInRepeat),
"this tries to use '(called ...)' to give names to values "
"arising in the course of working out what to repeat through",
"but this is not allowed. (Sorry: it's too hard to get right.)");
}
WRITE("for (%s=", val_var);
if (use_as_is) Calculus__Deferrals__compile_repeat_call(OUT, spec, NULL);
else Calculus__Deferrals__compile_repeat_domain(OUT, domain_prop, NULL);
WRITE(", %s=", aux_var);
if (use_as_is) Calculus__Deferrals__compile_repeat_call(OUT, spec, v1);
else Calculus__Deferrals__compile_repeat_domain(OUT, domain_prop, v1);
WRITE(": %s: %s=%s, %s=", val_var, val_var, aux_var, aux_var);
if (use_as_is) Calculus__Deferrals__compile_repeat_call(OUT, spec, v2);
else Calculus__Deferrals__compile_repeat_domain(OUT, domain_prop, v2);
WRITE(")");
} else {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
i6_schema loop_schema;
if (Kinds__Behaviour__write_loop_schema(&loop_schema, K, FALSE)) {
Calculus__Schemas__expand_textual(&loop_schema, OUT, val_var, aux_var);
if (ParseTree__is_lvalue(spec) == FALSE) {
if (Specifications__to_proposition(spec)) {
WRITE("if (");
Calculus__Deferrals__compile_test_of_proposition(OUT,
Lvalues__new_LOCAL_VARIABLE(EMPTY_WORDING, v1),
Specifications__to_proposition(spec));
WRITE(") ");
}
} else {
WRITE("if("); Specifications__Compiler__compile(OUT, spec);
WRITE("(%d, ", CONDITION_DUSAGE);
Specifications__Compiler__compile(OUT,
Lvalues__new_LOCAL_VARIABLE(EMPTY_WORDING, v1));
WRITE(")) ");
}
} else
Problems__Issue__sentence_problem(_p_(PM_BadRepeatDomain),
"this describes a collection of values which can't be repeated through",
"because the possible range is too large (or has no sensible ordering). "
"For instance, you can 'repeat with D running through doors' because "
"there are only a small number of doors and they can be put in order "
"of creation. But you can't 'repeat with N running through numbers' "
"because numbers are without end.");
END_COMPILATION_MODE;
}
}
#line 772 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_repeat_call(OUTPUT_STREAM, parse_node *spec, local_variable *fromv) {
WRITE("(");
Specifications__Compiler__compile(OUT, spec);
WRITE(")(%d,", LOOP_DOMAIN_DUSAGE);
if (fromv) WRITE("%s", LocalVariables__lvalue(fromv)); else WRITE("0");
WRITE(")");
}
#line 785 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_repeat_domain(OUTPUT_STREAM, pcalc_prop *prop, local_variable *fromv) {
pcalc_prop_deferral *pdef = Calculus__Deferrals__defer_loop_domain(prop);
WRITE("Prop_%d(", pdef->allocation_id);
int nc = Calculus__Deferrals__Cinders__find(OUT, prop, pdef);
if (nc > 0) WRITE(",");
if (fromv) WRITE("%s", LocalVariables__lvalue(fromv)); else WRITE("0");
WRITE(")");
}
#line 797 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__compile_loop_over_list_S(OUTPUT_STREAM, parse_node *spec, local_variable *v1) {
local_variable *index_in_list = LocalVariables__new(EMPTY_WORDING, K_number);
local_variable *copy_of_list = LocalVariables__new(EMPTY_WORDING, K_number);
kind *K = Specifications__to_kind(spec);
kind *CK = Kinds__unary_construction_material(K);
int pointery = FALSE;
if (Kinds__Behaviour__uses_pointer_values(CK)) {
pointery = TRUE;
LocalVariables__mark_to_free_at_end_of_scope(v1);
}
Frames__Blocks__set_scope_to_block_about_to_open(v1);
LocalVariables__set_kind(v1, CK);
Frames__Blocks__set_scope_to_block_about_to_open(index_in_list);
char val_var[8], aux_var[8], cop_var[8];
sprintf(val_var, "%s", LocalVariables__lvalue(v1));
sprintf(aux_var, "%s", LocalVariables__lvalue(index_in_list));
sprintf(cop_var, "%s", LocalVariables__lvalue(copy_of_list));
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
WRITE("for (%s=", cop_var);
Specifications__Compiler__compile(OUT, spec);
WRITE(", %s=1, ", aux_var);
if (pointery) {
WRITE("%s = BlkValueCreate(", val_var);
Kinds__RunTime__compile_strong_id(OUT, CK);
WRITE("), BlkValueCopyAZ(%s, ", val_var);
}
else
WRITE("%s=", val_var);
WRITE("LIST_OF_TY_GetItem(%s, %s, true)", cop_var, aux_var);
if (pointery)
WRITE(")");
WRITE(": ");
WRITE("%s<=LIST_OF_TY_GetLength(%s): ", aux_var, cop_var);
WRITE("%s++, ", aux_var);
if (pointery)
WRITE("BlkValueCopyAZ(%s, ", val_var);
else
WRITE("%s=", val_var);
WRITE("LIST_OF_TY_GetItem(%s, %s, true)", cop_var, aux_var);
if (pointery)
WRITE(")");
WRITE(")");
END_COMPILATION_MODE;
}
#line 853 "inform7/Chapter 18/Deciding to Defer.w"
void Calculus__Deferrals__prop_verify_descriptive(pcalc_prop *prop, char *billing,
parse_node *constructor) {
if (constructor == NULL) internal_error("description with null constructor");
/* best guess at the text to quote in any problem message */
wording EW = ParseTree__get_text(constructor);
if ((Wordings__empty(EW)) && (constructor->down))
EW = ParseTree__get_text(constructor->down);
if (Calculus__Variables__is_well_formed(prop) == FALSE)
internal_error("malformed proposition in description verification");
int N = Calculus__Variables__number_free(prop);
if (N == 1)
Calculus__Propositions__Checker__type_check(prop,
Calculus__Propositions__Checker__tc_problem_reporting(EW,
"involve a range of objects matching a description"));
if (N > 1) {
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, billing);
Problems__quote_wording(3, EW);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"In %1, you are asking for %2, but this should range over a "
"simpler description than '%3', please - it should not include any "
"determiners such as 'at least three', 'all' or 'most'. "
"(The range is always taken to be all of the things matching "
"the description.)");
Problems__issue_problem_end();
return;
}
if (N < 1) {
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, billing);
Problems__quote_wording(3, EW);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"In %1, you are asking for %2, but '%3' looks as if it ranges "
"over only a single specific object, not a whole collection of "
"objects.");
Problems__issue_problem_end();
}
}
#line 53 "inform7/Chapter 18/Cinders and Deferrals.w"
pcalc_prop_deferral *current_pdef = NULL; /* used only in this section */
#line 63 "inform7/Chapter 18/Cinders and Deferrals.w"
int Calculus__Deferrals__Cinders__find(OUTPUT_STREAM, pcalc_prop *prop, pcalc_prop_deferral *pdef) {
TRAVERSE_VARIABLE(pl);
int i, cinder_number = 0, started = FALSE;
pcalc_prop_deferral *save_current_pdef = current_pdef;
current_pdef = pdef;
TRAVERSE_PROPOSITION(pl, prop)
for (i=0; i<pl->arity; i++)
cinder_number =
Calculus__Deferrals__Cinders__cind_find_in_term(OUT, &(pl->terms[i]), cinder_number, &started);
current_pdef = save_current_pdef;
return cinder_number;
}
int Calculus__Deferrals__Cinders__cind_find_in_term(OUTPUT_STREAM, pcalc_term *pt, int cinder_number, int *started) {
/* do not clear the local I6 stream */
if (pt->function)
return Calculus__Deferrals__Cinders__cind_find_in_term(OUT, &(pt->function->fn_of), cinder_number, started);
if (pt->constant) {
if (Calculus__Deferrals__Cinders__spec_needs_to_be_cindered(pt->constant)) {
pt->cinder = cinder_number++;
if (*started) WRITE(",");
Specifications__Compiler__compile(OUT, pt->constant);
current_pdef->cinder_kinds[pt->cinder] =
Specifications__to_kind(pt->constant);
*started = TRUE;
} else pt->cinder = -1;
}
return cinder_number;
}
#line 115 "inform7/Chapter 18/Cinders and Deferrals.w"
int Calculus__Deferrals__Cinders__spec_needs_to_be_cindered(parse_node *spec) {
if (ParseTree__is(spec, CONSTANT_VNT)) return FALSE;
if (Lvalues__is_global_variable(spec)) return FALSE;
return TRUE;
}
#line 131 "inform7/Chapter 18/Cinders and Deferrals.w"
void Calculus__Deferrals__Cinders__declare(pcalc_prop *prop, pcalc_prop_deferral *pdef) {
TRAVERSE_VARIABLE(pl);
int i, cinder_number = 0;
pcalc_prop_deferral *save_current_pdef = current_pdef;
current_pdef = pdef;
TRAVERSE_PROPOSITION(pl, prop)
for (i=0; i<pl->arity; i++)
cinder_number = Calculus__Deferrals__Cinders__cind_declare_in(cinder_number, &(pl->terms[i]));
current_pdef = save_current_pdef;
}
int Calculus__Deferrals__Cinders__cind_declare_in(int cinder_number, pcalc_term *pt) {
if (pt->function)
return Calculus__Deferrals__Cinders__cind_declare_in(cinder_number, &(pt->function->fn_of));
if ((pt->constant) && (pt->cinder >= 0))
if (ParseTree__is(pt->constant, CONSTANT_VNT) == FALSE) {
char cinder_name[32];
sprintf(cinder_name, "const_%d", cinder_number++);
LocalVariables__add_named_call(cinder_name);
}
return cinder_number;
}
#line 163 "inform7/Chapter 18/Cinders and Deferrals.w"
kind *Calculus__Deferrals__Cinders__kind_of_value_of_term(pcalc_term pt) {
if (pt.variable >= 0) {
if (pt.term_checked_as_kind) return pt.term_checked_as_kind;
return K_object;
}
if (pt.constant) {
if (pt.cinder >= 0) return current_pdef->cinder_kinds[pt.cinder];
if (ParseTree__is_phrasal(pt.constant))
Dash__check_value(pt.constant, NULL);
return Specifications__to_kind(pt.constant);
}
if (pt.function) return K_object;
internal_error("Broken pcalc term");
return NULL;
}
#line 182 "inform7/Chapter 18/Cinders and Deferrals.w"
void Calculus__Deferrals__Cinders__compile(OUTPUT_STREAM, int c) {
WRITE("const_%d", c);
}
#line 16 "inform7/Chapter 18/Compile Deferred Propositions.w"
void Calculus__Propositions__Deferred__compile_comment_about_deferral_reason(OUTPUT_STREAM, int reason) {
switch(reason) {
case CONDITION_DEFER:
WRITE("! True or false?\n"); break;
case NOW_ASSERTION_DEFER:
WRITE("! Force this to be true via 'now':\n"); break;
case EXTREMAL_DEFER:
WRITE("! Find the extremal x satisfying:\n"); break;
case LOOP_DOMAIN_DEFER:
WRITE("! Find next x satisfying:\n"); break;
case LIST_OF_DEFER:
WRITE("! Construct a list of x satisfying:\n"); break;
case NUMBER_OF_DEFER:
WRITE("! How many x satisfy this?\n"); break;
case TOTAL_DEFER:
WRITE("! Find a total property value over all x satisfying:\n"); break;
case RANDOM_OF_DEFER:
WRITE("! Find a random x satisfying:\n"); break;
case MULTIPURPOSE_DEFER:
WRITE("! Abstraction for set of x such that:\n"); break;
default: internal_error("Unknown proposition deferral reason");
}
}
#line 48 "inform7/Chapter 18/Compile Deferred Propositions.w"
void Calculus__Propositions__Deferred__compile_remaining_deferred(OUTPUT_STREAM) {
Calculus__Propositions__Deferred__compilation_coroutine(OUT);
}
pcalc_prop_deferral *latest_pcd = NULL;
int Calculus__Propositions__Deferred__compilation_coroutine(OUTPUT_STREAM) {
int N = 0;
while (TRUE) {
pcalc_prop_deferral *pdef;
if (latest_pcd == NULL)
pdef = FIRST_OBJECT(pcalc_prop_deferral);
else pdef = NEXT_OBJECT(latest_pcd, pcalc_prop_deferral);
if (pdef == NULL) break;
latest_pcd = pdef;
{
#line 78 "inform7/Chapter 18/Compile Deferred Propositions.w"
pcalc_prop_deferral *save_current_pdef = current_pdef;
current_pdef = pdef;
int ct_locals_problem_thrown = FALSE, negated_quantifier_found = FALSE;
current_sentence = pdef->deferred_from;
pcalc_prop *proposition = Calculus__Propositions__copy(pdef->proposition_to_defer);
int multipurpose_routine = (pdef->reason == MULTIPURPOSE_DEFER)?TRUE:FALSE;
int reason = CONDITION_DEFER; /* redundant assignment to appease |gcc -O2| */
{
#line 123 "inform7/Chapter 18/Compile Deferred Propositions.w"
int changed = FALSE;
proposition = Calculus__Simplifications__negated_determiners(proposition, &changed, TRUE);
if (changed) {
LOGIF(PREDICATE_CALCULUS, "Calculus__Simplifications__negated_determiners: $D\n", proposition);
}
}
#line 87 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
{
#line 133 "inform7/Chapter 18/Compile Deferred Propositions.w"
LOGIF(PREDICATE_CALCULUS, "Compiling deferred proposition: %d: reason %d: $D\n",
pdef->allocation_id, pdef->reason, proposition);
Calculus__Propositions__Deferred__compile_comment_about_deferral_reason(OUT, pdef->reason);
text_stream *save_dl = dl; dl = OUT; logging_to_I6_text = TRUE;
LOG("! $D", proposition);
dl = save_dl; logging_to_I6_text = FALSE;
WRITE("\n");
}
#line 89 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "Prop_%d", pdef->allocation_id);
OUT = Routines__begin(OUT, i6_routine_identifier);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
{
#line 185 "inform7/Chapter 18/Compile Deferred Propositions.w"
int j, var_states[26], no_extras;
if (multipurpose_routine)
LocalVariables__add_named_call("reason"); /* no cinders exist here */
else
Calculus__Deferrals__Cinders__declare(proposition, pdef);
Calculus__Variables__determine_status(proposition, var_states, NULL);
for (j=0; j<26; j++)
if (var_states[j] != UNUSED_VST) {
char letter_var[8];
sprintf(letter_var, "%c", pcalc_vars[j]);
LocalVariables__add_internal_local(letter_var);
sprintf(letter_var, "%c_ix", pcalc_vars[j]);
LocalVariables__add_internal_local(letter_var);
}
no_extras = 0;
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, proposition)
if (pl->element == DOMAIN_OPEN_ATOM) {
char q_var[8];
sprintf(q_var, "qcy_%d", no_extras);
LocalVariables__add_internal_local(q_var);
sprintf(q_var, "qcn_%d", no_extras);
LocalVariables__add_internal_local(q_var);
no_extras++;
}
{
#line 784 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (multipurpose_routine) {
LocalVariables__add_internal_local("total");
LocalVariables__add_internal_local("counter");
LocalVariables__add_internal_local("selection");
LocalVariables__add_internal_local("best");
LocalVariables__add_internal_local("best_with");
} else {
switch (pdef->reason) {
case NUMBER_OF_DEFER:
LocalVariables__add_internal_local("counter");
break;
case RANDOM_OF_DEFER:
LocalVariables__add_internal_local("counter");
LocalVariables__add_internal_local("selection");
break;
case TOTAL_DEFER:
LocalVariables__add_internal_local("total");
break;
case LIST_OF_DEFER:
LocalVariables__add_internal_local("counter");
LocalVariables__add_internal_local("total");
LocalVariables__add_named_call("list");
LocalVariables__add_named_call("strong_kind");
break;
case EXTREMAL_DEFER:
LocalVariables__add_internal_local("best");
LocalVariables__add_internal_local("best_with");
break;
}
}
}
#line 213 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
WRITE(";\n");
}
#line 97 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
{
#line 219 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (multipurpose_routine) {
int use;
WRITE("if (reason >= 0) { x = reason; reason = %d; }\n",
CONDITION_DUSAGE);
WRITE("switch (reason) {\n");
INDENT;
pcalc_prop *safety_copy = Calculus__Propositions__copy(proposition);
for (use = EXTREMAL_DUSAGE; use <= CONDITION_DUSAGE; use++) {
if (use > EXTREMAL_DUSAGE) proposition = Calculus__Propositions__copy(safety_copy);
switch (use) {
case CONDITION_DUSAGE: reason = CONDITION_DEFER; break;
case LOOP_DOMAIN_DUSAGE: reason = LOOP_DOMAIN_DEFER; break;
case LIST_OF_DUSAGE: reason = LIST_OF_DEFER; break;
case NUMBER_OF_DUSAGE: reason = NUMBER_OF_DEFER; break;
case RANDOM_OF_DUSAGE: reason = RANDOM_OF_DEFER; break;
case TOTAL_DUSAGE: reason = TOTAL_DEFER; break;
case EXTREMAL_DUSAGE: reason = EXTREMAL_DEFER; break;
}
WRITE("%d: ", use);
Calculus__Propositions__Deferred__compile_comment_about_deferral_reason(OUT, reason);
INDENT;
{
#line 261 "inform7/Chapter 18/Compile Deferred Propositions.w"
property *prn = NULL;
property *def_prn = NULL;
int def_prn_sign = 0;
switch(reason) {
case NOW_ASSERTION_DEFER: break;
case CONDITION_DEFER:
{
#line 821 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
#line 267 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1017 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (multipurpose_routine) {
WRITE("if (property_loop_sign>0) best=MIN_NEGATIVE_NUMBER;\n");
WRITE("else best=MAX_POSITIVE_NUMBER;\n");
} else {
measurement_definition *mdef =
RETRIEVE_POINTER_measurement_definition(pdef->defn_ref);
Properties__Measurement__read_property_details(mdef, &def_prn, &def_prn_sign);
if (def_prn_sign == 1) {
WRITE("best = MIN_NEGATIVE_NUMBER;\n");
} else {
WRITE("best = MAX_POSITIVE_NUMBER;\n");
}
}
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 268 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1127 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("if (%c_ix > 0) {\n", pcalc_vars[0]);
INDENT;
WRITE("%c_ix--;\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("if (%c) jump NextOuterLoop_%d;\n", pcalc_vars[0], reason);
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 269 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 845 "inform7/Chapter 18/Compile Deferred Propositions.w"
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 270 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 877 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("BlkValueWrite(list, LIST_ITEM_KOV_F, strong_kind);\n");
WRITE("total = LIST_OF_TY_GetLength(list);\n");
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 271 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 963 "inform7/Chapter 18/Compile Deferred Propositions.w"
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 272 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 923 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("selection = -1;\n");
WRITE("while (true) {\n");
INDENT;
WRITE("counter = 0;\n");
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 273 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
}
{
#line 368 "inform7/Chapter 18/Compile Deferred Propositions.w"
int block_nesting = 0; /* how many |{| ... |}| blocks are open in I6 code being compiled */
/* The R-stack */
int R_stack_reason[27];
int R_stack_parity[27];
int R_sp = 0;
/* The Q-stack */
quantifier *Q_stack_quantifier[26];
int Q_stack_parameter[26];
int Q_stack_C_stack_level[26];
int Q_stack_block_nesting[26];
int Q_sp = 0;
/* The C-stack */
pcalc_term C_stack_term[26]; /* the term to which a called-name is being given */
int C_stack_index[26]; /* its index in the |deferred_calling_list| */
int C_sp = 0;
{
#line 413 "inform7/Chapter 18/Compile Deferred Propositions.w"
R_stack_reason[R_sp] = reason;
R_stack_parity[R_sp] = TRUE;
R_sp++;
}
#line 387 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
/* we now begin compiling the search code */
{
#line 459 "inform7/Chapter 18/Compile Deferred Propositions.w"
TRAVERSE_VARIABLE(pl);
int run_of_conditions = FALSE;
int no_deferred_callings = 0; /* how many |CALLED| atoms have been found to date */
TRAVERSE_PROPOSITION(pl, proposition) {
switch (pl->element) {
case NEGATION_OPEN_ATOM:
case NEGATION_CLOSE_ATOM:
{
#line 547 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 551 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 467 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
R_stack_parity[R_sp-1] = (R_stack_parity[R_sp-1])?FALSE:TRUE; /* reverse parity */
break;
case QUANTIFIER_ATOM:
{
#line 547 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 551 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 471 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
if (R_stack_parity[R_sp-1] == FALSE) negated_quantifier_found = TRUE;
quantifier *quant = RETRIEVE_POINTER_quantifier(pl->predicate);
int param = Calculus__Atoms__get_quantification_parameter(pl);
if (quant != exists_quantifier)
{
#line 633 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (R_stack_reason[R_sp-1] == NOW_ASSERTION_DEFER)
{
#line 654 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (quant == not_exists_quantifier) {
R_stack_parity[R_sp-1] = (R_stack_parity[R_sp-1])?FALSE:TRUE;
quant = for_all_quantifier;
}
}
#line 634 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
Q_stack_quantifier[Q_sp] = quant;
Q_stack_parameter[Q_sp] = param;
Q_stack_block_nesting[Q_sp] = block_nesting;
Q_stack_C_stack_level[Q_sp] = C_sp;
WRITE("qcy_%d = 0;\n", Q_sp);
WRITE("qcn_%d = 0;\n", Q_sp);
Q_sp++;
}
#line 475 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
{
#line 586 "inform7/Chapter 18/Compile Deferred Propositions.w"
pl = Calculus__Propositions__Deferred__compile_loop_header(OUT, pl->terms[0].variable, pl,
(R_stack_reason[R_sp-1] == NOW_ASSERTION_DEFER)?TRUE:FALSE,
(quant != exists_quantifier)?TRUE:FALSE, pdef);
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 589 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
#line 476 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
break;
case DOMAIN_OPEN_ATOM:
{
#line 547 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 551 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 479 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
{
#line 425 "inform7/Chapter 18/Compile Deferred Propositions.w"
R_stack_reason[R_sp] = FILTER_DEFER;
R_stack_parity[R_sp] = TRUE;
R_sp++;
}
#line 480 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
break;
case DOMAIN_CLOSE_ATOM:
{
#line 547 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 551 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 483 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
{
#line 438 "inform7/Chapter 18/Compile Deferred Propositions.w"
R_sp--; if (R_sp < 0) internal_error("R stack underflow");
switch(R_stack_reason[R_sp]) {
case FILTER_DEFER:
WRITE("qcn_%d++;\n", Q_sp-1);
break;
case NOW_ASSERTION_DEFER: break;
case CONDITION_DEFER:
{
#line 826 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("rtrue;\n");
}
#line 445 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1043 "inform7/Chapter 18/Compile Deferred Propositions.w"
char *source_of_property;
if (multipurpose_routine) source_of_property = "property_to_be_totalled";
else source_of_property = Properties__get_translation(def_prn);
if (multipurpose_routine) {
WRITE("if (property_loop_sign>0) {\n");
INDENT;
WRITE("if (%c.%s >= best) {\n", pcalc_vars[0], source_of_property);
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
OUTDENT;
WRITE("} else {\n");
INDENT;
WRITE("if (%c.%s <= best) {\n", pcalc_vars[0], source_of_property);
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
OUTDENT;
WRITE("}\n");
} else {
WRITE("if (%c.%s %s best) {\n",
pcalc_vars[0], source_of_property, (def_prn_sign == 1)?">=":"<=");
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
}
}
#line 446 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1141 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("return %c;\n", pcalc_vars[0]);
}
#line 447 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 858 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 448 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 892 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter > total) { total = 3*(total/2)+8; LIST_OF_TY_SetLength(list, total); }\n");
WRITE("BlkValueWrite(list, counter+LIST_ITEM_BASE-1, %c);\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 449 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 975 "inform7/Chapter 18/Compile Deferred Propositions.w"
char *source_of_property;
if (multipurpose_routine)
source_of_property = "property_to_be_totalled";
else {
prn = RETRIEVE_POINTER_property(pdef->defn_ref);
source_of_property = Properties__get_translation(prn);
}
if (source_of_property == NULL) internal_error("No property name");
WRITE("total = total + %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 450 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 938 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter == selection) return %c;\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 451 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
}
}
#line 484 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
break;
case CALLED_ATOM:
{
#line 721 "inform7/Chapter 18/Compile Deferred Propositions.w"
C_stack_term[C_sp] = pl->terms[0];
C_stack_index[C_sp] = no_deferred_callings++;
C_sp++;
}
#line 487 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
break;
default:
if (R_stack_reason[R_sp-1] == NOW_ASSERTION_DEFER)
{
#line 569 "inform7/Chapter 18/Compile Deferred Propositions.w"
Calculus__Atoms__Compile__compile(OUT, (R_stack_parity[R_sp-1])?NOW_ATOM_TRUE_TASK:NOW_ATOM_FALSE_TASK, pl, TRUE);
WRITE("\n");
}
#line 491 "inform7/Chapter 18/Compile Deferred Propositions.w"
else
{
#line 536 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions == FALSE) {
WRITE("if ");
if (R_stack_parity[R_sp-1] == FALSE) WRITE("(~~");
WRITE("(");
run_of_conditions = TRUE;
} else WRITE(" && ");
Calculus__Atoms__Compile__compile(OUT, TEST_ATOM_TASK, pl, TRUE);
}
#line 493 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
break;
}
}
{
#line 547 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 551 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 497 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
#line 389 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
while (Q_sp > 0)
{
#line 694 "inform7/Chapter 18/Compile Deferred Propositions.w"
Q_sp--; if (Q_sp < 0) internal_error("Q stack underflow");
WRITE("qcy_%d++;\n", Q_sp);
while (C_sp > Q_stack_C_stack_level[Q_sp])
{
#line 755 "inform7/Chapter 18/Compile Deferred Propositions.w"
C_sp--; if (C_sp < 0) internal_error("C stack underflow");
WRITE("deferred_calling_list-->%d = ", C_stack_index[C_sp]);
Calculus__Terms__compile(OUT, C_stack_term[C_sp]);
WRITE(";\n");
}
#line 698 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
while (block_nesting > Q_stack_block_nesting[Q_sp])
{
#line 770 "inform7/Chapter 18/Compile Deferred Propositions.w"
OUTDENT;
WRITE("}\n");
block_nesting--;
}
#line 701 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
WRITE("if (");
Quantifiers__compile_test(OUT, Q_stack_quantifier[Q_sp], Q_sp, Q_stack_parameter[Q_sp]);
WRITE(")");
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 706 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
#line 390 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
while (C_sp > 0)
{
#line 755 "inform7/Chapter 18/Compile Deferred Propositions.w"
C_sp--; if (C_sp < 0) internal_error("C stack underflow");
WRITE("deferred_calling_list-->%d = ", C_stack_index[C_sp]);
Calculus__Terms__compile(OUT, C_stack_term[C_sp]);
WRITE(";\n");
}
#line 391 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
/* we are now at the magic match point |M| in the search code */
{
#line 438 "inform7/Chapter 18/Compile Deferred Propositions.w"
R_sp--; if (R_sp < 0) internal_error("R stack underflow");
switch(R_stack_reason[R_sp]) {
case FILTER_DEFER:
WRITE("qcn_%d++;\n", Q_sp-1);
break;
case NOW_ASSERTION_DEFER: break;
case CONDITION_DEFER:
{
#line 826 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("rtrue;\n");
}
#line 445 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1043 "inform7/Chapter 18/Compile Deferred Propositions.w"
char *source_of_property;
if (multipurpose_routine) source_of_property = "property_to_be_totalled";
else source_of_property = Properties__get_translation(def_prn);
if (multipurpose_routine) {
WRITE("if (property_loop_sign>0) {\n");
INDENT;
WRITE("if (%c.%s >= best) {\n", pcalc_vars[0], source_of_property);
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
OUTDENT;
WRITE("} else {\n");
INDENT;
WRITE("if (%c.%s <= best) {\n", pcalc_vars[0], source_of_property);
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
OUTDENT;
WRITE("}\n");
} else {
WRITE("if (%c.%s %s best) {\n",
pcalc_vars[0], source_of_property, (def_prn_sign == 1)?">=":"<=");
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
}
}
#line 446 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1141 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("return %c;\n", pcalc_vars[0]);
}
#line 447 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 858 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 448 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 892 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter > total) { total = 3*(total/2)+8; LIST_OF_TY_SetLength(list, total); }\n");
WRITE("BlkValueWrite(list, counter+LIST_ITEM_BASE-1, %c);\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 449 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 975 "inform7/Chapter 18/Compile Deferred Propositions.w"
char *source_of_property;
if (multipurpose_routine)
source_of_property = "property_to_be_totalled";
else {
prn = RETRIEVE_POINTER_property(pdef->defn_ref);
source_of_property = Properties__get_translation(prn);
}
if (source_of_property == NULL) internal_error("No property name");
WRITE("total = total + %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 450 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 938 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter == selection) return %c;\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 451 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
}
}
#line 393 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
while (block_nesting > 0)
{
#line 770 "inform7/Chapter 18/Compile Deferred Propositions.w"
OUTDENT;
WRITE("}\n");
block_nesting--;
}
#line 395 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
/* we have now finished compiling the search code */
if (R_sp != 0) internal_error("R-stack failure");
if (Q_sp != 0) internal_error("Q-stack failure");
if (C_sp != 0) internal_error("C-stack failure");
}
#line 275 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
switch(reason) {
case NOW_ASSERTION_DEFER: break;
case CONDITION_DEFER:
{
#line 831 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("rfalse;\n");
}
#line 278 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1079 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return best_with;\n");
}
#line 279 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1146 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return nothing;\n");
}
#line 280 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 867 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return counter;\n");
}
#line 281 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 903 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("LIST_OF_TY_SetLength(list, counter);\n");
WRITE("return list;\n");
}
#line 282 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 989 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return total;\n");
}
#line 283 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 950 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("if ((counter == 0) || (selection >= 0)) return nothing;\n");
WRITE("selection = random(counter);\n");
OUTDENT;
WRITE("}\n");
}
#line 284 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
}
}
#line 240 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
OUTDENT;
}
OUTDENT;
WRITE("}\n");
} else {
reason = pdef->reason;
{
#line 261 "inform7/Chapter 18/Compile Deferred Propositions.w"
property *prn = NULL;
property *def_prn = NULL;
int def_prn_sign = 0;
switch(reason) {
case NOW_ASSERTION_DEFER: break;
case CONDITION_DEFER:
{
#line 821 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
#line 267 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1017 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (multipurpose_routine) {
WRITE("if (property_loop_sign>0) best=MIN_NEGATIVE_NUMBER;\n");
WRITE("else best=MAX_POSITIVE_NUMBER;\n");
} else {
measurement_definition *mdef =
RETRIEVE_POINTER_measurement_definition(pdef->defn_ref);
Properties__Measurement__read_property_details(mdef, &def_prn, &def_prn_sign);
if (def_prn_sign == 1) {
WRITE("best = MIN_NEGATIVE_NUMBER;\n");
} else {
WRITE("best = MAX_POSITIVE_NUMBER;\n");
}
}
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 268 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1127 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("if (%c_ix > 0) {\n", pcalc_vars[0]);
INDENT;
WRITE("%c_ix--;\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("if (%c) jump NextOuterLoop_%d;\n", pcalc_vars[0], reason);
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 269 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 845 "inform7/Chapter 18/Compile Deferred Propositions.w"
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 270 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 877 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("BlkValueWrite(list, LIST_ITEM_KOV_F, strong_kind);\n");
WRITE("total = LIST_OF_TY_GetLength(list);\n");
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 271 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 963 "inform7/Chapter 18/Compile Deferred Propositions.w"
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 272 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 923 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("selection = -1;\n");
WRITE("while (true) {\n");
INDENT;
WRITE("counter = 0;\n");
proposition = Calculus__Propositions__Deferred__compile_loop_header(OUT, 0, proposition, FALSE, FALSE, pdef);
WRITE("{\n");
INDENT;
}
#line 273 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
}
{
#line 368 "inform7/Chapter 18/Compile Deferred Propositions.w"
int block_nesting = 0; /* how many |{| ... |}| blocks are open in I6 code being compiled */
/* The R-stack */
int R_stack_reason[27];
int R_stack_parity[27];
int R_sp = 0;
/* The Q-stack */
quantifier *Q_stack_quantifier[26];
int Q_stack_parameter[26];
int Q_stack_C_stack_level[26];
int Q_stack_block_nesting[26];
int Q_sp = 0;
/* The C-stack */
pcalc_term C_stack_term[26]; /* the term to which a called-name is being given */
int C_stack_index[26]; /* its index in the |deferred_calling_list| */
int C_sp = 0;
{
#line 413 "inform7/Chapter 18/Compile Deferred Propositions.w"
R_stack_reason[R_sp] = reason;
R_stack_parity[R_sp] = TRUE;
R_sp++;
}
#line 387 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
/* we now begin compiling the search code */
{
#line 459 "inform7/Chapter 18/Compile Deferred Propositions.w"
TRAVERSE_VARIABLE(pl);
int run_of_conditions = FALSE;
int no_deferred_callings = 0; /* how many |CALLED| atoms have been found to date */
TRAVERSE_PROPOSITION(pl, proposition) {
switch (pl->element) {
case NEGATION_OPEN_ATOM:
case NEGATION_CLOSE_ATOM:
{
#line 547 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 551 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 467 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
R_stack_parity[R_sp-1] = (R_stack_parity[R_sp-1])?FALSE:TRUE; /* reverse parity */
break;
case QUANTIFIER_ATOM:
{
#line 547 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 551 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 471 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
if (R_stack_parity[R_sp-1] == FALSE) negated_quantifier_found = TRUE;
quantifier *quant = RETRIEVE_POINTER_quantifier(pl->predicate);
int param = Calculus__Atoms__get_quantification_parameter(pl);
if (quant != exists_quantifier)
{
#line 633 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (R_stack_reason[R_sp-1] == NOW_ASSERTION_DEFER)
{
#line 654 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (quant == not_exists_quantifier) {
R_stack_parity[R_sp-1] = (R_stack_parity[R_sp-1])?FALSE:TRUE;
quant = for_all_quantifier;
}
}
#line 634 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
Q_stack_quantifier[Q_sp] = quant;
Q_stack_parameter[Q_sp] = param;
Q_stack_block_nesting[Q_sp] = block_nesting;
Q_stack_C_stack_level[Q_sp] = C_sp;
WRITE("qcy_%d = 0;\n", Q_sp);
WRITE("qcn_%d = 0;\n", Q_sp);
Q_sp++;
}
#line 475 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
{
#line 586 "inform7/Chapter 18/Compile Deferred Propositions.w"
pl = Calculus__Propositions__Deferred__compile_loop_header(OUT, pl->terms[0].variable, pl,
(R_stack_reason[R_sp-1] == NOW_ASSERTION_DEFER)?TRUE:FALSE,
(quant != exists_quantifier)?TRUE:FALSE, pdef);
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 589 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
#line 476 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
break;
case DOMAIN_OPEN_ATOM:
{
#line 547 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 551 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 479 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
{
#line 425 "inform7/Chapter 18/Compile Deferred Propositions.w"
R_stack_reason[R_sp] = FILTER_DEFER;
R_stack_parity[R_sp] = TRUE;
R_sp++;
}
#line 480 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
break;
case DOMAIN_CLOSE_ATOM:
{
#line 547 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 551 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 483 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
{
#line 438 "inform7/Chapter 18/Compile Deferred Propositions.w"
R_sp--; if (R_sp < 0) internal_error("R stack underflow");
switch(R_stack_reason[R_sp]) {
case FILTER_DEFER:
WRITE("qcn_%d++;\n", Q_sp-1);
break;
case NOW_ASSERTION_DEFER: break;
case CONDITION_DEFER:
{
#line 826 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("rtrue;\n");
}
#line 445 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1043 "inform7/Chapter 18/Compile Deferred Propositions.w"
char *source_of_property;
if (multipurpose_routine) source_of_property = "property_to_be_totalled";
else source_of_property = Properties__get_translation(def_prn);
if (multipurpose_routine) {
WRITE("if (property_loop_sign>0) {\n");
INDENT;
WRITE("if (%c.%s >= best) {\n", pcalc_vars[0], source_of_property);
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
OUTDENT;
WRITE("} else {\n");
INDENT;
WRITE("if (%c.%s <= best) {\n", pcalc_vars[0], source_of_property);
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
OUTDENT;
WRITE("}\n");
} else {
WRITE("if (%c.%s %s best) {\n",
pcalc_vars[0], source_of_property, (def_prn_sign == 1)?">=":"<=");
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
}
}
#line 446 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1141 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("return %c;\n", pcalc_vars[0]);
}
#line 447 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 858 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 448 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 892 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter > total) { total = 3*(total/2)+8; LIST_OF_TY_SetLength(list, total); }\n");
WRITE("BlkValueWrite(list, counter+LIST_ITEM_BASE-1, %c);\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 449 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 975 "inform7/Chapter 18/Compile Deferred Propositions.w"
char *source_of_property;
if (multipurpose_routine)
source_of_property = "property_to_be_totalled";
else {
prn = RETRIEVE_POINTER_property(pdef->defn_ref);
source_of_property = Properties__get_translation(prn);
}
if (source_of_property == NULL) internal_error("No property name");
WRITE("total = total + %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 450 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 938 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter == selection) return %c;\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 451 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
}
}
#line 484 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
break;
case CALLED_ATOM:
{
#line 721 "inform7/Chapter 18/Compile Deferred Propositions.w"
C_stack_term[C_sp] = pl->terms[0];
C_stack_index[C_sp] = no_deferred_callings++;
C_sp++;
}
#line 487 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
break;
default:
if (R_stack_reason[R_sp-1] == NOW_ASSERTION_DEFER)
{
#line 569 "inform7/Chapter 18/Compile Deferred Propositions.w"
Calculus__Atoms__Compile__compile(OUT, (R_stack_parity[R_sp-1])?NOW_ATOM_TRUE_TASK:NOW_ATOM_FALSE_TASK, pl, TRUE);
WRITE("\n");
}
#line 491 "inform7/Chapter 18/Compile Deferred Propositions.w"
else
{
#line 536 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions == FALSE) {
WRITE("if ");
if (R_stack_parity[R_sp-1] == FALSE) WRITE("(~~");
WRITE("(");
run_of_conditions = TRUE;
} else WRITE(" && ");
Calculus__Atoms__Compile__compile(OUT, TEST_ATOM_TASK, pl, TRUE);
}
#line 493 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
break;
}
}
{
#line 547 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (run_of_conditions) {
if (R_stack_parity[R_sp-1] == FALSE) WRITE(")");
WRITE(")");
run_of_conditions = FALSE;
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 551 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 497 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
#line 389 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
while (Q_sp > 0)
{
#line 694 "inform7/Chapter 18/Compile Deferred Propositions.w"
Q_sp--; if (Q_sp < 0) internal_error("Q stack underflow");
WRITE("qcy_%d++;\n", Q_sp);
while (C_sp > Q_stack_C_stack_level[Q_sp])
{
#line 755 "inform7/Chapter 18/Compile Deferred Propositions.w"
C_sp--; if (C_sp < 0) internal_error("C stack underflow");
WRITE("deferred_calling_list-->%d = ", C_stack_index[C_sp]);
Calculus__Terms__compile(OUT, C_stack_term[C_sp]);
WRITE(";\n");
}
#line 698 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
while (block_nesting > Q_stack_block_nesting[Q_sp])
{
#line 770 "inform7/Chapter 18/Compile Deferred Propositions.w"
OUTDENT;
WRITE("}\n");
block_nesting--;
}
#line 701 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
WRITE("if (");
Quantifiers__compile_test(OUT, Q_stack_quantifier[Q_sp], Q_sp, Q_stack_parameter[Q_sp]);
WRITE(")");
{
#line 763 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("{\n");
INDENT;
block_nesting++;
}
#line 706 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
#line 390 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
while (C_sp > 0)
{
#line 755 "inform7/Chapter 18/Compile Deferred Propositions.w"
C_sp--; if (C_sp < 0) internal_error("C stack underflow");
WRITE("deferred_calling_list-->%d = ", C_stack_index[C_sp]);
Calculus__Terms__compile(OUT, C_stack_term[C_sp]);
WRITE(";\n");
}
#line 391 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
/* we are now at the magic match point |M| in the search code */
{
#line 438 "inform7/Chapter 18/Compile Deferred Propositions.w"
R_sp--; if (R_sp < 0) internal_error("R stack underflow");
switch(R_stack_reason[R_sp]) {
case FILTER_DEFER:
WRITE("qcn_%d++;\n", Q_sp-1);
break;
case NOW_ASSERTION_DEFER: break;
case CONDITION_DEFER:
{
#line 826 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("rtrue;\n");
}
#line 445 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1043 "inform7/Chapter 18/Compile Deferred Propositions.w"
char *source_of_property;
if (multipurpose_routine) source_of_property = "property_to_be_totalled";
else source_of_property = Properties__get_translation(def_prn);
if (multipurpose_routine) {
WRITE("if (property_loop_sign>0) {\n");
INDENT;
WRITE("if (%c.%s >= best) {\n", pcalc_vars[0], source_of_property);
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
OUTDENT;
WRITE("} else {\n");
INDENT;
WRITE("if (%c.%s <= best) {\n", pcalc_vars[0], source_of_property);
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
OUTDENT;
WRITE("}\n");
} else {
WRITE("if (%c.%s %s best) {\n",
pcalc_vars[0], source_of_property, (def_prn_sign == 1)?">=":"<=");
INDENT;
WRITE("best = %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("best_with = %c;\n", pcalc_vars[0]);
OUTDENT;
WRITE("}\n");
}
}
#line 446 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1141 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("return %c;\n", pcalc_vars[0]);
}
#line 447 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 858 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 448 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 892 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter > total) { total = 3*(total/2)+8; LIST_OF_TY_SetLength(list, total); }\n");
WRITE("BlkValueWrite(list, counter+LIST_ITEM_BASE-1, %c);\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 449 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 975 "inform7/Chapter 18/Compile Deferred Propositions.w"
char *source_of_property;
if (multipurpose_routine)
source_of_property = "property_to_be_totalled";
else {
prn = RETRIEVE_POINTER_property(pdef->defn_ref);
source_of_property = Properties__get_translation(prn);
}
if (source_of_property == NULL) internal_error("No property name");
WRITE("total = total + %c.%s;\n", pcalc_vars[0], source_of_property);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 450 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 938 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("counter++;\n");
WRITE("if (counter == selection) return %c;\n", pcalc_vars[0]);
WRITE("jump NextOuterLoop_%d;\n", reason);
}
#line 451 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
}
}
#line 393 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
while (block_nesting > 0)
{
#line 770 "inform7/Chapter 18/Compile Deferred Propositions.w"
OUTDENT;
WRITE("}\n");
block_nesting--;
}
#line 395 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
/* we have now finished compiling the search code */
if (R_sp != 0) internal_error("R-stack failure");
if (Q_sp != 0) internal_error("Q-stack failure");
if (C_sp != 0) internal_error("C-stack failure");
}
#line 275 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
switch(reason) {
case NOW_ASSERTION_DEFER: break;
case CONDITION_DEFER:
{
#line 831 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("rfalse;\n");
}
#line 278 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case EXTREMAL_DEFER:
{
#line 1079 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return best_with;\n");
}
#line 279 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LOOP_DOMAIN_DEFER:
{
#line 1146 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return nothing;\n");
}
#line 280 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case NUMBER_OF_DEFER:
{
#line 867 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return counter;\n");
}
#line 281 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case LIST_OF_DEFER:
{
#line 903 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("LIST_OF_TY_SetLength(list, counter);\n");
WRITE("return list;\n");
}
#line 282 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case TOTAL_DEFER:
{
#line 989 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("return total;\n");
}
#line 283 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
case RANDOM_OF_DEFER:
{
#line 950 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE(".NextOuterLoop_%d;\n", reason);
OUTDENT;
WRITE("}\n");
WRITE("if ((counter == 0) || (selection >= 0)) return nothing;\n");
WRITE("selection = random(counter);\n");
OUTDENT;
WRITE("}\n");
}
#line 284 "inform7/Chapter 18/Compile Deferred Propositions.w"
; break;
}
}
#line 247 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 98 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
{
#line 148 "inform7/Chapter 18/Compile Deferred Propositions.w"
if ((LocalVariables__are_we_using_table_lookup()) && (!ct_locals_problem_thrown)) {
ct_locals_problem_thrown = TRUE;
Problems__Issue__sentence_problem(_p_(PM_CantLookUpTableInDeferred),
"I am not able to look up table entries in this complicated "
"condition",
"which seems to involve making a potentially large number "
"of checks in rather few words (and may perhaps result from "
"a misunderstanding such as writing the name of a kind where "
"an individual object is intended?).");
}
}
#line 99 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
{
#line 165 "inform7/Chapter 18/Compile Deferred Propositions.w"
if (negated_quantifier_found) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"this involves a very complicated negative thought",
"which I'm not able to untangle. Perhaps you could rephrase "
"this more simply, or split it into more than one sentence?");
}
}
#line 100 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
END_COMPILATION_MODE;
OUT = Routines__end(OUT);
if (pdef->rtp_constant_needed)
{
#line 113 "inform7/Chapter 18/Compile Deferred Propositions.w"
WRITE("Constant PROP_SRC_%d = \"", pdef->allocation_id);
if (pdef->deferred_from)
Wordings__to_stream_raw_within_i6_literal(OUT, ParseTree__get_text(pdef->deferred_from));
else
WRITE("not sure where this came from");
WRITE("\";\n");
}
#line 105 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
current_pdef = save_current_pdef;
}
#line 62 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
N++;
}
return N;
}
#line 1214 "inform7/Chapter 18/Compile Deferred Propositions.w"
i6_schema loop_schema;
pcalc_prop *Calculus__Propositions__Deferred__compile_loop_header(OUTPUT_STREAM, int var, pcalc_prop *proposition,
int avoid_parent_optimisation, int grouped, pcalc_prop_deferral *pdef) {
kind *K = NULL;
pcalc_prop *kind_position = NULL;
pcalc_term var_term = Calculus__Terms__new_variable(var);
pcalc_term second_term = Calculus__Terms__new_variable(var); /* this value is never used, but just in case */
int parent_optimised = FALSE;
/* the default, if we are unable to provide either kind or parent optimisation */
Calculus__Schemas__modify(&loop_schema, "objectloop (*1 ofclass Object)");
{
#line 1254 "inform7/Chapter 18/Compile Deferred Propositions.w"
int bl = 0, enabled = FALSE;
TRAVERSE_VARIABLE(pl);
TRAVERSE_PROPOSITION(pl, proposition) {
switch (Calculus__Atoms__element_get_group(pl->element)) {
case OPEN_OPERATORS_GROUP: bl++; break;
case CLOSE_OPERATORS_GROUP: bl--; break;
}
if (grouped) {
if (pl->element == DOMAIN_OPEN_ATOM) enabled = TRUE;
if (pl->element == DOMAIN_CLOSE_ATOM) enabled = FALSE;
if (bl < 0) break;
if (enabled == FALSE) continue;
if (bl != 1) continue;
} else {
if (bl < 0) break;
if (bl > 0) continue;
}
{
#line 1279 "inform7/Chapter 18/Compile Deferred Propositions.w"
if ((pl->element == KIND_ATOM) && (pl->terms[0].variable == var)) {
K = pl->assert_kind;
kind_position = pl_prev;
}
if ((avoid_parent_optimisation == FALSE) &&
(pl->element == PREDICATE_ATOM) && (pl->arity == 2))
{
#line 1304 "inform7/Chapter 18/Compile Deferred Propositions.w"
binary_predicate *bp = RETRIEVE_POINTER_binary_predicate(pl->predicate);
if (bp == R_equality) {
int chk;
for (chk=0; chk<=1; chk++) {
pcalc_func *pf = pl->terms[chk].function;
if ((pf) && (pf->fn_of.variable == var) &&
(BinaryPredicates__write_optimised_loop_schema(&loop_schema, pf->bp))) {
second_term = pl->terms[1-chk];
parent_optimised = TRUE;
proposition = Calculus__Propositions__delete_atom(proposition, pl_prev);
break;
}
}
} else if ((pl->terms[0].variable == var) &&
(BinaryPredicates__write_optimised_loop_schema(&loop_schema, bp))) {
second_term = pl->terms[1];
parent_optimised = TRUE;
proposition = Calculus__Propositions__delete_atom(proposition, pl_prev);
}
}
#line 1286 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
#line 1271 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
}
}
#line 1226 "inform7/Chapter 18/Compile Deferred Propositions.w"
;
if ((K) && (parent_optimised == FALSE)) { /* parent optimisation is stronger, so we prefer that */
if (Kinds__Behaviour__write_loop_schema(&loop_schema, K, TRUE) == FALSE) {
Calculus__Schemas__modify(&loop_schema, "if (RunTimeProblem(RTP_CANTITERATE, PROP_SRC_%d))",
pdef->allocation_id);
pdef->rtp_constant_needed = TRUE;
}
proposition = Calculus__Propositions__delete_atom(proposition, kind_position);
}
Calculus__Schemas__expand(&loop_schema, OUT, &var_term, &second_term);
return proposition;
}
#line 283 "inform7/Chapter 19/Kinds.w"
kind *Kinds__base_construction(kind_constructor *con) {
if (con == NULL) internal_error("impossible construction");
if ((con == CON_KIND_VARIABLE) || (con == CON_INTERMEDIATE))
internal_error("forbidden construction");
switch (Kinds__Constructors__arity(con)) {
case 1:
if (con == CON_list_of) return Kinds__unary_construction(con, NULL);
return Kinds__unary_construction(con, K_value);
case 2: return Kinds__binary_construction(con, K_value, K_value);
}
kind **cache = Kinds__Constructors__cache_location(con);
if (cache) { if (*cache) return *cache; }
kind *K;
{
#line 380 "inform7/Chapter 19/Kinds.w"
K = CREATE(kind);
K->construct = NULL;
K->intermediate_result = NULL;
K->kind_variable_number = 0;
int i;
for (i=0; i<MAX_KIND_CONSTRUCTION_ARITY; i++) K->kc_args[i] = NULL;
}
#line 296 "inform7/Chapter 19/Kinds.w"
;
K->construct = con;
if (cache) *cache = K;
no_base_kinds_created++;
return K;
}
#line 313 "inform7/Chapter 19/Kinds.w"
kind *Kinds__intermediate_construction(unit_sequence *ik) {
if (ik == NULL) internal_error("made unknown as Kinds__intermediate_construction");
kind *K;
{
#line 380 "inform7/Chapter 19/Kinds.w"
K = CREATE(kind);
K->construct = NULL;
K->intermediate_result = NULL;
K->kind_variable_number = 0;
int i;
for (i=0; i<MAX_KIND_CONSTRUCTION_ARITY; i++) K->kc_args[i] = NULL;
}
#line 316 "inform7/Chapter 19/Kinds.w"
;
K->construct = CON_INTERMEDIATE;
K->intermediate_result = CREATE(unit_sequence);
*(K->intermediate_result) = *ik;
no_intermediate_kinds_created++;
return K;
}
#line 331 "inform7/Chapter 19/Kinds.w"
kind *Kinds__variable_construction(int N, kind *declaration) {
if ((N == 0) || (N > MAX_KIND_VARIABLES)) internal_error("bad kind variable");
kind *K;
{
#line 380 "inform7/Chapter 19/Kinds.w"
K = CREATE(kind);
K->construct = NULL;
K->intermediate_result = NULL;
K->kind_variable_number = 0;
int i;
for (i=0; i<MAX_KIND_CONSTRUCTION_ARITY; i++) K->kc_args[i] = NULL;
}
#line 334 "inform7/Chapter 19/Kinds.w"
;
K->construct = CON_KIND_VARIABLE;
K->kind_variable_number = N;
K->kc_args[0] = declaration;
return K;
}
#line 352 "inform7/Chapter 19/Kinds.w"
kind *Kinds__unary_construction(kind_constructor *con, kind *X) {
kind *K;
if (Kinds__Constructors__arity(con) != 1) internal_error("bad unary construction");
{
#line 380 "inform7/Chapter 19/Kinds.w"
K = CREATE(kind);
K->construct = NULL;
K->intermediate_result = NULL;
K->kind_variable_number = 0;
int i;
for (i=0; i<MAX_KIND_CONSTRUCTION_ARITY; i++) K->kc_args[i] = NULL;
}
#line 355 "inform7/Chapter 19/Kinds.w"
;
K->construct = con; K->kc_args[0] = X;
no_constructed_kinds_created++;
return K;
}
kind *Kinds__binary_construction(kind_constructor *con, kind *X, kind *Y) {
kind *K;
if (Kinds__Constructors__arity(con) != 2) internal_error("bad binary construction");
{
#line 380 "inform7/Chapter 19/Kinds.w"
K = CREATE(kind);
K->construct = NULL;
K->intermediate_result = NULL;
K->kind_variable_number = 0;
int i;
for (i=0; i<MAX_KIND_CONSTRUCTION_ARITY; i++) K->kc_args[i] = NULL;
}
#line 364 "inform7/Chapter 19/Kinds.w"
;
K->construct = con; K->kc_args[0] = X; K->kc_args[1] = Y;
no_constructed_kinds_created++;
if (con == CON_phrase) {
if ((X == NULL) || (Y == NULL)) internal_error("bad function kind");
if ((X->construct == CON_TUPLE_ENTRY) && (X->kc_args[0] == K_nil))
internal_error("nil nil");
if (Y->construct == CON_TUPLE_ENTRY) internal_error("bizarre");
}
return K;
}
#line 409 "inform7/Chapter 19/Kinds.w"
kind *Kinds__function_kind(int no_args, kind **args, kind *return_K) {
kind *arguments_K = K_nil;
int i;
for (i=no_args-1; i>=0; i--)
arguments_K = Kinds__binary_construction(CON_TUPLE_ENTRY, args[i], arguments_K);
if (return_K == NULL) return_K = K_nil;
return Kinds__binary_construction(CON_phrase, arguments_K, return_K);
}
#line 422 "inform7/Chapter 19/Kinds.w"
kind *Kinds__pair_kind(kind *X, kind *Y) {
return Kinds__binary_construction(CON_combination, X, Y);
}
#line 443 "inform7/Chapter 19/Kinds.w"
kind *Kinds__first_base_k(void) {
kind_constructor *con;
LOOP_OVER(con, kind_constructor)
if ((con != CON_KIND_VARIABLE) && (con != CON_INTERMEDIATE))
return Kinds__base_construction(con);
return NULL;
}
kind *Kinds__next_base_k(kind *K) {
if (K == NULL) return NULL;
kind_constructor *con = K->construct;
do {
con = NEXT_OBJECT(con, kind_constructor);
} while ((con == CON_KIND_VARIABLE) || (con == CON_INTERMEDIATE));
if (con == NULL) return NULL;
return Kinds__base_construction(con);
}
#line 465 "inform7/Chapter 19/Kinds.w"
kind_constructor *Kinds__get_construct(kind *K) {
if (K) return K->construct;
return NULL;
}
#line 473 "inform7/Chapter 19/Kinds.w"
int Kinds__is_intermediate(kind *K) {
if ((K) && (K->construct == CON_INTERMEDIATE)) return TRUE;
return FALSE;
}
int Kinds__get_variable_number(kind *K) {
if ((K) && (K->construct == CON_KIND_VARIABLE)) return K->kind_variable_number;
return -1;
}
kind *Kinds__get_variable_stipulation(kind *K) {
if ((K) && (K->construct == CON_KIND_VARIABLE)) return K->kc_args[0];
return NULL;
}
#line 491 "inform7/Chapter 19/Kinds.w"
int Kinds__is_proper_constructor(kind *K) {
if (Kinds__arity_of_constructor(K) > 0) return TRUE;
return FALSE;
}
int Kinds__arity_of_constructor(kind *K) {
if (K) return Kinds__Constructors__arity(K->construct);
return 0;
}
#line 504 "inform7/Chapter 19/Kinds.w"
kind *Kinds__unary_construction_material(kind *K) {
if (Kinds__arity_of_constructor(K) != 1) return NULL;
return K->kc_args[0];
}
#line 512 "inform7/Chapter 19/Kinds.w"
void Kinds__binary_construction_material(kind *K, kind **X, kind **Y) {
if (Kinds__arity_of_constructor(K) != 2) {
if (X) *X = NULL;
if (Y) *Y = NULL;
} else {
if (X) *X = K->kc_args[0];
if (Y) *Y = K->kc_args[1];
}
}
#line 526 "inform7/Chapter 19/Kinds.w"
int Kinds__contains(kind *K, kind_constructor *con) {
if (K == NULL) return FALSE;
if (K->construct == con) return TRUE;
int i;
for (i=0; i<MAX_KIND_CONSTRUCTION_ARITY; i++)
if (Kinds__contains(K->kc_args[i], con))
return TRUE;
return FALSE;
}
#line 549 "inform7/Chapter 19/Kinds.w"
kind *Kinds__substitute(kind *K, kind **meanings, int *changed) {
if (meanings == NULL) meanings = values_of_kind_variables;
int N = Kinds__get_variable_number(K);
if (N > 0) {
*changed = TRUE;
return meanings[N];
}
if (Kinds__is_proper_constructor(K)) {
kind *X = NULL, *X_after = NULL, *Y = NULL, *Y_after = NULL;
int tx = FALSE, ty = FALSE;
int a = Kinds__arity_of_constructor(K);
if (a == 1) {
X = Kinds__unary_construction_material(K);
X_after = Kinds__substitute(X, meanings, &tx);
if (tx) {
*changed = TRUE;
return Kinds__unary_construction(K->construct, X_after);
}
} else {
Kinds__binary_construction_material(K, &X, &Y);
X_after = Kinds__substitute(X, meanings, &tx);
Y_after = Kinds__substitute(Y, meanings, &ty);
if ((tx) || (ty)) {
*changed = TRUE;
return Kinds__binary_construction(K->construct, X_after, Y_after);
}
}
}
return K;
}
#line 585 "inform7/Chapter 19/Kinds.w"
kind *Kinds__weaken(kind *K) {
if (Kinds__is_proper_constructor(K)) {
kind *X = NULL, *Y = NULL;
int a = Kinds__arity_of_constructor(K);
if (a == 1) {
X = Kinds__unary_construction_material(K);
return Kinds__unary_construction(K->construct, Kinds__weaken(X));
} else {
Kinds__binary_construction_material(K, &X, &Y);
return Kinds__binary_construction(K->construct, Kinds__weaken(X), Kinds__weaken(Y));
}
} else {
if ((K) && (Kinds__Compare__lt(K, K_object))) return K_object;
}
return K;
}
#line 607 "inform7/Chapter 19/Kinds.w"
kind *Kinds__dereference_properties(kind *K) {
if ((K) && (K->construct == CON_property))
return Kinds__unary_construction_material(K);
if (Kinds__is_proper_constructor(K)) {
kind *X = NULL, *Y = NULL;
int a = Kinds__arity_of_constructor(K);
if (a == 1) {
X = Kinds__unary_construction_material(K);
return Kinds__unary_construction(K->construct,
Kinds__dereference_properties(X));
} else {
Kinds__binary_construction_material(K, &X, &Y);
return Kinds__binary_construction(K->construct,
Kinds__dereference_properties(X), Kinds__dereference_properties(Y));
}
}
return K;
}
#line 631 "inform7/Chapter 19/Kinds.w"
int notable_linguistic_kinds_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 637 "inform7/Chapter 19/Kinds.w"
#line 649 "inform7/Chapter 19/Kinds.w"
int no_kinds_of_object = 1;
kind *Kinds__new_base(wording W, kind *super) {
PROTECTED_MODEL_PROCEDURE;
kind *K = Kinds__base_construction(
Kinds__Constructors__new(Kinds__get_construct(super), "", "#NEW"));
{
#line 689 "inform7/Chapter 19/Kinds.w"
inference_subject *revised = NULL;
if (Wordings__nonempty(W)) Plugins__Call__name_to_early_infs(W, &revised);
if (revised) {
InferenceSubjects__renew(revised,
Kinds__Behaviour__as_subject(super), KIND_SUB, STORE_POINTER_kind_constructor(K->construct), LIKELY_CE);
Kinds__Behaviour__set_subject(K, revised);
}
}
#line 655 "inform7/Chapter 19/Kinds.w"
;
if (Kinds__Compare__le(super, K_object))
InferenceSubjects__falls_within(Kinds__Behaviour__as_subject(K), Kinds__Behaviour__as_subject(super));
{
#line 700 "inform7/Chapter 19/Kinds.w"
unsigned int mc = KIND_SLOW_MC;
if (Kinds__Compare__le(super, K_object)) mc = NAMETAG_MC;
nametag *nt = Nametags__new(W, STORE_POINTER_kind_constructor(K->construct), KIND_PRIORITY,
PARSE_EXACTLY_NTOPT + REGISTER_SINGULAR_NTOPT + REGISTER_PLURAL_NTOPT
+ ATTACH_TO_SEARCH_LIST_NTOPT, mc, NULL, NEUTER_GENDER);
if (Kinds__Compare__le(super, K_object))
Nametags__set_range_number(nt, no_kinds_of_object++);
Kinds__Constructors__attach_nametag(K->construct, nt);
}
#line 660 "inform7/Chapter 19/Kinds.w"
;
if (Preform__parse_nt_against_word_range(notable_linguistic_kinds_NTM, W, NULL, NULL)) {
Kinds__Constructors__mark_as_linguistic(K->construct);
switch (most_recent_result) {
case 0: K_natural_language = K; NaturalLanguages__stock_nl_kind(K); break;
case 1: K_grammatical_gender = K; break;
}
}
if (Preform__parse_nt_against_word_range(property_name_NTM, W, NULL, NULL)) {
property *P = most_recent_result_p;
Properties__Valued__set_kind(P, K);
Instances__make_kind_coincident(K, P);
if (Kinds__Compare__eq(K, K_grammatical_gender)) P_grammatical_gender = P;
}
Plugins__Call__new_base_kind_notify(K, Kinds__Behaviour__get_name_in_template_code(K), W);
latest_base_kind_of_value = K;
LOGIF(KIND_CREATIONS, "Created base kind $u\n", K);
return K;
}
#line 724 "inform7/Chapter 19/Kinds.w"
kind_constructor **Kinds__known_constructor_name(char *sn) {
IDENTIFIERS_CORRESPOND("ACTIVITY_TY", &CON_activity);
IDENTIFIERS_CORRESPOND("COMBINATION_TY", &CON_combination);
IDENTIFIERS_CORRESPOND("DESCRIPTION_OF_TY", &CON_description);
IDENTIFIERS_CORRESPOND("INTERMEDIATE_TY", &CON_INTERMEDIATE);
IDENTIFIERS_CORRESPOND("KIND_VARIABLE_TY", &CON_KIND_VARIABLE);
IDENTIFIERS_CORRESPOND("LIST_OF_TY", &CON_list_of);
IDENTIFIERS_CORRESPOND("PHRASE_TY", &CON_phrase);
IDENTIFIERS_CORRESPOND("NIL_TY", &CON_NIL);
IDENTIFIERS_CORRESPOND("PROPERTY_TY", &CON_property);
IDENTIFIERS_CORRESPOND("RELATION_TY", &CON_relation);
IDENTIFIERS_CORRESPOND("RULE_TY", &CON_rule);
IDENTIFIERS_CORRESPOND("RULEBOOK_TY", &CON_rulebook);
IDENTIFIERS_CORRESPOND("TABLE_COLUMN_TY", &CON_table_column);
IDENTIFIERS_CORRESPOND("TUPLE_ENTRY_TY", &CON_TUPLE_ENTRY);
IDENTIFIERS_CORRESPOND("VARIABLE_TY", &CON_variable);
return NULL;
}
kind **Kinds__known_kind_name(char *sn) {
IDENTIFIERS_CORRESPOND("ARITHMETIC_VALUE_TY", &K_arithmetic_value);
IDENTIFIERS_CORRESPOND("ENUMERATED_VALUE_TY", &K_enumerated_value);
IDENTIFIERS_CORRESPOND("EQUATION_TY", &K_equation);
IDENTIFIERS_CORRESPOND("TEXT_TY", &K_text);
IDENTIFIERS_CORRESPOND("NUMBER_TY", &K_number);
IDENTIFIERS_CORRESPOND("OBJECT_TY", &K_object);
IDENTIFIERS_CORRESPOND("POINTER_VALUE_TY", &K_pointer_value);
IDENTIFIERS_CORRESPOND("REAL_ARITHMETIC_VALUE_TY", &K_real_arithmetic_value);
IDENTIFIERS_CORRESPOND("REAL_NUMBER_TY", &K_real_number);
IDENTIFIERS_CORRESPOND("RESPONSE_TY", &K_response);
IDENTIFIERS_CORRESPOND("RULEBOOK_OUTCOME_TY", &K_rulebook_outcome);
IDENTIFIERS_CORRESPOND("SAYABLE_VALUE_TY", &K_sayable_value);
IDENTIFIERS_CORRESPOND("SNIPPET_TY", &K_snippet);
IDENTIFIERS_CORRESPOND("TABLE_TY", &K_table);
IDENTIFIERS_CORRESPOND("TRUTH_STATE_TY", &K_truth_state);
IDENTIFIERS_CORRESPOND("UNDERSTANDING_TY", &K_understanding);
IDENTIFIERS_CORRESPOND("UNICODE_CHARACTER_TY", &K_unicode_character);
IDENTIFIERS_CORRESPOND("USE_OPTION_TY", &K_use_option);
IDENTIFIERS_CORRESPOND("VALUE_TY", &K_value);
IDENTIFIERS_CORRESPOND("VERB_TY", &K_verb);
IDENTIFIERS_CORRESPOND("WORD_VALUE_TY", &K_word_value);
IDENTIFIERS_CORRESPOND("NIL_TY", &K_nil);
return NULL;
}
int Kinds__known_name(char *sn) {
if (Kinds__known_constructor_name(sn)) return TRUE;
if (Kinds__known_kind_name(sn)) return TRUE;
return FALSE;
}
#line 112 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__le(kind *from, kind *to) {
if (Kinds__Compare__test_kind_relation(from, to, FALSE) == ALWAYS_MATCH) return TRUE;
return FALSE;
}
int Kinds__Compare__lt(kind *from, kind *to) {
if (Kinds__Compare__eq(from, to)) return FALSE;
return Kinds__Compare__le(from, to);
}
#line 141 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__eq(kind *K1, kind *K2) {
int i;
if (K1 == NULL) { if (K2 == NULL) return TRUE; return FALSE; }
if (K2 == NULL) return FALSE;
if (K1->construct != K2->construct) return FALSE;
if ((K1->intermediate_result) && (K2->intermediate_result == NULL)) return FALSE;
if ((K1->intermediate_result == NULL) && (K2->intermediate_result)) return FALSE;
if ((K1->intermediate_result) &&
(Kinds__Dimensions__compare_unit_sequences(
K1->intermediate_result, K2->intermediate_result) == FALSE)) return FALSE;
if (Kinds__get_variable_number(K1) != Kinds__get_variable_number(K2))
return FALSE;
for (i=0; i<MAX_KIND_CONSTRUCTION_ARITY; i++)
if (Kinds__Compare__eq(K1->kc_args[i], K2->kc_args[i]) == FALSE)
return FALSE;
return TRUE;
}
#line 164 "inform7/Chapter 19/Kind Checking.w"
kind *Kinds__Compare__super(kind *K) {
if (Kinds__Compare__le(K, K_object)) {
inference_subject *infs = Kinds__Behaviour__as_subject(K);
return InferenceSubjects__as_kind(InferenceSubjects__narrowest_broader_subject(infs));
}
return NULL;
}
#line 178 "inform7/Chapter 19/Kind Checking.w"
kind *Kinds__Compare__max(kind *K1, kind *K2) {
if ((Kinds__FloatingPoint__uses_floating_point(K1) == FALSE) &&
(Kinds__FloatingPoint__uses_floating_point(K2)) &&
(Kinds__Compare__eq(Kinds__FloatingPoint__real_equivalent(K1), K2)))
return K2;
if ((Kinds__FloatingPoint__uses_floating_point(K2) == FALSE) &&
(Kinds__FloatingPoint__uses_floating_point(K1)) &&
(Kinds__Compare__eq(Kinds__FloatingPoint__real_equivalent(K2), K1)))
return K1;
return Kinds__Compare__traverse_kind_poset(K1, K2, 1);
}
kind *Kinds__Compare__traverse_kind_poset(kind *K1, kind *K2, int direction) {
if (K1 == NULL) return K2;
if (K2 == NULL) return K1;
kind_constructor *con = K1->construct;
int a1 = Kinds__Constructors__arity(con), a2 = Kinds__Constructors__arity(K2->construct);
if ((a1 > 0) || (a2 > 0)) {
if (K2->construct != con) return K_value;
int i;
kind *ka[MAX_KIND_CONSTRUCTION_ARITY];
for (i=0; i<a1; i++)
if (con->variance[i] == COVARIANT)
ka[i] = Kinds__Compare__traverse_kind_poset(K1->kc_args[i], K2->kc_args[i], direction);
else
ka[i] = Kinds__Compare__traverse_kind_poset(K1->kc_args[i], K2->kc_args[i], -direction);
if (a1 == 1) return Kinds__unary_construction(con, ka[0]);
else return Kinds__binary_construction(con, ka[0], ka[1]);
} else {
if (Kinds__Compare__le(K1, K2)) return (direction > 0)?K2:K1;
if (Kinds__Compare__le(K2, K1)) return (direction > 0)?K1:K2;
if (direction > 0) {
if ((Kinds__Compare__le(K1, K_object)) && (Kinds__Compare__le(K2, K_object))) {
kind *K;
for (K = K1; K; K = Kinds__Compare__super(K))
if (Kinds__Compare__le(K2, K))
return K;
}
}
}
return K_value;
}
#line 227 "inform7/Chapter 19/Kind Checking.w"
kind *Kinds__Compare__accumulative_max(kind *K1, kind *K2) {
if ((Kinds__Behaviour__definite(K1) == TRUE) && (Kinds__Behaviour__definite(K2) == FALSE) &&
(Kinds__Compare__compatible(K2, K1) == ALWAYS_MATCH)) return K1;
else if ((Kinds__Behaviour__definite(K2) == TRUE) && (Kinds__Behaviour__definite(K1) == FALSE) &&
(Kinds__Compare__compatible(K1, K2) == ALWAYS_MATCH)) return K2;
return Kinds__Compare__max(K1, K2);
}
#line 255 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__compatible(kind *from, kind *to) {
if (Kinds__Compare__eq(from, to)) return ALWAYS_MATCH;
LOGIF(KIND_CHECKING, "(Is the kind $u compatible with $u?", from, to);
switch(Kinds__Compare__test_kind_relation(from, to, TRUE)) {
case NEVER_MATCH: LOGIF(KIND_CHECKING, " No)\n"); return NEVER_MATCH;
case ALWAYS_MATCH: LOGIF(KIND_CHECKING, " Yes)\n"); return ALWAYS_MATCH;
case SOMETIMES_MATCH: LOGIF(KIND_CHECKING, " Sometimes)\n"); return SOMETIMES_MATCH;
}
internal_error("bad return value from Kinds__Compare__compatible"); return NEVER_MATCH;
}
#line 274 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__test_kind_relation(kind *from, kind *to, int comp) {
if (Kinds__get_variable_number(to) > 0) {
kind *var_k = to, *other_k = from;
{
#line 371 "inform7/Chapter 19/Kind Checking.w"
switch(kind_checker_mode) {
case MATCH_KIND_VARIABLES_AS_SYMBOLS:
if (Kinds__get_variable_number(other_k) ==
Kinds__get_variable_number(var_k)) return ALWAYS_MATCH;
return NEVER_MATCH;
case MATCH_KIND_VARIABLES_AS_UNIVERSAL: return ALWAYS_MATCH;
default: {
int vn = Kinds__get_variable_number(var_k);
if (Kinds__get_variable_stipulation(var_k))
{
#line 406 "inform7/Chapter 19/Kind Checking.w"
switch(kind_checker_mode) {
case MATCH_KIND_VARIABLES_INFERRING_VALUES:
if (Kinds__Compare__test_kind_relation(other_k,
Kinds__get_variable_stipulation(var_k), comp) != ALWAYS_MATCH)
return NEVER_MATCH;
LOGIF(KIND_CHECKING, "Inferring kind variable %d from $u (declaration $u)\n",
vn, other_k, Kinds__get_variable_stipulation(var_k));
values_of_kind_variables[vn] = other_k;
kind_variable_declaration *kvd = CREATE(kind_variable_declaration);
kvd->kv_number = vn;
kvd->kv_value = other_k;
kvd->next = NULL;
return ALWAYS_MATCH;
case MATCH_KIND_VARIABLES_AS_VALUES: return ALWAYS_MATCH;
}
}
#line 380 "inform7/Chapter 19/Kind Checking.w"
else
{
#line 427 "inform7/Chapter 19/Kind Checking.w"
switch(kind_checker_mode) {
case MATCH_KIND_VARIABLES_INFERRING_VALUES: return ALWAYS_MATCH;
case MATCH_KIND_VARIABLES_AS_VALUES:
LOGIF(KIND_CHECKING, "Checking $u against kind variable %d (=$u)\n",
other_k, vn, values_of_kind_variables[vn]);
if (Kinds__Compare__test_kind_relation(other_k, values_of_kind_variables[vn], comp) == NEVER_MATCH)
return NEVER_MATCH;
else
return ALWAYS_MATCH;
}
}
#line 382 "inform7/Chapter 19/Kind Checking.w"
;
}
}
}
#line 277 "inform7/Chapter 19/Kind Checking.w"
;
}
if (Kinds__get_variable_number(from) > 0) {
kind *var_k = from, *other_k = to;
{
#line 371 "inform7/Chapter 19/Kind Checking.w"
switch(kind_checker_mode) {
case MATCH_KIND_VARIABLES_AS_SYMBOLS:
if (Kinds__get_variable_number(other_k) ==
Kinds__get_variable_number(var_k)) return ALWAYS_MATCH;
return NEVER_MATCH;
case MATCH_KIND_VARIABLES_AS_UNIVERSAL: return ALWAYS_MATCH;
default: {
int vn = Kinds__get_variable_number(var_k);
if (Kinds__get_variable_stipulation(var_k))
{
#line 406 "inform7/Chapter 19/Kind Checking.w"
switch(kind_checker_mode) {
case MATCH_KIND_VARIABLES_INFERRING_VALUES:
if (Kinds__Compare__test_kind_relation(other_k,
Kinds__get_variable_stipulation(var_k), comp) != ALWAYS_MATCH)
return NEVER_MATCH;
LOGIF(KIND_CHECKING, "Inferring kind variable %d from $u (declaration $u)\n",
vn, other_k, Kinds__get_variable_stipulation(var_k));
values_of_kind_variables[vn] = other_k;
kind_variable_declaration *kvd = CREATE(kind_variable_declaration);
kvd->kv_number = vn;
kvd->kv_value = other_k;
kvd->next = NULL;
return ALWAYS_MATCH;
case MATCH_KIND_VARIABLES_AS_VALUES: return ALWAYS_MATCH;
}
}
#line 380 "inform7/Chapter 19/Kind Checking.w"
else
{
#line 427 "inform7/Chapter 19/Kind Checking.w"
switch(kind_checker_mode) {
case MATCH_KIND_VARIABLES_INFERRING_VALUES: return ALWAYS_MATCH;
case MATCH_KIND_VARIABLES_AS_VALUES:
LOGIF(KIND_CHECKING, "Checking $u against kind variable %d (=$u)\n",
other_k, vn, values_of_kind_variables[vn]);
if (Kinds__Compare__test_kind_relation(other_k, values_of_kind_variables[vn], comp) == NEVER_MATCH)
return NEVER_MATCH;
else
return ALWAYS_MATCH;
}
}
#line 382 "inform7/Chapter 19/Kind Checking.w"
;
}
}
}
#line 281 "inform7/Chapter 19/Kind Checking.w"
;
}
{
#line 293 "inform7/Chapter 19/Kind Checking.w"
if ((Kinds__get_construct(from) == CON_list_of) &&
(Kinds__Compare__eq(to, K_sayable_value)))
return Kinds__Compare__test_kind_relation(
Kinds__unary_construction_material(from), K_sayable_value, comp);
}
#line 283 "inform7/Chapter 19/Kind Checking.w"
;
{
#line 310 "inform7/Chapter 19/Kind Checking.w"
if (Kinds__Compare__eq(to, K_value)) return ALWAYS_MATCH;
if ((comp) && (Kinds__Compare__eq(from, K_value))) return ALWAYS_MATCH;
}
#line 284 "inform7/Chapter 19/Kind Checking.w"
;
{
#line 317 "inform7/Chapter 19/Kind Checking.w"
if ((to == NULL) && (from == NULL)) return ALWAYS_MATCH;
if ((to == NULL) || (from == NULL)) return NEVER_MATCH;
}
#line 285 "inform7/Chapter 19/Kind Checking.w"
;
{
#line 323 "inform7/Chapter 19/Kind Checking.w"
inference_subject *from_subj = Kinds__Behaviour__as_subject(from);
inference_subject *to_subj = Kinds__Behaviour__as_subject(to);
if ((InferenceSubjects__is_within(from_subj, Kinds__Behaviour__as_subject(K_object))) &&
(InferenceSubjects__is_within(to_subj, Kinds__Behaviour__as_subject(K_object)))) {
if (from_subj == to_subj) return ALWAYS_MATCH;
if (to_subj == NULL) return ALWAYS_MATCH;
if (from_subj == NULL) return SOMETIMES_MATCH;
if (InferenceSubjects__is_strictly_within(from_subj, to_subj)) return ALWAYS_MATCH;
if (InferenceSubjects__is_strictly_within(to_subj, from_subj)) return SOMETIMES_MATCH;
return NEVER_MATCH;
}
}
#line 286 "inform7/Chapter 19/Kind Checking.w"
;
{
#line 339 "inform7/Chapter 19/Kind Checking.w"
if (Kinds__Constructors__compatible(from->construct, to->construct, comp) == FALSE)
return NEVER_MATCH;
int f_a = Kinds__Constructors__arity(from->construct);
int t_a = Kinds__Constructors__arity(to->construct);
int arity = (f_a < t_a)?f_a:t_a;
int i, o = ALWAYS_MATCH, this_o = NEVER_MATCH;
for (i=0; i<arity; i++) {
if (Kinds__Constructors__variance(from->construct, i) == COVARIANT)
this_o = Kinds__Compare__test_kind_relation(from->kc_args[i], to->kc_args[i], comp);
else
this_o = Kinds__Compare__test_kind_relation(to->kc_args[i], from->kc_args[i], comp);
switch (this_o) {
case NEVER_MATCH: o = this_o; break;
case SOMETIMES_MATCH: if (o != NEVER_MATCH) o = this_o; break;
}
}
if ((o == SOMETIMES_MATCH) && (to->construct != CON_list_of)) return NEVER_MATCH;
return o;
}
#line 287 "inform7/Chapter 19/Kind Checking.w"
;
}
#line 447 "inform7/Chapter 19/Kind Checking.w"
int Kinds__Compare__compatible_with_description(parse_node *from_spec, parse_node *to_spec) {
LOGIF(KIND_CHECKING, "[Can we match from: $P to: $P?]\n", from_spec, to_spec);
kind *from = Specifications__to_kind(from_spec);
kind *to = Specifications__to_kind(to_spec);
int result = NEVER_MATCH;
if ((from) && (to)) result = Kinds__Compare__compatible(from, to);
else if (to) result = SOMETIMES_MATCH;
if ((Descriptions__is_qualified(to_spec)) || (Descriptions__to_instance(to_spec)))
result = Dash__worst_case(result, SOMETIMES_MATCH);
switch(result) {
case ALWAYS_MATCH: LOGIF(KIND_CHECKING, "[Always]\n"); break;
case SOMETIMES_MATCH: LOGIF(KIND_CHECKING, "[Sometimes]\n"); break;
case NEVER_MATCH: LOGIF(KIND_CHECKING, "[Never]\n"); break;
}
return result;
}
#line 471 "inform7/Chapter 19/Kind Checking.w"
void Kinds__Compare__show_variables(void) {
LOG("Variables: ");
int i;
for (i=1; i<=26; i++) {
kind *K = values_of_kind_variables[i];
if (K == NULL) continue;
LOG("%c=$u ", 'A'+i-1, K);
}
LOG("\n");
}
void Kinds__Compare__show_frame_variables(void) {
int shown = 0;
for (int i=1; i<=26; i++) {
kind *K = Frames__get_kind_variable(i);
if (K) {
if (shown++ == 0) LOGIF(MATCHING, "Stack frame uses kind variables: ");
LOGIF(MATCHING, "%c=$u ", 'A'+i-1, K);
}
}
if (shown == 0) LOGIF(MATCHING, "Stack frame sets no kind variables");
LOGIF(MATCHING, "\n");
}
#line 498 "inform7/Chapter 19/Kind Checking.w"
void Kinds__Compare__make_subkind(kind *sub, kind *super) {
PROTECTED_MODEL_PROCEDURE;
if (sub == NULL) {
LOG("Tried to set kind to $u\n", super);
internal_error("Tried to set the kind of a null kind");
}
if (Kinds__Compare__lt(sub, K_object) == FALSE) return;
if (Plugins__Call__set_subkind_notify(sub, super)) return;
kind *existing = Kinds__Compare__super(sub);
switch (Kinds__Compare__compatible(existing, super)) {
case NEVER_MATCH:
LOG("Tried to make $u a kind of $u\n", sub, super);
if (problem_count == 0) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, Kinds__Behaviour__get_superkind_set_at(sub));
Problems__quote_kind(3, super);
Problems__quote_kind(4, existing);
Problems__Issue__handmade_problem(_p_(PM_KindUnalterable));
Problems__issue_problem_segment(
"You wrote %1, but that seems to contradict %2, as %3 and %4 "
"are incompatible. (If %3 were a kind of %4 or vice versa "
"there'd be no problem, but they aren't.)");
Problems__issue_problem_end();
}
return;
case SOMETIMES_MATCH:
if (InferenceSubjects__is_within(Kinds__Behaviour__as_subject(super), Kinds__Behaviour__as_subject(sub))) {
if (problem_count == 0) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, Kinds__Behaviour__get_superkind_set_at(super));
Problems__quote_kind(3, super);
Problems__quote_kind(4, existing);
Problems__Issue__handmade_problem(_p_(PM_KindsCircular));
Problems__issue_problem_segment(
"You wrote %1, but that seems to contradict %2, as it would "
"make a circularity with %3 and %4 each being kinds of the "
"other.");
Problems__issue_problem_end();
}
return;
}
InferenceSubjects__falls_within(Kinds__Behaviour__as_subject(sub), Kinds__Behaviour__as_subject(super));
Kinds__Behaviour__set_superkind_set_at(sub, current_sentence);
LOGIF(KIND_CHANGES, "Making $u a subkind of $u\n", sub, super);
}
}
#line 549 "inform7/Chapter 19/Kind Checking.w"
void Kinds__Compare__log_poset(int n) {
switch (n) {
case 1:
{
#line 563 "inform7/Chapter 19/Kind Checking.w"
LOG("The subkind relation on (base) kinds:\n");
kind *A, *B;
LOOP_OVER_BASE_KINDS(A) {
int c = 0;
LOOP_OVER_BASE_KINDS(B) {
if ((Kinds__Compare__le(A, B)) && (Kinds__Compare__eq(A, B) == FALSE)) {
if (c++ == 0) LOG("$u <= ", A); else LOG(", ");
LOG("$u", B);
}
}
if (c > 0) LOG("\n");
}
}
#line 551 "inform7/Chapter 19/Kind Checking.w"
; break;
case 2:
{
#line 579 "inform7/Chapter 19/Kind Checking.w"
LOG("The (always) compatibility relation on (base) kinds, where it differs from <=:\n");
kind *A, *B;
LOOP_OVER_BASE_KINDS(A) {
int c = 0;
LOOP_OVER_BASE_KINDS(B) {
if ((Kinds__Compare__compatible(A, B) == ALWAYS_MATCH) &&
(Kinds__Compare__le(A, B) == FALSE) &&
(Kinds__Compare__eq(A, K_value) == FALSE)) {
if (c++ == 0) LOG("$u --> ", A); else LOG(", ");
LOG("$u", B);
}
}
if (c > 0) LOG("\n");
}
}
#line 552 "inform7/Chapter 19/Kind Checking.w"
; break;
case 3:
{
#line 597 "inform7/Chapter 19/Kind Checking.w"
LOG("The superkind function applied to base kinds:\n");
kind *A, *B;
LOOP_OVER_BASE_KINDS(A) {
for (B = A; B; B = Kinds__Compare__super(B))
LOG("$u -> ", B);
LOG("\n");
}
}
#line 553 "inform7/Chapter 19/Kind Checking.w"
; break;
case 4:
{
#line 608 "inform7/Chapter 19/Kind Checking.w"
LOG("Looking for partially ordered set violations.\n");
kind *A, *B, *C;
LOOP_OVER_BASE_KINDS(A)
if (Kinds__Compare__le(A, A) == FALSE)
LOG("Reflexivity violated: $u\n", A);
LOOP_OVER_BASE_KINDS(A)
LOOP_OVER_BASE_KINDS(B)
if ((Kinds__Compare__le(A, B)) && (Kinds__Compare__le(B, A)) && (Kinds__Compare__eq(A, B) == FALSE))
LOG("Antisymmetry violated: $u, $u\n", A, B);
LOOP_OVER_BASE_KINDS(A)
LOOP_OVER_BASE_KINDS(B)
LOOP_OVER_BASE_KINDS(C)
if ((Kinds__Compare__le(A, B)) && (Kinds__Compare__le(B, C)) && (Kinds__Compare__le(A, C) == FALSE))
LOG("Transitivity violated: $u, $u, $u\n", A, B, C);
}
#line 554 "inform7/Chapter 19/Kind Checking.w"
; break;
case 5:
{
#line 626 "inform7/Chapter 19/Kind Checking.w"
LOG("Looking for maximum violations.\n");
kind *A, *B;
LOOP_OVER_BASE_KINDS(A)
LOOP_OVER_BASE_KINDS(B)
if (Kinds__Compare__eq(Kinds__Compare__max(A, B), Kinds__Compare__max(B, A)) == FALSE)
LOG("Fail symmetry: max($u, $u) = $u, but max($u, $u) = $u\n",
A, B, Kinds__Compare__max(A, B), B, A, Kinds__Compare__max(B, A));
LOOP_OVER_BASE_KINDS(A)
LOOP_OVER_BASE_KINDS(B)
if (Kinds__Compare__le(A, Kinds__Compare__max(A, B)) == FALSE)
LOG("Fail maximality(A): max($u, $u) = $u\n", A, B, Kinds__Compare__max(A, B));
LOOP_OVER_BASE_KINDS(A)
LOOP_OVER_BASE_KINDS(B)
if (Kinds__Compare__le(B, Kinds__Compare__max(A, B)) == FALSE)
LOG("Fail maximality(B): max($u, $u) = $u\n", A, B, Kinds__Compare__max(A, B));
LOOP_OVER_BASE_KINDS(A)
if (Kinds__Compare__eq(Kinds__Compare__max(A, A), A) == FALSE)
LOG("Fail: max($u, $u) = $u\n",
A, A, Kinds__Compare__max(A, A));
}
#line 555 "inform7/Chapter 19/Kind Checking.w"
; break;
case 6:
{
#line 651 "inform7/Chapter 19/Kind Checking.w"
kind *tests[SIZE_OF_GRAB_BAG];
tests[0] = K_number;
tests[1] = K_container;
tests[2] = K_door;
tests[3] = K_thing;
tests[4] = Kinds__unary_construction(CON_list_of, K_container);
tests[5] = Kinds__unary_construction(CON_list_of, K_door);
tests[6] = Kinds__unary_construction(CON_list_of, K_person);
tests[7] = Kinds__unary_construction(CON_list_of, K_thing);
tests[8] = Kinds__binary_construction(CON_phrase,
Kinds__binary_construction(CON_TUPLE_ENTRY, K_door, K_nil), K_object);
tests[9] = Kinds__binary_construction(CON_phrase,
Kinds__binary_construction(CON_TUPLE_ENTRY, K_object, K_nil), K_door);
tests[10] = Kinds__binary_construction(CON_phrase,
Kinds__binary_construction(CON_TUPLE_ENTRY, K_object, K_nil), K_object);
int i, j;
for (i=0; i<SIZE_OF_GRAB_BAG; i++) for (j=i+1; j<SIZE_OF_GRAB_BAG; j++) {
if (Kinds__Compare__le(tests[i], tests[j])) LOG("$u <= $u\n", tests[i], tests[j]);
if (Kinds__Compare__le(tests[j], tests[i])) LOG("$u <= $u\n", tests[j], tests[i]);
kind *M = Kinds__Compare__max(tests[i], tests[j]);
if (Kinds__Compare__eq(M, K_value) == FALSE) LOG("max($u, $u) = $u\n", tests[i], tests[j], M);
}
}
#line 556 "inform7/Chapter 19/Kind Checking.w"
; break;
}
}
#line 155 "inform7/Chapter 19/Kind Constructors.w"
kind_constructor *Kinds__Constructors__new(kind_constructor *super, char *source_name,
char *initialisation_macro) {
kind_constructor *con = CREATE(kind_constructor);
kind_constructor **pC = Kinds__known_constructor_name(source_name);
if (pC) *pC = con;
if (super == Kinds__get_construct(K_value))
{
#line 183 "inform7/Chapter 19/Kind Constructors.w"
con->dt_tag = NULL;
con->group = 0; /* which is invalid, so the interpreter needs to set it */
/* A: how this came into being */
con->defined_in_source_text = FALSE;
con->is_incompletely_defined = FALSE;
con->where_defined_in_source_text = NULL; /* but will be filled in imminently */
con->stored_as = NULL;
/* B: constructing kinds */
con->constructor_arity = 0; /* by default a base constructor */
int i;
for (i=0; i<MAX_KIND_CONSTRUCTION_ARITY; i++) {
con->variance[i] = COVARIANT;
con->tupling[i] = NO_TUPLING;
}
con->cached_kind = NULL;
/* C: compatibility with other kinds */
con->superkind_set_at = NULL;
con->first_casting_rule = NULL;
con->first_instance_rule = NULL;
/* D: how constant values of this kind are expressed */
con->ways_to_write_literals = NULL;
con->named_values_created_with_assertions = FALSE;
con->named_values_created_with_table = NULL;
con->next_free_value = 1;
con->constant_compilation_method = NONE_CCM;
/* E: knowledge about values of this kind */
con->dt_knowledge = NULL; /* but will be filled in imminently, in almost all cases */
con->default_value = NULL;
/* F: behaviour as a property as well */
con->can_coincide_with_property = FALSE;
con->coinciding_property = NULL;
/* G: performing arithmetic */
strcpy(con->comparison_routine, "UnsignedCompare");
if ((con == CON_KIND_VARIABLE) || (con == CON_INTERMEDIATE) ||
((source_name) &&
((strcmp(source_name, "NUMBER_TY") == 0) ||
(strcmp(source_name, "REAL_NUMBER_TY") == 0))))
con->dimensional_form =
Kinds__Dimensions__fundamental_unit_sequence(NULL);
else
con->dimensional_form =
Kinds__Dimensions__fundamental_unit_sequence(Kinds__base_construction(con));
con->dimensional_form_fixed = FALSE;
Kinds__Dimensions__dim_initialise(&(con->dim_rules));
/* H: representing this kind at run-time */
con->weak_kind_ID = next_free_data_type_ID++;
con->name_in_template_code[0] = 0;
/* I: storing values at run-time */
con->multiple_block = FALSE;
con->small_block_size = 1;
con->heap_size_estimate = 0;
con->can_exchange = FALSE;
con->first_comparison_schema = NULL;
con->distinguisher = NULL;
con->loop_domain_schema = NULL;
/* J: printing and parsing values at run-time */
if (source_name[0]) {
strcpy(con->dt_I6_identifier, "DecimalNumber");
strcpy(con->name_of_printing_rule_ACTIONS, "DA_Name");
} else {
Identifiers__compose(con->dt_I6_identifier,
'E', (con->allocation_id)+1, EMPTY_WORDING);
strcpy(con->name_of_printing_rule_ACTIONS, con->dt_I6_identifier);
}
con->understand_as_values = NULL;
con->has_i6_GPR = FALSE;
con->I6_GPR_needed = FALSE;
con->explicit_i6_GPR = NULL;
con->recognition_only_GPR = NULL;
/* K: indexing and documentation */
con->specification_text = NULL;
con->constructor_description = NULL;
con->index_default_value = "--";
con->index_maximum_value = "--";
con->index_minimum_value = "--";
con->index_priority = LOWEST_INDEX_PRIORITY;
con->linguistic = FALSE;
con->indexed_grey_if_empty = FALSE;
con->documentation_reference = NULL;
Kinds__Interpreter__play_back_kind_macro(
Kinds__Interpreter__parse_kind_macro_name("#DEFAULTS"), con);
if (initialisation_macro)
Kinds__Interpreter__play_back_kind_macro(
Kinds__Interpreter__parse_kind_macro_name(initialisation_macro), con);
}
#line 161 "inform7/Chapter 19/Kind Constructors.w"
else
{
#line 290 "inform7/Chapter 19/Kind Constructors.w"
int I = con->allocation_id;
void *N = con->next_structure;
void *P = con->prev_structure;
*con = *super;
con->allocation_id = I;
con->next_structure = N;
con->prev_structure = P;
con->cached_kind = NULL; /* otherwise the superkind's cache is used by mistake */
con->name_in_template_code[0] = 0; /* otherwise this will be called |OBJECT_TY| by mistake */
}
#line 162 "inform7/Chapter 19/Kind Constructors.w"
;
if (source_name)
Extensions__IDs__truncated_strcpy(con->name_in_template_code, source_name, 31);
if ((con != CON_KIND_VARIABLE) && (con != CON_INTERMEDIATE))
con->dt_knowledge =
InferenceSubjects__new(global_constants,
KIND_SUB, STORE_POINTER_kind_constructor(con), LIKELY_CE);
con->where_defined_in_source_text = current_sentence;
kind **pK = Kinds__known_kind_name(source_name);
if (pK) *pK = Kinds__base_construction(con);
return con;
}
#line 305 "inform7/Chapter 19/Kind Constructors.w"
void Kinds__Constructors__attach_nametag(kind_constructor *con, nametag *nt) {
if ((con == NULL) || (nt == NULL)) internal_error("bad nametag attachment");
con->dt_tag = nt;
}
wording Kinds__Constructors__get_name(kind_constructor *con, int plural_form) {
if (con->dt_tag) {
nametag *nt = con->dt_tag;
if (nt) return Nametags__get_name(nt, plural_form);
}
return EMPTY_WORDING;
}
wording Kinds__Constructors__get_name_in_play(kind_constructor *con, int plural_form) {
if (con->dt_tag) {
nametag *nt = con->dt_tag;
if (nt) return Nametags__get_name_in_play(nt, plural_form);
}
return EMPTY_WORDING;
}
nametag *Kinds__Constructors__get_nametag(kind_constructor *con) {
if (con == NULL) return NULL;
return con->dt_tag;
}
#line 338 "inform7/Chapter 19/Kind Constructors.w"
void Kinds__Constructors__compile_I6_constants(OUTPUT_STREAM) {
WRITE("Constant UNKNOWN_TY = %d;\n", UNKNOWN_VNT);
kind_constructor *con;
LOOP_OVER(con, kind_constructor)
if (con->name_in_template_code[0])
WRITE("Constant %s = %d;\n",
con->name_in_template_code, con->weak_kind_ID);
WRITE("Constant BASE_KIND_HWM = %d; ! Base kind high-water-mark\n",
next_free_data_type_ID);
}
char *Kinds__Constructors__name_in_template_code(kind_constructor *con) {
return con->name_in_template_code;
}
#line 357 "inform7/Chapter 19/Kind Constructors.w"
kind_constructor *Kinds__Constructors__parse(char *sn) {
if (sn == NULL) return NULL;
kind_constructor *con;
LOOP_OVER(con, kind_constructor)
if (strcmp(sn, con->name_in_template_code) == 0)
return con;
return NULL;
}
#line 371 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__convert_to_unit(kind_constructor *con) {
if (con->is_incompletely_defined == TRUE) {
Kinds__Interpreter__play_back_kind_macro(
Kinds__Interpreter__parse_kind_macro_name("#UNIT"), con);
return TRUE;
}
if (Kinds__Constructors__is_arithmetic(con)) return TRUE; /* i.e., if it succeeded */
return FALSE;
}
int Kinds__Constructors__convert_to_enumeration(kind_constructor *con) {
if (con->is_incompletely_defined == TRUE) {
Kinds__Interpreter__play_back_kind_macro(
Kinds__Interpreter__parse_kind_macro_name("#ENUMERATION"), con);
if (con->linguistic)
Kinds__Interpreter__play_back_kind_macro(
Kinds__Interpreter__parse_kind_macro_name("#LINGUISTIC"), con);
return TRUE;
}
if (Kinds__Constructors__is_enumeration(con)) return TRUE; /* i.e., if it succeeded */
return FALSE;
}
#line 397 "inform7/Chapter 19/Kind Constructors.w"
void Kinds__Constructors__convert_to_real(kind_constructor *con) {
Kinds__Interpreter__play_back_kind_macro(
Kinds__Interpreter__parse_kind_macro_name("#REAL"), con);
}
#line 406 "inform7/Chapter 19/Kind Constructors.w"
void Kinds__Constructors__mark_as_linguistic(kind_constructor *con) {
con->linguistic = TRUE;
}
#line 413 "inform7/Chapter 19/Kind Constructors.w"
kind **Kinds__Constructors__cache_location(kind_constructor *con) {
if (con) return &(con->cached_kind);
return NULL;
}
int Kinds__Constructors__arity(kind_constructor *con) {
if (con == NULL) return 0;
if (con->group == PROPER_CONSTRUCTOR_GRP) return con->constructor_arity;
return 0;
}
int Kinds__Constructors__tupling(kind_constructor *con, int b) {
return con->tupling[b];
}
int Kinds__Constructors__variance(kind_constructor *con, int b) {
return con->variance[b];
}
#line 437 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__is_definite(kind_constructor *con) {
if ((con->group == BASE_CONSTRUCTOR_GRP) ||
(con->group == PROPER_CONSTRUCTOR_GRP))
return TRUE;
return FALSE;
}
int Kinds__Constructors__get_weak_ID(kind_constructor *con) {
if (con == NULL) return 0;
return con->weak_kind_ID;
}
int Kinds__Constructors__is_arithmetic(kind_constructor *con) {
if (con == NULL) return FALSE;
if ((Kinds__Constructors__is_definite(con)) &&
(Kinds__Constructors__compatible(con,
Kinds__get_construct(K_arithmetic_value), FALSE))) return TRUE;
return FALSE;
}
int Kinds__Constructors__is_arithmetic_and_real(kind_constructor *con) {
if (con == NULL) return FALSE;
if ((Kinds__Constructors__is_definite(con)) &&
(Kinds__Constructors__compatible(con,
Kinds__get_construct(K_real_arithmetic_value), FALSE))) return TRUE;
return FALSE;
}
int Kinds__Constructors__is_enumeration(kind_constructor *con) {
if (con == NULL) return FALSE;
if ((Kinds__Constructors__is_definite(con)) &&
(Kinds__Constructors__compatible(con,
Kinds__get_construct(K_enumerated_value), FALSE))) return TRUE;
return FALSE;
}
#line 478 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__find_cast(kind_constructor *from, kind_constructor *to) {
if (to) {
kind_constructor_casting_rule *dtcr;
for (dtcr = to->first_casting_rule; dtcr; dtcr = dtcr->next_casting_rule) {
if (dtcr->cast_from_kind_unparsed[0]) {
dtcr->cast_from_kind =
Kinds__Constructors__parse(dtcr->cast_from_kind_unparsed);
dtcr->cast_from_kind_unparsed[0] = 0;
}
if (from == dtcr->cast_from_kind)
return TRUE;
}
}
return FALSE;
}
#line 498 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__find_instance(kind_constructor *from, kind_constructor *to) {
kind_constructor_instance *dti;
for (dti = from->first_instance_rule; dti; dti = dti->next_instance_rule) {
if (dti->instance_of_this_unparsed[0]) {
dti->instance_of_this =
Kinds__Constructors__parse(dti->instance_of_this_unparsed);
dti->instance_of_this_unparsed[0] = 0;
}
if (dti->instance_of_this == to) return TRUE;
}
return FALSE;
}
#line 515 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__compatible(kind_constructor *from, kind_constructor *to, int allow_casts) {
if (to == from) return TRUE;
if ((to == NULL) || (from == NULL)) return FALSE;
if ((allow_casts) && (Kinds__Constructors__find_cast(from, to))) return TRUE;
if (Kinds__Constructors__find_instance(from, to)) return TRUE;
return FALSE;
}
#line 526 "inform7/Chapter 19/Kind Constructors.w"
int Kinds__Constructors__uses_pointer_values(kind_constructor *con) {
if (con == NULL) return FALSE;
if ((Kinds__Constructors__is_definite(con)) &&
(Kinds__Constructors__compatible(con, Kinds__get_construct(K_pointer_value), FALSE))) return TRUE;
return FALSE;
}
int Kinds__Constructors__allow_word_as_pointer(kind_constructor *left, kind_constructor *right) {
if (Kinds__Constructors__uses_pointer_values(left) == FALSE) return FALSE;
if (Kinds__Constructors__uses_pointer_values(right) == TRUE) return FALSE;
if (Kinds__Constructors__compatible(right, left, TRUE)) return TRUE;
return FALSE;
}
#line 247 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__start(void) {
Kinds__Interpreter__initialise_kind_text_archiver();
}
#line 262 "inform7/Chapter 19/Kind Interpreter.w"
kind_constructor *constructor_described = NULL;
int total_kind_command_lengths = 0;
void Kinds__Interpreter__despatch_kind_command(char *command) {
{
#line 291 "inform7/Chapter 19/Kind Interpreter.w"
total_kind_command_lengths += Platform__strlen(command) + 1;
if (total_kind_command_lengths >= MAX_KIND_COMMAND_FILE_LENGTH)
Kinds__Interpreter__kind_command_error(command, "too great an extent of kind commands");
if (Platform__strlen(command) >= MAX_KIND_COMMAND_LENGTH)
Kinds__Interpreter__kind_command_error(command, "kind command too long");
}
#line 266 "inform7/Chapter 19/Kind Interpreter.w"
;
if (Kinds__Interpreter__recording_a_kind_template()) {
if (strcmp(command, "*END") == 0) Kinds__Interpreter__end_kind_template();
else Kinds__Interpreter__record_into_kind_template(command);
return;
}
if (command[Platform__strlen(command)-1] == ':') {
if (Kinds__Interpreter__recording_a_kind_macro()) Kinds__Interpreter__end_kind_macro();
command[Platform__strlen(command)-1] = 0; /* remove the terminal colon */
{
#line 300 "inform7/Chapter 19/Kind Interpreter.w"
if (command[0] == '#') Kinds__Interpreter__begin_kind_macro(command);
else if (command[0] == '*') Kinds__Interpreter__begin_kind_template(command);
else {
char *name = command; int should_know = FALSE;
if (command[0] == '+') { name = command+1; should_know = TRUE; }
int do_know = Kinds__known_name(name);
if ((do_know == FALSE) && (should_know == TRUE))
internal_error("kind command describes kind with no known name");
if ((do_know == TRUE) && (should_know == FALSE))
internal_error("kind command describes already-known kind");
constructor_described =
Kinds__Constructors__new(Kinds__get_construct(K_value), name, NULL);
if ((constructor_described != CON_KIND_VARIABLE) &&
(constructor_described != CON_INTERMEDIATE))
Plugins__Call__new_base_kind_notify(
Kinds__base_construction(constructor_described), name, EMPTY_WORDING);
}
}
#line 277 "inform7/Chapter 19/Kind Interpreter.w"
;
return;
}
single_kind_command stc = Kinds__Interpreter__parse_kind_command(command);
if (Kinds__Interpreter__recording_a_kind_macro()) Kinds__Interpreter__record_into_kind_macro(stc);
else if (constructor_described) Kinds__Interpreter__apply_kind_command(stc, constructor_described);
else internal_error("kind command describes unspecified kind");
}
#line 322 "inform7/Chapter 19/Kind Interpreter.w"
single_kind_command Kinds__Interpreter__parse_kind_command(char *command) {
char *argument = NULL;
single_kind_command stc;
{
#line 361 "inform7/Chapter 19/Kind Interpreter.w"
int i;
for (i=0; command[i]; i++)
if (command[i] == ':') {
command[i++]=0;
while ((command[i] == ' ') || (command[i] == '\t')) i++;
argument = command + i;
break;
}
if (argument == NULL) Kinds__Interpreter__kind_command_error(command, "kind command without argument");
}
#line 326 "inform7/Chapter 19/Kind Interpreter.w"
;
{
#line 347 "inform7/Chapter 19/Kind Interpreter.w"
stc.which_kind_command = NULL;
stc.boolean_argument = NOT_APPLICABLE;
stc.numeric_argument = 0;
stc.textual_argument = NULL;
stc.ccm_argument = -1;
stc.vocabulary_argument = WordAssemblages__lit_0();
stc.constructor_argument[0] = 0;
stc.macro_argument = NULL;
stc.template_argument = NULL;
}
#line 328 "inform7/Chapter 19/Kind Interpreter.w"
;
{
#line 378 "inform7/Chapter 19/Kind Interpreter.w"
int i;
for (i=0; table_of_kind_commands[i].text_of_command; i++)
if (strcmp(command, table_of_kind_commands[i].text_of_command) == 0)
stc.which_kind_command = &(table_of_kind_commands[i]);
if (stc.which_kind_command == NULL) Kinds__Interpreter__kind_command_error(command, "no such kind command");
}
#line 329 "inform7/Chapter 19/Kind Interpreter.w"
;
switch(stc.which_kind_command->operand_type) {
case BOOLEAN_KCA:
{
#line 388 "inform7/Chapter 19/Kind Interpreter.w"
if (strcmp(argument, "yes") == 0) stc.boolean_argument = TRUE;
else if (strcmp(argument, "no") == 0) stc.boolean_argument = FALSE;
else Kinds__Interpreter__kind_command_error(command, "boolean kind command takes yes/no argument");
}
#line 332 "inform7/Chapter 19/Kind Interpreter.w"
; break;
case CCM_KCA:
{
#line 395 "inform7/Chapter 19/Kind Interpreter.w"
if (strcmp(argument, "none") == 0) stc.ccm_argument = NONE_CCM;
else if (strcmp(argument, "literal") == 0) stc.ccm_argument = LITERAL_CCM;
else if (strcmp(argument, "quantitative") == 0) stc.ccm_argument = NAMED_CONSTANT_CCM;
else if (strcmp(argument, "special") == 0) stc.ccm_argument = SPECIAL_CCM;
else Kinds__Interpreter__kind_command_error(command, "kind command with unknown constant-compilation-method");
}
#line 333 "inform7/Chapter 19/Kind Interpreter.w"
; break;
case CONSTRUCTOR_KCA:
{
#line 438 "inform7/Chapter 19/Kind Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == '>') && (argument[i+1] == '>') && (argument[i+2] == '>')) {
argument[i] = 0;
stc.textual_argument = Kinds__Interpreter__archive_kind_text(argument+i+3);
break;
}
Extensions__IDs__truncated_strcpy(stc.constructor_argument, argument, 31);
}
#line 334 "inform7/Chapter 19/Kind Interpreter.w"
; break;
case MACRO_KCA:
{
#line 457 "inform7/Chapter 19/Kind Interpreter.w"
stc.macro_argument = Kinds__Interpreter__parse_kind_macro_name(argument);
if (stc.macro_argument == NULL)
Kinds__Interpreter__kind_command_error(command, "unknown template name in kind command");
}
#line 335 "inform7/Chapter 19/Kind Interpreter.w"
; break;
case NUMERIC_KCA:
{
#line 433 "inform7/Chapter 19/Kind Interpreter.w"
stc.numeric_argument = atoi(argument);
}
#line 336 "inform7/Chapter 19/Kind Interpreter.w"
; break;
case TEMPLATE_KCA:
{
#line 450 "inform7/Chapter 19/Kind Interpreter.w"
stc.template_argument = Kinds__Interpreter__parse_kind_template_name(argument);
if (stc.template_argument == NULL)
Kinds__Interpreter__kind_command_error(command, "unknown template name in kind command");
}
#line 337 "inform7/Chapter 19/Kind Interpreter.w"
; break;
case TEXT_KCA:
{
#line 404 "inform7/Chapter 19/Kind Interpreter.w"
stc.textual_argument = Kinds__Interpreter__archive_kind_text(argument);
}
#line 338 "inform7/Chapter 19/Kind Interpreter.w"
; break;
case VOCABULARY_KCA:
{
#line 409 "inform7/Chapter 19/Kind Interpreter.w"
stc.vocabulary_argument = WordAssemblages__lit_0();
argument = Kinds__Interpreter__archive_kind_text(argument);
char *latest_word = argument;
int i, nw = 0;
for (i=0; argument[i]; i++)
if (argument[i] == ' ') {
argument[i++] = 0;
stc.vocabulary_argument = WordAssemblages__join(
stc.vocabulary_argument, WordAssemblages__lit_1(
Vocabulary__entry_for_text(latest_word)));
nw++;
latest_word = argument+i;
if (nw >= 30) {
Kinds__Interpreter__kind_command_error(command, "too many words in kind command");
break;
}
}
stc.vocabulary_argument = WordAssemblages__join(
stc.vocabulary_argument, WordAssemblages__lit_1(
Vocabulary__entry_for_text(latest_word)));
}
#line 339 "inform7/Chapter 19/Kind Interpreter.w"
; break;
}
return stc;
}
#line 500 "inform7/Chapter 19/Kind Interpreter.w"
kind_template_definition *Kinds__Interpreter__new_kind_template(char *name) {
kind_template_definition *ttd = CREATE(kind_template_definition);
ttd->template_name = Kinds__Interpreter__archive_kind_text(name);
return ttd;
}
kind_template_definition *Kinds__Interpreter__parse_kind_template_name(char *name) {
kind_template_definition *ttd;
LOOP_OVER(ttd, kind_template_definition)
if (strcmp(name, ttd->template_name) == 0) return ttd;
return NULL;
}
#line 518 "inform7/Chapter 19/Kind Interpreter.w"
kind_template_definition *current_kind_template = NULL; /* the one now being recorded */
int Kinds__Interpreter__recording_a_kind_template(void) {
if (current_kind_template) return TRUE;
return FALSE;
}
void Kinds__Interpreter__begin_kind_template(char *name) {
if (current_kind_template) internal_error("first stt still recording");
if (Kinds__Interpreter__parse_kind_template_name(name))
internal_error("duplicate definition of source text template");
current_kind_template = Kinds__Interpreter__new_kind_template(name);
current_kind_template->template_text = Kinds__Interpreter__begin_recording_kind_text();
}
void Kinds__Interpreter__record_into_kind_template(char *line) {
Kinds__Interpreter__record_kind_text(line);
}
void Kinds__Interpreter__end_kind_template(void) {
if (current_kind_template == NULL) internal_error("no stt currently recording");
Kinds__Interpreter__end_recording_kind_text();
current_kind_template = NULL;
}
#line 549 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__remember_to_transcribe_spec_template(kind_template_definition *ttd, kind_constructor *C) {
kind_template_obligation *tto = CREATE(kind_template_obligation);
tto->remembered_template = ttd;
tto->remembered_constructor = C;
}
#line 558 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__include_templates_for_kinds(void) {
kind_template_obligation *tto;
LOOP_OVER(tto, kind_template_obligation)
Kinds__Interpreter__transcribe_kind_template(tto->remembered_template, tto->remembered_constructor);
}
void Kinds__Interpreter__transcribe_kind_template(kind_template_definition *ttd, kind_constructor *con) {
if (ttd == NULL) internal_error("tried to transcribe missing source text template");
char *p = ttd->template_text;
int i = 0;
while (p[i]) {
char template_line_buffer[2*MAX_KIND_COMMAND_LENGTH], terminator = 0;
if ((p[i] == '\n') || (p[i] == ' ')) { i++; continue; }
{
#line 590 "inform7/Chapter 19/Kind Interpreter.w"
int j=0;
while ((p[i] != 0) && (p[i] != '\n') && (j+1 < MAX_KIND_COMMAND_LENGTH)) {
if (p[i] == '<') {
char template_wildcard_buffer[MAX_KIND_COMMAND_LENGTH];
int k=0;
i++;
while ((p[i] != 0) && (p[i] != '\n') && (p[i] != '>') &&
(k+1<MAX_KIND_COMMAND_LENGTH))
template_wildcard_buffer[k++] = p[i++];
template_wildcard_buffer[k++] = 0;
i++;
{
#line 619 "inform7/Chapter 19/Kind Interpreter.w"
if (strcmp(template_wildcard_buffer, "kind") == 0)
{
#line 635 "inform7/Chapter 19/Kind Interpreter.w"
Kinds__Interpreter__transcribe_constructor_name(template_line_buffer+j, con, FALSE);
}
#line 620 "inform7/Chapter 19/Kind Interpreter.w"
else if (strcmp(template_wildcard_buffer, "lower-case-kind") == 0)
{
#line 640 "inform7/Chapter 19/Kind Interpreter.w"
Kinds__Interpreter__transcribe_constructor_name(template_line_buffer+j, con, TRUE);
}
#line 622 "inform7/Chapter 19/Kind Interpreter.w"
else if (strcmp(template_wildcard_buffer, "kind-weak-ID") == 0)
{
#line 645 "inform7/Chapter 19/Kind Interpreter.w"
sprintf(template_line_buffer+j, "%d", con->weak_kind_ID);
}
#line 624 "inform7/Chapter 19/Kind Interpreter.w"
else if (strcmp(template_wildcard_buffer, "printing-routine") == 0)
{
#line 650 "inform7/Chapter 19/Kind Interpreter.w"
sprintf(template_line_buffer+j, "%s", con->dt_I6_identifier);
}
#line 626 "inform7/Chapter 19/Kind Interpreter.w"
else if (strcmp(template_wildcard_buffer, "comparison-routine") == 0)
{
#line 655 "inform7/Chapter 19/Kind Interpreter.w"
sprintf(template_line_buffer+j, "%s", con->comparison_routine);
}
#line 628 "inform7/Chapter 19/Kind Interpreter.w"
else internal_error("no such source text template wildcard");
j = Platform__strlen(template_line_buffer);
}
#line 601 "inform7/Chapter 19/Kind Interpreter.w"
;
} else template_line_buffer[j++] = p[i++];
}
if (j+1 >= MAX_KIND_COMMAND_LENGTH) {
Problems__Issue__sentence_problem(_p_(PM_KindNameTooLong),
"this is too long a name for a kind",
"and will have to be shortened.");
return;
}
template_line_buffer[j] = 0;
if ((j>0) && ((template_line_buffer[j-1] == '.') || (template_line_buffer[j-1] == ':'))) {
terminator = template_line_buffer[j-1];
template_line_buffer[j-1] = 0;
}
}
#line 571 "inform7/Chapter 19/Kind Interpreter.w"
;
if (template_line_buffer[0]) {
wording XW = Feeds__feed_text(template_line_buffer);
if (terminator != 0) Sentences__make_node(XW, terminator);
}
}
Sentences__Rearrangement__tidy_up_ofs_and_froms();
Sentences__RuleSubtrees__register_recently_lexed_phrases();
}
#line 660 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__transcribe_constructor_name(char *buffer, kind_constructor *con, int lower_case) {
buffer[0] = 0;
wording W = EMPTY_WORDING;
if (con->dt_tag) W = Kinds__Constructors__get_name(con, FALSE);
if (Wordings__nonempty(W)) {
if (Kinds__Constructors__arity(con) > 0) {
int full_length = Wordings__length(W);
int i, w1 = Wordings__first_wn(W);
for (i=0; i<full_length; i++) {
if (i > 0) strcpy(buffer+Platform__strlen(buffer), " ");
vocabulary_entry *ve = Lexer__word(w1+i);
if (ve == STROKE_V) break;
if ((ve == CAPITAL_K_V) || (ve == CAPITAL_L_V)) strcpy(buffer+Platform__strlen(buffer), "value");
else strcpy(buffer+Platform__strlen(buffer), Vocabulary__get_exemplar(ve, FALSE));
}
} else {
if (lower_case) Wordings__to_string_raw(buffer, W);
else Wordings__to_string(buffer, W);
}
}
}
#line 687 "inform7/Chapter 19/Kind Interpreter.w"
kind_macro_definition *current_kind_macro = NULL; /* the one now being recorded */
kind_macro_definition *Kinds__Interpreter__new_kind_macro(char *name) {
kind_macro_definition *tmd = CREATE(kind_macro_definition);
tmd->kind_macro_line_count = 0;
tmd->kind_macro_name = Kinds__Interpreter__archive_kind_text(name);
return tmd;
}
kind_macro_definition *Kinds__Interpreter__parse_kind_macro_name(char *name) {
kind_macro_definition *tmd;
LOOP_OVER(tmd, kind_macro_definition)
if (strcmp(name, tmd->kind_macro_name) == 0) return tmd;
return NULL;
}
#line 706 "inform7/Chapter 19/Kind Interpreter.w"
int Kinds__Interpreter__recording_a_kind_macro(void) {
if (current_kind_macro) return TRUE;
return FALSE;
}
void Kinds__Interpreter__begin_kind_macro(char *name) {
if (Kinds__Interpreter__parse_kind_macro_name(name))
internal_error("duplicate definition of kind command macro");
current_kind_macro = Kinds__Interpreter__new_kind_macro(name);
}
void Kinds__Interpreter__record_into_kind_macro(single_kind_command stc) {
if (current_kind_macro == NULL)
internal_error("kind macro not being recorded");
if (current_kind_macro->kind_macro_line_count >= MAX_KIND_MACRO_LENGTH)
internal_error("kind macro contains too many lines");
current_kind_macro->kind_macro_line[current_kind_macro->kind_macro_line_count++] = stc;
}
void Kinds__Interpreter__end_kind_macro(void) {
if (current_kind_macro == NULL) internal_error("ended kind macro outside one");
current_kind_macro = NULL;
}
#line 734 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__play_back_kind_macro(kind_macro_definition *macro, kind_constructor *con) {
int i;
if (macro == NULL) internal_error("no such kind macro to play back");
for (i=0; i<macro->kind_macro_line_count; i++)
Kinds__Interpreter__apply_kind_command(macro->kind_macro_line[i], con);
}
#line 749 "inform7/Chapter 19/Kind Interpreter.w"
char archive_for_kind_text[MAX_KIND_COMMAND_FILE_LENGTH]; /* text storage area */
char *top_of_afdtt = archive_for_kind_text; /* next free character */
int afdtt_recording_mode = FALSE;
void Kinds__Interpreter__initialise_kind_text_archiver(void) {
archive_for_kind_text[0] = 0;
}
char *Kinds__Interpreter__archive_kind_text(char *original) {
if (afdtt_recording_mode) internal_error("can't archive while recording");
char *new_location = top_of_afdtt;
top_of_afdtt = top_of_afdtt + Platform__strlen(original) + 1;
strcpy(new_location, original);
return new_location;
}
#line 768 "inform7/Chapter 19/Kind Interpreter.w"
char *Kinds__Interpreter__begin_recording_kind_text(void) {
top_of_afdtt[0] = 0;
afdtt_recording_mode = TRUE;
return top_of_afdtt;
}
void Kinds__Interpreter__record_kind_text(char *line) {
if (afdtt_recording_mode == FALSE) internal_error("can't record outside recording");
sprintf(top_of_afdtt + Platform__strlen(top_of_afdtt), "%s\n", line);
}
void Kinds__Interpreter__end_recording_kind_text(void) {
top_of_afdtt = top_of_afdtt + Platform__strlen(top_of_afdtt) + 1;
afdtt_recording_mode = FALSE;
}
#line 787 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__kind_command_error(char *command, char *error) {
LOG("Kind command error found at: %s\n", command);
internal_error(error);
}
#line 835 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__apply_kind_command(single_kind_command stc, kind_constructor *con) {
if (stc.which_kind_command == NULL) internal_error("null STC command");
int tcc = stc.which_kind_command->opcode_number;
{
#line 851 "inform7/Chapter 19/Kind Interpreter.w"
switch (tcc) {
case apply_template_KCC:
if (text_loaded_from_source) Kinds__Interpreter__transcribe_kind_template(stc.template_argument, con);
else Kinds__Interpreter__remember_to_transcribe_spec_template(stc.template_argument, con);
return;
case apply_macro_KCC:
Kinds__Interpreter__play_back_kind_macro(stc.macro_argument, con);
return;
}
}
#line 839 "inform7/Chapter 19/Kind Interpreter.w"
;
{
#line 869 "inform7/Chapter 19/Kind Interpreter.w"
switch (tcc) {
SET_BOOLEAN_FIELD(can_coincide_with_property)
SET_BOOLEAN_FIELD(can_exchange)
SET_BOOLEAN_FIELD(defined_in_source_text)
SET_BOOLEAN_FIELD(has_i6_GPR)
SET_BOOLEAN_FIELD(indexed_grey_if_empty)
SET_BOOLEAN_FIELD(is_incompletely_defined)
SET_BOOLEAN_FIELD(multiple_block)
SET_BOOLEAN_FIELD(named_values_created_with_assertions)
SET_INTEGER_FIELD(group)
SET_INTEGER_FIELD(heap_size_estimate)
SET_INTEGER_FIELD(index_priority)
SET_INTEGER_FIELD(small_block_size)
SET_CCM_FIELD(constant_compilation_method)
SET_TEXTUAL_FIELD(default_value)
SET_TEXTUAL_FIELD(distinguisher)
SET_TEXTUAL_FIELD(documentation_reference)
SET_TEXTUAL_FIELD(explicit_i6_GPR)
SET_TEXTUAL_FIELD(index_default_value)
SET_TEXTUAL_FIELD(index_maximum_value)
SET_TEXTUAL_FIELD(index_minimum_value)
SET_TEXTUAL_FIELD(loop_domain_schema)
SET_TEXTUAL_FIELD(recognition_only_GPR)
SET_TEXTUAL_FIELD(specification_text)
}
}
#line 841 "inform7/Chapter 19/Kind Interpreter.w"
;
{
#line 901 "inform7/Chapter 19/Kind Interpreter.w"
if (tcc == cast_KCC) {
kind_constructor_casting_rule *dtcr = CREATE(kind_constructor_casting_rule);
dtcr->next_casting_rule = con->first_casting_rule;
con->first_casting_rule = dtcr;
Extensions__IDs__truncated_strcpy(dtcr->cast_from_kind_unparsed, stc.constructor_argument, 31);
dtcr->cast_from_kind = NULL;
return;
}
if (tcc == instance_of_KCC) {
kind_constructor_instance *dti = CREATE(kind_constructor_instance);
dti->next_instance_rule = con->first_instance_rule;
con->first_instance_rule = dti;
Extensions__IDs__truncated_strcpy(dti->instance_of_this_unparsed, stc.constructor_argument, 31);
dti->instance_of_this = NULL;
return;
}
if (tcc == comparison_schema_KCC) {
kind_constructor_comparison_schema *dtcs = CREATE(kind_constructor_comparison_schema);
dtcs->next_comparison_schema = con->first_comparison_schema;
con->first_comparison_schema = dtcs;
Extensions__IDs__truncated_strcpy(dtcs->comparator_unparsed, stc.constructor_argument, 31);
dtcs->comparator = NULL;
dtcs->comparison_schema = stc.textual_argument;
return;
}
}
#line 842 "inform7/Chapter 19/Kind Interpreter.w"
;
{
#line 930 "inform7/Chapter 19/Kind Interpreter.w"
switch (tcc) {
case constructor_arity_KCC:
{
#line 990 "inform7/Chapter 19/Kind Interpreter.w"
char *p = stc.textual_argument;
int n = 0, c = 0;
while (p[n]) {
int comma = FALSE;
char *wd = p+n;
for (; p[n]; n++)
if ((p[n] == ' ') || (p[n] == ',')) {
if (p[n] == ',') comma = TRUE;
p[n] = 0;
n++;
break;
}
if (c >= 2) break;
if (strcmp(wd, "covariant") == 0) con->variance[c] = COVARIANT;
else if (strcmp(wd, "contravariant") == 0) con->variance[c] = CONTRAVARIANT;
else if (strcmp(wd, "optional") == 0) con->tupling[c] = ALLOW_NOTHING_TUPLING;
else if (strcmp(wd, "list") == 0) con->tupling[c] = ARBITRARY_TUPLING;
else if (wd[0]) {
LOG("Word: <%s>\n", wd);
internal_error("illegal constructor-arity keyword");
}
if (comma) c++;
}
con->constructor_arity = c+1;
}
#line 932 "inform7/Chapter 19/Kind Interpreter.w"
;
return;
case description_KCC:
con->constructor_description = stc.textual_argument;
return;
case comparison_routine_KCC:
if (Platform__strlen(stc.textual_argument) > 31) internal_error("overlong I6 identifier");
else strcpy(con->comparison_routine, stc.textual_argument);
return;
case i6_printing_routine_KCC:
if (Platform__strlen(stc.textual_argument) > 31) internal_error("overlong I6 identifier");
else strcpy(con->dt_I6_identifier, stc.textual_argument);
return;
case i6_printing_routine_actions_KCC:
if (Platform__strlen(stc.textual_argument) > 31) internal_error("overlong I6 identifier");
else strcpy(con->name_of_printing_rule_ACTIONS, stc.textual_argument);
return;
case singular_KCC: case plural_KCC: {
vocabulary_entry **array; int length;
WordAssemblages__as_array(&(stc.vocabulary_argument), &array, &length);
if (length == 1) {
Vocabulary__set_kind(array[0], Kinds__base_construction(con));
} else {
int i;
for (i=0; i<length; i++) {
Vocabulary__set_flags(array[i], KIND_SLOW_MC);
Preform__mark_vocabulary(array[i], k_kind_NTM);
}
if (con->group != PROPER_CONSTRUCTOR_GRP) {
vocabulary_entry *ve = WordAssemblages__hyphenated(&(stc.vocabulary_argument));
if (ve) Vocabulary__set_kind(ve, Kinds__base_construction(con));
}
}
feed_t id = Feeds__begin();
for (int i=0; i<length; i++)
Feeds__feed_text(Vocabulary__get_exemplar(array[i], FALSE));
wording LW = Feeds__end(id);
if (tcc == singular_KCC) {
int ro = 0;
if (con->group != PROPER_CONSTRUCTOR_GRP) ro = REGISTER_SINGULAR_NTOPT + REGISTER_PLURAL_NTOPT;
nametag *nt = Nametags__new(LW,
STORE_POINTER_kind_constructor(con), KIND_PRIORITY,
PARSE_EXACTLY_NTOPT + ro, KIND_SLOW_MC, NULL, NEUTER_GENDER);
con->dt_tag = nt;
} else {
Nametags__set_plural_name(con->dt_tag, LW);
}
return;
}
case modifying_adjective_KCC:
internal_error("the modifying-adjective syntax has been withdrawn");
return;
}
}
#line 843 "inform7/Chapter 19/Kind Interpreter.w"
;
internal_error("unimplemented kind command");
}
#line 1020 "inform7/Chapter 19/Kind Interpreter.w"
void Kinds__Interpreter__batch_done(void) {
}
#line 11 "inform7/Chapter 19/Using Kinds.w"
wording Kinds__Behaviour__get_name(kind *K, int plural_form) {
if (K == NULL) return EMPTY_WORDING;
return Kinds__Constructors__get_name(K->construct, plural_form);
}
wording Kinds__Behaviour__get_name_in_play(kind *K, int plural_form) {
if (K == NULL) return EMPTY_WORDING;
return Kinds__Constructors__get_name_in_play(K->construct, plural_form);
}
nametag *Kinds__Behaviour__get_nametag(kind *K) {
if (K == NULL) return NULL;
return K->construct->dt_tag;
}
#line 31 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__is_kind_of_kind(kind *K) {
if (K == NULL) return FALSE;
if (K->construct->group == KIND_OF_KIND_GRP) return TRUE;
return FALSE;
}
#line 42 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__definite(kind *K) {
if (K == NULL) return TRUE;
if (Kinds__Constructors__is_definite(K->construct) == FALSE) return FALSE;
int i, arity = Kinds__Constructors__arity(K->construct);
for (i=0; i<arity; i++)
if (Kinds__Behaviour__definite(K->kc_args[i]) == FALSE)
return FALSE;
return TRUE;
}
int Kinds__Behaviour__semidefinite(kind *K) {
if (K == NULL) return TRUE;
if (K->construct == CON_KIND_VARIABLE) return TRUE;
if (Kinds__Constructors__is_definite(K->construct) == FALSE) return FALSE;
int i, arity = Kinds__Constructors__arity(K->construct);
for (i=0; i<arity; i++)
if (Kinds__Behaviour__semidefinite(K->kc_args[i]) == FALSE)
return FALSE;
return TRUE;
}
int Kinds__Behaviour__involves_var(kind *K, int v) {
if (K == NULL) return FALSE;
if ((K->construct == CON_KIND_VARIABLE) && (v == K->kind_variable_number))
return TRUE;
int i, arity = Kinds__Constructors__arity(K->construct);
for (i=0; i<arity; i++)
if (Kinds__Behaviour__involves_var(K->kc_args[i], v))
return TRUE;
return FALSE;
}
#line 84 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__is_built_in(kind *K) {
if (K == NULL) return FALSE;
if (K->construct->defined_in_source_text) return FALSE;
return TRUE;
}
parse_node *Kinds__Behaviour__get_creating_sentence(kind *K) {
if (K == NULL) return FALSE;
return K->construct->where_defined_in_source_text;
}
#line 103 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__is_uncertainly_defined(kind *K) {
if (K == NULL) return FALSE;
return K->construct->is_incompletely_defined;
}
#line 111 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__is_an_enumeration(kind *K) {
if (K == NULL) return FALSE;
return Kinds__Constructors__is_enumeration(K->construct);
}
#line 121 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__convert_to_unit(kind *K) {
if (K == NULL) return FALSE;
return Kinds__Constructors__convert_to_unit(K->construct);
}
#line 129 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__convert_to_enumeration(kind *K) {
if (K) Kinds__Constructors__convert_to_enumeration(K->construct);
}
#line 136 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__convert_to_real(kind *K) {
if (K) Kinds__Constructors__convert_to_real(K->construct);
}
#line 145 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__new_enumerated_value(kind *K) {
if (K == NULL) return 0;
Kinds__Behaviour__convert_to_enumeration(K);
return K->construct->next_free_value++;
}
#line 154 "inform7/Chapter 19/Using Kinds.w"
kind *Kinds__Behaviour__stored_as(kind *K) {
if (K == NULL) return NULL;
return K->construct->stored_as;
}
#line 165 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__set_superkind_set_at(kind *K, parse_node *S) {
if (K == NULL) internal_error("set_superkind_set_at for null kind");
K->construct->superkind_set_at = S;
}
parse_node *Kinds__Behaviour__get_superkind_set_at(kind *K) {
if (K == NULL) return NULL;
return K->construct->superkind_set_at;
}
#line 181 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__has_named_constant_values(kind *K) {
if (K == NULL) return FALSE;
if (K->construct->named_values_created_with_assertions) return TRUE;
return FALSE;
}
table *Kinds__Behaviour__defined_by_table(kind *K) {
if (K == NULL) return NULL;
return K->construct->named_values_created_with_table;
}
void Kinds__Behaviour__set_defined_by_table(kind *K, table *t) {
if (K == NULL) internal_error("no such kind");
K->construct->named_values_created_with_table = t;
}
#line 203 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__get_constant_compilation_method(kind *K) {
if (K == NULL) return NONE_CCM;
return K->construct->constant_compilation_method;
}
#line 214 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__add_literal_pattern(kind *K, literal_pattern *lp) {
if (K == NULL) internal_error("can't add LP to null kind");
K->construct->ways_to_write_literals =
LiteralPatterns__list_add(
K->construct->ways_to_write_literals, lp,
Kinds__FloatingPoint__uses_floating_point(lp->kind_specified));
}
#line 225 "inform7/Chapter 19/Using Kinds.w"
literal_pattern *Kinds__Behaviour__list_of_literal_forms(kind *K) {
if (K == NULL) return NULL;
return K->construct->ways_to_write_literals;
}
#line 233 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__get_highest_valid_value_as_integer(kind *K) {
if (K == NULL) return 0;
kind_constructor *con = K->construct;
if (con == CON_activity) return NUMBER_CREATED(activity);
if (con == Kinds__get_construct(K_equation)) return NUMBER_CREATED(equation);
if (con == CON_rule) return NUMBER_CREATED(booking);
if (con == CON_rulebook) return NUMBER_CREATED(rulebook);
if (con == Kinds__get_construct(K_table)) return NUMBER_CREATED(table) + 1;
if (con == Kinds__get_construct(K_use_option)) return NUMBER_CREATED(use_option);
if (con == Kinds__get_construct(K_response)) return NUMBER_CREATED(response_message);
return con->next_free_value - 1;
}
#line 252 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__has_properties(kind *K) {
if (K == NULL) return FALSE;
if (Kinds__Behaviour__is_an_enumeration(K)) return TRUE;
if (Kinds__Compare__le(K, K_object)) return TRUE;
return FALSE;
}
#line 273 "inform7/Chapter 19/Using Kinds.w"
inference_subject *Kinds__Behaviour__as_subject(kind *K) {
if (K == NULL) return NULL;
return K->construct->dt_knowledge;
}
void Kinds__Behaviour__set_subject(kind *K, inference_subject *infs) {
if (K == NULL) return;
K->construct->dt_knowledge = infs;
}
#line 287 "inform7/Chapter 19/Using Kinds.w"
wording Kinds__Behaviour__get_name_text(inference_subject *from) {
kind *K = InferenceSubjects__as_kind(from);
return Kinds__Behaviour__get_name(K, FALSE);
}
void Kinds__Behaviour__complete_model(inference_subject *infs) { }
void Kinds__Behaviour__check_model(inference_subject *infs) { }
void Kinds__Behaviour__write_element_of_condition(inference_subject *infs, char *cond) {
kind *K = InferenceSubjects__as_kind(infs);
if (Kinds__Compare__lt(K, K_object))
sprintf(cond, "t_0 ofclass %s", Kinds__Behaviour__I6_classname(K));
else if (Kinds__Compare__eq(K, K_object))
sprintf(cond, "t_0");
}
#line 306 "inform7/Chapter 19/Using Kinds.w"
general_pointer Kinds__Behaviour__new_permission_granted(inference_subject *from) {
return STORE_POINTER_property_of_value_storage(
Properties__ValueImplementation__get_storage());
}
#line 316 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__make_adj_const_domain(inference_subject *infs,
instance *nc, property *prn) {
kind *K = InferenceSubjects__as_kind(infs);
Instances__make_adj_const_domain(nc, prn, K, NULL);
}
#line 326 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__compile(OUTPUT_STREAM, inference_subject *infs) {
kind *K = InferenceSubjects__as_nonobject_kind(infs);
Properties__ValueImplementation__compile_properties(OUT, K);
}
int Kinds__Behaviour__compile_all(OUTPUT_STREAM) {
return FALSE;
}
#line 346 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__compile_default_value(OUTPUT_STREAM, kind *K,
wording W, char *storage_name) {
if (Kinds__Compare__eq(K, K_value))
{
#line 456 "inform7/Chapter 19/Using Kinds.w"
Problems__quote_wording_as_source(1, W);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"I am unable to start %1 off with any value, because the "
"instructions do not tell me what kind of value it should be "
"(a number, a time, some text perhaps?).");
Problems__issue_problem_end();
return NOT_APPLICABLE;
}
#line 349 "inform7/Chapter 19/Using Kinds.w"
;
if (Kinds__Behaviour__definite(K) == FALSE)
{
#line 427 "inform7/Chapter 19/Using Kinds.w"
if (Wordings__nonempty(W)) {
Problems__quote_wording_as_source(1, W);
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"I am unable to create %1 with the kind of value '%2', "
"because this is a kind of value which is not allowed as "
"something to be stored in properties, variables and the "
"like. (See the Kinds index for which kinds of value "
"are available. The ones which aren't available are really "
"for internal use by Inform.)");
Problems__issue_problem_end();
} else {
Problems__quote_kind(1, K);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"I am unable to create a value of the kind '%1' "
"because this is a kind of value which is not allowed as "
"something to be stored in properties, variables and the "
"like. (See the Kinds index for which kinds of value "
"are available. The ones which aren't available are really "
"for internal use by Inform.)");
Problems__issue_problem_end();
}
return NOT_APPLICABLE;
}
#line 351 "inform7/Chapter 19/Using Kinds.w"
;
if ((Kinds__get_construct(K) == CON_list_of) ||
(Kinds__Compare__eq(K, K_stored_action)) ||
(Kinds__get_construct(K) == CON_phrase) ||
(Kinds__get_construct(K) == CON_relation)) {
if (Kinds__get_construct(K) == CON_list_of) {
text_stream *BC = Kinds__RunTime__begin_block_constant(OUT, K);
Kinds__RunTime__compile_default_value(BC, K);
WRITE_TO(BC, " 0");
Kinds__RunTime__end_block_constant(K);
} else if (Kinds__Compare__eq(K, K_stored_action)) {
text_stream *BC = Kinds__RunTime__begin_block_constant(OUT, K);
Kinds__RunTime__compile_block_value_header(BC, K_stored_action, FALSE, 6);
WRITE_TO(BC, "##Wait 0 0 selfobj false 0");
Kinds__RunTime__end_block_constant(K_stored_action);
} else if (Kinds__get_construct(K) == CON_relation) {
text_stream *BC = Kinds__RunTime__begin_block_constant(OUT, K);
Relations__compile_blank_relation(BC, K);
Kinds__RunTime__end_block_constant(K);
} else {
Kinds__RunTime__compile_default_value(OUT, K);
}
return TRUE;
}
if ((Kinds__get_construct(K) == CON_list_of) ||
(Kinds__get_construct(K) == CON_phrase) ||
(Kinds__get_construct(K) == CON_relation)) {
Kinds__RunTime__compile_default_value(OUT, K);
return TRUE;
}
char *dvot = Kinds__Behaviour__get_default_value(K);
if (dvot) {
if (dvot[0] == '/') {
text_stream *BC = Kinds__RunTime__begin_block_constant(OUT, K);
WRITE_TO(BC, "%s", dvot+1);
Kinds__RunTime__end_block_constant(K);
} else {
WRITE("%s", dvot);
}
return TRUE;
}
if (Kinds__Compare__lt(K, K_object))
{
#line 405 "inform7/Chapter 19/Using Kinds.w"
if (Wordings__nonempty(W)) {
Problems__quote_wording_as_source(1, W);
Problems__quote_kind(2, K);
Problems__quote_text(3, storage_name);
Problems__Issue__handmade_problem(_p_(PM_EmptyKind2));
Problems__issue_problem_segment(
"I am unable to put any value into the %3 %1, which needs to be %2, "
"because the world does not contain %2.");
Problems__issue_problem_end();
} else {
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(PM_EmptyKind));
Problems__issue_problem_segment(
"I am unable to find %2 to use here, because the world does not "
"contain %2.");
Problems__issue_problem_end();
}
return NOT_APPLICABLE;
}
#line 397 "inform7/Chapter 19/Using Kinds.w"
;
return FALSE;
}
#line 474 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__get_default_value(kind *K) {
if (K == NULL) return NULL;
if (K->construct->stored_as) K = K->construct->stored_as;
if (Kinds__Compare__eq(K, K_object)) return "nothing";
instance *I;
LOOP_OVER_INSTANCES(I, K)
return Instances__identifier(I);
if (Kinds__Compare__lt(K, K_object)) {
if (existing_story_file) return "nothing"; /* see above */
return NULL;
}
if (Kinds__Behaviour__is_an_enumeration(K)) return NULL;
if (Kinds__Compare__eq(K, K_rulebook_outcome))
return Rulebooks__Outcomes__get_default_value();
return K->construct->default_value;
}
#line 515 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__name_can_coincide_with_property(kind *K) {
if (K == NULL) return FALSE;
return K->construct->can_coincide_with_property;
}
property *Kinds__Behaviour__get_coinciding_property(kind *K) {
if (K == NULL) return NULL;
return K->construct->coinciding_property;
}
void Kinds__Behaviour__set_coinciding_property(kind *K, property *P) {
if (K == NULL) return;
K->construct->coinciding_property = P;
}
#line 536 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__uses_signed_comparisons(kind *K) {
if (K == NULL) return FALSE;
if (strcmp(K->construct->comparison_routine, "signed") == 0) return TRUE;
return FALSE;
}
char *Kinds__Behaviour__get_comparison_routine(kind *K) {
if (K == NULL) return "";
if (Kinds__FloatingPoint__uses_floating_point(K))
return K_real_number->construct->comparison_routine;
if (strcmp(K->construct->comparison_routine, "signed") == 0) return "";
return K->construct->comparison_routine;
}
#line 557 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__is_quasinumerical(kind *K) {
if (K == NULL) return FALSE;
return Kinds__Constructors__is_arithmetic(K->construct);
}
unit_sequence *Kinds__Behaviour__get_dimensional_form(kind *K) {
if (K == NULL) return NULL;
if (Kinds__Behaviour__is_quasinumerical(K) == FALSE) return NULL;
if (K->construct == CON_INTERMEDIATE) return K->intermediate_result;
return &(K->construct->dimensional_form);
}
int Kinds__Behaviour__test_if_derived(kind *K) {
if (K == NULL) return FALSE;
return K->construct->dimensional_form_fixed;
}
void Kinds__Behaviour__now_derived(kind *K) {
if (K == NULL) internal_error("can't derive null kind");
K->construct->dimensional_form_fixed = TRUE;
}
int Kinds__Behaviour__scale_factor(kind *K) {
if (K == NULL) return 1;
if (K->intermediate_result)
return Kinds__Dimensions__us_get_scaling_factor(K->intermediate_result);
return LiteralPatterns__scale_factor(K);
}
#line 590 "inform7/Chapter 19/Using Kinds.w"
dimensional_rules *Kinds__Behaviour__get_dim_rules(kind *K) {
if (K == NULL) return NULL;
return &(K->construct->dim_rules);
}
#line 598 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__get_name_in_template_code(kind *K) {
if (K == NULL) return "UNKNOWN_VNT";
return K->construct->name_in_template_code;
}
#line 610 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__I6_classname(kind *K) {
if (Kinds__Compare__eq(K, K_object)) return "K0_kind";
nametag *nt = Kinds__Behaviour__get_nametag(K);
if (nt == NULL) return NULL;
return Nametags__identifier(nt);
}
int Kinds__Behaviour__I6_classnumber(kind *K) {
nametag *nt = Kinds__Behaviour__get_nametag(K);
if (nt == NULL) return 0;
return Nametags__range_number(nt);
}
#line 626 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__write_support_routine_name(OUTPUT_STREAM, kind *K) {
if (K == NULL) internal_error("no support name for null kind");
if (K->construct->stored_as) K = K->construct->stored_as;
WRITE("%s_Support", K->construct->name_in_template_code);
}
#line 640 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__uses_pointer_values(kind *K) {
if (K == NULL) return FALSE;
return Kinds__Constructors__uses_pointer_values(K->construct);
}
#line 648 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__get_small_block_size(kind *K) {
if (K == NULL) return 0;
return K->construct->small_block_size;
}
#line 657 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__get_heap_size_estimate(kind *K) {
if (K == NULL) return 0;
return K->construct->heap_size_estimate;
}
#line 665 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__cast_possible(kind *from, kind *to) {
from = Kinds__weaken(from);
to = Kinds__weaken(to);
if ((to) && (from) && (to->construct != from->construct) &&
(Kinds__Behaviour__definite(to)) && (Kinds__Behaviour__definite(from)) &&
(Kinds__Compare__eq(from, K_object) == FALSE) &&
(Kinds__Compare__eq(to, K_object) == FALSE) &&
(to->construct != CON_property))
return TRUE;
return FALSE;
}
#line 681 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__cast_call(OUTPUT_STREAM, kind *from, kind *to) {
if (Kinds__Behaviour__cast_possible(from, to)) {
if (Kinds__Behaviour__get_name_in_template_code(to)[0] == 0) {
WRITE("(");
return TRUE;
}
if ((Kinds__FloatingPoint__uses_floating_point(from)) &&
(Kinds__FloatingPoint__uses_floating_point(to))) {
WRITE("(");
return TRUE;
}
WRITE("%s_to_%s(",
Kinds__Behaviour__get_name_in_template_code(from),
Kinds__Behaviour__get_name_in_template_code(to));
if (Kinds__Behaviour__uses_pointer_values(to)) {
Frames__compile_allocation(OUT, to);
WRITE(",");
}
return TRUE;
}
return FALSE;
}
#line 707 "inform7/Chapter 19/Using Kinds.w"
parse_node *Kinds__Behaviour__cast_constant(parse_node *value, kind *to) {
kind *from = Specifications__to_kind(value);
if (Kinds__Behaviour__cast_possible(from, to))
if ((Kinds__Compare__eq(from, K_number)) && (Kinds__Compare__eq(to, K_real_number))) {
wording W = ParseTree__get_text(value);
if (Preform__parse_nt_against_word_range(s_literal_real_number_NTM, W, NULL, NULL)) value = most_recent_result_p;
else internal_error("can't parse integer as real");
}
return value;
}
#line 742 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__interpret_test_equality(kind *left, kind *right) {
LOGIF(KIND_CHECKING, "Interpreting equality test of kinds $u, $u\n", left, right);
if ((Kinds__Compare__eq(left, K_truth_state)) || (Kinds__Compare__eq(right, K_truth_state)))
return "(*1 && true) == (*2 && true)";
kind_constructor *L = NULL, *R = NULL;
if ((left) && (right)) { L = left->construct; R = right->construct; }
kind_constructor_comparison_schema *dtcs;
for (dtcs = L->first_comparison_schema; dtcs; dtcs = dtcs->next_comparison_schema) {
if (dtcs->comparator_unparsed[0]) {
dtcs->comparator = Kinds__Constructors__parse(dtcs->comparator_unparsed);
dtcs->comparator_unparsed[0] = 0;
}
if (R == dtcs->comparator) return dtcs->comparison_schema;
}
if (Kinds__Constructors__uses_pointer_values(L)) {
if (Kinds__Constructors__allow_word_as_pointer(L, R)) {
pointer_allocation *pall =
Frames__add_allocation(Kinds__base_construction(L),
"*=-BlkValueCompare(*1, BlkValueCast(*##, *#2, *!2))==0");
return Frames__pall_get_expanded_schema(pall);
}
}
char *cr = Kinds__Behaviour__get_comparison_routine(left);
if ((cr[0] == 0) ||
(strcmp(cr, "signed") == 0) ||
(strcmp(cr, "UnsignedCompare") == 0)) return "*=-*1 == *2";
return "*=- *_1(*1, *2) == 0";
}
#line 783 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__interpret_store(node_type_t storage_class, kind *left, kind *right, int inc) {
LOGIF(KIND_CHECKING, "Interpreting assignment of kinds $u, $u\n", left, right);
kind_constructor *L = NULL, *R = NULL;
if ((left) && (right)) { L = left->construct; R = right->construct; }
int form = STORE_WORD_TO_WORD;
if (inc > 0) {
form = INCREASE_BY_WORD;
if (Kinds__FloatingPoint__uses_floating_point(left)) form = INCREASE_BY_REAL;
}
if (inc < 0) {
form = DECREASE_BY_WORD;
if (Kinds__FloatingPoint__uses_floating_point(left)) form = DECREASE_BY_REAL;
}
if (Kinds__Constructors__uses_pointer_values(L)) {
if (Kinds__Constructors__allow_word_as_pointer(L, R)) {
form = STORE_WORD_TO_POINTER;
if (inc > 0) form = INCREASE_BY_POINTER;
if (inc < 0) form = DECREASE_BY_POINTER;
} else {
form = STORE_POINTER_TO_POINTER;
if (inc > 0) form = INCREASE_BY_POINTER;
if (inc < 0) form = DECREASE_BY_POINTER;
}
}
return Lvalues__storage_class_schema(storage_class,
form, Kinds__Compare__eq(left, PL__TimesOfDay__kind()));
}
#line 816 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__get_distinguisher(kind *K) {
if (K == NULL) return NULL;
return K->construct->distinguisher;
}
#line 827 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__compile_domain_possible(kind *K) {
if (K == NULL) return FALSE;
if (Kinds__Compare__le(K, K_object)) return TRUE;
if (Kinds__Behaviour__is_an_enumeration(K)) return TRUE;
if (K->construct->loop_domain_schema) return TRUE;
return FALSE;
}
#line 857 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__write_loop_schema(i6_schema *sch, kind *K, int use_ix) {
if (K == NULL) return FALSE;
if (Kinds__Compare__lt(K, K_object)) {
if (PL__Counting__optimise_loop(sch, K) == FALSE)
Calculus__Schemas__modify(sch, "objectloop (*1 ofclass %s)",
Kinds__Behaviour__I6_classname(K));
return TRUE;
}
if (Kinds__Compare__eq(K, K_object)) {
Calculus__Schemas__modify(sch, "objectloop (*1 ofclass Object)");
return TRUE;
}
char *p = K->construct->loop_domain_schema;
char q[MAX_LOOP_DOMAIN_SCHEMA_LENGTH+4];
if (Kinds__Behaviour__is_an_enumeration(K)) {
Calculus__Schemas__modify(sch,
"for (*1=1: *1<=%d: *1++)", Kinds__Behaviour__get_highest_valid_value_as_integer(K));
return TRUE;
}
if (p == NULL) return FALSE;
if (use_ix)
{
#line 900 "inform7/Chapter 19/Using Kinds.w"
int i, j;
for (i=0, j=0; (p[i]) && (i<MAX_LOOP_DOMAIN_SCHEMA_LENGTH); i++)
if ((use_ix) && (i>0) && (p[i-1] == '*') && (p[i] == '2')) {
q[j++] = '1'; q[j++] = '_'; q[j++] = 'i'; q[j++] = 'x';
} else q[j++] = p[i];
q[j] = 0;
}
#line 883 "inform7/Chapter 19/Using Kinds.w"
else strcpy(q, p);
Calculus__Schemas__modify(sch, "%s", q);
return TRUE;
}
#line 912 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__requires_blanks_bitmap(kind *K) {
if (K == NULL) return FALSE;
if (Kinds__Compare__le(K, K_object)) return FALSE;
if (Kinds__Behaviour__is_an_enumeration(K)) return FALSE;
return TRUE;
}
#line 923 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__can_exchange(kind *K) {
if (K == NULL) return FALSE;
return K->construct->can_exchange;
}
#line 933 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__get_name_of_printing_rule(kind *K) {
if (K == NULL) return "DecimalNumber";
return K->construct->dt_I6_identifier;
}
#line 944 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__get_name_of_printing_rule_ACTIONS(kind *K) {
if (K == NULL) return "DA_Name";
return K->construct->name_of_printing_rule_ACTIONS;
}
#line 958 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__get_explicit_I6_GPR(kind *K) {
if (K == NULL) internal_error("Kinds__Behaviour__get_explicit_I6_GPR on null kind");
if (Kinds__Compare__le(K, K_object)) internal_error("wrong way to handle object grammar");
return K->construct->explicit_i6_GPR;
}
#line 967 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__offers_I6_GPR(kind *K) {
if (K == NULL) return FALSE;
return K->construct->has_i6_GPR;
}
#line 976 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__request_I6_GPR(kind *K) {
if (K == NULL) return FALSE;
if (Kinds__Compare__le(K, K_object)) internal_error("wrong way to handle object grammar");
if (K->construct->has_i6_GPR == FALSE) return FALSE; /* can't oblige */
K->construct->I6_GPR_needed = TRUE; /* make note to oblige later */
return TRUE;
}
#line 987 "inform7/Chapter 19/Using Kinds.w"
int Kinds__Behaviour__needs_I6_GPR(kind *K) {
if (K == NULL) return FALSE;
return K->construct->I6_GPR_needed;
}
#line 1002 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__set_parsing_grammar(kind *K, grammar_verb *gv) {
if (K == NULL) return;
if (Kinds__Compare__le(K, K_object)) internal_error("wrong way to handle object grammar");
K->construct->understand_as_values = gv;
}
grammar_verb *Kinds__Behaviour__get_parsing_grammar(kind *K) {
if (K == NULL) return NULL;
if (Kinds__Compare__le(K, K_object)) internal_error("wrong way to handle object grammar");
return K->construct->understand_as_values;
}
#line 1019 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__get_recognition_only_GPR(kind *K) {
if (K == NULL) return NULL;
return K->construct->recognition_only_GPR;
}
#line 1027 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__get_documentation_reference(kind *K) {
if (K == NULL) return NULL;
return K->construct->documentation_reference;
}
void Kinds__Behaviour__set_documentation_reference(kind *K, char *dr) {
if (K == NULL) return;
K->construct->documentation_reference = dr;
}
#line 1041 "inform7/Chapter 19/Using Kinds.w"
char *Kinds__Behaviour__get_index_default_value(kind *K) {
if (K == NULL) return NULL;
return K->construct->index_default_value;
}
char *Kinds__Behaviour__get_index_minimum_value(kind *K) {
if (K == NULL) return NULL;
return K->construct->index_minimum_value;
}
char *Kinds__Behaviour__get_index_maximum_value(kind *K) {
if (K == NULL) return NULL;
return K->construct->index_maximum_value;
}
int Kinds__Behaviour__get_index_priority(kind *K) {
if (K == NULL) return 0;
return K->construct->index_priority;
}
int Kinds__Behaviour__indexed_grey_if_empty(kind *K) {
if (K == NULL) return FALSE;
return K->construct->indexed_grey_if_empty;
}
#line 1072 "inform7/Chapter 19/Using Kinds.w"
void Kinds__Behaviour__set_specification_text(kind *K, char *desc) {
if (K == NULL) internal_error("can't set specification for null kind");
K->construct->specification_text = desc;
}
char *Kinds__Behaviour__get_specification_text(kind *K) {
if (K == NULL) internal_error("can't get specification of null kind");
return K->construct->specification_text;
}
#line 1085 "inform7/Chapter 19/Using Kinds.w"
int VM_non_support_problem_issued = FALSE;
void Kinds__Behaviour__notify_of_use(kind *K) {
if (VirtualMachines__supports(K) == FALSE) {
if (VM_non_support_problem_issued == FALSE) {
VM_non_support_problem_issued = TRUE;
Problems__Issue__handmade_problem(_p_(PM_KindRequiresGlulx));
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__issue_problem_segment(
"You wrote %1, but with the settings for this project as they are, "
"I'm unable to make use of %2. (Try changing to Glulx on the Settings "
"panel; that should fix it.)");
Problems__issue_problem_end();
}
}
}
#line 41 "inform7/Chapter 19/Describing Kinds.w"
int if_parsing_phrase_tokens_NTMR(wording W, int *X, void **XP) {
#line 42 "inform7/Chapter 19/Describing Kinds.w"
if (kind_parsing_mode != NORMAL_KIND_PARSING) return TRUE;
return FALSE;
}
#line 51 "inform7/Chapter 19/Describing Kinds.w"
int s_phrase_token_type_NTMR(wording W, int *X, void **XP) {
#line 52 "inform7/Chapter 19/Describing Kinds.w"
int s = kind_parsing_mode;
kind_parsing_mode = PHRASE_TOKEN_KIND_PARSING;
int t = Preform__parse_nt_against_word_range(s_descriptive_type_expression_NTM, W, NULL, NULL);
kind_parsing_mode = s;
if (t) { *X = most_recent_result; *XP = most_recent_result_p; }
return t;
}
#line 65 "inform7/Chapter 19/Describing Kinds.w"
int k_kind_for_template_NTMR(wording W, int *X, void **XP) {
#line 66 "inform7/Chapter 19/Describing Kinds.w"
int s = kind_parsing_mode;
kind_parsing_mode = PHRASE_TOKEN_KIND_PARSING;
int t = Preform__parse_nt_against_word_range(k_kind_NTM, W, NULL, NULL);
kind_parsing_mode = s;
if (t) { *XP = most_recent_result_p; return TRUE; }
return FALSE;
}
#line 78 "inform7/Chapter 19/Describing Kinds.w"
int s_kind_as_name_token_NTMR(wording W, int *X, void **XP) {
#line 79 "inform7/Chapter 19/Describing Kinds.w"
int s = kind_parsing_mode;
kind_parsing_mode = PHRASE_TOKEN_KIND_PARSING;
int t = Preform__parse_nt_against_word_range(k_kind_as_name_token_NTM, W, NULL, NULL);
kind_parsing_mode = s;
if (t) {
parse_node *spec = Specifications__from_kind(most_recent_result_p);
ParseTree__set_text(spec, W);
*XP = spec;
*X = TRUE;
return TRUE;
}
return FALSE;
}
#line 97 "inform7/Chapter 19/Describing Kinds.w"
int k_kind_as_name_token_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = NULL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = NULL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 103 "inform7/Chapter 19/Describing Kinds.w"
int k_kind_abbreviating_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Kinds__variable_construction(R[2], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 108 "inform7/Chapter 19/Describing Kinds.w"
#line 112 "inform7/Chapter 19/Describing Kinds.w"
int k_kind_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 119 "inform7/Chapter 19/Describing Kinds.w"
#line 123 "inform7/Chapter 19/Describing Kinds.w"
int k_kind_articled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 126 "inform7/Chapter 19/Describing Kinds.w"
#line 131 "inform7/Chapter 19/Describing Kinds.w"
int k_variable_definition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Kinds__variable_construction(R[2], RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 134 "inform7/Chapter 19/Describing Kinds.w"
#line 142 "inform7/Chapter 19/Describing Kinds.w"
int k_base_kind_NTMR(wording W, int *X, void **XP) {
#line 143 "inform7/Chapter 19/Describing Kinds.w"
kind *K = NULL;
if (Wordings__empty(W)) return FALSE;
if (Wordings__length(W) == 1) K = Vocabulary__get_kind(Lexer__word(Wordings__first_wn(W)));
if (K == NULL) {
if (Preform__parse_nt_against_word_range(definite_article_NTM, Wordings__first_word(W), NULL, NULL)) return FALSE;
parse_node *p = SParser__parse_excerpt(KIND_SLOW_MC, W);
if (p) {
excerpt_meaning *em = ParseTree__get_meaning(p);
K = Kinds__base_construction(
RETRIEVE_POINTER_kind_constructor(Semantics__Nouns__ExcerptMeanings__data(em)));
} else {
p = SParser__parse_excerpt(NAMETAG_MC, W);
if (p) {
nametag *nt = Nametags__disambiguate(p, KIND_PRIORITY);
if (nt) K = Kinds__base_construction(
RETRIEVE_POINTER_kind_constructor(Nametags__tag_holder(nt)));
}
}
}
if (K) { *XP = K; return TRUE; }
return FALSE;
}
#line 176 "inform7/Chapter 19/Describing Kinds.w"
int k_irregular_kind_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = K_text;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = K_text;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = K_stored_action;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = K_stored_action;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = Kinds__binary_construction(CON_rulebook, K_object, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *XP = Kinds__binary_construction(CON_rulebook, K_object, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *XP = Kinds__binary_construction(CON_rulebook, K_object, K_nil);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *XP = Kinds__binary_construction(CON_rulebook, K_action_name, K_nil);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *XP = Kinds__binary_construction(CON_rule, K_object, RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *XP = Kinds__binary_construction(CON_rule, K_object, RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10: *XP = Kinds__binary_construction(CON_rule, K_object, K_nil);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11: *XP = Kinds__binary_construction(CON_rule, K_action_name, K_nil);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12: *XP = Kinds__unary_construction(CON_property, K_truth_state);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 190 "inform7/Chapter 19/Describing Kinds.w"
#line 195 "inform7/Chapter 19/Describing Kinds.w"
int k_kind_construction_NTMR(wording W, int *X, void **XP) {
#line 196 "inform7/Chapter 19/Describing Kinds.w"
kind_constructor *con;
LOOP_OVER(con, kind_constructor)
if (Kinds__Constructors__arity(con) > 0) {
wording X = W;
wording Y = EMPTY_WORDING;
if (Kinds__Textual__parse_constructor_name(con, &X, &Y))
{
#line 218 "inform7/Chapter 19/Describing Kinds.w"
kind *KX = K_value, *KY = K_value;
{
#line 247 "inform7/Chapter 19/Describing Kinds.w"
if ((con == CON_rule) || (con == CON_rulebook)) {
KX = K_action_name; KY = K_nil;
}
}
#line 220 "inform7/Chapter 19/Describing Kinds.w"
;
if (Wordings__nonempty(X)) {
int tupling = Kinds__Constructors__tupling(con, 0);
if ((tupling == 0) && (Preform__parse_nt_against_word_range(k_single_material_NTM, X, NULL, NULL))) KX = most_recent_result_p;
else if ((tupling == 1) && (Preform__parse_nt_against_word_range(k_optional_material_NTM, X, NULL, NULL))) KX = most_recent_result_p;
else if ((tupling >= 2) && (Preform__parse_nt_against_word_range(k_tupled_material_NTM, X, NULL, NULL))) KX = most_recent_result_p;
else KX = NULL;
}
if (Wordings__nonempty(Y)) {
int tupling = Kinds__Constructors__tupling(con, 1);
if ((tupling == 0) && (Preform__parse_nt_against_word_range(k_single_material_NTM, Y, NULL, NULL))) KY = most_recent_result_p;
else if ((tupling == 1) && (Preform__parse_nt_against_word_range(k_optional_material_NTM, Y, NULL, NULL))) KY = most_recent_result_p;
else if ((tupling >= 2) && (Preform__parse_nt_against_word_range(k_tupled_material_NTM, Y, NULL, NULL))) KY = most_recent_result_p;
else KY = NULL;
}
{
#line 254 "inform7/Chapter 19/Describing Kinds.w"
if ((con == CON_relation) && (Wordings__empty(Y))) KY = KX;
}
#line 235 "inform7/Chapter 19/Describing Kinds.w"
;
if ((Kinds__Constructors__arity(con) == 1) && (KX)) {
*XP = Kinds__unary_construction(con, KX); return TRUE;
}
if ((Kinds__Constructors__arity(con) == 2) && (KX) && (KY)) {
*XP = Kinds__binary_construction(con, KX, KY); return TRUE;
}
}
#line 202 "inform7/Chapter 19/Describing Kinds.w"
;
}
return FALSE;
}
#line 260 "inform7/Chapter 19/Describing Kinds.w"
int k_single_material_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 264 "inform7/Chapter 19/Describing Kinds.w"
int k_optional_material_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = K_nil;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *XP = K_action_name;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 271 "inform7/Chapter 19/Describing Kinds.w"
int k_tupled_material_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = K_nil;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *XP = Kinds__binary_construction(CON_TUPLE_ENTRY, RP[1], K_nil);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 276 "inform7/Chapter 19/Describing Kinds.w"
int k_tuple_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Kinds__binary_construction(CON_TUPLE_ENTRY, RP[1], RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Kinds__binary_construction(CON_TUPLE_ENTRY, RP[1], K_nil);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 280 "inform7/Chapter 19/Describing Kinds.w"
#line 288 "inform7/Chapter 19/Describing Kinds.w"
int Kinds__Textual__parse_constructor_name(kind_constructor *con, wording *KW, wording *LW) {
wording W = *KW;
for (int p=1; p<=2; p++) {
wording NW = Kinds__Constructors__get_name(con, (p==1)?FALSE:TRUE);
if (Wordings__nonempty(NW)) {
int full_length = Wordings__length(NW);
int k1 = Wordings__first_wn(NW);
*KW = EMPTY_WORDING; *LW = EMPTY_WORDING;
{
#line 311 "inform7/Chapter 19/Describing Kinds.w"
int base = 0, length = full_length;
int k;
for (k=0; k<full_length; k++)
if (Lexer__word(k1+k) == STROKE_V) {
length = k - base;
if (length > 0)
{
#line 325 "inform7/Chapter 19/Describing Kinds.w"
if (Wordings__length(W) >= length) {
int i, p, failed = FALSE;
for (i=0, p=Wordings__first_wn(W); i<length; i++) {
vocabulary_entry *ve = Lexer__word(k1+base+i);
if ((ve == CAPITAL_K_V) || (ve == CAPITAL_L_V)) {
int from = p;
if (i == length-1) { p = Wordings__last_wn(W)+1; }
else {
int bl = 0;
while (p <= Wordings__last_wn(W)) {
vocabulary_entry *nw = Lexer__word(p);
if (nw == OPENBRACKET_V) bl++;
else if (nw == CLOSEBRACKET_V) bl--;
else if (bl == 0) {
if (nw == Lexer__word(k1+base+i+1)) break;
}
p++;
}
if (p > Wordings__last_wn(W)) { failed = TRUE; break; }
}
if (ve == CAPITAL_K_V) { *KW = Wordings__new(from, p-1); }
else { *LW = Wordings__new(from, p-1); }
} else {
if (ve != Lexer__word(p++)) { failed = TRUE; break; }
}
}
if (p != Wordings__last_wn(W)+1) failed = TRUE;
if (failed == FALSE) return TRUE;
}
}
#line 316 "inform7/Chapter 19/Describing Kinds.w"
;
base = k+1;
}
length = full_length - base;
if (length > 0)
{
#line 325 "inform7/Chapter 19/Describing Kinds.w"
if (Wordings__length(W) >= length) {
int i, p, failed = FALSE;
for (i=0, p=Wordings__first_wn(W); i<length; i++) {
vocabulary_entry *ve = Lexer__word(k1+base+i);
if ((ve == CAPITAL_K_V) || (ve == CAPITAL_L_V)) {
int from = p;
if (i == length-1) { p = Wordings__last_wn(W)+1; }
else {
int bl = 0;
while (p <= Wordings__last_wn(W)) {
vocabulary_entry *nw = Lexer__word(p);
if (nw == OPENBRACKET_V) bl++;
else if (nw == CLOSEBRACKET_V) bl--;
else if (bl == 0) {
if (nw == Lexer__word(k1+base+i+1)) break;
}
p++;
}
if (p > Wordings__last_wn(W)) { failed = TRUE; break; }
}
if (ve == CAPITAL_K_V) { *KW = Wordings__new(from, p-1); }
else { *LW = Wordings__new(from, p-1); }
} else {
if (ve != Lexer__word(p++)) { failed = TRUE; break; }
}
}
if (p != Wordings__last_wn(W)+1) failed = TRUE;
if (failed == FALSE) return TRUE;
}
}
#line 320 "inform7/Chapter 19/Describing Kinds.w"
;
}
#line 296 "inform7/Chapter 19/Describing Kinds.w"
;
}
}
*KW = EMPTY_WORDING; *LW = EMPTY_WORDING;
return FALSE;
}
#line 361 "inform7/Chapter 19/Describing Kinds.w"
int k_kind_of_kind_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = RP[1]; if (Kinds__Behaviour__is_kind_of_kind(RP[1]) == FALSE) return FALSE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 363 "inform7/Chapter 19/Describing Kinds.w"
#line 369 "inform7/Chapter 19/Describing Kinds.w"
int Kinds__Textual__parse_variable(vocabulary_entry *ve) {
if (ve == NULL) return 0;
return Kinds__Textual__parse_kind_variable_name(Vocabulary__get_exemplar(ve, TRUE), TRUE);
}
int Kinds__Textual__parse_kind_variable_name(char *p, int allow_lower) {
if (p == NULL) return 0;
if ((p[1] == 0) || ((p[1] == 's') && (p[2] == 0))) {
if ((p[0] >= 'A') && (p[0] <= 'Z')) return p[0] - 'A' + 1;
if ((allow_lower) && (p[0] >= 'a') && (p[0] <= 'z')) return p[0] - 'a' + 1;
}
return 0;
}
int Kinds__Textual__parse_kind_variable_name_singular(char *p) {
if ((p) && (p[1] == 0) && (p[0] >= 'A') && (p[0] <= 'Z'))
return p[0] - 'A' + 1;
return 0;
}
#line 407 "inform7/Chapter 19/Describing Kinds.w"
int k_kind_variable_NTMR(wording W, int *X, void **XP) {
#line 408 "inform7/Chapter 19/Describing Kinds.w"
int k = Kinds__Textual__parse_kind_variable_name(Lexer__word_raw_text(Wordings__first_wn(W)), FALSE);
if (k != 0) {
kind *K = Frames__get_kind_variable(k);
if (K) { *X = k; *XP = K; return TRUE; }
}
return FALSE;
}
#line 421 "inform7/Chapter 19/Describing Kinds.w"
int k_formal_kind_variable_NTMR(wording W, int *X, void **XP) {
#line 422 "inform7/Chapter 19/Describing Kinds.w"
int k = Kinds__Textual__parse_kind_variable_name(Lexer__word_raw_text(Wordings__first_wn(W)), FALSE);
if (k != 0) {
*X = k; *XP = Kinds__variable_construction(k, NULL); return TRUE;
}
return FALSE;
}
#line 432 "inform7/Chapter 19/Describing Kinds.w"
int k_formal_kind_variable_singular_NTMR(wording W, int *X, void **XP) {
#line 433 "inform7/Chapter 19/Describing Kinds.w"
int k = Kinds__Textual__parse_kind_variable_name_singular(Lexer__word_raw_text(Wordings__first_wn(W)));
if (k != 0) {
*X = k; *XP = Kinds__variable_construction(k, NULL); return TRUE;
}
return FALSE;
}
#line 444 "inform7/Chapter 19/Describing Kinds.w"
int k_kind_variable_texts_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 471 "inform7/Chapter 19/Describing Kinds.w"
#line 480 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__log(kind *K) {
Kinds__Textual__write(dl, K);
}
#line 487 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__write(OUTPUT_STREAM, kind *K) {
Kinds__Textual__write_inner(OUT, K, FALSE, FALSE);
}
void Kinds__Textual__write_plural(OUTPUT_STREAM, kind *K) {
Kinds__Textual__write_inner(OUT, K, TRUE, FALSE);
}
#line 498 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__write_articled(OUTPUT_STREAM, kind *K) {
TEMPORARY_STREAM;
Kinds__Textual__write_inner(TEMP, K, FALSE, TRUE);
Inflections__preface_by_article(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
#line 508 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__write_inner(OUTPUT_STREAM, kind *K, int plural_form, int substituting) {
if (K == NULL) { WRITE("nothing"); return; }
if (K == K_nil) { WRITE("nothing"); return; }
kind_constructor *con = NULL;
if (Kinds__is_proper_constructor(K)) con = Kinds__get_construct(K);
{
#line 525 "inform7/Chapter 19/Describing Kinds.w"
kind_constructor *con = Kinds__get_construct(K);
if (con == CON_NIL) { WRITE("nothing<nil>"); return; }
if (con == CON_TUPLE_ENTRY) {
{
#line 540 "inform7/Chapter 19/Describing Kinds.w"
kind *head = NULL, *tail = NULL;
Kinds__binary_construction_material(K, &head, &tail);
Kinds__Textual__write_inner(OUT, head, FALSE, substituting);
if (Kinds__get_construct(tail) != CON_NIL) {
WRITE(", ");
Kinds__Textual__write_inner(OUT, tail, FALSE, substituting);
}
}
#line 527 "inform7/Chapter 19/Describing Kinds.w"
; return; }
if (con == CON_KIND_VARIABLE) {
{
#line 551 "inform7/Chapter 19/Describing Kinds.w"
int vn = Kinds__get_variable_number(K);
if ((substituting) && (vn > 0)) {
kind *subst = Frames__get_kind_variable(vn);
if (subst) { Kinds__Textual__write_inner(OUT, subst, plural_form, TRUE); return; }
}
WRITE("%c", 'A' + vn - 1);
if (plural_form) WRITE("s");
kind *S = Kinds__get_variable_stipulation(K);
if ((S) && (Kinds__Compare__eq(S, K_value) == FALSE)) {
WRITE(" ["); Kinds__Textual__write(OUT, S); WRITE("]"); }
}
#line 528 "inform7/Chapter 19/Describing Kinds.w"
; return; }
if (con == CON_INTERMEDIATE) {
if (OUT == dl)
LOG("$Q", Kinds__Behaviour__get_dimensional_form(K));
else
Kinds__Dimensions__index_unit_sequence(OUT, Kinds__Behaviour__get_dimensional_form(K), FALSE);
return;
}
}
#line 513 "inform7/Chapter 19/Describing Kinds.w"
;
if (con)
{
#line 571 "inform7/Chapter 19/Describing Kinds.w"
kind *first_base = NULL, *second_base = NULL;
if (Kinds__Constructors__arity(con) == 1)
first_base = Kinds__unary_construction_material(K);
else
Kinds__binary_construction_material(K, &first_base, &second_base);
{
#line 589 "inform7/Chapter 19/Describing Kinds.w"
if ((con == CON_property) && (Kinds__Compare__eq(first_base, K_truth_state))) {
WRITE("either/or property");
return;
}
}
#line 576 "inform7/Chapter 19/Describing Kinds.w"
;
wording KW = Kinds__Behaviour__get_name(K, plural_form);
int k1 = Wordings__first_wn(KW);
int full_length = Wordings__length(KW);
int from, to;
{
#line 597 "inform7/Chapter 19/Describing Kinds.w"
int k_present = 0, l_present = 0; /* these initialisations can have no effect but gcc requires them */
int choice_from[2][2], choice_to[2][2];
{
#line 628 "inform7/Chapter 19/Describing Kinds.w"
int from, i;
choice_from[0][0] = -1; choice_from[0][1] = -1;
choice_from[1][0] = -1; choice_from[1][1] = -1;
for (i=0, from = -1; i<full_length; i++) {
if (from == -1) { from = i; k_present = 0; l_present = 0; }
if (Lexer__word(k1+i) == CAPITAL_K_V) k_present = 1;
if (Lexer__word(k1+i) == CAPITAL_L_V) l_present = 1;
if (Lexer__word(k1+i) == STROKE_V)
{
#line 642 "inform7/Chapter 19/Describing Kinds.w"
choice_from[k_present][l_present] = from;
choice_to[k_present][l_present] = i-1;
from = -1;
}
#line 635 "inform7/Chapter 19/Describing Kinds.w"
;
}
{
#line 642 "inform7/Chapter 19/Describing Kinds.w"
choice_from[k_present][l_present] = from;
choice_to[k_present][l_present] = i-1;
from = -1;
}
#line 637 "inform7/Chapter 19/Describing Kinds.w"
;
}
#line 599 "inform7/Chapter 19/Describing Kinds.w"
;
k_present = 1; l_present = 1;
if ((con == CON_rule) || (con == CON_rulebook)) {
if (Kinds__Compare__eq(first_base, K_action_name)) k_present = 0;
} else {
if (Kinds__Compare__eq(first_base, K_nil)) k_present = 0;
}
if ((con == CON_property) && (Kinds__Compare__eq(first_base, K_value))) k_present = 0;
if ((con == CON_table_column) && (Kinds__Compare__eq(first_base, K_value))) k_present = 0;
if ((con == CON_relation) && (Kinds__Compare__eq(first_base, second_base))) l_present = 0;
if (Kinds__Constructors__arity(con) == 1) l_present = 0;
else if (Kinds__Compare__eq(second_base, K_nil)) l_present = 0;
if (choice_from[k_present][l_present] == -1) {
if ((k_present == 0) && (choice_from[1][l_present] >= 0)) k_present++;
else if ((l_present == 0) && (choice_from[k_present][1] >= 0)) l_present++;
else if ((k_present == 0) && (l_present == 0) && (choice_from[1][1] >= 0)) {
k_present++; l_present++;
}
}
from = choice_from[k_present][l_present];
to = choice_to[k_present][l_present];
if ((from < 0) || (from >= full_length) || (to < 0) || (to >= full_length) || (to<from)) {
LOG("$w: %d, %d, %d\n", KW, from, to, full_length);
internal_error("constructor form choice failed");
}
}
#line 581 "inform7/Chapter 19/Describing Kinds.w"
;
{
#line 649 "inform7/Chapter 19/Describing Kinds.w"
int i;
for (i=from; i<=to; i++) {
if (i > from) WRITE(" ");
if (Lexer__word(k1+i) == CAPITAL_K_V) Kinds__Textual__desc_base(OUT, con, 0, first_base, substituting);
else if (Lexer__word(k1+i) == CAPITAL_L_V) Kinds__Textual__desc_base(OUT, con, 1, second_base, substituting);
else WRITE(Vocabulary__get_exemplar(Lexer__word(k1+i), FALSE));
}
}
#line 582 "inform7/Chapter 19/Describing Kinds.w"
;
}
#line 514 "inform7/Chapter 19/Describing Kinds.w"
else
{
#line 565 "inform7/Chapter 19/Describing Kinds.w"
wording W = Kinds__Behaviour__get_name(K, plural_form);
Wordings__to_stream(OUT, W);
}
#line 515 "inform7/Chapter 19/Describing Kinds.w"
;
}
#line 660 "inform7/Chapter 19/Describing Kinds.w"
void Kinds__Textual__desc_base(OUTPUT_STREAM, kind_constructor *con, int b, kind *K, int substituting) {
if (K == NULL) { WRITE("nothing"); return; }
if (K == K_nil) { WRITE("nothing"); return; }
int pluralised = TRUE;
int tupled = Kinds__Constructors__tupling(con, b);
int bracketed = FALSE;
if ((tupled > 1) && (Kinds__get_construct(K) == CON_TUPLE_ENTRY)) {
kind *first_base = NULL, *second_base = NULL;
Kinds__binary_construction_material(K, &first_base, &second_base);
if ((second_base) && (Kinds__get_construct(second_base) == CON_TUPLE_ENTRY)) bracketed = TRUE;
}
if ((b == 1) && (con == CON_phrase) && (Kinds__get_construct(K) == CON_phrase)) bracketed = TRUE;
if (bracketed) WRITE("(");
if ((tupled > 1) || (con == CON_phrase)) pluralised = FALSE;
Kinds__Textual__write_inner(OUT, K, pluralised, substituting);
if (bracketed) WRITE(")");
}
#line 315 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__kind_prior(kind *A, kind *B) {
if (A == NULL) {
if (B == NULL) return FALSE;
return TRUE;
}
if (B == NULL) {
if (A == NULL) return FALSE;
return FALSE;
}
if (Kinds__get_construct(A)->allocation_id < Kinds__get_construct(B)->allocation_id) return TRUE;
return FALSE;
}
#line 332 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__dim_initialise(dimensional_rules *dimrs) {
dimrs->multiplications = NULL;
}
#line 339 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__record_multiplication_rule(kind *left, kind *right, kind *outcome) {
dimensional_rules *dimrs = Kinds__Behaviour__get_dim_rules(left);
dimensional_rule *dimr;
for (dimr = dimrs->multiplications; dimr; dimr = dimr->next)
if (dimr->right == right) {
Problems__Issue__sentence_problem(_p_(PM_DimensionRedundant),
"multiplication rules can only be given once",
"and this combination is already established.");
return;
}
dimensional_rule *dimr_new = CREATE(dimensional_rule);
dimr_new->right = right;
dimr_new->outcome = outcome;
if (current_sentence)
dimr_new->name = ParseTree__get_text(current_sentence);
else
dimr_new->name = EMPTY_WORDING;
dimr_new->next = dimrs->multiplications;
dimrs->multiplications = dimr_new;
}
#line 384 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__dim_set_multiplication(kind *left, kind *right,
kind *outcome) {
if ((Kinds__is_proper_constructor(left)) ||
(Kinds__is_proper_constructor(right)) ||
(Kinds__is_proper_constructor(outcome))) {
Problems__Issue__sentence_problem(_p_(PM_DimensionNotBaseKOV),
"multiplication rules can only involve simple kinds of value",
"rather than complicated ones such as lists of other values.");
return;
}
if ((Kinds__Behaviour__is_quasinumerical(left) == FALSE) ||
(Kinds__Behaviour__is_quasinumerical(right) == FALSE) ||
(Kinds__Behaviour__is_quasinumerical(outcome) == FALSE)) {
Problems__Issue__sentence_problem(_p_(PM_NonDimensional),
"multiplication rules can only be given between kinds of "
"value which are known to be numerical",
"and not all of these are. Saying something like 'Pressure is a "
"kind of value.' is not enough - you may think 'pressure' ought "
"to be numerical, but Inform doesn't know that yet. You need "
"to add something like '100 Pa specifies a pressure.' before "
"Inform will realise.");
return;
}
Kinds__Dimensions__record_multiplication_rule(left, right, outcome);
if ((Kinds__Compare__eq(left, outcome)) && (Kinds__Compare__eq(right, K_number))) return;
if ((Kinds__Compare__eq(right, outcome)) && (Kinds__Compare__eq(left, K_number))) return;
Kinds__Dimensions__make_unit_derivation(left, right, outcome);
}
#line 417 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__arithmetic_op_is_unary(int op) {
switch (op) {
case CUBEROOT_OPERATION:
case ROOT_OPERATION:
case REALROOT_OPERATION:
case UNARY_MINUS_OPERATION:
return TRUE;
}
return FALSE;
}
#line 445 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__gcd(int m, int n) {
if ((m<1) || (n<1)) internal_error("applied Kinds__Dimensions__gcd outside natural numbers");
while (TRUE) {
int rem = m%n;
if (rem == 0) return n;
m = n; n = rem;
}
}
#line 458 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__lcm(int m, int n) {
return (m/Kinds__Dimensions__gcd(m, n))*n;
}
#line 468 "inform7/Chapter 19/Dimensions.w"
unit_sequence Kinds__Dimensions__fundamental_unit_sequence(kind *B) {
unit_sequence us;
if (B == NULL) {
us.no_unit_pairs = 0;
us.unit_pairs[0].fund_unit = NULL; us.unit_pairs[0].power = 0; /* redundant, but appeases |gcc -O2| */
} else {
us.no_unit_pairs = 1;
us.unit_pairs[0].fund_unit = B; us.unit_pairs[0].power = 1;
}
return us;
}
#line 484 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__compare_unit_sequences(unit_sequence *ik1, unit_sequence *ik2) {
int i;
if (ik1 == ik2) return TRUE;
if ((ik1 == NULL) || (ik2 == NULL)) return FALSE;
if (ik1->no_unit_pairs != ik2->no_unit_pairs) return FALSE;
for (i=0; i<ik1->no_unit_pairs; i++)
if ((Kinds__Compare__eq(ik1->unit_pairs[i].fund_unit, ik2->unit_pairs[i].fund_unit) == FALSE) ||
(ik1->unit_pairs[i].power != ik2->unit_pairs[i].power))
return FALSE;
return TRUE;
}
#line 520 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__multiply_unit_sequences(unit_sequence *us1, int s1, unit_sequence *us2, int s2,
unit_sequence *result) {
if ((result == us1) || (result == us2)) internal_error("result must be different structure");
result->no_unit_pairs = 0;
int i1 = 0, i2 = 0; /* read position in sequences 1, 2 */
kind *t1 = NULL; int p1 = 0; /* start with no current term from sequence 1 */
kind *t2 = NULL; int p2 = 0; /* start with no current term from sequence 2 */
while (TRUE) {
{
#line 545 "inform7/Chapter 19/Dimensions.w"
if ((t1 == NULL) && (us1) && (i1 < us1->no_unit_pairs)) {
t1 = us1->unit_pairs[i1].fund_unit; p1 = us1->unit_pairs[i1].power; i1++;
}
}
#line 530 "inform7/Chapter 19/Dimensions.w"
;
{
#line 552 "inform7/Chapter 19/Dimensions.w"
if ((t2 == NULL) && (us2) && (i2 < us2->no_unit_pairs)) {
t2 = us2->unit_pairs[i2].fund_unit; p2 = us2->unit_pairs[i2].power; i2++;
}
}
#line 531 "inform7/Chapter 19/Dimensions.w"
;
if (Kinds__Compare__eq(t1, t2)) {
if (t1 == NULL) break; /* both sequences have now run out */
{
#line 562 "inform7/Chapter 19/Dimensions.w"
int p = p1*s1 + p2*s2; /* combined power of |t1| $=$ |t2| */
if (p != 0) {
if (result->no_unit_pairs == MAX_BASE_UNITS_IN_SEQUENCE)
{
#line 599 "inform7/Chapter 19/Dimensions.w"
Problems__Issue__sentence_problem(_p_(PM_UnitSequenceOverflow),
"reading that sentence led me into calculating such a complicated "
"kind of value that I ran out of memory",
"which my programmer really didn't expect to happen. I think you "
"must have made an awful lot of numerical kinds of value, and "
"then specified how they multiply so that one of them became "
"weirdly tricky. Can you simplify?");
return;
}
#line 565 "inform7/Chapter 19/Dimensions.w"
;
result->unit_pairs[result->no_unit_pairs].fund_unit = t1;
result->unit_pairs[result->no_unit_pairs++].power = p;
}
t1 = NULL; t2 = NULL; /* dispose of both terms as dealt with */
}
#line 534 "inform7/Chapter 19/Dimensions.w"
;
} else {
{
#line 581 "inform7/Chapter 19/Dimensions.w"
if ((t2 == NULL) || ((t1 != NULL) && (Kinds__Dimensions__kind_prior(t1, t2)))) {
if (result->no_unit_pairs == MAX_BASE_UNITS_IN_SEQUENCE)
{
#line 599 "inform7/Chapter 19/Dimensions.w"
Problems__Issue__sentence_problem(_p_(PM_UnitSequenceOverflow),
"reading that sentence led me into calculating such a complicated "
"kind of value that I ran out of memory",
"which my programmer really didn't expect to happen. I think you "
"must have made an awful lot of numerical kinds of value, and "
"then specified how they multiply so that one of them became "
"weirdly tricky. Can you simplify?");
return;
}
#line 583 "inform7/Chapter 19/Dimensions.w"
;
result->unit_pairs[result->no_unit_pairs].fund_unit = t1;
result->unit_pairs[result->no_unit_pairs++].power = p1*s1;
t1 = NULL; /* dispose of the head of sequence 1 as dealt with */
} else if ((t1 == NULL) || ((t2 != NULL) && (Kinds__Dimensions__kind_prior(t2, t1)))) {
if (result->no_unit_pairs == MAX_BASE_UNITS_IN_SEQUENCE)
{
#line 599 "inform7/Chapter 19/Dimensions.w"
Problems__Issue__sentence_problem(_p_(PM_UnitSequenceOverflow),
"reading that sentence led me into calculating such a complicated "
"kind of value that I ran out of memory",
"which my programmer really didn't expect to happen. I think you "
"must have made an awful lot of numerical kinds of value, and "
"then specified how they multiply so that one of them became "
"weirdly tricky. Can you simplify?");
return;
}
#line 589 "inform7/Chapter 19/Dimensions.w"
;
result->unit_pairs[result->no_unit_pairs].fund_unit = t2;
result->unit_pairs[result->no_unit_pairs++].power = p2*s2;
t2 = NULL; /* dispose of the head of sequence 1 as dealt with */
} else internal_error("unit pairs disarrayed");
}
#line 536 "inform7/Chapter 19/Dimensions.w"
;
}
}
LOGIF(KIND_CREATIONS, "Multiplication: $Q * $Q = $Q\n", us1, us2, result);
}
#line 620 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__root_unit_sequence(unit_sequence *us, int pow, unit_sequence *result) {
if (us == NULL) return FALSE;
*result = *us;
int i;
for (i=0; i<result->no_unit_pairs; i++) {
if ((result->unit_pairs[i].power) % pow != 0) return FALSE;
result->unit_pairs[i].power = (result->unit_pairs[i].power)/pow;
}
return TRUE;
}
#line 640 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__dim_substitute(unit_sequence *existing, kind *fundamental, unit_sequence *derived) {
int i, j, p = 0, found = FALSE;
if (existing == NULL) return;
for (i=0; i<existing->no_unit_pairs; i++)
if (Kinds__Compare__eq(existing->unit_pairs[i].fund_unit, fundamental)) {
p = existing->unit_pairs[i].power;
found = TRUE;
{
#line 656 "inform7/Chapter 19/Dimensions.w"
for (j=i; j<existing->no_unit_pairs-1; j++)
existing->unit_pairs[j] = existing->unit_pairs[j+1];
existing->no_unit_pairs--;
}
#line 647 "inform7/Chapter 19/Dimensions.w"
;
}
if (found)
{
#line 663 "inform7/Chapter 19/Dimensions.w"
unit_sequence result;
Kinds__Dimensions__multiply_unit_sequences(existing, 1, derived, p, &result);
*existing = result;
}
#line 650 "inform7/Chapter 19/Dimensions.w"
;
}
#line 671 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__us_get_scaling_factor(unit_sequence *us) {
if (us == NULL) return 1;
return us->scaling_factor;
}
#line 679 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__index_unit_sequence(OUTPUT_STREAM, unit_sequence *deriv, int briefly) {
if (deriv == NULL) return;
if (deriv->no_unit_pairs == 0) { WRITE("dimensionless"); return; }
int j;
for (j=0; j<deriv->no_unit_pairs; j++) {
kind *fundamental = deriv->unit_pairs[j].fund_unit;
int power = deriv->unit_pairs[j].power;
if (briefly) {
if (j>0) WRITE(".");
WRITE("(");
Kinds__Index__index_kind(fundamental, FALSE, FALSE);
WRITE(")");
if (power != 1) WRITE("<sup>%d</sup>", power);
} else {
if (j>0) WRITE(" times ");
if (power < 0) { power = -power; WRITE("reciprocal of "); }
wording W = Kinds__Behaviour__get_name(fundamental, FALSE);
Wordings__to_stream(OUT, W);
switch (power) {
case 1: break;
case 2: WRITE(" squared"); break;
case 3: WRITE(" cubed"); break;
default: WRITE(" to the power %d", power); break;
}
}
}
}
#line 711 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__log_unit_sequence(unit_sequence *deriv) {
if (deriv == NULL) { LOG("<null-us>"); return; }
if (deriv->no_unit_pairs == 0) { LOG("dimensionless"); return; }
int j;
for (j=0; j<deriv->no_unit_pairs; j++) {
if (j>0) LOG(".");
LOG("($u)", deriv->unit_pairs[j].fund_unit);
if (deriv->unit_pairs[j].power != 1) LOG("%d", deriv->unit_pairs[j].power);
}
}
#line 741 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__make_unit_derivation(kind *left, kind *right, kind *outcome) {
kind *terms[3];
terms[0] = left; terms[1] = right; terms[2] = outcome;
int newest_term = -1;
{
#line 757 "inform7/Chapter 19/Dimensions.w"
int i; kind *max = NULL;
for (i=0; i<3; i++)
if ((Kinds__Dimensions__kind_prior(max, terms[i])) && (Kinds__Behaviour__test_if_derived(terms[i]) == FALSE)) {
newest_term = i; max = terms[i];
}
}
#line 745 "inform7/Chapter 19/Dimensions.w"
;
if (newest_term >= 0) {
unit_sequence *derivation = NULL;
{
#line 767 "inform7/Chapter 19/Dimensions.w"
unit_sequence *kx = NULL, *ky = NULL; int sx = 0, sy = 0;
switch (newest_term) {
case 0: /* here $L$ is newest and we derive $L = R^{-1}O$ */
kx = Kinds__Behaviour__get_dimensional_form(terms[1]); sx = -1;
ky = Kinds__Behaviour__get_dimensional_form(terms[2]); sy = 1;
break;
case 1: /* here $R$ is newest and we derive $R = L^{-1}O$ */
kx = Kinds__Behaviour__get_dimensional_form(terms[0]); sx = -1;
ky = Kinds__Behaviour__get_dimensional_form(terms[2]); sy = 1;
break;
case 2: /* here $O$ is newest and we derive $O = LR$ */
kx = Kinds__Behaviour__get_dimensional_form(terms[0]); sx = 1;
ky = Kinds__Behaviour__get_dimensional_form(terms[1]); sy = 1;
break;
}
derivation = Kinds__Behaviour__get_dimensional_form(terms[newest_term]);
unit_sequence result;
Kinds__Dimensions__multiply_unit_sequences(kx, sx, ky, sy, &result);
*derivation = result;
Kinds__Behaviour__now_derived(terms[newest_term]);
}
#line 748 "inform7/Chapter 19/Dimensions.w"
;
{
#line 794 "inform7/Chapter 19/Dimensions.w"
kind *R;
LOOP_OVER_BASE_KINDS(R)
if (Kinds__Behaviour__is_quasinumerical(R)) {
unit_sequence *existing = Kinds__Behaviour__get_dimensional_form(R);
Kinds__Dimensions__dim_substitute(existing, terms[newest_term], derivation);
}
}
#line 749 "inform7/Chapter 19/Dimensions.w"
;
} else
{
#line 811 "inform7/Chapter 19/Dimensions.w"
unit_sequence product;
Kinds__Dimensions__multiply_unit_sequences(
Kinds__Behaviour__get_dimensional_form(terms[0]), 1,
Kinds__Behaviour__get_dimensional_form(terms[1]), 1, &product);
if (Kinds__Dimensions__compare_unit_sequences(&product,
Kinds__Behaviour__get_dimensional_form(terms[2])) == FALSE)
Problems__Issue__sentence_problem(_p_(PM_DimensionsInconsistent),
"this is inconsistent with what is already known about those kinds of value",
"all three of which already have well-established relationships - see the "
"Kinds index for more.");
}
#line 751 "inform7/Chapter 19/Dimensions.w"
;
}
#line 828 "inform7/Chapter 19/Dimensions.w"
int Kinds__Dimensions__dimensionless(kind *K) {
if (K == NULL) return FALSE;
if (Kinds__Compare__eq(K, K_number)) return TRUE;
if (Kinds__Compare__eq(K, K_real_number)) return TRUE;
if (Kinds__Behaviour__is_quasinumerical(K) == FALSE) return FALSE;
return Kinds__Dimensions__us_dimensionless(Kinds__Behaviour__get_dimensional_form(K));
}
int Kinds__Dimensions__us_dimensionless(unit_sequence *us) {
if ((us) && (us->no_unit_pairs == 0)) return TRUE;
return FALSE;
}
#line 845 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__index_dimensional_rules(void) {
INDEX("<p><hr><p>");
{
#line 855 "inform7/Chapter 19/Dimensions.w"
INDEX("<a name=calculator>");
HTML__begin_plain_html_table(ifl);
HTML__first_html_column(ifl, 0);
INDEX("<img border=0 src=inform:/doc_images/calc2.png>&nbsp;");
INDEX("Kinds of value marked with the <b>calculator symbol</b> are numerical - "
"these are values we can add, multiply and so on. The range of these "
"numbers depends on the Format setting for the project (Glulx format "
"supports much higher numbers than Z-code).");
HTML__end_html_row(ifl);
HTML__end_html_table(ifl);
INDEX("<p>");
}
#line 847 "inform7/Chapter 19/Dimensions.w"
;
{
#line 870 "inform7/Chapter 19/Dimensions.w"
HTML__begin_plain_html_table(ifl);
HTML__first_html_column(ifl, 0);
INDEX("<b>kind of value</b>");
HTML__next_html_column(ifl, 0);
INDEX("<b>minimum</b>");
HTML__next_html_column(ifl, 0);
INDEX("<b>maximum</b>");
HTML__next_html_column(ifl, 0);
INDEX("<b>dimensions</b>");
HTML__end_html_row(ifl);
kind *R;
LOOP_OVER_BASE_KINDS(R)
if (Kinds__Behaviour__is_quasinumerical(R)) {
if (Kinds__is_intermediate(R)) continue;
HTML__first_html_column(ifl, 0);
Kinds__Index__index_kind(R, FALSE, FALSE);
HTML__next_html_column(ifl, 0);
{
#line 906 "inform7/Chapter 19/Dimensions.w"
if (Kinds__Compare__eq(R, K_number)) INDEX("1");
else {
char *p = Kinds__Behaviour__get_index_minimum_value(R);
if (p) INDEX("%s", p);
else LiteralPatterns__index_value(
Kinds__Behaviour__list_of_literal_forms(R), 1);
}
}
#line 889 "inform7/Chapter 19/Dimensions.w"
;
HTML__next_html_column(ifl, 0);
{
#line 917 "inform7/Chapter 19/Dimensions.w"
if (Kinds__Compare__eq(R, K_number)) {
if (VirtualMachines__is_16_bit()) INDEX("32767");
else INDEX("2147483647");
} else {
char *p = Kinds__Behaviour__get_index_maximum_value(R);
if (p) INDEX("%s", p);
else {
if (VirtualMachines__is_16_bit())
LiteralPatterns__index_value(
Kinds__Behaviour__list_of_literal_forms(R), 32767);
else
LiteralPatterns__index_value(
Kinds__Behaviour__list_of_literal_forms(R), 2147483647);
}
}
}
#line 891 "inform7/Chapter 19/Dimensions.w"
;
HTML__next_html_column(ifl, 0);
if (Kinds__Dimensions__dimensionless(R)) INDEX("<i>dimensionless</i>");
else {
unit_sequence *deriv = Kinds__Behaviour__get_dimensional_form(R);
Kinds__Dimensions__index_unit_sequence(ifl, deriv, TRUE);
}
HTML__end_html_row(ifl);
}
HTML__end_html_table(ifl); INDEX("<p>");
}
#line 848 "inform7/Chapter 19/Dimensions.w"
;
{
#line 938 "inform7/Chapter 19/Dimensions.w"
kind *L, *R, *O;
int NP = 0, wn;
LOOP_OVER_MULTIPLICATIONS(L, R, O, wn) {
if (NP++ == 0) {
INDEX("<p>This is how multiplication changes kinds:<p>\n");
HTML__begin_plain_html_table(ifl);
}
HTML__first_html_column(ifl, 0);
if (wn >= 0) Index__link(wn);
HTML__next_html_column(ifl, 0);
Kinds__Index__index_kind(L, FALSE, FALSE);
INDEX("<font color=\"#808080\"> x </font>");
Kinds__Index__index_kind(R, FALSE, FALSE);
INDEX("<font color=\"#808080\"> = </font>");
Kinds__Index__index_kind(O, FALSE, FALSE);
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;");
HTML__next_html_column(ifl, 0);
LiteralPatterns__index_benchmark_value(L);
INDEX("<font color=\"#808080\"> x </font>");
LiteralPatterns__index_benchmark_value(R);
INDEX("<font color=\"#808080\"> = </font>");
LiteralPatterns__index_benchmark_value(O);
HTML__end_html_row(ifl);
}
if (NP > 0) { HTML__end_html_table(ifl); INDEX("<p>"); }
}
#line 849 "inform7/Chapter 19/Dimensions.w"
;
}
#line 968 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__log_unit_analysis(void) {
LOG("Dimensionless: ");
int c = 0; kind *R;
LOOP_OVER_BASE_KINDS(R)
if (Kinds__Dimensions__dimensionless(R)) { if (c++ > 0) LOG(", "); LOG("$u", R); }
LOG("\nBase units: ");
c = 0;
LOOP_OVER_BASE_KINDS(R)
if ((Kinds__Dimensions__dimensionless(R) == FALSE) &&
(Kinds__Dimensions__kind_is_derived(R) == FALSE) &&
(Kinds__Behaviour__is_quasinumerical(R)))
{ if (c++ > 0) LOG(", "); LOG("$u", R); }
LOG("\nDerived units:\n");
LOOP_OVER_BASE_KINDS(R)
if ((Kinds__Dimensions__kind_is_derived(R)) && (Kinds__is_intermediate(R) == FALSE)) {
unit_sequence *deriv = Kinds__Behaviour__get_dimensional_form(R);
LOG("$u = $Q\n", R, deriv);
}
}
int Kinds__Dimensions__kind_is_derived(kind *K) {
if (Kinds__is_intermediate(K)) return TRUE;
if ((Kinds__Behaviour__is_quasinumerical(K)) &&
(Kinds__Behaviour__test_if_derived(K) == TRUE) &&
(Kinds__Dimensions__dimensionless(K) == FALSE)) return TRUE;
return FALSE;
}
#line 1029 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__kind_rescale_multiplication(OUTPUT_STREAM, kind *kindx, kind *kindy) {
if ((kindx == NULL) || (kindy == NULL)) return;
kind *kindo = Kinds__Dimensions__arithmetic_on_kinds(kindx, kindy, TIMES_OPERATION);
if (kindo == NULL) return;
int k_X = Kinds__Behaviour__scale_factor(kindx);
int k_Y = Kinds__Behaviour__scale_factor(kindy);
int k_O = Kinds__Behaviour__scale_factor(kindo);
if (k_X*k_Y > k_O) WRITE("/%d", (k_X*k_Y/k_O));
if (k_X*k_Y < k_O) WRITE("*%d", (k_O/k_X/k_Y));
}
#line 1046 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__kind_rescale_division(OUTPUT_STREAM, kind *kindx, kind *kindy) {
if ((kindx == NULL) || (kindy == NULL)) return;
kind *kindo = Kinds__Dimensions__arithmetic_on_kinds(kindx, kindy, DIVIDE_OPERATION);
if (kindo == NULL) return;
int k_X = Kinds__Behaviour__scale_factor(kindx);
int k_Y = Kinds__Behaviour__scale_factor(kindy);
int k_O = Kinds__Behaviour__scale_factor(kindo);
if (k_O*k_Y > k_X) WRITE("*%d", (k_O*k_Y/k_X));
if (k_O*k_Y < k_X) WRITE("/%d", (k_X/k_O/k_Y));
}
#line 1060 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__kind_rescale_root(OUTPUT_STREAM, kind *kindx, int power) {
if (kindx == NULL) return;
kind *kindo = NULL;
if (power == 2) kindo = Kinds__Dimensions__arithmetic_on_kinds(kindx, NULL, ROOT_OPERATION);
if (power == 3) kindo = Kinds__Dimensions__arithmetic_on_kinds(kindx, NULL, CUBEROOT_OPERATION);
if (kindo == NULL) return;
int k_X = Kinds__Behaviour__scale_factor(kindx);
int k_O = Kinds__Behaviour__scale_factor(kindo);
if (power == 2)
{
#line 1085 "inform7/Chapter 19/Dimensions.w"
if (k_O*k_O > k_X) WRITE("*%d", (k_O*k_O/k_X));
if (k_O*k_O < k_X) WRITE("/%d", (k_X/k_O/k_O));
}
#line 1069 "inform7/Chapter 19/Dimensions.w"
else if (power == 3)
{
#line 1096 "inform7/Chapter 19/Dimensions.w"
if (k_O*k_O*k_O > k_X) WRITE("*%d", (k_O*k_O*k_O/k_X));
if (k_O*k_O*k_O < k_X) WRITE("/%d", (k_X/k_O/k_O/k_O));
}
#line 1070 "inform7/Chapter 19/Dimensions.w"
else internal_error("can only scale square and cube roots");
}
#line 1109 "inform7/Chapter 19/Dimensions.w"
kind *Kinds__Dimensions__arithmetic_on_kinds(kind *K1, kind *K2, int op) {
if (K1 == NULL) return NULL;
if ((Kinds__Dimensions__arithmetic_op_is_unary(op) == FALSE) && (K2 == NULL)) return NULL;
unit_sequence *operand1 = Kinds__Behaviour__get_dimensional_form(K1);
if (operand1 == NULL) return NULL;
unit_sequence *operand2 = Kinds__Behaviour__get_dimensional_form(K2);
if ((Kinds__Dimensions__arithmetic_op_is_unary(op) == FALSE) && (operand2 == NULL)) return NULL;
unit_sequence result;
switch (op) {
case PLUS_OPERATION:
case MINUS_OPERATION:
case EQUALS_OPERATION:
case APPROXIMATION_OPERATION:
if (Kinds__Dimensions__compare_unit_sequences(operand1, operand2)) {
result = *operand1;
break;
}
return NULL;
case UNARY_MINUS_OPERATION:
case REMAINDER_OPERATION:
result = *operand1;
break;
case ROOT_OPERATION:
if (Kinds__Dimensions__root_unit_sequence(operand1, 2, &result) == FALSE)
return NULL;
break;
case REALROOT_OPERATION:
if (Kinds__Dimensions__root_unit_sequence(operand1, 2, &result) == FALSE)
return NULL;
break;
case CUBEROOT_OPERATION:
if (Kinds__Dimensions__root_unit_sequence(operand1, 3, &result) == FALSE)
return NULL;
break;
case TIMES_OPERATION:
Kinds__Dimensions__multiply_unit_sequences(operand1, 1, operand2, 1, &result);
break;
case DIVIDE_OPERATION:
Kinds__Dimensions__multiply_unit_sequences(operand1, 1, operand2, -1, &result);
break;
default: return NULL;
}
{
#line 1173 "inform7/Chapter 19/Dimensions.w"
if (Kinds__Dimensions__arithmetic_op_is_unary(op)) {
if ((op == REALROOT_OPERATION) && (Kinds__Compare__eq(K1, K_number)))
return K_real_number;
if (Kinds__Dimensions__dimensionless(K1)) return K1;
} else {
if ((Kinds__Dimensions__dimensionless(K1)) &&
(Kinds__Dimensions__dimensionless(K2))) {
if (Kinds__Compare__eq(K2, K_number)) return K1;
if (Kinds__Compare__eq(K1, K_number)) return K2;
if (Kinds__Compare__eq(K1, K2)) return K1;
}
}
}
#line 1155 "inform7/Chapter 19/Dimensions.w"
;
{
#line 1192 "inform7/Chapter 19/Dimensions.w"
if (Kinds__Dimensions__us_dimensionless(&result)) {
if (Kinds__Dimensions__arithmetic_op_is_unary(op)) {
if (Kinds__FloatingPoint__uses_floating_point(K1)) return K_real_number;
return K_number;
} else {
if ((Kinds__FloatingPoint__uses_floating_point(K1)) ||
(Kinds__FloatingPoint__uses_floating_point(K2))) return K_real_number;
return K_number;
}
}
}
#line 1156 "inform7/Chapter 19/Dimensions.w"
;
{
#line 1209 "inform7/Chapter 19/Dimensions.w"
kind *R;
LOOP_OVER_BASE_KINDS(R)
if (Kinds__Dimensions__compare_unit_sequences(&result,
Kinds__Behaviour__get_dimensional_form(R)))
return R;
}
#line 1157 "inform7/Chapter 19/Dimensions.w"
;
{
#line 1240 "inform7/Chapter 19/Dimensions.w"
result.scaling_factor = Kinds__Dimensions__lcm(Kinds__Behaviour__scale_factor(K1), Kinds__Behaviour__scale_factor(K2));
return Kinds__intermediate_construction(&result);
}
#line 1158 "inform7/Chapter 19/Dimensions.w"
;
}
#line 1246 "inform7/Chapter 19/Dimensions.w"
kind *Kinds__Dimensions__to_rational_power(kind *F, int n, int m) {
if ((n < 1) || (m < 1)) internal_error("bad rational power");
if (Kinds__Dimensions__dimensionless(F)) return F;
kind *K = K_number;
int op = TIMES_OPERATION;
if (n < 0) { n = -n; op = DIVIDE_OPERATION; }
while (n > 0) {
K = Kinds__Dimensions__arithmetic_on_kinds(K, F, op);
n--;
}
if (m == 1) return K;
unit_sequence result;
unit_sequence *operand = Kinds__Behaviour__get_dimensional_form(K);
if (Kinds__Dimensions__root_unit_sequence(operand, m, &result) == FALSE) return NULL;
{
#line 1209 "inform7/Chapter 19/Dimensions.w"
kind *R;
LOOP_OVER_BASE_KINDS(R)
if (Kinds__Dimensions__compare_unit_sequences(&result,
Kinds__Behaviour__get_dimensional_form(R)))
return R;
}
#line 1261 "inform7/Chapter 19/Dimensions.w"
;
return NULL;
}
#line 1268 "inform7/Chapter 19/Dimensions.w"
void Kinds__Dimensions__perform_arithmetic(OUTPUT_STREAM, int op, equation *eqn,
parse_node *X, equation_node *EX, kind *KX,
parse_node *Y, equation_node *EY, kind *KY) {
int binary = TRUE;
if (Kinds__Dimensions__arithmetic_op_is_unary(op)) binary = FALSE;
int use_fp = FALSE, promote_X = FALSE, promote_Y = FALSE, reduce_modulo_1440 = FALSE;
if ((KX) && (KY)) {
kind *KR = Kinds__Dimensions__arithmetic_on_kinds(KX, KY, op);
if (Kinds__Compare__eq(KR, PL__TimesOfDay__kind())) reduce_modulo_1440 = TRUE;
}
{
#line 1311 "inform7/Chapter 19/Dimensions.w"
if (binary) {
if (Kinds__FloatingPoint__uses_floating_point(KX)) {
if (Kinds__FloatingPoint__uses_floating_point(KY)) {
use_fp = TRUE; promote_X = FALSE; promote_Y = FALSE;
} else {
use_fp = TRUE; promote_X = FALSE; promote_Y = TRUE;
}
} else {
if (Kinds__FloatingPoint__uses_floating_point(KY)) {
use_fp = TRUE; promote_X = TRUE; promote_Y = FALSE;
} else {
use_fp = FALSE; promote_X = FALSE; promote_Y = FALSE;
}
}
} else {
if (Kinds__FloatingPoint__uses_floating_point(KX)) {
use_fp = TRUE; promote_X = FALSE; promote_Y = FALSE;
} else {
use_fp = FALSE; promote_X = FALSE; promote_Y = FALSE;
}
}
}
#line 1278 "inform7/Chapter 19/Dimensions.w"
;
if (reduce_modulo_1440) WRITE("(NUMBER_TY_to_TIME_TY(");
switch (op) {
case EQUALS_OPERATION:
{
#line 1486 "inform7/Chapter 19/Dimensions.w"
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1486 "inform7/Chapter 19/Dimensions.w"
;
WRITE(" = ");
if (promote_Y) Kinds__FloatingPoint__begin_flotation(OUT, KY);
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1489 "inform7/Chapter 19/Dimensions.w"
;
if (promote_Y) Kinds__FloatingPoint__end_flotation(OUT, KY);
}
#line 1281 "inform7/Chapter 19/Dimensions.w"
; break;
case PLUS_OPERATION:
{
#line 1336 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Plus(");
if (promote_X) Kinds__FloatingPoint__begin_flotation(OUT, KX);
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1339 "inform7/Chapter 19/Dimensions.w"
;
if (promote_X) Kinds__FloatingPoint__end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) Kinds__FloatingPoint__begin_flotation(OUT, KY);
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1343 "inform7/Chapter 19/Dimensions.w"
;
if (promote_Y) Kinds__FloatingPoint__end_flotation(OUT, KY);
WRITE(")");
} else {
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1347 "inform7/Chapter 19/Dimensions.w"
;
WRITE(" + ");
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1349 "inform7/Chapter 19/Dimensions.w"
;
}
}
#line 1282 "inform7/Chapter 19/Dimensions.w"
; break;
case MINUS_OPERATION:
{
#line 1355 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Minus(");
if (promote_X) Kinds__FloatingPoint__begin_flotation(OUT, KX);
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1358 "inform7/Chapter 19/Dimensions.w"
;
if (promote_X) Kinds__FloatingPoint__end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) Kinds__FloatingPoint__begin_flotation(OUT, KY);
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1362 "inform7/Chapter 19/Dimensions.w"
;
if (promote_Y) Kinds__FloatingPoint__end_flotation(OUT, KY);
WRITE(")");
} else {
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1366 "inform7/Chapter 19/Dimensions.w"
;
WRITE(" - ");
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1368 "inform7/Chapter 19/Dimensions.w"
;
}
}
#line 1283 "inform7/Chapter 19/Dimensions.w"
; break;
case TIMES_OPERATION:
{
#line 1374 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Times(");
if (promote_X) Kinds__FloatingPoint__begin_flotation(OUT, KX);
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1377 "inform7/Chapter 19/Dimensions.w"
;
if (promote_X) Kinds__FloatingPoint__end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) Kinds__FloatingPoint__begin_flotation(OUT, KY);
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1381 "inform7/Chapter 19/Dimensions.w"
;
if (promote_Y) Kinds__FloatingPoint__end_flotation(OUT, KY);
WRITE(")");
} else {
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1385 "inform7/Chapter 19/Dimensions.w"
;
WRITE(" * ");
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1387 "inform7/Chapter 19/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_multiplication(OUT, KX, KY);
}
}
#line 1284 "inform7/Chapter 19/Dimensions.w"
; break;
case DIVIDE_OPERATION:
{
#line 1394 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Divide(");
if (promote_X) Kinds__FloatingPoint__begin_flotation(OUT, KX);
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1397 "inform7/Chapter 19/Dimensions.w"
;
if (promote_X) Kinds__FloatingPoint__end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) Kinds__FloatingPoint__begin_flotation(OUT, KY);
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1401 "inform7/Chapter 19/Dimensions.w"
;
if (promote_Y) Kinds__FloatingPoint__end_flotation(OUT, KY);
WRITE(")");
} else {
WRITE("IntegerDivide(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1406 "inform7/Chapter 19/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_division(OUT, KX, KY);
WRITE(", ");
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1409 "inform7/Chapter 19/Dimensions.w"
;
WRITE(")");
}
}
#line 1285 "inform7/Chapter 19/Dimensions.w"
; break;
case REMAINDER_OPERATION:
{
#line 1416 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Remainder(");
if (promote_X) Kinds__FloatingPoint__begin_flotation(OUT, KX);
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1419 "inform7/Chapter 19/Dimensions.w"
;
if (promote_X) Kinds__FloatingPoint__end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) Kinds__FloatingPoint__begin_flotation(OUT, KY);
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1423 "inform7/Chapter 19/Dimensions.w"
;
if (promote_Y) Kinds__FloatingPoint__end_flotation(OUT, KY);
WRITE(")");
} else {
WRITE("IntegerRemainder(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1428 "inform7/Chapter 19/Dimensions.w"
;
WRITE(", ");
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1430 "inform7/Chapter 19/Dimensions.w"
;
WRITE(")");
}
}
#line 1286 "inform7/Chapter 19/Dimensions.w"
; break;
case APPROXIMATION_OPERATION:
{
#line 1437 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Approximate(");
if (promote_X) Kinds__FloatingPoint__begin_flotation(OUT, KX);
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1440 "inform7/Chapter 19/Dimensions.w"
;
if (promote_X) Kinds__FloatingPoint__end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) Kinds__FloatingPoint__begin_flotation(OUT, KY);
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1444 "inform7/Chapter 19/Dimensions.w"
;
if (promote_Y) Kinds__FloatingPoint__end_flotation(OUT, KY);
WRITE(")");
} else {
WRITE("RoundOffTime(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1449 "inform7/Chapter 19/Dimensions.w"
;
WRITE(", ");
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1451 "inform7/Chapter 19/Dimensions.w"
;
WRITE(")");
}
}
#line 1287 "inform7/Chapter 19/Dimensions.w"
; break;
case ROOT_OPERATION:
{
#line 1458 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Root(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1460 "inform7/Chapter 19/Dimensions.w"
;
WRITE(")");
} else {
WRITE("SquareRoot(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1464 "inform7/Chapter 19/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_root(OUT, KX, 2);
WRITE(")");
}
}
#line 1288 "inform7/Chapter 19/Dimensions.w"
; break;
case REALROOT_OPERATION: use_fp = TRUE;
{
#line 1458 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Root(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1460 "inform7/Chapter 19/Dimensions.w"
;
WRITE(")");
} else {
WRITE("SquareRoot(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1464 "inform7/Chapter 19/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_root(OUT, KX, 2);
WRITE(")");
}
}
#line 1289 "inform7/Chapter 19/Dimensions.w"
; break;
case CUBEROOT_OPERATION:
{
#line 1472 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Cube_Root(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1474 "inform7/Chapter 19/Dimensions.w"
;
WRITE(")");
} else {
WRITE("CubeRoot(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1478 "inform7/Chapter 19/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_root(OUT, KX, 3);
WRITE(")");
}
}
#line 1290 "inform7/Chapter 19/Dimensions.w"
; break;
case POWER_OPERATION:
{
#line 1510 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Pow(");
if (promote_X) Kinds__FloatingPoint__begin_flotation(OUT, KX);
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1513 "inform7/Chapter 19/Dimensions.w"
;
if (promote_X) Kinds__FloatingPoint__end_flotation(OUT, KX);
WRITE(", ");
if (promote_Y) Kinds__FloatingPoint__begin_flotation(OUT, KY);
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1517 "inform7/Chapter 19/Dimensions.w"
;
if (promote_Y) Kinds__FloatingPoint__end_flotation(OUT, KY);
WRITE(")");
} else {
int p = 0;
if (Y) p = Rvalues__to_int(Y);
else p = Rvalues__to_int(EY->leaf_constant);
if (p <= 0) Equations__enode_compilation_error(eqn, EY);
else {
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1526 "inform7/Chapter 19/Dimensions.w"
;
while (p > 1) {
WRITE(" * ");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1528 "inform7/Chapter 19/Dimensions.w"
;
Kinds__Dimensions__kind_rescale_multiplication(OUT, KX, KX);
p--;
}
}
}
}
#line 1291 "inform7/Chapter 19/Dimensions.w"
; break;
case UNARY_MINUS_OPERATION:
{
#line 1495 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
WRITE("REAL_NUMBER_TY_Negate(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1497 "inform7/Chapter 19/Dimensions.w"
;
WRITE(")");
} else {
WRITE("-(");
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1501 "inform7/Chapter 19/Dimensions.w"
;
WRITE(")");
}
}
#line 1292 "inform7/Chapter 19/Dimensions.w"
; break;
case IMPLICIT_APPLICATION_OPERATION:
{
#line 1538 "inform7/Chapter 19/Dimensions.w"
if (use_fp) {
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1539 "inform7/Chapter 19/Dimensions.w"
;
WRITE("(");
if (promote_Y) Kinds__FloatingPoint__begin_flotation(OUT, KY);
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1542 "inform7/Chapter 19/Dimensions.w"
;
if (promote_Y) Kinds__FloatingPoint__end_flotation(OUT, KY);
WRITE(")");
} else {
{
#line 1555 "inform7/Chapter 19/Dimensions.w"
if (X) Specifications__Compiler__compile_to_kind(OUT, X, KX); else Equations__enode_compile(OUT, eqn, EX);
}
#line 1546 "inform7/Chapter 19/Dimensions.w"
;
WRITE("(");
{
#line 1560 "inform7/Chapter 19/Dimensions.w"
if (Y) Specifications__Compiler__compile_to_kind(OUT, Y, KY); else Equations__enode_compile(OUT, eqn, EY);
}
#line 1548 "inform7/Chapter 19/Dimensions.w"
;
WRITE(")");
}
}
#line 1293 "inform7/Chapter 19/Dimensions.w"
; break;
default:
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"this doesn't seem to be an arithmetic operation",
"suggesting a problem with some inline definition.");
break;
}
if (reduce_modulo_1440) WRITE("))");
}
#line 27 "inform7/Chapter 19/Floating-Point Values.w"
generalised_kind Kinds__FloatingPoint__new_gk(kind *K) {
if (K == NULL) internal_error("can't generalise the null kind");
generalised_kind gK;
gK.valid_kind = K;
gK.promotion = 0;
return gK;
}
void Kinds__FloatingPoint__log_gk(generalised_kind gK) {
LOG("$u", gK.valid_kind);
if (gK.promotion == 1) { LOG("=>real"); }
if (gK.promotion == -1) { LOG("=>int"); }
}
kind *Kinds__FloatingPoint__underlying(generalised_kind gK) {
return gK.valid_kind;
}
int Kinds__FloatingPoint__is_real(generalised_kind gK) {
if (gK.promotion == 1) return TRUE;
if (Kinds__FloatingPoint__uses_floating_point(gK.valid_kind)) return TRUE;
return FALSE;
}
generalised_kind Kinds__FloatingPoint__to_integer(generalised_kind gK) {
if (Kinds__FloatingPoint__is_real(gK)) {
if (gK.promotion == 1) gK.promotion = 0;
else {
kind *K = Kinds__FloatingPoint__integer_equivalent(gK.valid_kind);
if (Kinds__FloatingPoint__uses_floating_point(K) == FALSE) gK.valid_kind = K;
else gK.promotion = -1;
}
}
if (Kinds__FloatingPoint__is_real(gK))
internal_error("gK inconsistent");
return gK;
}
generalised_kind Kinds__FloatingPoint__to_real(generalised_kind gK) {
if (Kinds__FloatingPoint__is_real(gK) == FALSE) {
if (gK.promotion == -1) gK.promotion = 0;
else {
kind *K = Kinds__FloatingPoint__real_equivalent(gK.valid_kind);
if (Kinds__FloatingPoint__uses_floating_point(K)) gK.valid_kind = K;
else gK.promotion = 1;
}
}
if (Kinds__FloatingPoint__is_real(gK) == FALSE)
internal_error("gK inconsistent");
return gK;
}
#line 82 "inform7/Chapter 19/Floating-Point Values.w"
void Kinds__FloatingPoint__begin_flotation(OUTPUT_STREAM, kind *K) {
if (Kinds__Behaviour__scale_factor(K) != 1) WRITE("REAL_NUMBER_TY_Divide(");
WRITE("NUMBER_TY_to_REAL_NUMBER_TY");
WRITE("(");
}
void Kinds__FloatingPoint__end_flotation(OUTPUT_STREAM, kind *K) {
WRITE(")");
if (Kinds__Behaviour__scale_factor(K) != 1)
WRITE(", NUMBER_TY_to_REAL_NUMBER_TY(%d))",
Kinds__Behaviour__scale_factor(K));
}
void Kinds__FloatingPoint__begin_deflotation(OUTPUT_STREAM, kind *K) {
WRITE("REAL_NUMBER_TY_to_NUMBER_TY(");
if (Kinds__Behaviour__scale_factor(K) != 1) WRITE("REAL_NUMBER_TY_Times(");
}
void Kinds__FloatingPoint__end_deflotation(OUTPUT_STREAM, kind *K) {
if (Kinds__Behaviour__scale_factor(K) != 1)
WRITE(", NUMBER_TY_to_REAL_NUMBER_TY(%d))",
Kinds__Behaviour__scale_factor(K));
WRITE(")");
}
int Kinds__FloatingPoint__uses_floating_point(kind *K) {
if (K == NULL) return FALSE;
return Kinds__Constructors__is_arithmetic_and_real(K->construct);
}
kind *Kinds__FloatingPoint__real_equivalent(kind *K) {
if (Kinds__Compare__eq(K, K_number)) return K_real_number;
return K;
}
kind *Kinds__FloatingPoint__integer_equivalent(kind *K) {
if (Kinds__Compare__eq(K, K_real_number)) return K_number;
return K;
}
#line 81 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__describe(OUTPUT_STREAM, scaling_transformation sc) {
WRITE("scaling: x units --> ");
if (sc.use_integer_scaling)
WRITE("%d x + %x stored at runtime (int)", sc.int_M, sc.int_O);
else
WRITE("%g x + %g stored at runtime (real)", sc.real_M, sc.real_O);
switch (sc.scaling_mode) {
case LP_SCALED_UP: WRITE(" (defined as benchmark * "); break;
case LP_SCALED_DOWN: WRITE(" (defined as benchmark / "); break;
case LP_SCALED_AT: WRITE(" (defined as scaled at "); break;
}
if (sc.use_integer_scaling) WRITE("%d)", sc.int_scalar);
else WRITE("%g)", sc.real_scalar);
}
#line 102 "inform7/Chapter 19/Scaled Arithmetic Values.w"
scaling_transformation Kinds__Scalings__new(int integer_valued,
int scaled, int int_s, double real_s, int offset, double real_offset) {
scaling_transformation sc;
sc.use_integer_scaling = integer_valued;
sc.int_O = 0; sc.real_O = 0.0;
if (integer_valued) sc.int_O = offset; else sc.real_O = (double) real_offset;
sc.int_M = 1; sc.real_M = 1.0;
sc.scaling_mode = scaled;
sc.int_scalar = int_s;
sc.real_scalar = real_s;
return sc;
}
#line 119 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__convert_to_real(scaling_transformation *sc) {
if (sc->use_integer_scaling) {
sc->real_O = (double) sc->int_O; sc->int_O = 0;
sc->real_M = (double) sc->int_M; sc->int_M = 1;
sc->real_scalar = (double) sc->int_scalar; sc->int_scalar = 1;
sc->use_integer_scaling = FALSE;
}
}
#line 136 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__determine_M(scaling_transformation *sc,
scaling_transformation *benchmark_sc,
int first, int equiv, int alt) {
int rescale_the_others_by_this = 1; /* in effect, don't */
if (first)
{
#line 157 "inform7/Chapter 19/Scaled Arithmetic Values.w"
if (((sc->int_scalar != 1) || (sc->real_scalar != 1.0)) &&
((sc->scaling_mode == LP_SCALED_UP) ||
(sc->scaling_mode == LP_SCALED_DOWN) ||
(equiv) ||
((sc->scaling_mode == LP_SCALED_AT) && (sc->use_integer_scaling == FALSE))))
Problems__Issue__sentence_problem(_p_(PM_LPCantScaleYet),
"this tries to scale up or down a value which so far has no point of "
"reference to scale from",
"which is impossible.");
sc->int_M = sc->int_scalar;
}
#line 140 "inform7/Chapter 19/Scaled Arithmetic Values.w"
else
{
#line 174 "inform7/Chapter 19/Scaled Arithmetic Values.w"
if (((sc->int_scalar != 1) || (sc->real_scalar != 1.0)) &&
((alt) && (sc->scaling_mode == LP_SCALED_AT)))
Problems__Issue__sentence_problem(_p_(PM_LPCantScaleTwice),
"this tries to specify the scaling for a kind of value whose "
"scaling is already established",
"which is impossible.");
if (equiv)
{
#line 195 "inform7/Chapter 19/Scaled Arithmetic Values.w"
if (sc->use_integer_scaling)
sc->int_M = sc->int_scalar;
else
sc->real_M = sc->real_scalar;
}
#line 182 "inform7/Chapter 19/Scaled Arithmetic Values.w"
else
{
#line 227 "inform7/Chapter 19/Scaled Arithmetic Values.w"
if (benchmark_sc == NULL) internal_error("no benchmark for comparison");
if (sc->scaling_mode == LP_SCALED_DOWN) {
if (sc->use_integer_scaling) {
int B = benchmark_sc->int_M;
int k = sc->int_scalar;
int g = Kinds__Dimensions__gcd(B, k);
sc->int_M = B/g;
rescale_the_others_by_this = k/g;
} else {
double B = benchmark_sc->real_M;
double k = sc->real_scalar;
sc->real_M = B/k;
}
} else if (sc->scaling_mode == LP_SCALED_UP) {
if (sc->use_integer_scaling) {
int B = benchmark_sc->int_M;
int k = sc->int_scalar;
sc->int_M = B*k;
} else {
double B = benchmark_sc->real_M;
double k = sc->real_scalar;
sc->real_M = B*k;
}
}
}
#line 184 "inform7/Chapter 19/Scaled Arithmetic Values.w"
;
}
#line 141 "inform7/Chapter 19/Scaled Arithmetic Values.w"
;
return rescale_the_others_by_this;
}
#line 262 "inform7/Chapter 19/Scaled Arithmetic Values.w"
scaling_transformation Kinds__Scalings__enlarge(scaling_transformation sc, int F) {
if (sc.use_integer_scaling) {
sc.int_M *= F;
} else {
sc.real_M *= F;
}
return sc;
}
scaling_transformation Kinds__Scalings__contract(scaling_transformation sc, int F,
int *loses_accuracy) {
*loses_accuracy = FALSE;
if (sc.use_integer_scaling) {
if (sc.int_M % F != 0) *loses_accuracy = TRUE;
sc.int_M /= F;
} else {
sc.real_M /= F;
}
return sc;
}
#line 288 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__compare(scaling_transformation A, scaling_transformation B) {
if (A.use_integer_scaling != B.use_integer_scaling)
internal_error("scalings incomparable");
if (A.use_integer_scaling) {
if (A.int_M > B.int_M) return 1;
if (A.int_M < B.int_M) return -1;
if (A.int_O > B.int_O) return 1;
if (A.int_O < B.int_O) return -1;
} else {
if (A.real_M > B.real_M) return 1;
if (A.real_M < B.real_M) return -1;
if (A.real_O > B.real_O) return 1;
if (A.real_O < B.real_O) return -1;
}
return 0;
}
#line 309 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__get_integer_multiplier(scaling_transformation sc) {
return sc.int_M;
}
#line 316 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__involves_scale_change(scaling_transformation sc) {
if (sc.int_M != 1) return TRUE;
if (sc.real_M != 1.0) return TRUE;
return FALSE;
}
#line 328 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__quantum(scaling_transformation sc) {
return (int) Kinds__Scalings__quanta_to_value(sc, 1);
}
double Kinds__Scalings__real_quantum(scaling_transformation sc) {
return Kinds__Scalings__real_quanta_to_value(sc, 1.0);
}
#line 340 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int Kinds__Scalings__quanta_to_value(scaling_transformation sc, int q) {
return q*sc.int_M + sc.int_O;
}
double Kinds__Scalings__real_quanta_to_value(scaling_transformation sc, double q) {
return q*sc.real_M + sc.real_O;
}
#line 360 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__value_to_quanta(int v, scaling_transformation sc, int *q, int *r) {
if (sc.use_integer_scaling == FALSE) internal_error("inversion unimplemented");
if (r) *r = (v - sc.int_O) % (sc.int_M);
if (q) *q = (v - sc.int_O) / (sc.int_M);
}
double Kinds__Scalings__real_value_to_quanta(double v, scaling_transformation sc) {
return (v - sc.real_O) / (sc.real_M);
}
#line 376 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_quanta_to_value(OUTPUT_STREAM, scaling_transformation sc,
char *V_var, int label) {
if (sc.use_integer_scaling) {
char offset_text[16]; sprintf(offset_text, "%d+x", sc.int_O);
Kinds__Scalings__compile_scale_and_add(OUT,
V_var, sc.int_M, offset_text, label);
} else {
if (sc.real_M != 1.0) {
WRITE("%s = REAL_NUMBER_TY_Times(%s, ", V_var, V_var);
Kinds__Scalings__I6_real_literal(OUT, sc.real_M);
WRITE(");\n");
}
if (sc.real_O != 0.0) {
WRITE("%s = REAL_NUMBER_TY_Plus(%s, ", V_var, V_var);
Kinds__Scalings__I6_real_literal(OUT, sc.real_O);
WRITE(");\n");
}
WRITE("if (REAL_NUMBER_TY_Nan(%s)) jump Failed_LP_%d;\n", V_var, label);
}
}
#line 413 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_scale_and_add(OUTPUT_STREAM, char *var,
int scale_factor, char *to_add, int label) {
if (scale_factor > 1) {
long long int max = 2147483647LL;
if (VirtualMachines__is_16_bit()) max = 32767LL;
WRITE("if (sgn == 1) {\n"); INDENT;
WRITE("if ((%s > %d) || ((%s == %d) && (%s > %d)))\n",
var, (int) (max/scale_factor), var, (int) (max/scale_factor),
to_add, (int) (max%scale_factor)); INDENT;
WRITE("jump Failed_LP_%d;\n", label);
OUTDENT; OUTDENT; WRITE("} else {\n"); INDENT;
max++;
WRITE("if ((%s > %d) || ((%s == %d) && (%s > %d)))\n",
var, (int) (max/scale_factor), var, (int) (max/scale_factor),
to_add, (int) (max%scale_factor)); INDENT;
WRITE("jump Failed_LP_%d;\n", label);
OUTDENT; OUTDENT; WRITE("}\n");
}
WRITE("%s = %d*%s + %s;\n", var, scale_factor, var, to_add);
}
#line 438 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_value_to_quanta(OUTPUT_STREAM, scaling_transformation sc,
char *V_var, char *R_var) {
if (sc.use_integer_scaling) {
if (sc.int_O != 0)
WRITE("%s = %s - %d;\n", V_var, V_var, sc.int_O);
if (sc.int_M != 1) {
if (R_var) WRITE("%s = %s %% %d;\n", R_var, V_var, sc.int_M);
WRITE("%s = %s/%d;\n", V_var, V_var, sc.int_M);
}
} else {
if (sc.int_M != 0.0) {
WRITE("%s = REAL_NUMBER_TY_Minus(%s, ", V_var, V_var);
Kinds__Scalings__I6_real_literal(OUT, sc.real_O);
WRITE(");\n");
}
if (sc.real_M != 1.0) {
WRITE("%s = REAL_NUMBER_TY_Divide(%s, ", V_var, V_var);
Kinds__Scalings__I6_real_literal(OUT, sc.real_M);
WRITE(");\n");
}
}
}
#line 467 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_threshold_test(OUTPUT_STREAM, scaling_transformation sc,
char *V_var, char *op) {
if (sc.use_integer_scaling) {
WRITE("NUMBER_TY_Abs(%s) %s %d", V_var, op, Kinds__Scalings__quantum(sc));
} else {
WRITE("REAL_NUMBER_TY_Compare(REAL_NUMBER_TY_Abs(%s), ", V_var);
Kinds__Scalings__I6_real_literal(OUT, Kinds__Scalings__real_quantum(sc));
WRITE(") %s 0", op);
}
}
#line 484 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__compile_print_in_quanta(OUTPUT_STREAM, scaling_transformation sc,
char *V_var, char *R_var, char *S_var) {
Kinds__Scalings__compile_value_to_quanta(OUT, sc, V_var, R_var);
if (sc.use_integer_scaling) {
WRITE("print value;\n");
WRITE("if (%s > 0) {\n", R_var); INDENT;
{
#line 509 "inform7/Chapter 19/Scaled Arithmetic Values.w"
WRITE("print \".\";\n");
int M = sc.int_M;
int cl10M = 1; while (M > cl10M) cl10M = cl10M*10;
WRITE("! M = %d, ceiling(log_10(M)) = %d\n", M, cl10M);
if (cl10M % M == 0)
{
#line 533 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int t = cl10M/M;
if (t != 1) WRITE("%s = %s*%d;\n", R_var, R_var, t);
WRITE("%s = %d;\n", S_var, cl10M);
WRITE("while ((%s %% 10 == 0) && (%s > 0)) {\n", R_var, R_var); INDENT;
WRITE("%s = %s/10;\n", R_var, R_var);
WRITE("%s = %s/10;\n", S_var, S_var);
OUTDENT; WRITE("}\n");
WRITE("while (%s < %s/10) {\n", R_var, S_var); INDENT;
WRITE("print \"0\";\n");
WRITE("%s = %s/10;\n", S_var, S_var);
OUTDENT; WRITE("}\n");
WRITE("print %s;\n", R_var);
}
#line 517 "inform7/Chapter 19/Scaled Arithmetic Values.w"
else
{
#line 553 "inform7/Chapter 19/Scaled Arithmetic Values.w"
int R = 1;
while (R<=M) {
R = R*10;
int g = Kinds__Dimensions__gcd(R, M);
WRITE("print ((%s*%d/%d)%%10 + 10)%%10;\n", R_var, (R/g), (M/g));
}
}
#line 519 "inform7/Chapter 19/Scaled Arithmetic Values.w"
;
}
#line 492 "inform7/Chapter 19/Scaled Arithmetic Values.w"
;
OUTDENT; WRITE("}\n");
} else {
WRITE("REAL_NUMBER_TY_Say(%s);", V_var);
}
}
#line 563 "inform7/Chapter 19/Scaled Arithmetic Values.w"
void Kinds__Scalings__I6_real_literal(OUTPUT_STREAM, double x) {
WRITE("$");
if (x > 0) WRITE("+");
WRITE("%g", x);
}
#line 64 "inform7/Chapter 19/Runtime Support for Kinds.w"
int Kinds__RunTime__weak_id(kind *K) {
if (K == NULL) return UNKNOWN_WEAK_ID;
return Kinds__Constructors__get_weak_ID(Kinds__get_construct(K));
}
#line 73 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_weak_id(OUTPUT_STREAM, kind *K) {
if (K == NULL) { WRITE("UNKNOWN_TY"); return; }
kind_constructor *con = Kinds__get_construct(K);
char *sn = Kinds__Constructors__name_in_template_code(con);
if (sn[0]) WRITE("%s", sn); else WRITE("%d", Kinds__RunTime__weak_id(K));
}
#line 121 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_strong_id(OUTPUT_STREAM, kind *K) {
runtime_kind_structure *rks = Kinds__RunTime__get_rks(K);
if (rks) {
WRITE("%s", rks->rks_identifier);
} else {
Kinds__RunTime__compile_weak_id(OUT, K);
}
}
#line 142 "inform7/Chapter 19/Runtime Support for Kinds.w"
runtime_kind_structure *Kinds__RunTime__get_rks(kind *K) {
kind *divert = Kinds__Behaviour__stored_as(K);
if (divert) K = divert;
runtime_kind_structure *rks = NULL;
if (K) {
int arity = Kinds__arity_of_constructor(K);
if (arity > 0) {
if (Kinds__get_construct(K) != CON_TUPLE_ENTRY)
{
#line 177 "inform7/Chapter 19/Runtime Support for Kinds.w"
LOOP_OVER(rks, runtime_kind_structure)
if (Kinds__Compare__eq(K, rks->kind_described))
break;
if (rks == NULL)
{
#line 187 "inform7/Chapter 19/Runtime Support for Kinds.w"
rks = CREATE(runtime_kind_structure);
rks->kind_described = K;
rks->make_default = FALSE;
rks->default_requested_here = NULL;
char *p = rks->rks_identifier;
sprintf(p, "KD%d_", rks->allocation_id);
TEMPORARY_STREAM;
Kinds__Textual__write(TEMP, K);
int i = Platform__strlen(p), j=0;
char *written = STREAM_TEXT(TEMP);
for (; (i<30) && (written[j]); j++) {
if ((written[j] == ',') || (written[j] == '(') || (written[j] == ')'))
continue;
if ((written[j] == '-') || (written[j+1] == '>')) {
if (i == 30) continue;
p[i] = 't'; p[i+1] = 'o'; i+=2; j++; continue;
}
p[i++] = written[j];
}
p[i] = 0;
CLOSE_TEMPORARY_STREAM;
Identifiers__purify(p);
}
#line 180 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
}
#line 150 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
switch (arity) {
case 1: {
kind *k = Kinds__unary_construction_material(K);
Kinds__RunTime__get_rks(k);
break;
}
case 2: {
kind *k = NULL, *l = NULL;
Kinds__binary_construction_material(K, &k, &l);
Kinds__RunTime__get_rks(k);
Kinds__RunTime__get_rks(l);
break;
}
}
}
}
return rks;
}
#line 214 "inform7/Chapter 19/Runtime Support for Kinds.w"
int Kinds__RunTime__compile_default_value(OUTPUT_STREAM, kind *K) {
Kinds__RunTime__precompile_default_value(K);
runtime_kind_structure *rks = Kinds__RunTime__get_rks(K);
if (rks == NULL) return FALSE;
WRITE("Default_Value_%d", rks->allocation_id);
return TRUE;
}
int Kinds__RunTime__precompile_default_value(kind *K) {
runtime_kind_structure *rks = Kinds__RunTime__get_rks(K);
if (rks == NULL) return FALSE;
rks->make_default = TRUE;
if (rks->default_requested_here == NULL) rks->default_requested_here = current_sentence;
return TRUE;
}
#line 242 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_structures(OUTPUT_STREAM) {
runtime_kind_structure *rks;
LOOP_OVER(rks, runtime_kind_structure) {
kind *K = rks->kind_described;
int id = rks->allocation_id;
{
#line 256 "inform7/Chapter 19/Runtime Support for Kinds.w"
WRITE("Array %s --> ! ", rks->rks_identifier);
Kinds__Textual__write(OUT, K);
WRITE("\n");
INDENT;
Kinds__RunTime__compile_weak_id(OUT, K); WRITE(" ");
{
#line 267 "inform7/Chapter 19/Runtime Support for Kinds.w"
int arity = Kinds__arity_of_constructor(K);
if (Kinds__get_construct(K) == CON_phrase) {
arity--;
kind *X = NULL, *result = NULL;
Kinds__binary_construction_material(K, &X, &result);
{
#line 304 "inform7/Chapter 19/Runtime Support for Kinds.w"
while (Kinds__get_construct(X) == CON_TUPLE_ENTRY) {
arity++;
Kinds__binary_construction_material(X, NULL, &X);
}
WRITE("%d ", arity);
X = Kinds__unary_construction_material(K);
while (Kinds__get_construct(X) == CON_TUPLE_ENTRY) {
arity++;
kind *term = NULL;
Kinds__binary_construction_material(X, &term, &X);
Kinds__RunTime__compile_strong_id(OUT, term); WRITE(" ");
}
}
#line 272 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
WRITE(" "); Kinds__RunTime__compile_strong_id(OUT, result);
} else if (Kinds__get_construct(K) == CON_combination) {
arity--;
kind *X = Kinds__unary_construction_material(K);
{
#line 304 "inform7/Chapter 19/Runtime Support for Kinds.w"
while (Kinds__get_construct(X) == CON_TUPLE_ENTRY) {
arity++;
Kinds__binary_construction_material(X, NULL, &X);
}
WRITE("%d ", arity);
X = Kinds__unary_construction_material(K);
while (Kinds__get_construct(X) == CON_TUPLE_ENTRY) {
arity++;
kind *term = NULL;
Kinds__binary_construction_material(X, &term, &X);
Kinds__RunTime__compile_strong_id(OUT, term); WRITE(" ");
}
}
#line 277 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
} else {
{
#line 285 "inform7/Chapter 19/Runtime Support for Kinds.w"
WRITE("%d", arity);
switch (arity) {
case 1: {
kind *X = Kinds__unary_construction_material(K);
WRITE(" "); Kinds__RunTime__compile_strong_id(OUT, X);
break;
}
case 2: {
kind *X = NULL, *Y = NULL;
Kinds__binary_construction_material(K, &X, &Y);
WRITE(" "); Kinds__RunTime__compile_strong_id(OUT, X);
WRITE(" "); Kinds__RunTime__compile_strong_id(OUT, Y);
break;
}
}
}
#line 279 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
}
}
#line 261 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
OUTDENT; WRITE(";\n");
}
#line 247 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
if (rks->make_default)
{
#line 320 "inform7/Chapter 19/Runtime Support for Kinds.w"
char identifier[32];
sprintf(identifier, "Default_Value_%d", id);
current_sentence = rks->default_requested_here;
if (Kinds__get_construct(K) == CON_phrase) {
Phrases__Constants__compile_default_closure(OUT, identifier, K);
} else if (Kinds__get_construct(K) == CON_relation) {
Relations__compile_default_relation(OUT, identifier, K);
} else if (Kinds__get_construct(K) == CON_list_of) {
Lists__compile_default_list(OUT, identifier, K);
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"While working on '%1', I needed to be able to make a default value "
"for the kind '%2', but there's no obvious way to make one.");
Problems__issue_problem_end();
}
}
#line 248 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
}
{
#line 342 "inform7/Chapter 19/Runtime Support for Kinds.w"
OUT = Routines__begin(OUT, "DefaultValueFinder");
LocalVariables__add_named_call("K");
runtime_kind_structure *rks;
LOOP_OVER(rks, runtime_kind_structure) {
kind *K = rks->kind_described;
if (rks->make_default) {
WRITE("if (K == ");
Kinds__RunTime__compile_strong_id(OUT, K);
WRITE(") return Default_Value_%d;\n", rks->allocation_id);
}
}
WRITE("return 0;\n");
OUT = Routines__end(OUT);
}
#line 250 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
}
#line 365 "inform7/Chapter 19/Runtime Support for Kinds.w"
int total_heap_allocation = 0;
void Kinds__RunTime__ensure_basic_heap_present(void) {
total_heap_allocation += 256; /* enough for the initial free-space block */
}
#line 376 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_heap_allocator(OUTPUT_STREAM) {
{
#line 390 "inform7/Chapter 19/Runtime Support for Kinds.w"
int max_heap = 1;
if (total_heap_allocation < UseOptions__get_dynamic_memory_allocation())
total_heap_allocation = UseOptions__get_dynamic_memory_allocation();
while (max_heap < total_heap_allocation) max_heap = max_heap*2;
WRITE("#ifdef TARGET_ZCODE;\n");
WRITE("Constant MEMORY_HEAP_SIZE = %d;\n", max_heap);
WRITE("#ifnot;\n");
WRITE("Constant MEMORY_HEAP_SIZE = %d;\n", 4*max_heap);
WRITE("#endif;\n");
LOG("Providing for a total heap of %d, given requirement of %d\n",
max_heap, total_heap_allocation);
}
#line 377 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
}
#line 405 "inform7/Chapter 19/Runtime Support for Kinds.w"
text_stream BCON_struct;
text_stream *BCON = NULL;
int block_constant_counter = 0;
text_stream *Kinds__RunTime__begin_block_constant(OUTPUT_STREAM, kind *K) {
if (BCON == NULL) {
BCON = &BCON_struct;
if (STREAM_OPEN_IN_MEMORY(BCON) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for names stream");
}
char block_constant_id[32];
sprintf(block_constant_id, "BC_%d", block_constant_counter++);
WRITE("%s", block_constant_id);
WRITE_TO(BCON, "Array %s --> ", block_constant_id);
return BCON;
}
void Kinds__RunTime__end_block_constant(kind *K) {
WRITE_TO(BCON, ";\n");
}
#line 429 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_block_constants(OUTPUT_STREAM) {
if (BCON) {
STREAM_COPY(OUT, BCON);
STREAM_CLOSE(BCON);
}
}
#line 446 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_heap_allocation(OUTPUT_STREAM, kind *K, int multiplier,
int stack_offset) {
if (Kinds__Behaviour__uses_pointer_values(K) == FALSE)
internal_error("unable to allocate heap storage for this kind of value");
if (Kinds__Behaviour__get_heap_size_estimate(K) == 0)
internal_error("no heap storage estimate for this kind of value");
total_heap_allocation += (Kinds__Behaviour__get_heap_size_estimate(K) + 8)*multiplier;
if (stack_offset >= 0) WRITE("BlkValueCreateOnStack(%d, ", stack_offset);
else WRITE("BlkValueCreate(");
Kinds__RunTime__compile_strong_id(OUT, K);
if (Kinds__get_construct(K) == CON_relation)
Kinds__RunTime__precompile_default_value(K);
WRITE(")");
}
#line 472 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_block_value_header(OUTPUT_STREAM, kind *K,
int individual, int size) {
if (individual == FALSE) WRITE("0 ");
int n = 0, c = 1, w = 4;
if (VirtualMachines__is_16_bit()) w = 2;
while (c < (size + 3)*w) { n++; c = c*2; }
int flags = BLK_FLAG_RESIDENT + BLK_FLAG_WORD;
if (Kinds__get_construct(K) == CON_list_of) flags += BLK_FLAG_TRUNCMULT;
if (Kinds__get_construct(K) == CON_relation) flags += BLK_FLAG_MULTIPLE;
if (VirtualMachines__is_16_bit())
WRITE("(%d) ", 0x100*n + flags);
else
WRITE("(%d) ", 0x1000000*n + 0x10000*flags);
Kinds__RunTime__compile_weak_id(OUT, K);
WRITE(" ");
WRITE("MAX_POSITIVE_NUMBER ");
}
#line 495 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__compile_data_type_support_routines(OUTPUT_STREAM) {
kind *K;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__Compare__lt(K, K_object)) continue;
char *printing_rule_name = Kinds__Behaviour__get_name_of_printing_rule(K);
if (Kinds__Behaviour__stored_as(K) == NULL)
if (Kinds__Behaviour__is_an_enumeration(K)) {
{
#line 555 "inform7/Chapter 19/Runtime Support for Kinds.w"
OUT = Routines__begin(OUT, printing_rule_name);
LocalVariables__add_named_call("value");
WRITE("switch(value) {\n"); INDENT;
instance *I;
LOOP_OVER_INSTANCES(I, K) {
WRITE("%s: print \"", Instances__identifier(I));
wording NW = Instances__get_name_in_play(I, FALSE);
LOOP_THROUGH_WORDING(k, NW) {
CompiledText__from_ISO_string(OUT, Lexer__word_raw_text(k), 0);
if (k < Wordings__last_wn(NW)) WRITE(" ");
}
WRITE("\";\n");
}
/* this default case should never be needed, unless the user has blundered at the I6 level: */
wording W = Kinds__Behaviour__get_name(K, FALSE);
WRITE("default: print \"<illegal ");
if (Wordings__nonempty(W)) Wordings__to_stream(OUT, W); else WRITE("value");
WRITE(">\";\n");
OUTDENT; WRITE("}\n");
OUT = Routines__end(OUT);
}
#line 502 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
{
#line 591 "inform7/Chapter 19/Runtime Support for Kinds.w"
int j = Kinds__Behaviour__get_highest_valid_value_as_integer(K);
char rname[32];
sprintf(rname, "A_%s", printing_rule_name);
OUT = Routines__begin(OUT, rname);
LocalVariables__add_named_call("value");
WRITE("return (value %% %d)+1;\n", j);
OUT = Routines__end(OUT);
sprintf(rname, "B_%s", printing_rule_name);
OUT = Routines__begin(OUT, rname);
LocalVariables__add_named_call("value");
WRITE("return ((value+%d) %% %d)+1;\n", j-2, j);
OUT = Routines__end(OUT);
}
#line 503 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
{
#line 615 "inform7/Chapter 19/Runtime Support for Kinds.w"
char rname[32];
sprintf(rname, "R_%s", printing_rule_name);
OUT = Routines__begin(OUT, rname);
LocalVariables__add_named_call("a");
LocalVariables__add_named_call("b");
if (Kinds__Behaviour__is_quasinumerical(K))
WRITE("if (a == 0 && b == 0) return (random(MAX_POSITIVE_NUMBER));\n");
else
WRITE("if (a == 0 && b == 0) return (random(%d));\n",
Kinds__Behaviour__get_highest_valid_value_as_integer(K));
WRITE("if (a == b) return b;\n");
WRITE("if (a > b) return b+(random(MAX_POSITIVE_NUMBER) %% (a-b+1));\n");
WRITE("return a+(random(MAX_POSITIVE_NUMBER) %% (b-a+1));\n");
OUT = Routines__end(OUT);
}
#line 504 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
}
}
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__Behaviour__is_built_in(K)) continue;
if (Kinds__Compare__lt(K, K_object)) continue;
char *printing_rule_name = Kinds__Behaviour__get_name_of_printing_rule(K);
if (Kinds__Behaviour__is_an_enumeration(K)) continue;
if (Kinds__Behaviour__stored_as(K) == NULL) {
if (Kinds__Behaviour__is_quasinumerical(K)) {
{
#line 542 "inform7/Chapter 19/Runtime Support for Kinds.w"
OUT = Routines__begin(OUT, printing_rule_name);
LocalVariables__add_named_call("value");
if (Kinds__Behaviour__list_of_literal_forms(K))
LiteralPatterns__printing_routine(OUT,
Kinds__Behaviour__list_of_literal_forms(K));
else {
WRITE(";\n"); INDENT; WRITE("print value;\n");
}
OUT = Routines__end(OUT);
}
#line 514 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
{
#line 615 "inform7/Chapter 19/Runtime Support for Kinds.w"
char rname[32];
sprintf(rname, "R_%s", printing_rule_name);
OUT = Routines__begin(OUT, rname);
LocalVariables__add_named_call("a");
LocalVariables__add_named_call("b");
if (Kinds__Behaviour__is_quasinumerical(K))
WRITE("if (a == 0 && b == 0) return (random(MAX_POSITIVE_NUMBER));\n");
else
WRITE("if (a == 0 && b == 0) return (random(%d));\n",
Kinds__Behaviour__get_highest_valid_value_as_integer(K));
WRITE("if (a == b) return b;\n");
WRITE("if (a > b) return b+(random(MAX_POSITIVE_NUMBER) %% (a-b+1));\n");
WRITE("return a+(random(MAX_POSITIVE_NUMBER) %% (b-a+1));\n");
OUT = Routines__end(OUT);
}
#line 515 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
} else {
{
#line 531 "inform7/Chapter 19/Runtime Support for Kinds.w"
OUT = Routines__begin(OUT, printing_rule_name);
LocalVariables__add_named_call("value");
WRITE("! weak kind ID: %d\n", printing_rule_name, Kinds__RunTime__weak_id(K));
WRITE("print value;\n");
OUT = Routines__end(OUT);
}
#line 517 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
}
}
}
{
#line 635 "inform7/Chapter 19/Runtime Support for Kinds.w"
{
#line 647 "inform7/Chapter 19/Runtime Support for Kinds.w"
OUT = Routines__begin(OUT, "PrintKindValuePair");
LocalVariables__add_named_call("k");
LocalVariables__add_named_call("v");
WRITE("k = KindAtomic(k);\n");
WRITE(" switch(k) {\n"); INDENT;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__Compare__lt(K, K_object)) continue;
WRITE("%d: print (%s) v;\n",
Kinds__RunTime__weak_id(K),
Kinds__Behaviour__get_name_of_printing_rule(K));
}
WRITE("default: print v;\n");
OUTDENT; WRITE("}\n");
OUT = Routines__end(OUT);
}
#line 635 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
{
#line 667 "inform7/Chapter 19/Runtime Support for Kinds.w"
OUT = Routines__begin(OUT, "DefaultValueOfKOV");
LocalVariables__add_named_call("sk");
LocalVariables__add_internal_local_c("k", "weak kind ID");
WRITE("k = KindAtomic(sk);\n");
WRITE("switch(k) {\n"); INDENT;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__Compare__lt(K, K_object)) continue;
if (Kinds__Behaviour__definite(K)) {
WRITE("%d: return ", Kinds__RunTime__weak_id(K));
if (Kinds__Behaviour__uses_pointer_values(K))
WRITE("BlkValueCreate(sk)");
else
Kinds__Behaviour__compile_default_value(OUT, K, EMPTY_WORDING, "list entry");
WRITE(";\n");
}
}
WRITE("default: return 0;\n");
OUTDENT; WRITE("}\n");
OUT = Routines__end(OUT);
}
#line 636 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
{
#line 696 "inform7/Chapter 19/Runtime Support for Kinds.w"
OUT = Routines__begin(OUT, "KOVComparisonFunction");
LocalVariables__add_named_call("k");
WRITE("k = KindAtomic(k);\n");
WRITE("switch(k) {\n"); INDENT;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__Compare__lt(K, K_object)) continue;
if (Kinds__Behaviour__definite(K)) {
if (Kinds__Behaviour__uses_signed_comparisons(K) == FALSE)
WRITE("%d: return %s;\n",
Kinds__RunTime__weak_id(K),
Kinds__Behaviour__get_comparison_routine(K));
}
}
WRITE("default: return 0;\n");
OUTDENT; WRITE("}\n");
OUT = Routines__end(OUT);
}
#line 637 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
{
#line 716 "inform7/Chapter 19/Runtime Support for Kinds.w"
OUT = Routines__begin(OUT, "KOVDomainSize");
LocalVariables__add_named_call("k");
WRITE("k = KindAtomic(k);\n");
WRITE("switch(k) {\n"); INDENT;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__Compare__lt(K, K_object)) continue;
if (Kinds__Behaviour__is_an_enumeration(K))
WRITE("%d: return %d;\n", Kinds__RunTime__weak_id(K),
Kinds__Behaviour__get_highest_valid_value_as_integer(K));
}
WRITE("default: return 0;\n");
OUTDENT; WRITE("}\n");
OUT = Routines__end(OUT);
}
#line 638 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
{
#line 734 "inform7/Chapter 19/Runtime Support for Kinds.w"
OUT = Routines__begin(OUT, "KOVIsBlockValue");
LocalVariables__add_named_call("k");
WRITE("k = KindAtomic(k);\n");
WRITE("if (k == ");
int j = 0;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__Compare__lt(K, K_object)) continue;
if (Kinds__Behaviour__uses_pointer_values(K)) {
if (j++ > 0) WRITE(" or ");
WRITE("%d", Kinds__RunTime__weak_id(K));
}
}
WRITE(") rtrue;\n");
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
}
#line 639 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
{
#line 755 "inform7/Chapter 19/Runtime Support for Kinds.w"
OUT = Routines__begin(OUT, "KOVSupportFunction");
LocalVariables__add_named_call("k");
LocalVariables__add_named_call("fail");
WRITE("k = KindAtomic(k);\n");
WRITE("switch(k) {\n"); INDENT;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__Behaviour__uses_pointer_values(K)) {
WRITE("%d: return ", Kinds__RunTime__weak_id(K));
Kinds__Behaviour__write_support_routine_name(OUT, K);
WRITE(";\n");
}
}
OUTDENT; WRITE("}\n");
WRITE("if (fail) BlkValueError(fail);\n");
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
}
#line 640 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
}
#line 522 "inform7/Chapter 19/Runtime Support for Kinds.w"
;
}
#line 777 "inform7/Chapter 19/Runtime Support for Kinds.w"
void Kinds__RunTime__I7_Kind_Name_routine(OUTPUT_STREAM) {
kind *K;
OUT = Routines__begin(OUT, "I7_Kind_Name");
LocalVariables__add_named_call("k");
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__Compare__lt(K, K_object)) {
wording W = Kinds__Behaviour__get_name(K, FALSE);
WRITE("if (k == %s) print \"", Kinds__Behaviour__I6_classname(K));
Wordings__to_stream_raw(OUT, W);
WRITE("\";\n");
}
}
OUT = Routines__end(OUT);
}
#line 25 "inform7/Chapter 19/Kinds Index.w"
void Kinds__Index__index_kinds(int pass) {
int priority;
if (pass == 1) {
INDEX("<p></p>");
tabulating_kinds_index = TRUE;
HTML__begin_wide_html_table(ifl);
{
#line 111 "inform7/Chapter 19/Kinds Index.w"
INDEX("<tr bgcolor=\"#888\"><td height=\"1\" colspan=\"5\" cellpadding=\"0\"></td></tr>");
}
#line 31 "inform7/Chapter 19/Kinds Index.w"
;
{
#line 89 "inform7/Chapter 19/Kinds Index.w"
HTML__first_html_column_nowrap(ifl, 0, "#e0e0e0");
INDEX("<b>basic kinds</b>");
Kinds__Index__index_kind_col_head("default value", "default");
Kinds__Index__index_kind_col_head("repeat", "repeat");
Kinds__Index__index_kind_col_head("props", "props");
Kinds__Index__index_kind_col_head("under", "under");
HTML__end_html_row(ifl);
}
#line 32 "inform7/Chapter 19/Kinds Index.w"
;
{
#line 111 "inform7/Chapter 19/Kinds Index.w"
INDEX("<tr bgcolor=\"#888\"><td height=\"1\" colspan=\"5\" cellpadding=\"0\"></td></tr>");
}
#line 33 "inform7/Chapter 19/Kinds Index.w"
;
{
#line 133 "inform7/Chapter 19/Kinds Index.w"
INDEX("<tr style=\"display:none\" id=\"default\"><td colspan=\"5\">"
"The <b>default value</b> is used when we make something like "
"a variable but don't tell Inform what its value is. For instance, if "
"we write 'Zero hour is a time that varies', but don't tell Inform "
"anything specific like 'Zero hour is 11:21 PM.', then Inform uses "
"the value in the table above to decide what it will be. "
"The same applies if we create a property (for instance, 'A person "
"has a number called lucky number.'). Kinds of value not included "
"in the table cannot be used in variables and properties.<hr></td></tr>");
INDEX("<tr style=\"display:none\" id=\"repeat\"><td colspan=\"5\">"
"A tick for <b>repeat</b> means that it's possible to "
"repeat through values of this kind. For instance, 'repeat with T "
"running through times:' is allowed, but 'repeat with N running "
"through numbers:' is not - there are too many numbers for this to "
"make sense. A tick here also means it's possible to form lists such "
"as 'list of rulebooks', or to count the 'number of scenes'.<hr></td></tr>");
INDEX("<tr style=\"display:none\" id=\"props\"><td colspan=\"5\">"
"A tick for <b>props</b> means that values of this "
"kind can have properties. For instance, 'A scene can be thrilling or "
"dull.' makes an either/or property of a scene, but 'A number can be "
"nice or nasty.' is not allowed because it would cost too much storage "
"space. (Of course 'Definition:' can always be used to make adjectives "
"applying to numbers; it's only properties which have storage "
"worries.)<hr></td></tr>");
INDEX("<tr style=\"display:none\" id=\"under\"><td colspan=\"5\">"
"A tick for <b>under</b> means that it's possible "
"to understand values of this kind. For instance, 'Understand \"award "
"[number]\" as awarding.' might be allowed, if awarding were an action "
"applying to a number, but 'Understand \"run [rule]\" as rule-running.' "
"is not allowed - there are so many rules with such long names that "
"Inform doesn't add them to its vocabulary during play.<hr></td></tr>");
}
#line 34 "inform7/Chapter 19/Kinds Index.w"
;
}
for (priority = 1; priority <= LOWEST_INDEX_PRIORITY; priority++) {
kind *K;
LOOP_OVER_BASE_KINDS(K) {
if (Kinds__Compare__lt(K, K_object)) continue;
if (priority == Kinds__Behaviour__get_index_priority(K)) {
if ((priority == 8) || (Kinds__Behaviour__definite(K))) {
switch (pass) {
case 1:
{
#line 116 "inform7/Chapter 19/Kinds Index.w"
char *repeat = "cross", *props = "cross", *under = "cross";
int shaded = FALSE;
if ((Kinds__Behaviour__get_highest_valid_value_as_integer(K) == 0) &&
(Kinds__Behaviour__indexed_grey_if_empty(K)))
shaded = TRUE;
if (Kinds__Behaviour__compile_domain_possible(K)) repeat = "tick";
if (Kinds__Behaviour__has_properties(K)) props = "tick";
if (Kinds__Behaviour__offers_I6_GPR(K)) under = "tick";
Kinds__Index__begin_chart_row();
Kinds__Index__index_kind_name_cell(shaded, K);
if (priority == 8) { repeat = NULL; props = NULL; under = NULL; }
Kinds__Index__end_chart_row(shaded, K, repeat, props, under);
}
#line 44 "inform7/Chapter 19/Kinds Index.w"
; break;
case 2:
{
#line 168 "inform7/Chapter 19/Kinds Index.w"
HTML__open_para(ifl, 1, "halftight");
Index__anchor_numbered(Kinds__get_construct(K)->allocation_id); /* ...the anchor to which the grey icon in the table led */
INDEX("<b>"); Kinds__Index__index_kind(K, FALSE, TRUE); INDEX("</b>");
INDEX(" (<i>plural</i> "); Kinds__Index__index_kind(K, TRUE, FALSE); INDEX(")");
if (Kinds__Behaviour__get_documentation_reference(K))
Index__DocReferences__link(Kinds__Behaviour__get_documentation_reference(K)); /* blue help icon, if any */
INDEX("</p>");
if (Kinds__is_proper_constructor(K)) {
HTML__open_para(ifl, 1, "tight");
int i, a = Kinds__Constructors__arity(Kinds__get_construct(K));
if ((a == 2) &&
(Kinds__Constructors__variance(Kinds__get_construct(K), 0) ==
Kinds__Constructors__variance(Kinds__get_construct(K), 1)))
a = 1;
INDEX("<i>");
for (i=0; i<a; i++) {
if (i > 0) INDEX(", ");
if (Kinds__Constructors__variance(Kinds__get_construct(K), i) > 0)
INDEX("covariant");
else
INDEX("contravariant");
if (a > 1) INDEX(" in %c", 'K'+i);
}
INDEX("&nbsp;<a href=#contra><img border=0 src=inform:/doc_images/shelp.png></a>");
INDEX("</i></p>");
}
}
#line 46 "inform7/Chapter 19/Kinds Index.w"
;
HTML__open_para(ifl, 1, "tight");
{
#line 206 "inform7/Chapter 19/Kinds Index.w"
int f = FALSE;
INDEX("<i>Matches:</i> ");
kind *K2;
LOOP_OVER_BASE_KINDS(K2) {
if ((Kinds__Behaviour__is_kind_of_kind(K2)) &&
(Kinds__Compare__le(K, K2)) &&
(Kinds__Compare__eq(K2, K_word_value) == FALSE) &&
(Kinds__Compare__eq(K2, K_pointer_value) == FALSE)) {
if (f) INDEX(", ");
Kinds__Index__index_kind(K2, FALSE, TRUE);
f = TRUE;
}
}
INDEX("<br>");
}
#line 48 "inform7/Chapter 19/Kinds Index.w"
;
{
#line 233 "inform7/Chapter 19/Kinds Index.w"
char *explanation = Kinds__Behaviour__get_specification_text(K);
if (explanation) INDEX("%s<br>\n", explanation);
World__Inferences__index(Kinds__Behaviour__as_subject(K), FALSE);
}
#line 49 "inform7/Chapter 19/Kinds Index.w"
;
{
#line 198 "inform7/Chapter 19/Kinds Index.w"
if (Kinds__Behaviour__list_of_literal_forms(K)) {
LiteralPatterns__index_all(K);
INDEX("<br>");
}
}
#line 50 "inform7/Chapter 19/Kinds Index.w"
;
{
#line 225 "inform7/Chapter 19/Kinds Index.w"
if (Kinds__Behaviour__is_an_enumeration(K)) {
INDEX("</p>");
Data__Objects__index_instances(K, 1);
}
}
#line 51 "inform7/Chapter 19/Kinds Index.w"
;
INDEX("</p>\n"); break;
}
if (Kinds__Compare__eq(K, K_object))
{
#line 81 "inform7/Chapter 19/Kinds Index.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__eq(Kinds__Compare__super(K), K_object))
Data__Objects__index(NULL, K, 2, (pass == 1)?FALSE:TRUE);
}
#line 54 "inform7/Chapter 19/Kinds Index.w"
;
}
}
}
if ((priority == 1) || (priority == 6) || (priority == 7)) {
if (pass == 1) {
{
#line 111 "inform7/Chapter 19/Kinds Index.w"
INDEX("<tr bgcolor=\"#888\"><td height=\"1\" colspan=\"5\" cellpadding=\"0\"></td></tr>");
}
#line 60 "inform7/Chapter 19/Kinds Index.w"
;
if (priority == 7) {
{
#line 100 "inform7/Chapter 19/Kinds Index.w"
HTML__first_html_column_nowrap(ifl, 0, "#e0e0e0");
INDEX("<b>making new kinds from old</b>");
Kinds__Index__index_kind_col_head("default value", "default");
Kinds__Index__index_kind_col_head("", NULL);
Kinds__Index__index_kind_col_head("", NULL);
Kinds__Index__index_kind_col_head("", NULL);
HTML__end_html_row(ifl);
}
#line 62 "inform7/Chapter 19/Kinds Index.w"
;
{
#line 111 "inform7/Chapter 19/Kinds Index.w"
INDEX("<tr bgcolor=\"#888\"><td height=\"1\" colspan=\"5\" cellpadding=\"0\"></td></tr>");
}
#line 63 "inform7/Chapter 19/Kinds Index.w"
;
}
} else INDEX("<hr>");
}
}
if (pass == 1) {
{
#line 111 "inform7/Chapter 19/Kinds Index.w"
INDEX("<tr bgcolor=\"#888\"><td height=\"1\" colspan=\"5\" cellpadding=\"0\"></td></tr>");
}
#line 70 "inform7/Chapter 19/Kinds Index.w"
;
HTML__end_html_table(ifl);
tabulating_kinds_index = FALSE;
} else {
{
#line 240 "inform7/Chapter 19/Kinds Index.w"
INDEX("<p><a name=contra>"
"<small><b>Covariance</b> means that if K is a kind of L, then something "
"you make from K can be used as the same thing made from L. For example, "
"a list of doors can be used as a list of things, because 'list of K' is "
"covariant. <b>Contravariance</b> means it works the other way round. "
"For example, an activity on things can be used as an activity on doors, "
"but not vice versa, because 'activity of K' is contravariant.</small></p>");
}
#line 74 "inform7/Chapter 19/Kinds Index.w"
;
}
}
#line 253 "inform7/Chapter 19/Kinds Index.w"
void Kinds__Index__index_kind_col_head(char *name, char *anchor) {
HTML__next_html_column_nowrap(ifl, 0);
INDEX("<i>%s</i>&nbsp;", name);
if (anchor)
INDEX("<a href=\"#\" onClick=\"showBasic('%s');\">"
"<img border=0 src=inform:/doc_images/shelp.png></a>", anchor);
}
#line 265 "inform7/Chapter 19/Kinds Index.w"
int striper = FALSE;
void Kinds__Index__begin_chart_row(void) {
char *col = NULL;
if (striper) col = "#f0f0ff";
striper = striper?FALSE:TRUE;
HTML__first_html_column_nowrap(ifl, 0, col);
}
#line 285 "inform7/Chapter 19/Kinds Index.w"
int Kinds__Index__index_kind_name_cell(int shaded, kind *K) {
if (shaded) INDEX("<font color=\"%s\">", KINDS_INDEX_SHADE);
Kinds__Index__index_kind(K, FALSE, TRUE);
if (Kinds__Behaviour__is_quasinumerical(K))
INDEX("&nbsp;<a href=\"Kinds.html?segment2\"><img border=0 src=inform:/doc_images/calc1.png></a>");
if (Kinds__Behaviour__get_documentation_reference(K))
Index__DocReferences__link(Kinds__Behaviour__get_documentation_reference(K));
int i = Instances__count(K);
if (i >= 1) INDEX(" [%d]", i);
Index__below_link_numbered(Kinds__get_construct(K)->allocation_id); /* a grey see below icon leading to an anchor on pass 2 */
if (shaded) INDEX("</font>");
return shaded;
}
#line 303 "inform7/Chapter 19/Kinds Index.w"
void Kinds__Index__end_chart_row(int shaded, kind *K,
char *tick1, char *tick2, char *tick3) {
if (tick1) HTML__next_html_column(ifl, 0);
else HTML__next_html_column_spanning(ifl, 0, 4);
if (shaded) INDEX("<font color=\"%s\">", KINDS_INDEX_SHADE);
{
#line 330 "inform7/Chapter 19/Kinds Index.w"
int found = FALSE;
instance *inst;
LOOP_OVER_INSTANCES(inst, K) {
Instances__index_name(inst);
found = TRUE;
break;
}
if (found == FALSE) {
char *p = Kinds__Behaviour__get_index_default_value(K);
if (strcmp(p, "<0-in-literal-pattern>") == 0)
{
#line 351 "inform7/Chapter 19/Kinds Index.w"
if (Kinds__Behaviour__list_of_literal_forms(K))
LiteralPatterns__index_value(
Kinds__Behaviour__list_of_literal_forms(K), 0);
else
INDEX("--");
}
#line 340 "inform7/Chapter 19/Kinds Index.w"
else if (strcmp(p, "<first-constant>") == 0)
INDEX("--");
else INDEX(p);
}
}
#line 308 "inform7/Chapter 19/Kinds Index.w"
;
if (shaded) INDEX("</font>");
if (tick1) {
HTML__next_html_column_centred(ifl, 0);
if (tick1)
INDEX("<img border=0 alt=\"%s\" src=inform:/doc_images/%s%s.png>",
tick1, shaded?"grey":"", tick1);
HTML__next_html_column_centred(ifl, 0);
if (tick2)
INDEX("<img border=0 alt=\"%s\" src=inform:/doc_images/%s%s.png>",
tick2, shaded?"grey":"", tick2);
HTML__next_html_column_centred(ifl, 0);
if (tick3)
INDEX("<img border=0 alt=\"%s\" src=inform:/doc_images/%s%s.png>",
tick3, shaded?"grey":"", tick3);
}
HTML__end_html_row(ifl);
}
#line 360 "inform7/Chapter 19/Kinds Index.w"
void Kinds__Index__index_kind(kind *K, int plural, int with_links) {
if (K == NULL) return;
wording W = Kinds__Behaviour__get_name(K, plural);
if (Wordings__nonempty(W)) {
if (Kinds__is_proper_constructor(K)) {
{
#line 381 "inform7/Chapter 19/Kinds Index.w"
int length = Wordings__length(W), w1 = Wordings__first_wn(W), tinted = TRUE;
int i, first_stroke = -1, last_stroke = -1;
for (i=0; i<length; i++) {
if (Lexer__word(w1+i) == STROKE_V) {
if (first_stroke == -1) first_stroke = i;
last_stroke = i;
}
}
int from = 0, to = length-1;
if (last_stroke >= 0) from = last_stroke+1; else tinted = FALSE;
if (tinted) INDEX("<font color=\"%s\">", KINDS_INDEX_SHADE);
for (i=from; i<=to; i++) {
int j, untinted = FALSE;
for (j=0; j<first_stroke; j++)
if (Lexer__word(w1+j) == Lexer__word(w1+i))
untinted = TRUE;
if (untinted) INDEX("</font>");
if (i>from) INDEX(" ");
char *p = Vocabulary__get_exemplar(Lexer__word(w1+i), FALSE);
if (Lexer__word(w1+i) == CAPITAL_K_V) p = "K";
if (Lexer__word(w1+i) == CAPITAL_L_V) p = "L";
INDEX("%s", p);
if (untinted) INDEX("<font color=\"%s\">", KINDS_INDEX_SHADE);
}
if (tinted) INDEX("</font>");
}
#line 365 "inform7/Chapter 19/Kinds Index.w"
;
} else {
Wordings__index(W);
if (with_links) {
int wn = Wordings__first_wn(W);
if (Kinds__Behaviour__get_creating_sentence(K))
wn = Wordings__first_wn(ParseTree__get_text(Kinds__Behaviour__get_creating_sentence(K)));
Index__link(wn);
}
}
}
}
#line 15 "inform7/Chapter 20/Specifications.w"
parse_node *Specifications__from_kind(kind *K) {
return Descriptions__from_kind(K, FALSE);
}
kind *Specifications__to_kind(parse_node *spec) {
if (ParseTree__is(spec, AMBIGUITY_NT)) spec = spec->down;
if (Specifications__is_description(spec))
return Descriptions__to_kind(spec);
if (ParseTree__is_lvalue(spec)) return Lvalues__to_kind(spec);
else if (ParseTree__is_rvalue(spec)) return Rvalues__to_kind(spec);
return NULL;
}
kind *Specifications__to_true_kind(parse_node *spec) {
if (ParseTree__is_lvalue(spec)) return Lvalues__to_kind(spec);
else if (ParseTree__is_rvalue(spec)) return Rvalues__to_kind(spec);
return NULL;
}
kind *Specifications__to_true_kind_disambiguated(parse_node *spec) {
if (ParseTree__is(spec, AMBIGUITY_NT)) spec = spec->down;
if (ParseTree__is(spec, TEST_VALUE_VNT)) spec = spec->down;
if (ParseTree__is_lvalue(spec)) return Lvalues__to_kind(spec);
else if (ParseTree__is_rvalue(spec)) return Rvalues__to_kind(spec);
return NULL;
}
#line 47 "inform7/Chapter 20/Specifications.w"
int Specifications__is_kind_like(parse_node *spec) {
if (Descriptions__is_kind_like(spec)) return TRUE;
return FALSE;
}
#line 57 "inform7/Chapter 20/Specifications.w"
int Specifications__is_description_like(parse_node *p) {
int g = FALSE;
if (Specifications__is_description(p)) g = TRUE;
if (Rvalues__is_object(p)) g = TRUE;
if (Rvalues__is_nothing_object_constant(p)) g = FALSE;
return g;
}
int Specifications__is_description(parse_node *p) {
if ((ParseTree__is(p, TEST_VALUE_VNT)) &&
(Rvalues__is_CONSTANT_construction(p->down, CON_description))) return TRUE;
return FALSE;
}
pcalc_prop *Specifications__to_proposition(parse_node *p) {
if (p == NULL) return NULL;
if (Specifications__is_description(p))
return Descriptions__to_proposition(p);
return ParseTree__get_proposition(p);
}
#line 83 "inform7/Chapter 20/Specifications.w"
instance *Specifications__object_exactly_described_if_any(parse_node *spec) {
if (spec == NULL) return NULL;
if (Specifications__is_description(spec))
return Descriptions__to_instance(spec);
if (Rvalues__is_object(spec)) {
if (Rvalues__is_nothing_object_constant(spec)) return NULL;
return Rvalues__to_instance(spec);
}
return NULL;
}
#line 100 "inform7/Chapter 20/Specifications.w"
parse_node *Specifications__new_new_variable_like(kind *K) {
K = Kinds__unary_construction(CON_variable, K);
parse_node *spec = Specifications__from_kind(K);
return spec;
}
kind *Specifications__kind_of_new_variable_like(parse_node *S) {
kind *K = Specifications__to_kind(S);
return Kinds__unary_construction_material(K);
}
int Specifications__is_new_variable_like(parse_node *spec) {
if ((Specifications__is_kind_like(spec)) &&
(Kinds__get_construct(Specifications__to_kind(spec)) == CON_variable))
return TRUE;
return FALSE;
}
#line 124 "inform7/Chapter 20/Specifications.w"
void Specifications__write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
if (spec == NULL) WRITE("something unknown");
else if (ParseTree__is_lvalue(spec)) Lvalues__write_out_in_English(OUT, spec);
else if (ParseTree__is_rvalue(spec)) Rvalues__write_out_in_English(OUT, spec);
else if (ParseTree__is_condition(spec)) Conditions__write_out_in_English(OUT, spec);
else if (ParseTree__is(spec, AMBIGUITY_NT)) Specifications__write_out_in_English(OUT, spec->down);
else WRITE("something unrecognised");
}
#line 147 "inform7/Chapter 20/Specifications.w"
int cco = 0; /* comparison count: used to make the debugging log vaguely searchable */
char *c_s_stage_law = ""; /* name of the law being applied, which caused this to be called */
int Specifications__compare_specificity(parse_node *spec1, parse_node *spec2, int *wont_mix) {
LOGIF(SPECIFICITIES, "Law %s (test %d): comparing $P with $P\n",
c_s_stage_law, cco++, spec1, spec2);
{
#line 188 "inform7/Chapter 20/Specifications.w"
if ((spec1 == NULL) && (spec2 != NULL)) return -1;
if ((spec1 != NULL) && (spec2 == NULL)) return 1;
if ((spec1 == NULL) && (spec2 == NULL)) return 0;
}
#line 154 "inform7/Chapter 20/Specifications.w"
;
int a = Specifications__is_description(spec1),
b = Specifications__is_description(spec2);
instance *I1 = Specifications__object_exactly_described_if_any(spec1);
instance *I2 = Specifications__object_exactly_described_if_any(spec2);
{
#line 198 "inform7/Chapter 20/Specifications.w"
int aa = TRUE;
if ((a) && (I1 == NULL)) aa = FALSE;
int ba = TRUE;
if ((b) && (I2 == NULL)) ba = FALSE;
if ((aa) && (!ba)) return 1;
if ((!aa) && (ba)) return -1;
}
#line 161 "inform7/Chapter 20/Specifications.w"
;
{
#line 209 "inform7/Chapter 20/Specifications.w"
if ((I1) && (I2 == NULL)) return 1;
if ((I1 == NULL) && (I2)) return -1;
}
#line 163 "inform7/Chapter 20/Specifications.w"
;
if (I1)
{
#line 220 "inform7/Chapter 20/Specifications.w"
LOGIF(SPECIFICITIES, "Test %d: Comparing specificity of instances $O and $O\n",
cco, I1, I2);
int pref = Plugins__Call__more_specific(I1, I2);
if (pref != 0) return pref;
}
#line 164 "inform7/Chapter 20/Specifications.w"
;
if (wont_mix)
{
#line 228 "inform7/Chapter 20/Specifications.w"
int ev1 = ((a) || (ParseTree__is_value(spec1)));
int ev2 = ((b) || (ParseTree__is_value(spec2)));
if (Lvalues__get_storage_form(spec1) == PROPERTY_VALUE_VNT) ev1 = FALSE;
if (Lvalues__get_storage_form(spec2) == PROPERTY_VALUE_VNT) ev2 = FALSE;
if ((ev1) && (ev2)) {
int x = Kinds__Compare__compatible_with_description(spec1, spec2);
int y = Kinds__Compare__compatible_with_description(spec2, spec1);
if (x == ALWAYS_MATCH) {
if (y == ALWAYS_MATCH) return 0;
else return 1;
}
if (y == ALWAYS_MATCH) {
if (x == ALWAYS_MATCH) return 0;
else return -1;
}
if (wont_mix) *wont_mix = TRUE;
}
}
#line 166 "inform7/Chapter 20/Specifications.w"
;
if ((a == TRUE) && (b == TRUE)) { /* case 1: both are descriptions */
return Descriptions__compare_specificity(spec1, spec2);
} else if ((a == FALSE) && (b == FALSE)) { /* case 2: neither is a description */
{
#line 256 "inform7/Chapter 20/Specifications.w"
int t1 = ParseTree__is(spec1, TABLE_ENTRY_VNT);
int t2 = ParseTree__is(spec2, TABLE_ENTRY_VNT);
if ((t1 == TRUE) && (t2 == FALSE)) return 1;
if ((t1 == FALSE) && (t2 == TRUE)) return -1;
}
#line 171 "inform7/Chapter 20/Specifications.w"
;
} else { /* case 3: one is a description, the other isn't */
{
#line 269 "inform7/Chapter 20/Specifications.w"
if (I1) { if (a == TRUE) return 1; else return -1; }
else { if (a == TRUE) return -1; else return 1; }
}
#line 173 "inform7/Chapter 20/Specifications.w"
;
}
return 0;
}
#line 277 "inform7/Chapter 20/Specifications.w"
parse_node *Specifications__new_UNKNOWN(wording W) {
return ParseTree__new_with_words(UNKNOWN_VNT, W);
}
#line 23 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_action_name(action_name *val) { CONV_FROM(action_name, K_action_name) }
parse_node *Rvalues__from_action_pattern(action_pattern *val) {
if (((PL__Actions__Patterns__is_unspecific(val) == FALSE) &&
(PL__Actions__Patterns__is_overspecific(val) == FALSE)) ||
(preform_lookahead_mode)) {
CONV_FROM(action_pattern, K_stored_action);
} else {
CONV_FROM(action_pattern, K_description_of_action);
}
}
parse_node *Rvalues__from_activity(activity *val) { CONV_FROM(activity, Activities__to_kind(val)) }
parse_node *Rvalues__from_binary_predicate(binary_predicate *val) { CONV_FROM(binary_predicate, Kinds__base_construction(CON_relation)) }
parse_node *Rvalues__from_constant_phrase(constant_phrase *val) { CONV_FROM(constant_phrase, Kinds__base_construction(CON_phrase)) }
parse_node *Rvalues__from_equation(equation *val) { CONV_FROM(equation, K_equation) }
parse_node *Rvalues__from_grammar_verb(grammar_verb *val) { CONV_FROM(grammar_verb, K_understanding) }
parse_node *Rvalues__from_named_rulebook_outcome(named_rulebook_outcome *val) { CONV_FROM(named_rulebook_outcome, K_rulebook_outcome) }
parse_node *Rvalues__from_property(property *val) { CONV_FROM(property, Properties__to_kind(val)) }
parse_node *Rvalues__from_rule(rule *val) { CONV_FROM(rule, Rules__to_kind(val)) }
parse_node *Rvalues__from_rulebook(rulebook *val) { CONV_FROM(rulebook, Rulebooks__to_kind(val)) }
parse_node *Rvalues__from_scene(scene *val) { CONV_FROM(scene, K_scene) }
parse_node *Rvalues__from_table(table *val) { CONV_FROM(table, K_table) }
parse_node *Rvalues__from_table_column(table_column *val) { CONV_FROM(table_column, Tables__Columns__to_kind(val)) }
parse_node *Rvalues__from_use_option(use_option *val) { CONV_FROM(use_option, K_use_option) }
parse_node *Rvalues__from_verb_conjugation(verb_conjugation *val) { CONV_FROM(verb_conjugation, K_verb) }
#line 56 "inform7/Chapter 20/Rvalues.w"
action_name *Rvalues__to_action_name(parse_node *spec) { CONV_TO(action_name) }
action_pattern *Rvalues__to_action_pattern(parse_node *spec) { CONV_TO(action_pattern) }
activity *Rvalues__to_activity(parse_node *spec) { CONV_TO(activity) }
binary_predicate *Rvalues__to_binary_predicate(parse_node *spec) { CONV_TO(binary_predicate) }
constant_phrase *Rvalues__to_constant_phrase(parse_node *spec) { CONV_TO(constant_phrase) }
equation *Rvalues__to_equation(parse_node *spec) { CONV_TO(equation) }
grammar_verb *Rvalues__to_grammar_verb(parse_node *spec) { CONV_TO(grammar_verb) }
named_rulebook_outcome *Rvalues__to_named_rulebook_outcome(parse_node *spec) { CONV_TO(named_rulebook_outcome) }
property *Rvalues__to_property(parse_node *spec) { CONV_TO(property) }
rule *Rvalues__to_rule(parse_node *spec) { CONV_TO(rule) }
rulebook *Rvalues__to_rulebook(parse_node *spec) { CONV_TO(rulebook) }
scene *Rvalues__to_scene(parse_node *spec) { CONV_TO(scene) }
table *Rvalues__to_table(parse_node *spec) { CONV_TO(table) }
table_column *Rvalues__to_table_column(parse_node *spec) { CONV_TO(table_column) }
use_option *Rvalues__to_use_option(parse_node *spec) { CONV_TO(use_option) }
verb_conjugation *Rvalues__to_verb_conjugation(parse_node *spec) { CONV_TO(verb_conjugation) }
#line 77 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_instance(instance *I) {
parse_node *val = ParseTree__new(CONSTANT_VNT);
ParseTree__set_kind_of_value(val, Instances__to_kind(I));
ParseTree__set_constant_instance(val, I);
ParseTree__annotate_int(val, constant_enumeration_ANNOT, Instances__get_numerical_value(I));
ParseTree__set_text(val, Instances__get_name(I, FALSE));
return val;
}
instance *Rvalues__to_instance(parse_node *spec) { CONV_TO(instance) }
#line 91 "inform7/Chapter 20/Rvalues.w"
int Rvalues__is_object(parse_node *spec) {
if ((ParseTree__is(spec, CONSTANT_VNT)) &&
(Kinds__Compare__le(ParseTree__get_kind_of_value(spec), K_object)))
return TRUE;
return FALSE;
}
instance *Rvalues__to_object_instance(parse_node *spec) {
if (Rvalues__is_object(spec)) return Rvalues__to_instance(spec);
return NULL;
}
#line 108 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__new_self_object_constant(void) {
parse_node *spec = ParseTree__new(CONSTANT_VNT);
ParseTree__set_kind_of_value(spec, K_object);
ParseTree__annotate_int(spec, self_object_ANNOT, TRUE);
return spec;
}
parse_node *Rvalues__new_nothing_object_constant(void) {
parse_node *spec = ParseTree__new(CONSTANT_VNT);
ParseTree__set_kind_of_value(spec, K_object);
ParseTree__annotate_int(spec, nothing_object_ANNOT, TRUE);
return spec;
}
#line 126 "inform7/Chapter 20/Rvalues.w"
int Rvalues__is_nothing_object_constant(parse_node *spec) {
if (ParseTree__int_annotation(spec, nothing_object_ANNOT)) return TRUE;
return FALSE;
}
int Rvalues__is_self_object_constant(parse_node *spec) {
if (ParseTree__int_annotation(spec, self_object_ANNOT)) return TRUE;
return FALSE;
}
#line 141 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_encoded_notation(kind *K, int encoded_value, wording W) {
parse_node *spec = ParseTree__new_with_words(CONSTANT_VNT, W);
ParseTree__set_kind_of_value(spec, K);
ParseTree__annotate_int(spec, explicit_literal_ANNOT, TRUE);
ParseTree__annotate_int(spec, constant_number_ANNOT, encoded_value);
return spec;
}
int Rvalues__to_encoded_notation(parse_node *spec) {
if (ParseTree__int_annotation(spec, explicit_literal_ANNOT))
return ParseTree__int_annotation(spec, constant_number_ANNOT);
return 0;
}
#line 159 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_int(int n, wording W) {
parse_node *spec = ParseTree__new_with_words(CONSTANT_VNT, W);
ParseTree__set_kind_of_value(spec, K_number);
ParseTree__annotate_int(spec, explicit_literal_ANNOT, TRUE);
ParseTree__annotate_int(spec, constant_number_ANNOT, n);
return spec;
}
int Rvalues__to_int(parse_node *spec) {
if (spec == NULL) return 0;
if (ParseTree__int_annotation(spec, explicit_literal_ANNOT))
return ParseTree__int_annotation(spec, constant_number_ANNOT);
return 0;
}
#line 179 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_IEEE_754(unsigned int n, wording W) {
parse_node *spec = ParseTree__new_with_words(CONSTANT_VNT, W);
ParseTree__set_kind_of_value(spec, K_real_number);
ParseTree__annotate_int(spec, explicit_literal_ANNOT, TRUE);
ParseTree__annotate_int(spec, constant_number_ANNOT, (int) n);
return spec;
}
unsigned int Rvalues__to_IEEE_754(parse_node *spec) {
if (Rvalues__is_CONSTANT_of_kind(spec, K_real_number))
return (unsigned int) ParseTree__int_annotation(spec, constant_number_ANNOT);
return 0x7F800001; /* which is a NaN value */
}
#line 196 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_boolean(int flag, wording W) {
parse_node *spec = ParseTree__new_with_words(CONSTANT_VNT, W);
ParseTree__set_kind_of_value(spec, K_truth_state);
ParseTree__annotate_int(spec, explicit_literal_ANNOT, TRUE);
ParseTree__annotate_int(spec, constant_number_ANNOT, flag);
return spec;
}
int Rvalues__to_boolean(parse_node *spec) {
if (Rvalues__is_CONSTANT_of_kind(spec, K_truth_state))
return ParseTree__int_annotation(spec, constant_number_ANNOT);
return FALSE;
}
#line 213 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_Unicode_point(int code_point, wording W) {
parse_node *spec = ParseTree__new_with_words(CONSTANT_VNT, W);
ParseTree__set_kind_of_value(spec, K_unicode_character);
ParseTree__annotate_int(spec, explicit_literal_ANNOT, TRUE);
ParseTree__annotate_int(spec, constant_number_ANNOT, code_point);
return spec;
}
int Rvalues__to_Unicode_point(parse_node *spec) {
if (Rvalues__is_CONSTANT_of_kind(spec, K_unicode_character))
return ParseTree__int_annotation(spec, constant_number_ANNOT);
return 0;
}
#line 231 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_time(int minutes_since_midnight, wording W) {
parse_node *spec = ParseTree__new_with_words(CONSTANT_VNT, W);
ParseTree__set_kind_of_value(spec, PL__TimesOfDay__kind());
ParseTree__annotate_int(spec, explicit_literal_ANNOT, TRUE);
ParseTree__annotate_int(spec, constant_number_ANNOT, minutes_since_midnight);
return spec;
}
int Rvalues__to_time(parse_node *spec) {
if (Rvalues__is_CONSTANT_of_kind(spec, PL__TimesOfDay__kind()))
return ParseTree__int_annotation(spec, constant_number_ANNOT);
return 0;
}
#line 249 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_wording_of_list(kind *K, wording W) {
parse_node *spec = ParseTree__new_with_words(CONSTANT_VNT, W);
ParseTree__set_kind_of_value(spec, K);
return spec;
}
#line 258 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_wording(wording W) {
parse_node *spec = ParseTree__new_with_words(CONSTANT_VNT, W);
ParseTree__set_kind_of_value(spec, K_text);
return spec;
}
#line 268 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_unescaped_wording(wording W) {
parse_node *spec = Rvalues__from_wording(W);
ParseTree__annotate_int(spec, text_unescaped_ANNOT, TRUE);
return spec;
}
#line 278 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_permanent_STREAM(text_stream *S) {
parse_node *spec = ParseTree__new(CONSTANT_VNT);
ParseTree__set_kind_of_value(spec, K_text);
ParseTree__annotate_int(spec, explicit_literal_ANNOT, TRUE);
ParseTree__set_constant_text(spec, S);
return spec;
}
#line 292 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__from_pair(parse_node *X, parse_node *Y) {
if (X == NULL) X = Specifications__new_UNKNOWN(EMPTY_WORDING);
if (Y == NULL) Y = Specifications__new_UNKNOWN(EMPTY_WORDING);
kind *kX = Specifications__to_true_kind_disambiguated(X);
kind *kY = Specifications__to_true_kind_disambiguated(Y);
kind *K = Kinds__pair_kind(kX, kY);
parse_node *spec = ParseTree__new(CONSTANT_VNT);
ParseTree__set_kind_of_value(spec, K);
spec->down = X; spec->down->next = Y;
return spec;
}
void Rvalues__to_pair(parse_node *pair, parse_node **X, parse_node **Y) {
*X = pair->down;
*Y = pair->down->next;
}
#line 315 "inform7/Chapter 20/Rvalues.w"
parse_node *Rvalues__constant_description(pcalc_prop *prop, wording W) {
parse_node *con = ParseTree__new_with_words(CONSTANT_VNT, W);
ParseTree__set_kind_of_value(con,
Kinds__unary_construction(CON_description, K_object));
Rvalues__set_constant_description_proposition(con, prop);
return con;
}
void Rvalues__set_constant_description_proposition(parse_node *spec, pcalc_prop *prop) {
if (Rvalues__is_CONSTANT_construction(spec, CON_description)) {
ParseTree__set_proposition(spec, prop);
ParseTree__set_kind_of_value(spec,
Kinds__unary_construction(CON_description,
Calculus__Variables__infer_kind_of_variable_0(prop)));
} else internal_error("set constant description proposition wrongly");
}
#line 335 "inform7/Chapter 20/Rvalues.w"
int Rvalues__is_CONSTANT_construction(parse_node *spec, kind_constructor *con) {
if ((ParseTree__is(spec, CONSTANT_VNT)) &&
(Kinds__get_construct(ParseTree__get_kind_of_value(spec)) == con))
return TRUE;
return FALSE;
}
int Rvalues__is_CONSTANT_of_kind(parse_node *spec, kind *K) {
if ((ParseTree__is(spec, CONSTANT_VNT)) &&
(Kinds__Compare__eq(ParseTree__get_kind_of_value(spec), K)))
return TRUE;
return FALSE;
}
#line 387 "inform7/Chapter 20/Rvalues.w"
int Rvalues__compare_CONSTANT(parse_node *spec1, parse_node *spec2) {
if (ParseTree__is(spec1, CONSTANT_VNT) == FALSE) return FALSE;
if (ParseTree__is(spec2, CONSTANT_VNT) == FALSE) return FALSE;
kind *K1 = ParseTree__get_kind_of_value(spec1);
kind *K2 = ParseTree__get_kind_of_value(spec2);
if ((Kinds__Compare__le(K1, K2) == FALSE) &&
(Kinds__Compare__le(K2, K1) == FALSE)) return FALSE;
if (Kinds__Compare__eq(K1, K_text)) {
if (Wordings__match_perhaps_quoted(
ParseTree__get_text(spec1), ParseTree__get_text(spec2))) return TRUE;
return FALSE;
}
switch (Kinds__Behaviour__get_constant_compilation_method(K1)) {
case LITERAL_CCM:
if (Rvalues__to_encoded_notation(spec1) == Rvalues__to_encoded_notation(spec2)) return TRUE;
return FALSE;
case NAMED_CONSTANT_CCM: {
instance *I1 = Rvalues__to_instance(spec1);
instance *I2 = Rvalues__to_instance(spec2);
if (I1 == I2) return TRUE;
return FALSE;
}
case SPECIAL_CCM: {
COMPARE_CONSTANTS_USING(CON_activity, activity, Rvalues__to_activity)
KKCOMPARE_CONSTANTS_USING(object, instance, Rvalues__to_object_instance)
COMPARE_CONSTANTS_USING(CON_phrase, constant_phrase, Rvalues__to_constant_phrase)
COMPARE_CONSTANTS_USING(CON_property, property, Rvalues__to_property)
COMPARE_CONSTANTS_USING(CON_rule, rule, Rvalues__to_rule)
COMPARE_CONSTANTS_USING(CON_rulebook, rulebook, Rvalues__to_rulebook)
COMPARE_CONSTANTS_USING(CON_table_column, table_column, Rvalues__to_table_column)
KCOMPARE_CONSTANTS(action_name, action_name)
KCOMPARE_CONSTANTS(equation, equation)
COMPARE_CONSTANTS_USING(CON_relation, binary_predicate, Rvalues__to_binary_predicate)
KCOMPARE_CONSTANTS(rulebook_outcome, named_rulebook_outcome)
KCOMPARE_CONSTANTS(scene, scene)
KCOMPARE_CONSTANTS(table, table)
KCOMPARE_CONSTANTS(understanding, grammar_verb)
KCOMPARE_CONSTANTS(use_option, use_option)
}
}
return FALSE;
}
#line 433 "inform7/Chapter 20/Rvalues.w"
void Rvalues__write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
switch (ParseTree__get_type(spec)) {
case PHRASE_TO_DECIDE_VALUE_VNT: {
kind *dtr = Specifications__to_kind(spec);
if (dtr == NULL) WRITE("a phrase");
else {
WRITE("an instruction to work out ");
Kinds__Textual__write_articled(OUT, dtr);
}
break;
}
case CONSTANT_VNT: {
wording W = ParseTree__get_text(spec);
if (Rvalues__is_CONSTANT_construction(spec, CON_property)) {
if (Wordings__nonempty(W)) Wordings__to_stream_raw(OUT, W);
else WRITE("the name of a property");
return;
}
if (Wordings__nonempty(W)) Wordings__to_stream_raw(OUT, W);
else {
WRITE("a nameless ");
kind *dtr = Specifications__to_kind(spec);
Kinds__Textual__write(OUT, dtr);
}
break;
}
}
}
#line 465 "inform7/Chapter 20/Rvalues.w"
void Rvalues__log(parse_node *spec) {
switch (ParseTree__get_type(spec)) {
case CONSTANT_VNT: {
instance *I = Rvalues__to_instance(spec);
if (I)
if (Instances__identifier(I))
LOG("(%s)", Instances__identifier(I));
if (Rvalues__is_object(spec)) {
if (ParseTree__int_annotation(spec, self_object_ANNOT)) LOG("(-self-)");
else if (ParseTree__int_annotation(spec, nothing_object_ANNOT)) LOG("(-nothing-)");
else LOG("($O)", Rvalues__to_instance(spec));
}
}
}
}
#line 486 "inform7/Chapter 20/Rvalues.w"
kind *Rvalues__to_kind(parse_node *spec) {
if (spec == NULL) internal_error("Rvalues__to_kind on NULL");
switch (ParseTree__get_type(spec)) {
case CONSTANT_VNT:
if (Rvalues__is_object(spec))
{
#line 515 "inform7/Chapter 20/Rvalues.w"
if (ParseTree__int_annotation(spec, self_object_ANNOT)) return K_object;
else if (ParseTree__int_annotation(spec, nothing_object_ANNOT)) return K_object;
else {
instance *I = Rvalues__to_instance(spec);
if (I) return Instances__to_kind(I);
}
}
#line 491 "inform7/Chapter 20/Rvalues.w"
;
if (Rvalues__is_CONSTANT_construction(spec, CON_relation))
{
#line 525 "inform7/Chapter 20/Rvalues.w"
binary_predicate *bp = Rvalues__to_binary_predicate(spec);
return BinaryPredicates__kind(bp);
}
#line 493 "inform7/Chapter 20/Rvalues.w"
;
if (Rvalues__is_CONSTANT_construction(spec, CON_property))
{
#line 531 "inform7/Chapter 20/Rvalues.w"
property *prn = Rvalues__to_property(spec);
if (prn->either_or) return Kinds__unary_construction(CON_property, K_truth_state);
return Kinds__unary_construction(CON_property, Properties__Valued__kind(prn));
}
#line 495 "inform7/Chapter 20/Rvalues.w"
;
if (Rvalues__is_CONSTANT_construction(spec, CON_phrase))
{
#line 550 "inform7/Chapter 20/Rvalues.w"
return Phrases__Constants__kind(Rvalues__to_constant_phrase(spec));
}
#line 497 "inform7/Chapter 20/Rvalues.w"
;
if (Rvalues__is_CONSTANT_construction(spec, CON_list_of))
{
#line 538 "inform7/Chapter 20/Rvalues.w"
return Lists__kind_of_list_at(ParseTree__get_text(spec));
}
#line 499 "inform7/Chapter 20/Rvalues.w"
;
if (Rvalues__is_CONSTANT_construction(spec, CON_table_column))
{
#line 543 "inform7/Chapter 20/Rvalues.w"
return Kinds__unary_construction(CON_table_column,
Tables__Columns__get_kind(Rvalues__to_table_column(spec)));
}
#line 501 "inform7/Chapter 20/Rvalues.w"
;
return ParseTree__get_kind_of_value(spec);
case PHRASE_TO_DECIDE_VALUE_VNT:
{
#line 577 "inform7/Chapter 20/Rvalues.w"
parse_node *deciding_inv = spec->down->down;
if (deciding_inv) {
phrase *ph = ParseTree__get_phrase_invoked(deciding_inv);
if ((ph) && (Phrases__TypeData__get_mor(&(ph->type_data)) == DECIDES_VALUE_MOR)) {
if (Phrases__TypeData__return_decided_dimensionally(&(ph->type_data))) {
if (ParseTree__get_kind_resulting(deciding_inv)) return ParseTree__get_kind_resulting(deciding_inv);
return K_value;
} else {
if (ParseTree__get_kind_resulting(deciding_inv)) return ParseTree__get_kind_resulting(deciding_inv);
kind *K = Phrases__TypeData__get_return_kind(&(ph->type_data));
if (Kinds__Behaviour__definite(K) == FALSE) return K_value;
return K;
}
}
}
return NULL;
}
#line 504 "inform7/Chapter 20/Rvalues.w"
;
}
internal_error("unknown evaluating VALUE type"); return NULL;
}
#line 597 "inform7/Chapter 20/Rvalues.w"
void Rvalues__compile(OUTPUT_STREAM, parse_node *spec_found) {
switch(ParseTree__get_type(spec_found)) {
case PHRASE_TO_DECIDE_VALUE_VNT:
Invocations__Compiler__compile_invocation_list(OUT,
spec_found->down->down, ParseTree__get_text(spec_found));
return;
case CONSTANT_VNT: {
kind *kind_of_constant = ParseTree__get_kind_of_value(spec_found);
int ccm = Kinds__Behaviour__get_constant_compilation_method(kind_of_constant);
switch(ccm) {
case NONE_CCM: /* constant values of this kind cannot exist */
LOG("SP: $P; kind: $u\n", spec_found, kind_of_constant);
internal_error("Tried to compile CONSTANT SP for a disallowed kind");
return;
case LITERAL_CCM:
{
#line 626 "inform7/Chapter 20/Rvalues.w"
WRITE("%d", Rvalues__to_int(spec_found));
}
#line 611 "inform7/Chapter 20/Rvalues.w"
; return;
case NAMED_CONSTANT_CCM:
{
#line 631 "inform7/Chapter 20/Rvalues.w"
instance *I = ParseTree__get_constant_instance(spec_found);
WRITE("%s", Instances__identifier(I));
}
#line 612 "inform7/Chapter 20/Rvalues.w"
; return;
case SPECIAL_CCM:
{
#line 638 "inform7/Chapter 20/Rvalues.w"
if (Plugins__Call__compile_constant(OUT, kind_of_constant, spec_found))
return;
if (Kinds__get_construct(kind_of_constant) == CON_activity) {
activity *act = Rvalues__to_activity(spec_found);
WRITE("%s", Activities__identifier(act));
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_combination) {
for (parse_node *term = spec_found->down; term; term = term->next) {
Specifications__Compiler__compile(OUT, term);
if (term->next) WRITE(", ");
}
return;
}
if (Kinds__Compare__eq(kind_of_constant, K_equation)) {
equation *eqn = Rvalues__to_equation(spec_found);
WRITE("%s", Equations__identifier(eqn));
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_description) {
Calculus__Deferrals__compile_multiple_use_proposition(OUT,
spec_found, Kinds__unary_construction_material(kind_of_constant));
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_list_of) {
Lists__compile_literal_list(OUT, ParseTree__get_text(spec_found));
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_phrase) {
constant_phrase *cphr = Rvalues__to_constant_phrase(spec_found);
Phrases__Constants__compile(OUT, cphr);
return;
}
if (Kinds__Compare__le(kind_of_constant, K_object)) {
if (ParseTree__int_annotation(spec_found, self_object_ANNOT)) WRITE("self");
else if (ParseTree__int_annotation(spec_found, nothing_object_ANNOT)) WRITE("nothing");
else {
instance *I = Rvalues__to_instance(spec_found);
WRITE("%s", Instances__identifier(I));
parse_node *NB = Routines__Compile__line_being_compiled();
if (NB) Instances__note_usage(I, NB);
}
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_property) {
{
#line 760 "inform7/Chapter 20/Rvalues.w"
int parity = 1;
if (Preform__parse_nt_against_word_range(negated_clause_NTM, ParseTree__get_text(spec_found), NULL, NULL)) parity = -1;
property *prn = Rvalues__to_property(spec_found);
if (prn == NULL) internal_error("PROPERTY SP with null property");
if (Properties__is_either_or(prn)) {
if (Properties__EitherOr__stored_in_negation(prn))
WRITE("%s%s", (parity>0)?"~":"",
Properties__get_translation(Properties__EitherOr__get_negation(prn)));
else
WRITE("%s%s", (parity<0)?"~":"",
Properties__get_translation(prn));
} else WRITE("%s", Properties__get_translation(prn));
}
#line 683 "inform7/Chapter 20/Rvalues.w"
;
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_relation) {
binary_predicate *bp = Rvalues__to_binary_predicate(spec_found);
WRITE("Rel_Record_%d", bp->allocation_id);
BinaryPredicates__mark_as_needed(bp);
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_rule) {
rule *R = Rvalues__to_rule(spec_found);
Rules__compile(OUT, R);
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_rulebook) {
rulebook *rb = Rvalues__to_rulebook(spec_found);
WRITE("%d", rb->allocation_id);
return;
}
if (Kinds__Compare__eq(kind_of_constant, K_rulebook_outcome)) {
named_rulebook_outcome *rbno =
Rvalues__to_named_rulebook_outcome(spec_found);
WRITE("RBNO_%d", rbno->allocation_id);
return;
}
if (Kinds__Compare__eq(kind_of_constant, K_table)) {
table *t = Rvalues__to_table(spec_found);
WRITE("%s", Tables__identifier(t));
return;
}
if (Kinds__get_construct(kind_of_constant) == CON_table_column) {
table_column *tc = Rvalues__to_table_column(spec_found);
WRITE("%d", Tables__Columns__get_id(tc));
return;
}
if (Kinds__Compare__eq(kind_of_constant, K_text)) {
Strings__compile_general(OUT, spec_found);
return;
}
if (Kinds__Compare__eq(kind_of_constant, K_understanding)) {
if (Wordings__empty(ParseTree__get_text(spec_found)))
internal_error("Text no longer available for CONSTANT/UNDERSTANDING");
PL__Parsing__compile_understanding(OUT, ParseTree__get_text(spec_found), FALSE);
return;
}
if (Kinds__Compare__eq(kind_of_constant, K_use_option)) {
use_option *uo = Rvalues__to_use_option(spec_found);
WRITE("%d", uo->allocation_id);
return;
}
if (Kinds__Compare__eq(kind_of_constant, K_verb)) {
verb_conjugation *vc = Rvalues__to_verb_conjugation(spec_found);
WRITE("ConjugateVerb_%d", vc->allocation_id);
return;
}
if (Kinds__Compare__eq(kind_of_constant, K_response)) {
rule *R = Rvalues__to_rule(spec_found);
int c = ParseTree__int_annotation(spec_found, response_code_ANNOT);
Strings__compile_response_constant(OUT, R, c);
Rules__now_rule_needs_response(R, c, EMPTY_WORDING);
return;
}
LOG("Kov is $u\n", kind_of_constant);
internal_error("no special ccm provided");
}
#line 613 "inform7/Chapter 20/Rvalues.w"
; return;
}
}
}
}
#line 66 "inform7/Chapter 20/Lvalues.w"
parse_node *Lvalues__new_LOCAL_VARIABLE(wording W, local_variable *lvar) {
parse_node *spec = ParseTree__new(LOCAL_VARIABLE_VNT);
ParseTree__set_text(spec, W);
ParseTree__set_constant_local_variable(spec, lvar);
if (lvar == NULL) internal_error("bad local variable");
return spec;
}
parse_node *Lvalues__new_actual_NONLOCAL_VARIABLE(nonlocal_variable *nlv) {
parse_node *spec = ParseTree__new(NONLOCAL_VARIABLE_VNT);
ParseTree__set_constant_nonlocal_variable(spec, nlv);
ParseTree__set_text(spec, nlv->name);
return spec;
}
#line 85 "inform7/Chapter 20/Lvalues.w"
parse_node *Lvalues__new_TABLE_ENTRY(wording W) {
parse_node *spec = ParseTree__new_with_words(TABLE_ENTRY_VNT, W);
return spec;
}
#line 93 "inform7/Chapter 20/Lvalues.w"
parse_node *Lvalues__new_LIST_ENTRY(parse_node *owner, parse_node *index) {
parse_node *spec = ParseTree__new(LIST_ENTRY_VNT);
spec->down = owner;
spec->down->next = index;
return spec;
}
#line 109 "inform7/Chapter 20/Lvalues.w"
parse_node *Lvalues__new_PROPERTY_VALUE(parse_node *prop, parse_node *owner) {
parse_node *spec = ParseTree__new(PROPERTY_VALUE_VNT);
spec->down = prop;
spec->down->next = owner;
ParseTree__set_text(spec,
Wordings__union(ParseTree__get_text(prop), ParseTree__get_text(owner)));
return spec;
}
#line 121 "inform7/Chapter 20/Lvalues.w"
parse_node *Lvalues__underlying_property(parse_node *spec) {
if (ParseTree__is(spec, PROPERTY_VALUE_VNT)) {
if (Rvalues__is_self_object_constant(spec->down->next))
return spec->down;
return spec;
}
internal_error("no underlying property"); return NULL;
}
#line 133 "inform7/Chapter 20/Lvalues.w"
node_type_t Lvalues__get_storage_form(parse_node *spec) {
if (ParseTree__is_lvalue(spec)) return ParseTree__get_type(spec);
return UNKNOWN_VNT;
}
#line 141 "inform7/Chapter 20/Lvalues.w"
int Lvalues__is_actual_NONLOCAL_VARIABLE(parse_node *spec) {
if (ParseTree__is(spec, NONLOCAL_VARIABLE_VNT)) return TRUE;
return FALSE;
}
nonlocal_variable *Lvalues__get_nonlocal_variable_if_any(parse_node *spec) {
if (ParseTree__is(spec, NONLOCAL_VARIABLE_VNT))
return ParseTree__get_constant_nonlocal_variable(spec);
return NULL;
}
int Lvalues__is_constant_NONLOCAL_VARIABLE(parse_node *spec) {
nonlocal_variable *nlv = Lvalues__get_nonlocal_variable_if_any(spec);
if (nlv) return NonlocalVariables__is_constant(nlv);
return FALSE;
}
#line 162 "inform7/Chapter 20/Lvalues.w"
int Lvalues__is_global_variable(parse_node *spec) {
if (Lvalues__get_nonlocal_variable_if_any(spec)) return TRUE;
return FALSE;
}
#line 170 "inform7/Chapter 20/Lvalues.w"
void Lvalues__write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
switch(ParseTree__get_type(spec)) {
case LOCAL_VARIABLE_VNT: WRITE("a temporary named value"); break;
case NONLOCAL_VARIABLE_VNT:
if (ParseTree__get_kind_of_value(spec)) {
Kinds__Textual__write_articled(OUT, ParseTree__get_kind_of_value(spec));
WRITE(" that varies");
} else WRITE("a non-temporary variable");
break;
case TABLE_ENTRY_VNT: WRITE("a table entry"); break;
case LIST_ENTRY_VNT: WRITE("a list entry"); break;
case PROPERTY_VALUE_VNT:
if ((ParseTree__no_children(spec) == 2) &&
(Rvalues__is_CONSTANT_construction(spec->down, CON_property))) {
property *prn = Rvalues__to_property(
spec->down);
WRITE("a property whose value is ");
Kinds__Textual__write_articled(OUT, Properties__Valued__kind(prn));
} else WRITE("a property belonging to something");
break;
default: WRITE("a stored value"); break;
}
}
#line 197 "inform7/Chapter 20/Lvalues.w"
void Lvalues__log(parse_node *spec) {
switch (ParseTree__get_type(spec)) {
case LOCAL_VARIABLE_VNT: {
local_variable *lvar = ParseTree__get_constant_local_variable(spec);
LOG("(%s;$u)",
LocalVariables__lvalue(lvar),
LocalVariables__unproblematic_kind(lvar));
break;
}
case NONLOCAL_VARIABLE_VNT: {
nonlocal_variable *q = ParseTree__get_constant_nonlocal_variable(spec);
LOG("($Z)", q);
break;
}
}
}
#line 217 "inform7/Chapter 20/Lvalues.w"
kind *Lvalues__to_kind(parse_node *spec) {
if (spec == NULL) internal_error("Rvalues__to_kind on NULL");
switch (ParseTree__get_type(spec)) {
case LOCAL_VARIABLE_VNT:
{
#line 232 "inform7/Chapter 20/Lvalues.w"
local_variable *lvar = ParseTree__get_constant_local_variable(spec);
if (lvar == NULL) return K_value; /* for "existing" */
return LocalVariables__unproblematic_kind(lvar);
}
#line 220 "inform7/Chapter 20/Lvalues.w"
;
case NONLOCAL_VARIABLE_VNT:
{
#line 239 "inform7/Chapter 20/Lvalues.w"
nonlocal_variable *nlv = ParseTree__get_constant_nonlocal_variable(spec);
return NonlocalVariables__kind(nlv);
}
#line 221 "inform7/Chapter 20/Lvalues.w"
;
case TABLE_ENTRY_VNT:
{
#line 246 "inform7/Chapter 20/Lvalues.w"
if (ParseTree__no_children(spec) > 0) { /* i.e., always, for actual table entry specifications */
parse_node *fts = spec->down;
table_column *tc = Rvalues__to_table_column(fts);
return Tables__Columns__get_kind(tc);
}
return NULL; /* can happen when scanning phrase arguments, which are generic */
}
#line 222 "inform7/Chapter 20/Lvalues.w"
;
case LIST_ENTRY_VNT:
{
#line 256 "inform7/Chapter 20/Lvalues.w"
if (ParseTree__no_children(spec) == 2) { /* i.e., always, for actual list entry specifications */
kind *K1 = Specifications__to_kind(spec->down);
if (Kinds__unary_construction_material(K1)) return Kinds__unary_construction_material(K1);
return K_value; /* to help the type-checker produce better problem messages */
}
return NULL; /* can happen when scanning phrase arguments, which are generic */
}
#line 223 "inform7/Chapter 20/Lvalues.w"
;
case PROPERTY_VALUE_VNT:
{
#line 266 "inform7/Chapter 20/Lvalues.w"
if (ParseTree__no_children(spec) == 2) {
property *prn = Rvalues__to_property(spec->down);
if ((prn) && (Properties__is_either_or(prn) == FALSE)) return Properties__Valued__kind(prn);
return K_value; /* to help the type-checker produce better problem messages */
}
return NULL; /* can happen when scanning phrase arguments, which are generic */
}
#line 224 "inform7/Chapter 20/Lvalues.w"
;
}
return K_value; /* a generic answer for storage of an unknown sort */
}
#line 276 "inform7/Chapter 20/Lvalues.w"
local_variable *Lvalues__get_local_variable_if_any(parse_node *spec) {
if (ParseTree__is(spec, LOCAL_VARIABLE_VNT))
return ParseTree__get_constant_local_variable(spec);
return NULL;
}
#line 287 "inform7/Chapter 20/Lvalues.w"
void Lvalues__compile(OUTPUT_STREAM, parse_node *spec_found) {
switch (ParseTree__get_type(spec_found)) {
case LOCAL_VARIABLE_VNT:
{
#line 302 "inform7/Chapter 20/Lvalues.w"
local_variable *lvar = ParseTree__get_constant_local_variable(spec_found);
if (lvar == NULL) {
LOG("Bad: %08x\n", spec_found);
internal_error("Compiled never-specified LOCAL VARIABLE SP");
}
WRITE("%s", LocalVariables__lvalue(lvar));
return;
}
#line 289 "inform7/Chapter 20/Lvalues.w"
;
case NONLOCAL_VARIABLE_VNT:
{
#line 313 "inform7/Chapter 20/Lvalues.w"
nonlocal_variable *nlv = ParseTree__get_constant_nonlocal_variable(spec_found);
WRITE("%s", NonlocalVariables__lvalue_identifier(nlv));
return;
}
#line 290 "inform7/Chapter 20/Lvalues.w"
;
case PROPERTY_VALUE_VNT:
{
#line 320 "inform7/Chapter 20/Lvalues.w"
if (ParseTree__no_children(spec_found) != 2) internal_error("malformed PROPERTY_OF SP");
if (spec_found->down == NULL) internal_error("PROPERTY_OF with null arg 0");
if (spec_found->down->next == NULL) internal_error("PROPERTY_OF with null arg 1");
property *prn = Rvalues__to_property(spec_found->down);
if (prn == NULL) internal_error("PROPERTY_OF with null property");
parse_node *prop_spec = spec_found->down;
parse_node *owner = spec_found->down->next;
kind *owner_kind = Specifications__to_kind(owner);
{
#line 357 "inform7/Chapter 20/Lvalues.w"
if (Rvalues__is_self_object_constant(owner)) {
inference_subject *infs = Properties__Conditions__of_what(prn);
instance *I = InferenceSubjects__as_object_instance(infs);
if (I) owner = Rvalues__from_instance(I);
}
}
#line 329 "inform7/Chapter 20/Lvalues.w"
;
WRITE("GProperty(");
Kinds__RunTime__compile_weak_id(OUT, owner_kind);
WRITE(", ");
{
#line 374 "inform7/Chapter 20/Lvalues.w"
if (ParseTree__int_annotation(spec_found, record_as_self_ANNOT)) WRITE("self=");
Specifications__Compiler__compile(OUT, owner);
}
#line 334 "inform7/Chapter 20/Lvalues.w"
;
WRITE(",");
Specifications__Compiler__compile(OUT, prop_spec);
WRITE(")");
return;
}
#line 291 "inform7/Chapter 20/Lvalues.w"
;
case LIST_ENTRY_VNT:
{
#line 380 "inform7/Chapter 20/Lvalues.w"
if (ParseTree__no_children(spec_found) != 2) internal_error("malformed LIST_OF SP");
if (spec_found->down == NULL) internal_error("LIST_OF with null arg 0");
if (spec_found->down->next == NULL) internal_error("LIST_OF with null arg 1");
WRITE("LIST_OF_TY_GetItem(");
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__Compiler__compile(OUT, spec_found->down);
END_COMPILATION_MODE;
WRITE(",");
Specifications__Compiler__compile(OUT, spec_found->down->next);
WRITE(")");
return;
}
#line 292 "inform7/Chapter 20/Lvalues.w"
;
case TABLE_ENTRY_VNT:
{
#line 396 "inform7/Chapter 20/Lvalues.w"
switch(ParseTree__no_children(spec_found)) {
case 1:
LocalVariables__used_stack_selection();
LocalVariables__add_table_lookup();
WRITE("TableLookUpEntry(ct_0,");
Specifications__Compiler__compile(OUT, spec_found->down);
WRITE(",ct_1)");
break;
case 2: /* never here except when printing debugging code */
WRITE("(false)");
break;
case 3:
WRITE("TableLookUpEntry(");
Specifications__Compiler__compile(OUT, spec_found->down->next->next);
WRITE(",");
Specifications__Compiler__compile(OUT, spec_found->down);
WRITE(",");
Specifications__Compiler__compile(OUT, spec_found->down->next);
WRITE(")");
break;
case 4:
WRITE("TableLookUpCorr(");
Specifications__Compiler__compile(OUT, spec_found->down->next->next->next);
WRITE(",");
Specifications__Compiler__compile(OUT, spec_found->down);
WRITE(",");
Specifications__Compiler__compile(OUT, spec_found->down->next);
WRITE(",");
Specifications__Compiler__compile(OUT, spec_found->down->next->next);
WRITE(")");
break;
default: internal_error("TABLE REFERENCE with bad number of args");
}
return;
}
#line 293 "inform7/Chapter 20/Lvalues.w"
;
default: LOG("Offender: $P\n", spec_found);
internal_error("unable to compile this STORAGE species");
}
}
#line 459 "inform7/Chapter 20/Lvalues.w"
char *Lvalues__storage_class_schema(node_type_t storage_class, int kind_of_store,
int reducing_modulo_1440) {
switch(kind_of_store) {
case STORE_WORD_TO_WORD:
switch(storage_class) {
case LOCAL_VARIABLE_VNT: return "*=-*1 = *<2";
case NONLOCAL_VARIABLE_VNT: return "*=-*1 = *<2";
case TABLE_ENTRY_VNT: return "*=-*1*-,1,*<2)";
case PROPERTY_VALUE_VNT: return "*=-Write*+1*-,*<2)";
case LIST_ENTRY_VNT: return "*=-Write*1*-,*<2)";
}
return "";
case STORE_WORD_TO_POINTER:
switch(storage_class) {
case LOCAL_VARIABLE_VNT: return "*=-BlkValueCast(*1, *#2, *!2)";
case NONLOCAL_VARIABLE_VNT: return "*=-BlkValueCast(*1, *#2, *!2)";
case TABLE_ENTRY_VNT: return "*=-BlkValueCast(*1*-,5), *#2, *!2)";
case PROPERTY_VALUE_VNT: return "*=-BlkValueCast(*+1, *#2, *!2)";
case LIST_ENTRY_VNT: return "*=-BlkValueCast(*1, *#2, *!2)";
}
return "";
case STORE_POINTER_TO_POINTER:
switch(storage_class) {
case LOCAL_VARIABLE_VNT: return "*=-BlkValueCopy(*1, *<2)";
case NONLOCAL_VARIABLE_VNT: return "*=-BlkValueCopy(*1, *<2)";
case TABLE_ENTRY_VNT: return "*=-BlkValueCopy(*1*-,5), *<2)";
case PROPERTY_VALUE_VNT: return "*=-BlkValueCopy(*+1, *<2)";
case LIST_ENTRY_VNT: return "*=-BlkValueCopy(*1, *<2)";
}
return "";
case INCREASE_BY_WORD:
if (reducing_modulo_1440) {
switch(storage_class) {
case LOCAL_VARIABLE_VNT: return "*=-*1 = NUMBER_TY_to_TIME_TY(*1 + *<2)";
case NONLOCAL_VARIABLE_VNT: return "*=-*1 = NUMBER_TY_to_TIME_TY(*1 + *<2)";
case TABLE_ENTRY_VNT: return "*=-*1*-,1,NUMBER_TY_to_TIME_TY(*1 + *<2))";
case PROPERTY_VALUE_VNT: return "*=-Write*+1*-,NUMBER_TY_to_TIME_TY(*+1 + *<2))";
case LIST_ENTRY_VNT: return "*=-Write*1*-,NUMBER_TY_to_TIME_TY(*1 + *<2))";
}
} else {
switch(storage_class) {
case LOCAL_VARIABLE_VNT: return "*=-*1 = *1 + *<2";
case NONLOCAL_VARIABLE_VNT: return "*=-*1 = *1 + *<2";
case TABLE_ENTRY_VNT: return "*=-*1*-,1,*1 + *<2)";
case PROPERTY_VALUE_VNT: return "*=-Write*+1*-,*+1 + *<2)";
case LIST_ENTRY_VNT: return "*=-Write*1*-,*1 + *<2)";
}
}
return "";
case INCREASE_BY_REAL:
switch(storage_class) {
case LOCAL_VARIABLE_VNT: return "*=-*1 = REAL_NUMBER_TY_Plus(*1, *<2)";
case NONLOCAL_VARIABLE_VNT: return "*=-*1 = REAL_NUMBER_TY_Plus(*1, *<2)";
case TABLE_ENTRY_VNT: return "*=-*1*-,1,REAL_NUMBER_TY_Plus(*1, *<2))";
case PROPERTY_VALUE_VNT: return "*=-Write*+1*-,REAL_NUMBER_TY_Plus(*+1, *<2))";
case LIST_ENTRY_VNT: return "*=-Write*1*-,REAL_NUMBER_TY_Plus(*1, *<2))";
}
return "";
case INCREASE_BY_POINTER:
internal_error("pointer value increments not implemented");
return "";
case DECREASE_BY_WORD:
if (reducing_modulo_1440) {
switch(storage_class) {
case LOCAL_VARIABLE_VNT: return "*=-*1 = NUMBER_TY_to_TIME_TY(*1 - *<2)";
case NONLOCAL_VARIABLE_VNT: return "*=-*1 = NUMBER_TY_to_TIME_TY(*1 - *<2)";
case TABLE_ENTRY_VNT: return "*=-*1*-,1,NUMBER_TY_to_TIME_TY(*1 - *<2))";
case PROPERTY_VALUE_VNT: return "*=-Write*+1*-,NUMBER_TY_to_TIME_TY(*+1 - *<2))";
case LIST_ENTRY_VNT: return "*=-Write*1*-,NUMBER_TY_to_TIME_TY(*1 - *<2))";
}
} else {
switch(storage_class) {
case LOCAL_VARIABLE_VNT: return "*=-*1 = *1 - *<2";
case NONLOCAL_VARIABLE_VNT: return "*=-*1 = *1 - *<2";
case TABLE_ENTRY_VNT: return "*=-*1*-,1,*1 - *<2)";
case PROPERTY_VALUE_VNT: return "*=-Write*+1*-,*+1 - *<2)";
case LIST_ENTRY_VNT: return "*=-Write*1*-,*1 - *<2)";
}
}
return "";
case DECREASE_BY_REAL:
switch(storage_class) {
case LOCAL_VARIABLE_VNT: return "*=-*1 = REAL_NUMBER_TY_Minus(*1, *<2)";
case NONLOCAL_VARIABLE_VNT: return "*=-*1 = REAL_NUMBER_TY_Minus(*1, *<2)";
case TABLE_ENTRY_VNT: return "*=-*1*-,1,REAL_NUMBER_TY_Minus(*1, *<2))";
case PROPERTY_VALUE_VNT: return "*=-Write*+1*-,REAL_NUMBER_TY_Minus(*+1, *<2))";
case LIST_ENTRY_VNT: return "*=-Write*1*-,REAL_NUMBER_TY_Minus(*1, *<2))";
}
return "";
case DECREASE_BY_POINTER:
internal_error("pointer value decrements not implemented");
return "";
}
return "";
}
#line 59 "inform7/Chapter 20/Conditions.w"
parse_node *Conditions__new(time_period *tp) {
parse_node *spec = ParseTree__new(TEST_PROPOSITION_VNT);
if (TimePeriods__get_tense(tp) != IS_TENSE) internal_error("tense improperly applied");
Conditions__attach_historic_requirement(spec, tp);
return spec;
}
#line 69 "inform7/Chapter 20/Conditions.w"
parse_node *Conditions__new_LOGICAL_AND(parse_node *spec1, parse_node *spec2) {
parse_node *spec = ParseTree__new(LOGICAL_AND_VNT);
spec->down = spec1;
spec->down->next = spec2;
return spec;
}
parse_node *Conditions__new_LOGICAL_OR(parse_node *spec1, parse_node *spec2) {
parse_node *spec = ParseTree__new(LOGICAL_OR_VNT);
spec->down = spec1;
spec->down->next = spec2;
return spec;
}
#line 86 "inform7/Chapter 20/Conditions.w"
parse_node *Conditions__negate(parse_node *cond) {
if (ParseTree__is(cond, LOGICAL_NOT_VNT)) return cond->down;
parse_node *spec = ParseTree__new_with_words(LOGICAL_NOT_VNT, ParseTree__get_text(cond));
spec->down = cond;
return spec;
}
#line 97 "inform7/Chapter 20/Conditions.w"
parse_node *Conditions__new_TEST_PROPOSITION(pcalc_prop *prop) {
parse_node *spec = ParseTree__new(TEST_PROPOSITION_VNT);
ParseTree__set_proposition(spec, prop);
return spec;
}
#line 107 "inform7/Chapter 20/Conditions.w"
parse_node *Conditions__new_TEST_PHRASE_OPTION(int opt_num) {
parse_node *spec = ParseTree__new(TEST_PHRASE_OPTION_VNT);
ParseTree__annotate_int(spec, phrase_option_ANNOT, opt_num);
return spec;
}
#line 116 "inform7/Chapter 20/Conditions.w"
parse_node *Conditions__new_TEST_ACTION(action_pattern *ap, wording W) {
if (ap == NULL) internal_error("null action pattern");
parse_node *spec = ParseTree__new_with_words(TEST_VALUE_VNT, W);
spec->down = Rvalues__from_action_pattern(ap);
ParseTree__set_text(spec->down, W);
return spec;
}
int Conditions__is_TEST_ACTION(parse_node *spec) {
if ((ParseTree__is(spec, TEST_VALUE_VNT)) &&
(Rvalues__to_action_pattern(spec->down))) return TRUE;
return FALSE;
}
parse_node *Conditions__action_tested(parse_node *spec) {
if (Conditions__is_TEST_ACTION(spec) == FALSE)
internal_error("action improperly extracted");
return spec->down;
}
#line 141 "inform7/Chapter 20/Conditions.w"
parse_node *Conditions__attach_tense(parse_node *cond, int t) {
parse_node *spec = NULL;
if (ParseTree__is(cond, LOGICAL_TENSE_VNT)) {
spec = cond;
TimePeriods__set_tense(ParseTree__get_condition_tense(spec), t);
} else {
spec = ParseTree__new_with_words(LOGICAL_TENSE_VNT, ParseTree__get_text(cond));
ParseTree__set_condition_tense(spec, TimePeriods__store(TimePeriods__new_tense_marker(t)));
spec->down = cond;
}
return spec;
}
parse_node *Conditions__attach_historic_requirement(parse_node *cond, time_period *tp) {
if (ParseTree__is(cond, AMBIGUITY_NT)) {
parse_node *amb = NULL;
for (cond = cond->down; cond; cond = cond->next_alternative) {
parse_node *reading = ParseTree__duplicate(cond);
reading->next_alternative = NULL;
reading = Conditions__attach_historic_requirement(reading, tp);
amb = ParseTree__add_possible_reading(amb,
reading, ParseTree__get_text(cond));
}
return amb;
}
int t = IS_TENSE;
parse_node *spec = NULL;
if (ParseTree__is(cond, LOGICAL_TENSE_VNT)) {
spec = cond;
t = TimePeriods__get_tense(ParseTree__get_condition_tense(cond));
} else {
spec = ParseTree__new_with_words(LOGICAL_TENSE_VNT, ParseTree__get_text(cond));
spec->down = cond;
t = IS_TENSE;
}
ParseTree__set_condition_tense(spec, tp);
TimePeriods__set_tense(ParseTree__get_condition_tense(spec), t);
return spec;
}
#line 184 "inform7/Chapter 20/Conditions.w"
void Conditions__write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
if (Specifications__is_description(spec)) {
Descriptions__write_out_in_English(OUT, spec);
} else if ((ParseTree__is(spec, TEST_VALUE_VNT)) && (ParseTree__is(spec->down, CONSTANT_VNT))) {
kind *K = Specifications__to_kind(spec->down);
if (K) {
Kinds__Textual__write_articled(OUT, K);
return;
}
} else {
WRITE("a condition");
}
}
#line 201 "inform7/Chapter 20/Conditions.w"
void Conditions__log(parse_node *spec) {
if (ParseTree__get_condition_tense(spec))
TimePeriods__log(ParseTree__get_condition_tense(spec));
if (ParseTree__is(spec, TEST_PROPOSITION_VNT))
LOG("(test: $D)", Specifications__to_proposition(spec));
if (Specifications__is_description(spec)) {
LOG("(st: $D)", Descriptions__to_proposition(spec));
}
}
#line 220 "inform7/Chapter 20/Conditions.w"
int Conditions__compare_specificity_of_CONDITIONs(parse_node *spec1, parse_node *spec2) {
if ((spec1 == NULL) && (spec2 == NULL)) return 0;
int count1 = Conditions__count(spec1);
int count2 = Conditions__count(spec2);
if (count1 > count2) return 1;
if (count1 < count2) return -1;
return 0;
}
#line 235 "inform7/Chapter 20/Conditions.w"
int Conditions__count(parse_node *spec) {
if (spec == NULL) return 0;
if (ParseTree__is_condition(spec) == FALSE) return 1;
switch (ParseTree__get_type(spec)) {
case LOGICAL_AND_VNT:
return Conditions__count(spec->down)
+ Conditions__count(spec->down->next);
case LOGICAL_OR_VNT:
return -1;
case LOGICAL_NOT_VNT:
return Conditions__count(spec->down);
case LOGICAL_TENSE_VNT:
return Conditions__count(spec->down);
case TEST_PROPOSITION_VNT:
return Calculus__Propositions__length(Specifications__to_proposition(spec));
case TEST_PHRASE_OPTION_VNT:
case TEST_VALUE_VNT:
return 1;
}
return 0;
}
#line 264 "inform7/Chapter 20/Conditions.w"
void Conditions__compile(OUTPUT_STREAM, parse_node *spec_found) {
WRITE("(");
switch (ParseTree__get_type(spec_found)) {
case TEST_PROPOSITION_VNT:
Calculus__Deferrals__compile_test_of_proposition(OUT, NULL,
Specifications__to_proposition(spec_found));
break;
case LOGICAL_TENSE_VNT: Chronology__compile_past_tense_condition(OUT, spec_found); break;
case LOGICAL_NOT_VNT:
{
#line 293 "inform7/Chapter 20/Conditions.w"
if (ParseTree__no_children(spec_found) != 1)
internal_error("Compiled malformed LOGICAL_NOT_VNT");
WRITE("(~~(");
Specifications__Compiler__compile(OUT, spec_found->down);
WRITE("))");
}
#line 272 "inform7/Chapter 20/Conditions.w"
; break;
case LOGICAL_AND_VNT: case LOGICAL_OR_VNT:
{
#line 302 "inform7/Chapter 20/Conditions.w"
if (ParseTree__no_children(spec_found) != 2)
internal_error("Compiled malformed logical operator");
parse_node *left_operand = spec_found->down;
parse_node *right_operand = spec_found->down->next;
if ((left_operand == NULL) || (right_operand == NULL))
internal_error("Compiled CONDITION/AND with LHS operands");
Specifications__Compiler__compile(OUT, left_operand);
if (ParseTree__is(spec_found, LOGICAL_AND_VNT)) WRITE(" && ");
if (ParseTree__is(spec_found, LOGICAL_OR_VNT)) WRITE(" || ");
Specifications__Compiler__compile(OUT, right_operand);
}
#line 273 "inform7/Chapter 20/Conditions.w"
; break;
case TEST_VALUE_VNT: {
if (Conditions__is_TEST_ACTION(spec_found)) {
action_pattern *ap = Rvalues__to_action_pattern(
Conditions__action_tested(spec_found));
PL__Actions__Patterns__compile_pattern_match(OUT, *ap, FALSE);
} else if (Specifications__is_description(spec_found)) {
WRITE("true"); /* purely for problem recovery */
} else Specifications__Compiler__compile(OUT, spec_found->down);
break;
}
case TEST_PHRASE_OPTION_VNT:
{
#line 321 "inform7/Chapter 20/Conditions.w"
WRITE("phrase_options & %d", ParseTree__int_annotation(spec_found, phrase_option_ANNOT));
}
#line 284 "inform7/Chapter 20/Conditions.w"
; break;
}
WRITE(")");
}
#line 13 "inform7/Chapter 20/Descriptions.w"
parse_node *Descriptions__from_proposition(pcalc_prop *prop, wording W) {
parse_node *spec = ParseTree__new_with_words(TEST_VALUE_VNT, W);
spec->down = Rvalues__constant_description(prop, W);
return spec;
}
pcalc_prop *Descriptions__to_proposition(parse_node *spec) {
if (Specifications__is_description(spec)) spec = spec->down;
else internal_error("tried to extract proposition from non-description");
if (Rvalues__is_CONSTANT_construction(spec, CON_description))
return Specifications__to_proposition(spec);
return NULL;
}
#line 30 "inform7/Chapter 20/Descriptions.w"
void Descriptions__set_proposition(parse_node *spec, pcalc_prop *prop) {
if (Specifications__is_description(spec)) spec = spec->down;
else internal_error("tried to set proposition for non-description");
if (Rvalues__is_CONSTANT_construction(spec, CON_description))
Rvalues__set_constant_description_proposition(spec, prop);
else internal_error("set domain proposition wrongly");
}
#line 43 "inform7/Chapter 20/Descriptions.w"
parse_node *Descriptions__from_kind(kind *K, int composited) {
parse_node *spec = Descriptions__from_proposition(NULL, EMPTY_WORDING);
if (K) { /* a test made only for error recovery */
pcalc_prop *prop;
if (composited)
prop = Calculus__Atoms__KIND_new_composited(K, Calculus__Terms__new_variable(0));
else
prop = Calculus__Atoms__KIND_new(K, Calculus__Terms__new_variable(0));
Calculus__Propositions__Checker__type_check(prop,
Calculus__Propositions__Checker__tc_no_problem_reporting());
Descriptions__set_proposition(spec, prop);
}
return spec;
}
kind *Descriptions__to_kind(parse_node *spec) {
return Calculus__Variables__infer_kind_of_variable_0(
Descriptions__to_proposition(spec));
}
#line 67 "inform7/Chapter 20/Descriptions.w"
int Descriptions__makes_kind_explicit(parse_node *spec) {
if ((Specifications__is_description(spec)) &&
(Descriptions__explicit_kind(spec))) return TRUE;
return FALSE;
}
kind *Descriptions__explicit_kind(parse_node *spec) {
return Calculus__Propositions__describes_kind(Descriptions__to_proposition(spec));
}
#line 83 "inform7/Chapter 20/Descriptions.w"
parse_node *Descriptions__from_instance(instance *I, wording W) {
if (I == NULL) internal_error("description of null instance");
parse_node *val = Rvalues__from_instance(I);
pcalc_prop *prop = Calculus__Atoms__prop_x_is_constant(val);
Calculus__Propositions__Checker__type_check(prop,
Calculus__Propositions__Checker__tc_no_problem_reporting());
return Descriptions__from_proposition(prop, W);
}
instance *Descriptions__to_instance(parse_node *spec) {
if (Specifications__is_description(spec)) {
pcalc_prop *prop = Descriptions__to_proposition(spec);
parse_node *val = Calculus__Propositions__describes_value(prop);
if (val == NULL) return NULL;
return Rvalues__to_instance(val);
}
return NULL;
}
#line 110 "inform7/Chapter 20/Descriptions.w"
parse_node *Descriptions__to_rvalue(parse_node *spec) {
if (Specifications__is_description(spec) == FALSE) internal_error("not a description");
pcalc_prop *prop = Calculus__Propositions__copy(
Descriptions__to_proposition(spec));
if (prop) {
prop = Calculus__Propositions__trim_universal_quantifier(prop);
if (Calculus__Variables__number_free(prop) != 1)
return NULL; /* Specifications__new_UNKNOWN(ParseTree__get_text(spec)); */
}
parse_node *con = ParseTree__new(CONSTANT_VNT);
ParseTree__set_kind_of_value(con,
Kinds__unary_construction(CON_description,
Calculus__Variables__infer_kind_of_variable_0(prop)));
ParseTree__set_proposition(con, prop);
ParseTree__set_text(con, ParseTree__get_text(spec));
return con;
}
#line 138 "inform7/Chapter 20/Descriptions.w"
int Descriptions__is_qualified(parse_node *spec) {
if ((Specifications__is_description(spec)) &&
((Descriptions__is_complex(spec)) ||
(Descriptions__number_of_adjectives_applied_to(spec) > 0)))
return TRUE;
return FALSE;
}
int Descriptions__is_kind_like(parse_node *spec) {
if ((Specifications__is_description(spec)) &&
(Calculus__Propositions__length(Descriptions__to_proposition(spec)) == 1) &&
(Descriptions__explicit_kind(spec)))
return TRUE;
return FALSE;
}
int Descriptions__is_complex(parse_node *spec) {
if (Specifications__is_description(spec))
return Calculus__Propositions__is_complex(
Descriptions__to_proposition(spec));
return FALSE;
}
int Descriptions__is_adjectives_plus_kind(parse_node *spec) {
if (Specifications__is_description(spec)) {
if (Descriptions__number_of_adjectives_applied_to(spec) == 0)
return FALSE;
kind *K = Descriptions__explicit_kind(spec);
if (K) return TRUE;
}
return FALSE;
}
#line 182 "inform7/Chapter 20/Descriptions.w"
int Descriptions__number_of_adjectives_applied_to(parse_node *spec) {
return Calculus__Propositions__count_unary_predicates(
Descriptions__to_proposition(spec));
}
adjective_usage *Descriptions__first_adjective_usage(parse_node *spec) {
return Calculus__Propositions__first_adjective_usage(
Descriptions__to_proposition(spec), NULL);
}
void Descriptions__add_to_adjective_list(adjective_usage *au, parse_node *spec) {
pcalc_prop *prop = Descriptions__to_proposition(spec);
adjectival_phrase *aph = Adjectives__Usages__get_aph(au);
int negated = FALSE;
if (Adjectives__Usages__get_parity(au) == FALSE) negated = TRUE;
prop = Calculus__Propositions__concatenate(prop,
Calculus__Atoms__unary_PREDICATE_from_aph(aph, negated));
Calculus__Propositions__Checker__type_check(prop,
Calculus__Propositions__Checker__tc_no_problem_reporting());
Descriptions__set_proposition(spec, prop);
}
void Descriptions__add_to_adjective_list_w(adjective_usage *au, parse_node *spec) {
quantifier *Q = Descriptions__get_quantifier(spec);
int N = Descriptions__get_quantification_parameter(spec);
pcalc_prop *prop = Descriptions__get_inner_prop(spec);
adjectival_phrase *aph = Adjectives__Usages__get_aph(au);
int negated = FALSE;
if (Adjectives__Usages__get_parity(au) == FALSE) negated = TRUE;
prop = Calculus__Propositions__concatenate(prop,
Calculus__Atoms__unary_PREDICATE_from_aph(aph, negated));
Calculus__Propositions__Checker__type_check(prop,
Calculus__Propositions__Checker__tc_no_problem_reporting());
Descriptions__set_proposition(spec, prop);
if (Q) Descriptions__quantify(spec, Q, N);
}
#line 223 "inform7/Chapter 20/Descriptions.w"
void Descriptions__quantify(parse_node *spec, quantifier *q, int par) {
pcalc_prop *prop = Descriptions__to_proposition(spec);
if (q != exists_quantifier)
prop = Calculus__Propositions__concatenate(Calculus__Atoms__new(DOMAIN_OPEN_ATOM), prop);
prop = Calculus__Propositions__concatenate(Calculus__Atoms__QUANTIFIER_new(q, 0, par), prop);
if (q != exists_quantifier)
prop = Calculus__Propositions__concatenate(prop, Calculus__Atoms__new(DOMAIN_CLOSE_ATOM));
Descriptions__set_proposition(spec, prop);
Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_no_problem_reporting());
}
pcalc_prop *Descriptions__get_inner_prop(parse_node *spec) {
pcalc_prop *prop = Descriptions__to_proposition(spec);
if ((prop) && (Calculus__Atoms__get_quantifier(prop))) {
prop = Calculus__Propositions__copy(prop);
prop = Calculus__Propositions__ungroup_after(prop, prop, NULL);
return prop->next;
}
return Calculus__Propositions__from_spec(spec);
}
pcalc_prop *Descriptions__get_quantified_prop(parse_node *spec) {
pcalc_prop *prop = Descriptions__to_proposition(spec);
if ((prop) && (Calculus__Atoms__get_quantifier(prop)) &&
(Calculus__Atoms__get_quantification_parameter(prop) > 0)) {
prop = Calculus__Propositions__copy(prop);
prop = Calculus__Propositions__ungroup_after(prop, prop, NULL);
return prop->next;
}
return Calculus__Propositions__from_spec(spec);
}
quantifier *Descriptions__get_quantifier(parse_node *spec) {
if (Specifications__is_description(spec))
return Calculus__Atoms__get_quantifier(Descriptions__to_proposition(spec));
return NULL;
}
int Descriptions__get_quantification_parameter(parse_node *spec) {
if (Specifications__is_description(spec))
return Calculus__Atoms__get_quantification_parameter(Descriptions__to_proposition(spec));
return 0;
}
#line 272 "inform7/Chapter 20/Descriptions.w"
void Descriptions__attach_calling(parse_node *spec, wording C) {
kind *K = Descriptions__explicit_kind(spec);
pcalc_prop *prop = Descriptions__to_proposition(spec);
prop = Calculus__Propositions__concatenate(
prop,
Calculus__Atoms__CALLED_new(C, Calculus__Terms__new_variable(0), K));
Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_no_problem_reporting());
Descriptions__set_proposition(spec, prop);
}
wording Descriptions__get_calling(parse_node *spec) {
if (Specifications__is_description(spec))
for (pcalc_prop *pp = Descriptions__to_proposition(spec); pp; pp = pp->next)
if (pp->element == CALLED_ATOM)
return Calculus__Atoms__CALLED_get_name(pp);
return EMPTY_WORDING;
}
void Descriptions__clear_calling(parse_node *spec) {
if (spec == NULL) return;
pcalc_prop *pp, *prev_pp = NULL;
for (pp = Descriptions__to_proposition(spec); pp; prev_pp = pp, pp = pp->next)
if (pp->element == CALLED_ATOM) {
Descriptions__set_proposition(spec,
Calculus__Propositions__delete_atom(
Descriptions__to_proposition(spec), prev_pp));
return;
}
}
int Descriptions__makes_callings(parse_node *spec) {
if (spec == NULL) return FALSE;
if (Specifications__is_description(spec)) {
if (Calculus__Propositions__contains_callings(Descriptions__to_proposition(spec)))
return TRUE;
wording C = Descriptions__get_calling(spec);
if (Wordings__nonempty(C)) return TRUE;
}
return FALSE;
}
#line 316 "inform7/Chapter 20/Descriptions.w"
void Descriptions__write_out_in_English(OUTPUT_STREAM, parse_node *spec) {
kind *K = Specifications__to_kind(spec);
WRITE("a description");
if (K) {
wording KW = Kinds__Behaviour__get_name(K, TRUE);
if (Wordings__nonempty(KW)) {
WRITE(" of ");
Wordings__to_stream_raw(OUT, KW);
}
}
}
#line 334 "inform7/Chapter 20/Descriptions.w"
int Descriptions__compare_specificity(parse_node *spec1, parse_node *spec2) {
{
#line 356 "inform7/Chapter 20/Descriptions.w"
int comp1 = Descriptions__is_complex(spec1);
int comp2 = Descriptions__is_complex(spec2);
if ((comp1) || (comp2)) {
if (comp2 == FALSE) return 1;
if (comp1 == FALSE) return -1;
int len1 = Calculus__Propositions__length(Descriptions__to_proposition(spec1));
int len2 = Calculus__Propositions__length(Descriptions__to_proposition(spec2));
if ((len1 > 0) || (len2 > 0)) {
LOGIF(SPECIFICITIES,
"Test %d: Comparing specificity of props:\n(%d) $D\n(%d) $D\n",
cco, len1, Descriptions__to_proposition(spec1), len2, Descriptions__to_proposition(spec2));
}
if (len1 > len2) return 1;
if (len1 < len2) return -1;
}
}
#line 335 "inform7/Chapter 20/Descriptions.w"
;
{
#line 375 "inform7/Chapter 20/Descriptions.w"
if (Kinds__Compare__compatible_with_description(spec1, spec2) == ALWAYS_MATCH) {
if (Kinds__Compare__compatible_with_description(spec2, spec1) != ALWAYS_MATCH) return 1;
} else {
if (Kinds__Compare__compatible_with_description(spec2, spec1) == ALWAYS_MATCH) return -1;
}
}
#line 336 "inform7/Chapter 20/Descriptions.w"
;
{
#line 384 "inform7/Chapter 20/Descriptions.w"
int count1 = Descriptions__number_of_adjectives_applied_to(spec1);
int count2 = Descriptions__number_of_adjectives_applied_to(spec2);
if (count1 > count2) return 1;
if (count1 < count2) return -1;
}
#line 337 "inform7/Chapter 20/Descriptions.w"
;
{
#line 392 "inform7/Chapter 20/Descriptions.w"
kind *k1 = Descriptions__explicit_kind(spec1);
kind *k2 = Descriptions__explicit_kind(spec2);
if ((k1) && (k2)) {
if (Kinds__Compare__lt(k1, k2)) return 1;
if (Kinds__Compare__lt(k2, k1)) return -1;
}
}
#line 338 "inform7/Chapter 20/Descriptions.w"
;
return 0;
}
#line 84 "inform7/Chapter 20/Compiling from Specifications.w"
void Specifications__Compiler__compile(OUTPUT_STREAM, parse_node *spec) {
LOGIF(EXPRESSIONS, "Compiling: $P\n", spec);
spec = NonlocalVariables__substitute_constants(spec);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(SPECIFICATIONS_CMODE);
LOG_INDENT;
parse_node breakable_copy = *spec;
Specifications__Compiler__spec_compile_primitive(OUT, &breakable_copy);
LOG_OUTDENT;
END_COMPILATION_MODE;
}
#line 100 "inform7/Chapter 20/Compiling from Specifications.w"
void Specifications__Compiler__spec_compile_primitive(OUTPUT_STREAM, parse_node *spec) {
kind *K_found = Specifications__to_kind(spec);
Kinds__Behaviour__notify_of_use(K_found);
char *suffix = "";
if (TEST_COMPILATION_MODE(DEREFERENCE_POINTERS_CMODE)) {
kind *K = Specifications__to_kind(spec);
if ((K) && (Kinds__Behaviour__uses_pointer_values(K))) {
WRITE("BlkValueCopy(");
Frames__compile_allocation(OUT, K);
WRITE(", ");
suffix = ")";
}
}
if (ParseTree__is_lvalue(spec)) Lvalues__compile(OUT, spec);
else if (ParseTree__is_rvalue(spec)) Rvalues__compile(OUT, spec);
else if (ParseTree__is_condition(spec)) Conditions__compile(OUT, spec);
WRITE("%s", suffix);
}
#line 124 "inform7/Chapter 20/Compiling from Specifications.w"
void Specifications__Compiler__compile_to_kind(OUTPUT_STREAM, parse_node *value, kind *K_wanted) {
Kinds__Behaviour__notify_of_use(K_wanted);
kind *K_found = Specifications__to_kind(value);
Kinds__Behaviour__notify_of_use(K_found);
if ((Kinds__Compare__eq(K_wanted, K_understanding)) && (Kinds__Compare__eq(K_found, K_text))) {
ParseTree__set_kind_of_value(value, K_understanding);
K_found = K_understanding;
}
int casting = Kinds__Behaviour__cast_call(OUT, K_found, K_wanted);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(PERMIT_LOCALS_IN_TEXT_CMODE);
Specifications__Compiler__compile(OUT, value);
END_COMPILATION_MODE;
if (casting) WRITE(")");
}
#line 145 "inform7/Chapter 20/Compiling from Specifications.w"
void Specifications__Compiler__compile_constant_to_kind(OUTPUT_STREAM, parse_node *value, kind *K_wanted) {
Kinds__Behaviour__notify_of_use(K_wanted);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
COMPILATION_MODE_ENTER(CONSTANT_CMODE);
Specifications__Compiler__compile(OUT, Kinds__Behaviour__cast_constant(value, K_wanted));
END_COMPILATION_MODE;
}
#line 86 "inform7/Chapter 20/Dash.w"
int dash_mode = ISSUE_PROBLEMS_DMODE; /* default */
kind **kind_of_var_to_create = NULL;
int dash_recursion_count = 0;
#line 109 "inform7/Chapter 20/Dash.w"
int no_gross_problems_thrown = 0;
int no_interesting_problems_thrown = 0;
int initial_problem_count = 0;
int backtraced_problem_count = 0;
int Dash__problems_have_been_issued(void) {
if (initial_problem_count < problem_count) return TRUE;
return FALSE;
}
#line 124 "inform7/Chapter 20/Dash.w"
kind_variable_declaration *most_recent_interpretation = NULL;
parse_node *Dash_ambiguity_list = NULL;
#line 145 "inform7/Chapter 20/Dash.w"
int unique_DR_call_identifier = 0, DR_call_counter = 0; /* solely to make the log more legible */
#line 158 "inform7/Chapter 20/Dash.w"
int Dash__worst_case(int rv1, int rv2) {
if ((rv1 == NEVER_MATCH) || (rv2 == NEVER_MATCH)) return NEVER_MATCH;
if ((rv1 == SOMETIMES_MATCH) || (rv2 == SOMETIMES_MATCH)) return SOMETIMES_MATCH;
return ALWAYS_MATCH;
}
#line 178 "inform7/Chapter 20/Dash.w"
int Dash__check_condition(parse_node *p) {
parse_node *cn = ParseTree__new(CONDITION_CONTEXT_NT);
cn->down = p;
LOGIF(MATCHING, "Dash (1): condition\n");
return Dash__funnel_to_level_2(cn, FALSE);
}
int Dash__check_value(parse_node *p, kind *K) {
parse_node *vn = ParseTree__new(RVALUE_CONTEXT_NT);
if (K) ParseTree__set_kind_required_by_context(vn, K);
vn->down = p;
if (K) LOGIF(MATCHING, "Dash (1): value of kind $u\n", K);
if (K == NULL) LOGIF(MATCHING, "Dash (1): value\n");
return Dash__funnel_to_level_2(vn, FALSE);
}
int Dash__check_value_silently(parse_node *p, kind *K) {
parse_node *vn = ParseTree__new(RVALUE_CONTEXT_NT);
if (K) ParseTree__set_kind_required_by_context(vn, K);
vn->down = p;
if (K) LOGIF(MATCHING, "Dash (1): value of kind $u\n", K);
if (K == NULL) LOGIF(MATCHING, "Dash (1): value\n");
return Dash__funnel_to_level_2(vn, TRUE);
}
int Dash__check_invl(parse_node *p) {
LOGIF(MATCHING, "Dash (1): invocation list '$w'\n", ParseTree__get_text(p));
return Dash__funnel_to_level_2(p, FALSE);
}
int Dash__funnel_to_level_2(parse_node *p, int silently) {
no_gross_problems_thrown = 0;
dash_recursion_count = 0;
BEGIN_DASH_MODE;
if (!silently) DASH_MODE_ENTER(ISSUE_PROBLEMS_DMODE);
initial_problem_count = problem_count;
DASH_MODE_CREATE(NULL);
Kinds__Compare__show_frame_variables();
int rv = Dash__typecheck_recursive(p, NULL, TRUE);
END_DASH_MODE;
return rv;
}
#line 242 "inform7/Chapter 20/Dash.w"
int Dash__typecheck_recursive(parse_node *p, parse_node *context, int consider_alternatives) {
if (p == NULL) internal_error("Dash on null node");
if (dash_recursion_count >= MAX_DASH_RECURSION) return NEVER_MATCH;
dash_recursion_count++;
int outer_id = unique_DR_call_identifier;
int problem_count_before = problem_count;
unique_DR_call_identifier = DR_call_counter++;
LOG_INDENT;
LOG_DASH("(2)");
int return_value = Dash__typecheck_recursive_inner(p, context, consider_alternatives);
switch(return_value) {
case ALWAYS_MATCH: LOG_DASH_LEFT; LOGIF(MATCHING, "== always\n"); break;
case SOMETIMES_MATCH: LOG_DASH_LEFT; LOGIF(MATCHING, "== sometimes\n"); break;
case NEVER_MATCH: LOG_DASH_LEFT; LOGIF(MATCHING, "== never\n"); break;
default: internal_error("impossible verdict from Dash");
}
LOG_OUTDENT;
if ((problem_count > problem_count_before) && (consider_alternatives))
{
#line 280 "inform7/Chapter 20/Dash.w"
if (problem_count > backtraced_problem_count) {
if ((p) && (p->down) &&
(ParseTree__get_type(p) == INVOCATION_LIST_NT)) {
it_is_not_worth_adding = TRUE;
{
#line 296 "inform7/Chapter 20/Dash.w"
parse_node *inv;
LOOP_THROUGH_ALTERNATIVES(inv, p->down) LOG("$e\n", inv);
int to_show = 0;
LOOP_THROUGH_ALTERNATIVES(inv, p->down) {
phrase *ph = ParseTree__get_phrase_invoked(inv);
if (Phrases__TypeData__is_a_spare_say_X_phrase(&(ph->type_data))) continue;
to_show++;
}
int announce = TRUE;
char *latest = Problems__Issue__latest_sigil();
if ((latest) && (strcmp(latest, "PM_AllInvsFailed") == 0)) announce = FALSE;
if (announce)
{
#line 321 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_begin("*");
if (to_show > 1)
Problems__issue_problem_segment("I was trying to match one of these phrases:");
else
Problems__issue_problem_segment("I was trying to match this phrase:");
Problems__issue_problem_end();
}
#line 310 "inform7/Chapter 20/Dash.w"
;
{
#line 331 "inform7/Chapter 20/Dash.w"
int shown = 0;
LOOP_THROUGH_ALTERNATIVES(inv, p->down) {
phrase *ph = ParseTree__get_phrase_invoked(inv);
if (Phrases__TypeData__is_a_spare_say_X_phrase(&(ph->type_data))) continue;
shown++;
Problems__quote_number(1, &shown);
Problems__quote_invocation(2, inv);
if (announce == FALSE) {
Problems__issue_problem_begin("***");
announce = TRUE;
} else {
Problems__issue_problem_begin("****");
}
if (to_show > 1) Problems__issue_problem_segment("%1. %2");
else Problems__issue_problem_segment("%2");
Problems__issue_problem_end();
}
}
#line 311 "inform7/Chapter 20/Dash.w"
;
int real_found = FALSE;
{
#line 352 "inform7/Chapter 20/Dash.w"
int any = FALSE;
inv_token_problem_token *itpt;
LOOP_OVER(itpt, inv_token_problem_token)
if (ParseTree__is(itpt->as_parsed, UNKNOWN_VNT) == FALSE)
if (itpt->already_described == FALSE) {
itpt->already_described = TRUE;
if (any == FALSE) {
any = TRUE;
Problems__issue_problem_begin("*");
Problems__issue_problem_segment("I recognised:");
Problems__issue_problem_end();
}
{
#line 370 "inform7/Chapter 20/Dash.w"
Problems__quote_wording_tinted_green(1, itpt->problematic_text);
Problems__quote_spec(2, itpt->as_parsed);
Problems__issue_problem_begin("****");
if (ParseTree__is_value(itpt->as_parsed)) {
kind *K = Specifications__to_kind(itpt->as_parsed);
int changed = FALSE;
K = Kinds__substitute(K, NULL, &changed);
Problems__quote_kind(3, K);
if (Kinds__Compare__eq(K, K_real_number)) real_found = TRUE;
if (ParseTree__is_lvalue(itpt->as_parsed))
{
#line 391 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment("%1 = <i>%2</i>, holding <i>%3</i>");
}
#line 380 "inform7/Chapter 20/Dash.w"
else if (ParseTree__is(itpt->as_parsed, PHRASE_TO_DECIDE_VALUE_VNT))
{
#line 396 "inform7/Chapter 20/Dash.w"
char *seg = "%1 = an instruction to work out <i>%3</i>";
if (K == NULL) seg = "%1 = a phrase";
parse_node *found_invl = itpt->as_parsed->down;
parse_node *inv;
LOOP_THROUGH_ALTERNATIVES(inv, found_invl) {
LOG("$e\n", inv);
if (Dash__reading_passed(inv) == FALSE) {
seg = "%1 = an instruction I think should work out <i>%3</i>, "
"but which I can't make sense of";
for (int i=0; i<Invocations__get_no_tokens(inv); i++) {
parse_node *tok = Invocations__get_token_as_parsed(inv, i);
if (ParseTree__is(tok, UNKNOWN_VNT)) {
Problems__quote_wording(4, ParseTree__get_text(tok));
seg = "%1 = an instruction I think should work out <i>%3</i>, "
"but which I can't perform because '%4' doesn't make sense here";
break;
}
}
}
}
Problems__issue_problem_segment(seg);
}
#line 382 "inform7/Chapter 20/Dash.w"
else
{
#line 421 "inform7/Chapter 20/Dash.w"
char *seg = "%1 = <i>%3</i>";
if (Rvalues__is_CONSTANT_construction(itpt->as_parsed, CON_property)) {
property *prn = ParseTree__get_constant_property(itpt->as_parsed);
if (Properties__is_value_property(prn)) {
binary_predicate *bp = Properties__Valued__get_stored_relation(prn);
if (bp) {
seg = "%1 = <i>%3</i>, which is used to store %4, "
"but is not the same thing as the relation itself";
Problems__quote_relation(4, bp);
}
}
}
Problems__issue_problem_segment(seg);
}
#line 384 "inform7/Chapter 20/Dash.w"
;
} else Problems__issue_problem_segment("%1 = <i>%2</i>");
Problems__issue_problem_end();
}
#line 364 "inform7/Chapter 20/Dash.w"
;
}
}
#line 313 "inform7/Chapter 20/Dash.w"
;
{
#line 466 "inform7/Chapter 20/Dash.w"
int unknowns = 0;
inv_token_problem_token *itpt;
LOOP_OVER(itpt, inv_token_problem_token)
if ((ParseTree__is(itpt->as_parsed, UNKNOWN_VNT)) &&
(itpt->new_name == FALSE))
if (itpt->already_described == FALSE) {
itpt->already_described = TRUE;
if (unknowns < 5) {
Problems__quote_wording_tinted_red(++unknowns,
itpt->problematic_text);
}
}
if (unknowns > 0) {
Problems__issue_problem_begin("*");
char *chunk = "";
switch (unknowns) {
case 1: chunk = "But I didn't recognise '%1'."; break;
case 2: chunk = "But I didn't recognise '%1' or '%2'."; break;
case 3: chunk = "But I didn't recognise '%1', '%2' or '%3'."; break;
case 4: chunk = "But I didn't recognise '%1', '%2', '%3' or '%4'."; break;
default: chunk = "But I didn't recognise '%1', '%2', '%3', '%4' and so on."; break;
}
Problems__issue_problem_segment(chunk);
Problems__issue_problem_end();
}
}
#line 314 "inform7/Chapter 20/Dash.w"
;
{
#line 438 "inform7/Chapter 20/Dash.w"
int unknowns = 0;
inv_token_problem_token *itpt;
LOOP_OVER(itpt, inv_token_problem_token)
if ((ParseTree__is(itpt->as_parsed, UNKNOWN_VNT)) && (itpt->new_name))
if (itpt->already_described == FALSE) {
itpt->already_described = TRUE;
if (unknowns < 5) {
Problems__quote_wording_tinted_red(++unknowns,
itpt->problematic_text);
}
}
if (unknowns > 0) {
Problems__issue_problem_begin("*");
char *chunk = "";
switch (unknowns) {
case 1: chunk = "The name '%1' doesn't yet exist."; break;
case 2: chunk = "The names '%1' and '%2' don't yet exist."; break;
case 3: chunk = "The names '%1', '%2' and '%3' don't yet exist."; break;
case 4: chunk = "The names '%1', '%2', '%3' and '%4' don't yet exist."; break;
default: chunk = "The names '%1', '%2', '%3', '%4', and so on, don't yet exist."; break;
}
Problems__issue_problem_segment(chunk);
Problems__issue_problem_end();
}
}
#line 315 "inform7/Chapter 20/Dash.w"
;
if (real_found)
{
#line 495 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_begin("*");
Problems__issue_problem_segment(
" %PNote that Inform's kinds 'number' and 'real number' are not "
"interchangeable. A 'number' like 7 can be used where a 'real "
"number' is expected - it becomes 7.000 - but not vice versa. "
"Use 'R to the nearest whole number' if you want to make a "
"conversion.");
Problems__issue_problem_end();
}
#line 316 "inform7/Chapter 20/Dash.w"
;
}
#line 284 "inform7/Chapter 20/Dash.w"
;
it_is_not_worth_adding = FALSE;
backtraced_problem_count = problem_count;
}
}
}
#line 264 "inform7/Chapter 20/Dash.w"
;
unique_DR_call_identifier = outer_id;
return return_value;
}
#line 521 "inform7/Chapter 20/Dash.w"
int Dash__typecheck_recursive_inner(parse_node *p, parse_node *context, int consider_alternatives) {
LOG_DASH("(3)");
switch (p->node_type) {
case CONDITION_CONTEXT_NT:
{
#line 548 "inform7/Chapter 20/Dash.w"
return SWITCH_CONTEXT_AND_RECURSE(p);
}
#line 524 "inform7/Chapter 20/Dash.w"
;
case RVALUE_CONTEXT_NT:
{
#line 548 "inform7/Chapter 20/Dash.w"
return SWITCH_CONTEXT_AND_RECURSE(p);
}
#line 526 "inform7/Chapter 20/Dash.w"
;
case MATCHING_RVALUE_CONTEXT_NT:
{
#line 593 "inform7/Chapter 20/Dash.w"
int rv = SWITCH_CONTEXT_AND_RECURSE(p);
if (rv != NEVER_MATCH)
rv = Dash__worst_case(rv,
Kinds__Compare__compatible_with_description(p->down,
ParseTree__get_token_to_be_parsed_against(p)));
return rv;
}
#line 527 "inform7/Chapter 20/Dash.w"
;
case SPECIFIC_RVALUE_CONTEXT_NT:
{
#line 617 "inform7/Chapter 20/Dash.w"
int rv = SWITCH_CONTEXT_AND_RECURSE(p);
if (rv != NEVER_MATCH) {
kind *K = Specifications__to_kind(p->down);
if ((Kinds__Behaviour__uses_pointer_values(K) == FALSE) &&
(ParseTree__is(p->down, CONSTANT_VNT))) {
parse_node *val = ParseTree__get_token_to_be_parsed_against(p);
if (!(Rvalues__compare_CONSTANT(p->down, val)))
{
#line 698 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p->down));
Problems__quote_spec(3, p->down);
Problems__quote_spec(4, val);
Problems__Issue__handmade_problem(_p_(PM_NotExactValueWanted));
Problems__issue_problem_segment(
"In the sentence %1, I was expecting that '%2' would be the specific "
"value '%4'.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 624 "inform7/Chapter 20/Dash.w"
;
} else {
rv = Dash__worst_case(rv, SOMETIMES_MATCH);
LOGIF(MATCHING, "dropping to sometimes level for value comparison\n");
}
}
return rv;
}
#line 528 "inform7/Chapter 20/Dash.w"
;
case VOID_CONTEXT_NT:
{
#line 637 "inform7/Chapter 20/Dash.w"
int rv = SWITCH_CONTEXT_AND_RECURSE(p);
if (rv != NEVER_MATCH) {
if (!(ParseTree__is(p->down, PHRASE_TO_DECIDE_VALUE_VNT))) {
{
#line 713 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p->down));
Problems__Issue__handmade_problem(_p_(...));
Problems__issue_problem_segment(
"In the sentence %1, I was expecting that '%2' would be a phrase.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 640 "inform7/Chapter 20/Dash.w"
;
}
}
return rv;
}
#line 529 "inform7/Chapter 20/Dash.w"
;
case LVALUE_CONTEXT_NT:
{
#line 554 "inform7/Chapter 20/Dash.w"
int rv = SWITCH_CONTEXT_AND_RECURSE(p);
if (ParseTree__is_lvalue(p->down) == FALSE)
{
#line 648 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p->down));
Problems__Issue__handmade_problem(_p_(PM_ValueAsStorageItem));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is a value, not a place where a value is "
"stored. "
"%PFor example, if 'The tally is a number that varies.', then "
"I can 'increment the tally', but I can't 'increment 37' - the "
"number 37 is always what it is. Similarly, I can't 'increment "
"the number of people'. Phrases like 'increment' work only on "
"stored values, like values that vary, or table entries.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 556 "inform7/Chapter 20/Dash.w"
;
return rv;
}
#line 531 "inform7/Chapter 20/Dash.w"
;
case LVALUE_TR_CONTEXT_NT:
{
#line 562 "inform7/Chapter 20/Dash.w"
int rv = SWITCH_CONTEXT_AND_RECURSE(p);
if (ParseTree__is(p->down, TABLE_ENTRY_VNT) == FALSE)
{
#line 666 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p->down));
Problems__Issue__handmade_problem(_p_(PM_ValueAsTableReference));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is a value, not a reference to an entry "
"in a table.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 564 "inform7/Chapter 20/Dash.w"
;
return rv;
}
#line 532 "inform7/Chapter 20/Dash.w"
;
case LVALUE_LOCAL_CONTEXT_NT:
{
#line 570 "inform7/Chapter 20/Dash.w"
int rv = SWITCH_CONTEXT_AND_RECURSE(p);
if (ParseTree__is(p->down, LOCAL_VARIABLE_VNT) == FALSE)
{
#line 679 "inform7/Chapter 20/Dash.w"
if (TEST_DASH_MODE(ISSUE_LOCAL_PROBLEMS_DMODE)) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
if (Specifications__is_kind_like(p->down))
Problems__quote_text(3, "a kind of value");
else
Problems__quote_kind_of(3, p->down);
Problems__Issue__handmade_problem(_p_(PM_ExistingVarNotFound));
Problems__issue_problem_segment(
"In the sentence %1, I was expecting that '%2' would be the "
"name of a temporary value, but it turned out to be %3.");
Problems__issue_problem_end();
}
return NEVER_MATCH;
}
#line 572 "inform7/Chapter 20/Dash.w"
;
return rv;
}
#line 533 "inform7/Chapter 20/Dash.w"
;
case NEW_LOCAL_CONTEXT_NT:
{
#line 742 "inform7/Chapter 20/Dash.w"
kind *K = ParseTree__get_kind_required_by_context(p);
parse_node *check = p->down;
if (ParseTree__is(check, AMBIGUITY_NT)) check = check->down;
if (LocalVariables__permit_as_new_local(check, FALSE)) {
if (kind_of_var_to_create) *kind_of_var_to_create = K;
return ALWAYS_MATCH;
}
{
#line 759 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
if (Specifications__is_kind_like(p->down))
Problems__quote_text(3, "a kind of value");
else
Problems__quote_kind_of(3, p->down);
Problems__quote_kind(4, K);
Problems__Issue__handmade_problem(_p_(PM_KindOfVariable));
Problems__issue_problem_segment(
"In the sentence %1, I was expecting that '%2' would be a new "
"variable name (to hold %4), but it turned out to be %3.");
Problems__issue_problem_end();
}
#line 749 "inform7/Chapter 20/Dash.w"
;
return NEVER_MATCH;
}
#line 535 "inform7/Chapter 20/Dash.w"
;
default:
{
#line 783 "inform7/Chapter 20/Dash.w"
kind *kind_needed = NULL;
int condition_context = FALSE;
if (context) {
kind_needed = ParseTree__get_kind_required_by_context(context);
if ((ParseTree__is(context, CONDITION_CONTEXT_NT)) ||
(ParseTree__is(context, LOGICAL_AND_VNT)) ||
(ParseTree__is(context, LOGICAL_OR_VNT)) ||
(ParseTree__is(context, LOGICAL_NOT_VNT)) ||
(ParseTree__is(context, LOGICAL_TENSE_VNT)))
condition_context = TRUE;
}
LOG_DASH("(4)");
int outcome = ALWAYS_MATCH;
if ((consider_alternatives) && (p->next_alternative))
{
#line 832 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4A)");
parse_node *list_of_possible_readings[MAX_INVOCATIONS_PER_PHRASE];
int no_of_possible_readings = 0;
int no_of_passed_readings = 0;
{
#line 856 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4A.a)");
parse_node *alt;
LOOP_THROUGH_ALTERNATIVES(alt, p)
if ((ParseTree__is(alt, INVOCATION_NT)) &&
(ParseTree__get_phrase_invoked(alt) != phrase_being_compiled))
{
#line 873 "inform7/Chapter 20/Dash.w"
if (no_of_possible_readings >= MAX_INVOCATIONS_PER_PHRASE) internal_error("overrun");
list_of_possible_readings[no_of_possible_readings++] = alt;
Dash__clear_flags(alt);
}
#line 861 "inform7/Chapter 20/Dash.w"
;
LOOP_THROUGH_ALTERNATIVES(alt, p)
if (!((ParseTree__is(alt, INVOCATION_NT)) &&
(ParseTree__get_phrase_invoked(alt) != phrase_being_compiled)))
{
#line 873 "inform7/Chapter 20/Dash.w"
if (no_of_possible_readings >= MAX_INVOCATIONS_PER_PHRASE) internal_error("overrun");
list_of_possible_readings[no_of_possible_readings++] = alt;
Dash__clear_flags(alt);
}
#line 865 "inform7/Chapter 20/Dash.w"
;
LOGIF(MATCHING, "Resolving %d possible readings:\n", no_of_possible_readings);
for (int i=0; i<no_of_possible_readings; i++)
LOGIF(MATCHING, "Possibility (P%d) $e\n", i, list_of_possible_readings[i]);
}
#line 837 "inform7/Chapter 20/Dash.w"
;
{
#line 883 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4A.b)");
for (int ref = 0; ref<no_of_possible_readings; ref++) {
parse_node *inv = list_of_possible_readings[ref];
{
#line 909 "inform7/Chapter 20/Dash.w"
LOGIF(MATCHING, "(P%d) Trying <$w>: $e\n", ref, ParseTree__get_text(inv), inv);
BEGIN_DASH_MODE;
DASH_MODE_EXIT(ISSUE_PROBLEMS_DMODE);
/* DASH_MODE_EXIT(ISSUE_INTERESTING_PROBLEMS_DMODE); */
int rv = Dash__typecheck_recursive(inv, context, FALSE);
END_DASH_MODE;
Dash__set_flag(inv, TESTED_DASHFLAG);
if (rv != NEVER_MATCH) {
Dash__set_flag(inv, PASSED_DASHFLAG);
outcome = Dash__worst_case(outcome, rv);
}
}
#line 887 "inform7/Chapter 20/Dash.w"
;
LOGIF(MATCHING, "(P%d) %s: $e\n", ref, Dash__verdict_to_text(inv), inv);
if (Dash__test_flag(inv, PASSED_DASHFLAG)) {
no_of_passed_readings++;
if (Dash__test_flag(inv, UNPROVEN_DASHFLAG) == FALSE) break;
}
if (Dash__problems_have_been_issued()) break; /* to prevent duplication of problem messages */
}
LOGIF(MATCHING, "List %s: ", (no_of_passed_readings > 0)?"passed":"failed");
for (int i=0; i<no_of_possible_readings; i++) {
parse_node *inv = list_of_possible_readings[i];
LOGIF(MATCHING, "%s ", Dash__quick_verdict_to_text(inv));
}
LOGIF(MATCHING, "|\n");
}
#line 838 "inform7/Chapter 20/Dash.w"
;
if (Dash__problems_have_been_issued()) return NEVER_MATCH;
if (no_of_passed_readings > 0)
{
#line 927 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4A.c)");
{
#line 947 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4A.c.1)");
int invocational = TRUE;
if (ParseTree__is(Dash_ambiguity_list, AMBIGUITY_NT)) invocational = FALSE;
LOGIF(MATCHING, "Winnow %s from $T\n",
(invocational)?"invocationally":"regularly", Dash_ambiguity_list);
if (invocational) Dash_ambiguity_list->down = NULL;
parse_node *last_survivor = NULL;
for (int ref = 0; ref<no_of_possible_readings; ref++) {
parse_node *inv = list_of_possible_readings[ref];
inv->next_alternative = NULL;
if (Dash__test_flag(inv, PASSED_DASHFLAG)) {
if (invocational) {
if (last_survivor) last_survivor->next_alternative = inv;
else Dash_ambiguity_list->down = inv;
last_survivor = inv;
} else {
parse_node *link = Dash_ambiguity_list->next;
ParseTree__copy(Dash_ambiguity_list, inv);
Dash_ambiguity_list->next = link;
Dash_ambiguity_list->next_alternative = NULL;
break;
}
}
}
if (invocational) {
p = Dash_ambiguity_list->down;
int nfi = -1, number_ambiguity = FALSE;
parse_node *inv;
LOOP_THROUGH_ALTERNATIVES(inv, p)
if (ParseTree__is(inv, INVOCATION_NT)) {
int nti = Invocations__get_no_tokens(inv);
if (nfi == -1) nfi = nti;
else if (nfi != nti) number_ambiguity = TRUE;
}
if (number_ambiguity)
{
#line 1000 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_UnequalValueAmbiguity));
Problems__issue_problem_segment(
"The phrase %1 is ambiguous in a way that I can't disentangle. "
"It has more than one plausible interpretation, such that it "
"would only be possible to tell which is valid at run-time: "
"ordinarily that would be fine, but because the different "
"interpretations are so different (and involve different "
"numbers of values being used) there's no good way to cope. "
"Try rewording one of the phrases which caused this clash: "
"there's a good chance the problem will then go away.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 986 "inform7/Chapter 20/Dash.w"
;
}
LOGIF(MATCHING, "After winnowing, CS is $T\n", current_sentence);
}
#line 928 "inform7/Chapter 20/Dash.w"
;
{
#line 1021 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4A.c.2)");
parse_node *inv;
LOOP_THROUGH_ALTERNATIVES(inv, p)
if (ParseTree__is(inv, INVOCATION_NT))
if (Dash__set_up_any_local_required(inv) == NEVER_MATCH)
return NEVER_MATCH;
}
#line 929 "inform7/Chapter 20/Dash.w"
;
}
#line 840 "inform7/Chapter 20/Dash.w"
else
{
#line 1031 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4A.d)");
THIS_IS_AN_ORDINARY_PROBLEM;
if (Invocations__length_of_list(p) == 0) return NEVER_MATCH;
LOGIF(MATCHING, "All possibilities failed: issuing problem\n");
return Dash__failed(list_of_possible_readings, no_of_possible_readings,
context, kind_needed);
}
#line 841 "inform7/Chapter 20/Dash.w"
;
LOGIF(MATCHING, "Ambiguity resolved to: $E", p);
}
#line 798 "inform7/Chapter 20/Dash.w"
else
{
#line 809 "inform7/Chapter 20/Dash.w"
switch (p->node_type) {
case PHRASE_TO_DECIDE_VALUE_VNT:
outcome = Dash__typecheck_recursive(p->down, context, TRUE);
break;
case INVOCATION_LIST_NT: case INVOCATION_LIST_SAY_NT: case AMBIGUITY_NT:
if (p->down == NULL)
{
#line 2053 "inform7/Chapter 20/Dash.w"
THIS_IS_A_GROSS_PROBLEM;
if (Preform__parse_nt_against_word_range(structural_phrase_problem_diagnosis_NTM, ParseTree__get_text(p), NULL, NULL) == FALSE) {
if (Wordings__mismatched_brackets(ParseTree__get_text(p))) {
Problems__Issue__sentence_problem(_p_(PM_UnpairedBrackets),
"this is a phrase which I don't recognise",
"perhaps because it uses brackets '(' and ')' or braces '{' and '}' "
"in a way that doesn't make sense to me. Each open '(' or '{' has "
"to have a matching ')' or '}'.");
} else {
Problems__Issue__sentence_problem(_p_(PM_UnknownPhrase),
"this is a phrase which I don't recognise",
"possibly because it is one you meant to define but never got round "
"to, or because the wording is wrong (see the Phrasebook section of "
"the Index to check). Alternatively, it may be that the text "
"immediately previous to this was a definition whose ending, normally "
"a full stop, is missing?");
}
}
return NEVER_MATCH;
}
#line 815 "inform7/Chapter 20/Dash.w"
;
BEGIN_DASH_MODE;
DASH_MODE_INVL(p);
outcome = Dash__typecheck_recursive(p->down, context, TRUE);
END_DASH_MODE;
break;
case INVOCATION_NT:
{
#line 1052 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I)");
int no_gross_problems_thrown_before = no_gross_problems_thrown;
int no_interesting_problems_thrown_before = no_interesting_problems_thrown;
int qualified = FALSE;
parse_node *inv = p;
Phrases__Parser__parse_within_inv(inv);
Dash__set_flag(inv, TESTED_DASHFLAG);
phrase *ph = ParseTree__get_phrase_invoked(inv);
if (ph) {
ParseTree__set_kind_resulting(inv, Phrases__TypeData__get_return_kind(&(ph->type_data)));
/* are the arguments of the right kind? */
if (outcome != NEVER_MATCH)
{
#line 1102 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.a)");
if (Phrases__TypeData__arithmetic_operation(ph) == TOTAL_OPERATION)
{
#line 1112 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.a.1)");
parse_node *P = Invocations__get_token_as_parsed(inv, 0);
int rv = Dash__typecheck_recursive(P, NULL, TRUE);
if ((rv != NEVER_MATCH) && (Rvalues__is_CONSTANT_construction(P, CON_property))) {
property *prn = Rvalues__to_property(P);
if (Properties__is_value_property(prn))
ParseTree__set_kind_resulting(inv, Properties__Valued__kind(prn));
else {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__Issue__sentence_problem(_p_(PM_TotalEitherOr),
"this seems to be an attempt to total up an either/or property",
"and by definition such a property has nothing to total.");
}
}
} else
{
#line 1133 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.a.1) failed as nonproperty");
if (Kinds__get_construct(ParseTree__get_kind_of_value(P)) == CON_table_column) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__Issue__sentence_problem(_p_(PM_TotalTableColumn),
"this seems to be an attempt to total up the column of a table",
"whereas it's only legal to use 'total' for properties.");
}
}
outcome = NEVER_MATCH;
}
#line 1126 "inform7/Chapter 20/Dash.w"
;
}
#line 1104 "inform7/Chapter 20/Dash.w"
else if (Phrases__TypeData__is_arithmetic_phrase(ph))
{
#line 1146 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.a.2)");
int op_number = Phrases__TypeData__arithmetic_operation(ph);
LOGIF(MATCHING, "Arithmetic operation <op-%d>\n", op_number);
parse_node *L, *R;
kind *kind_wanted, *left_kind, *right_kind, *kind_produced;
{
#line 1161 "inform7/Chapter 20/Dash.w"
L = Invocations__get_token(inv, 0);
left_kind = Dash__fix_arithmetic_operand(L);
if (Kinds__Dimensions__arithmetic_op_is_unary(op_number)) {
R = NULL; right_kind = NULL;
} else {
R = Invocations__get_token(inv, 1);
right_kind = Dash__fix_arithmetic_operand(R);
}
if (((left_kind) && (Kinds__Behaviour__is_quasinumerical(left_kind) == FALSE)) ||
((right_kind) && (Kinds__Behaviour__is_quasinumerical(right_kind) == FALSE)))
kind_produced = NULL;
else
kind_produced = Kinds__Dimensions__arithmetic_on_kinds(left_kind, right_kind, op_number);
kind_wanted = kind_needed;
}
#line 1152 "inform7/Chapter 20/Dash.w"
;
LOGIF(MATCHING, "$u (~) $u = $u\n", left_kind, right_kind, kind_produced);
if (kind_produced) ParseTree__set_kind_resulting(inv, kind_produced);
else
{
#line 1182 "inform7/Chapter 20/Dash.w"
LOG("Fail: $u (~) $u = $u\n", left_kind, right_kind, kind_produced);
if ((left_kind) && (Kinds__Compare__eq(left_kind, K_value) == FALSE) &&
(right_kind) && (Kinds__Compare__eq(right_kind, K_value) == FALSE)) {
THIS_IS_AN_INTERESTING_PROBLEM {
LOG("So the inv subtree is:\n$T\n", inv);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(L));
Problems__quote_wording(3, ParseTree__get_text(R));
Problems__quote_kind(4, left_kind);
Problems__quote_kind(5, right_kind);
switch(op_number) {
case PLUS_OPERATION: Problems__quote_text(6, "adding"); Problems__quote_text(7, "to"); break;
case MINUS_OPERATION: Problems__quote_text(6, "subtracting"); Problems__quote_text(7, "from"); break;
case TIMES_OPERATION: Problems__quote_text(6, "multiplying"); Problems__quote_text(7, "by"); break;
case DIVIDE_OPERATION:
case REMAINDER_OPERATION: Problems__quote_text(6, "dividing"); Problems__quote_text(7, "by"); break;
case APPROXIMATION_OPERATION: Problems__quote_text(6, "rounding"); Problems__quote_text(7, "to"); break;
}
Problems__Issue__handmade_problem(_p_(PM_BadArithmetic));
Problems__issue_problem_segment(
"You wrote %1, but that seems to involve %6 %4 ('%2') %7 %5 ('%3'), "
"which is not good arithmetic.");
Problems__issue_problem_end();
}
}
outcome = NEVER_MATCH;
}
#line 1156 "inform7/Chapter 20/Dash.w"
;
}
#line 1105 "inform7/Chapter 20/Dash.w"
;
}
#line 1064 "inform7/Chapter 20/Dash.w"
;
if (outcome != NEVER_MATCH)
{
#line 1220 "inform7/Chapter 20/Dash.w"
if (Phrases__TypeData__is_arithmetic_phrase(ph) == FALSE) {
LOG_DASH("(4I.b)");
int i, exit_at_once = FALSE;
for (i=0; i<Invocations__get_no_tokens(inv); i++) {
LOGIF(MATCHING, "(4I.b) trying argument %d (prior to this, best possible: %d)\n",
i, outcome);
Invocations__set_token_check_to_do(inv, i, NULL);
{
#line 1237 "inform7/Chapter 20/Dash.w"
parse_node *ith_spec = ph->type_data.token_sequence[i].to_match;
if ((ph->type_data.token_sequence[i].construct == KIND_NAME_PT_CONSTRUCT) && (outcome != NEVER_MATCH))
{
#line 1311 "inform7/Chapter 20/Dash.w"
outcome = NEVER_MATCH;
parse_node *ith_token = Invocations__get_token_as_parsed(inv, i);
LOGIF(MATCHING, "(4I.b) thinking about reparsing: $P\n", ith_token);
int warned_already = FALSE;
if (ParseTree__is(ith_token, AMBIGUITY_NT)) ith_token = ith_token->down;
if ((ParseTree__is(ith_token, UNKNOWN_VNT)) ||
(Specifications__is_description(ith_token)) ||
(Rvalues__is_CONSTANT_construction(ith_token, CON_property)) ||
(Specifications__is_kind_like(ith_token)) ||
((Phrases__TypeData__is_a_let_assignment(ph) == FALSE) &&
(ParseTree__is(ith_token, PHRASE_TO_DECIDE_VALUE_VNT)))) {
wording W = ParseTree__get_text(ith_token);
kind *K = NULL;
parse_node *reparsed = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, W, NULL, NULL)) reparsed = most_recent_result_p;
if (Specifications__is_kind_like(reparsed))
K = Specifications__to_kind(reparsed);
if ((K == NULL) && (Preform__parse_nt_against_word_range(k_kind_NTM, W, NULL, NULL))) K = most_recent_result_p;
if (K == NULL) {
if ((Preform__parse_nt_against_word_range(value_property_name_NTM, W, NULL, NULL)) &&
(Properties__Valued__coincides_with_kind(most_recent_result_p)))
K = Properties__Valued__kind(most_recent_result_p);
}
LOGIF(MATCHING, "(4I.b) reparsed as: $u (vs spec $P)\n", K, ith_spec);
if ((K) && (Specifications__is_kind_like(ith_spec))) {
kind *ikind = Specifications__to_kind(ith_spec);
if (Kinds__Behaviour__definite(K)) {
if (Kinds__Compare__compatible(K, ikind) == ALWAYS_MATCH) {
LOGIF(MATCHING, "(4I.b) allows name-of token: $P\n", reparsed);
Invocations__set_token_as_parsed(inv, i, ParseTree__duplicate(reparsed));
outcome = ALWAYS_MATCH;
} else {
THIS_IS_AN_ORDINARY_PROBLEM {
warned_already = TRUE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_kind(3, ikind);
Problems__Issue__handmade_problem(_p_(PM_NameOfKindMismatch));
Problems__issue_problem_segment(
"You wrote %1, but although '%2' is the name of a kind, "
"it isn't the name of a kind of %3, which this phrase needs.");
Problems__issue_problem_end();
}
}
} else {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM {
warned_already = TRUE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_kind(3, ikind);
Problems__Issue__handmade_problem(_p_(PM_BadLocalKOV));
Problems__issue_problem_segment(
"You wrote %1, but although '%2' is the name of a kind, "
"it isn't a definite kind and is instead a general "
"description which might apply to many different kinds. "
"(For example, 'let R be a relation' is vague because it doesn't "
"make clear what R will relate - 'let R be a relation of numbers' "
"would be fine.)");
Problems__issue_problem_end();
}
}
}
}
ith_token = Invocations__get_token_as_parsed(inv, i);
if ((!Specifications__is_kind_like(ith_token)) && (warned_already == FALSE)) {
THIS_IS_AN_ORDINARY_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(ith_token));
Problems__Issue__handmade_problem(_p_(PM_NameOfKindIsnt));
Problems__issue_problem_segment(
"You wrote %1, but although '%2' does have a meaning, "
"it isn't the name of a kind, which this phrase needs.");
Problems__issue_problem_end();
}
}
}
#line 1239 "inform7/Chapter 20/Dash.w"
else {
int save_kcm = kind_checker_mode;
kind_checker_mode = MATCH_KIND_VARIABLES_AS_UNIVERSAL;
kind *create = NULL;
BEGIN_DASH_MODE;
DASH_MODE_EXIT(ISSUE_PROBLEMS_DMODE);
DASH_MODE_CREATE(&create);
int rv = Dash__typecheck_recursive(Invocations__get_token(inv, i), context, TRUE);
END_DASH_MODE;
switch(rv) {
case NEVER_MATCH:
LOGIF(MATCHING, "(4I.b) on $w failed at token %d\n", ParseTree__get_text(p), i);
outcome = NEVER_MATCH;
if (Dash__problems_have_been_issued()) exit_at_once = TRUE;
break;
case SOMETIMES_MATCH:
LOGIF(MATCHING, "(4I.b) on $w qualified at token %d\n", ParseTree__get_text(p), i);
Invocations__set_token_check_to_do(inv, i, ith_spec);
qualified = TRUE;
break;
}
kind_checker_mode = save_kcm;
if (create) {
if ((Routines__Compile__disallow_let()) && (Phrases__TypeData__is_a_let_assignment(ph))) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_LetCreatedInIf));
Problems__issue_problem_segment(
"You wrote %1, but when a temporary value is created "
"inside an 'if ..., ...' or an 'otherwise ...', it only "
"lasts until that line is complete - which means it "
"can never be used for anything, because it goes away "
"as soon as created. To make something more durable, "
"create it before the 'if' or 'otherwise'.");
Problems__issue_problem_end();
}
}
Invocations__set_token_variable_kind(inv, i, create);
}
}
}
#line 1227 "inform7/Chapter 20/Dash.w"
;
if (exit_at_once) break;
}
LOGIF(MATCHING, "(4I.b) argument type matching %s\n",
(outcome==NEVER_MATCH)?"failed":"passed");
}
}
#line 1065 "inform7/Chapter 20/Dash.w"
;
if (outcome != NEVER_MATCH)
{
#line 1396 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.c)");
int exit_at_once = FALSE;
kind_variable_declaration *kvd_marker = LAST_OBJECT(kind_variable_declaration);
if (Phrases__TypeData__contains_variables(&(ph->type_data))) {
kind_variable_declaration *save_most_recent_interpretation = most_recent_interpretation;
int pass, save_kcm = kind_checker_mode;
for (pass = 1; pass <= 2; pass++) {
LOGIF(MATCHING, "(4I.c) prototype check pass %d\n", pass);
if (Log__aspect_switched_on(MATCHING_DA)) Kinds__Compare__show_variables();
if (pass == 1) kind_checker_mode = MATCH_KIND_VARIABLES_INFERRING_VALUES;
else kind_checker_mode = MATCH_KIND_VARIABLES_AS_VALUES;
int i;
for (i=0; i<Invocations__get_no_tokens(inv); i++) {
if ((ph->type_data.token_sequence[i].token_kind) &&
(ph->type_data.token_sequence[i].construct != NEW_LOCAL_PT_CONSTRUCT)) {
parse_node *token_spec = Invocations__get_token_as_parsed(inv, i);
kind *kind_read = Specifications__to_kind(token_spec);
LOGIF(MATCHING, "Token %d: $P: kind $u: template $u\n", i,
token_spec, kind_read, ph->type_data.token_sequence[i].token_kind);
switch(Kinds__Compare__compatible(kind_read, ph->type_data.token_sequence[i].token_kind)) {
case NEVER_MATCH:
LOGIF(MATCHING, "(4I.c) failed at token %d\n", i);
outcome = NEVER_MATCH;
if (Dash__problems_have_been_issued()) exit_at_once = TRUE;
break;
case SOMETIMES_MATCH:
outcome = Dash__worst_case(outcome, SOMETIMES_MATCH);
/* we won't use |with_qualifications| -- we don't know exactly what they are */
LOGIF(MATCHING, "(4I.c) dropping to sometimes at token %d\n", i);
break;
case ALWAYS_MATCH:
break;
}
}
if (exit_at_once) break;
}
if (exit_at_once) break;
if ((pass == 1) && (outcome != NEVER_MATCH)) {
LOGIF(MATCHING, "(4I.c) prototype check passed\n");
most_recent_interpretation = NULL;
kind_variable_declaration *kvdm = kvd_marker;
if (kvdm) kvdm = NEXT_OBJECT(kvdm, kind_variable_declaration);
else kvdm = FIRST_OBJECT(kind_variable_declaration);
while (kvdm) {
kvdm->next = most_recent_interpretation;
most_recent_interpretation = kvdm;
kvdm = NEXT_OBJECT(kvdm, kind_variable_declaration);
}
}
}
kind_checker_mode = save_kcm;
if (outcome != NEVER_MATCH) ParseTree__set_kind_variable_declarations(inv, most_recent_interpretation);
most_recent_interpretation = save_most_recent_interpretation;
}
if (Kinds__contains(ParseTree__get_kind_resulting(inv), CON_KIND_VARIABLE)) {
int changed = FALSE;
kind *K = Kinds__substitute(ParseTree__get_kind_resulting(inv), NULL, &changed);
if (changed) {
LOGIF(MATCHING, "(4I.c) amended kind returned to $u\n", K);
ParseTree__set_kind_resulting(inv, K);
} else
{
#line 1465 "inform7/Chapter 20/Dash.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"In the line %1, you seem to be using '%2' to produce a value, but "
"it's not clear what kind of value this will be. It seems to use "
"a phrase which has been declared wrongly, because the kind it decides "
"is given only by a symbol which isn't otherwise defined.");
Problems__issue_problem_end();
outcome = NEVER_MATCH;
}
#line 1459 "inform7/Chapter 20/Dash.w"
;
}
}
#line 1066 "inform7/Chapter 20/Dash.w"
;
if (outcome != NEVER_MATCH)
{
#line 1503 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.d)");
if (Phrases__TypeData__is_assignment_phrase(ph)) {
parse_node *target = Invocations__get_token_as_parsed(inv, 0);
parse_node *new_value = Invocations__get_token_as_parsed(inv, 1);
parse_node *target_spec = ph->type_data.token_sequence[0].to_match;
parse_node *new_value_spec = ph->type_data.token_sequence[1].to_match;
local_variable *lvar = Lvalues__get_local_variable_if_any(target);
if ((lvar) && (LocalVariables__protected(lvar)))
outcome = NEVER_MATCH;
else {
if (Kinds__Compare__le(Specifications__to_kind(target_spec), K_object))
{
#line 1530 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.d.1)");
instance *target_wo = Rvalues__to_object_instance(target);
property *prn = NULL;
int make_check = FALSE;
if (Kinds__Compare__eq(ParseTree__get_kind_of_value(new_value_spec), K_value))
{
#line 1555 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.d.1.a)");
instance *I = Rvalues__to_instance(new_value);
if (I == NULL) outcome = NEVER_MATCH;
else {
prn = Kinds__Behaviour__get_coinciding_property(Instances__to_kind(I));
if (prn == NULL) outcome = NEVER_MATCH;
else make_check = TRUE;
}
}
#line 1535 "inform7/Chapter 20/Dash.w"
;
if (Rvalues__is_CONSTANT_construction(new_value_spec, CON_property))
{
#line 1578 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.d.1.b)");
if (Rvalues__is_CONSTANT_construction(new_value, CON_property))
prn = Rvalues__to_property(new_value);
else if (Descriptions__number_of_adjectives_applied_to(new_value) == 1) {
adjectival_phrase *aph = Adjectives__Usages__get_aph(Descriptions__first_adjective_usage(new_value));
if (Adjectives__Phrases__has_ENUMERATIVE_meaning(aph))
prn = Kinds__Behaviour__get_coinciding_property(Instances__to_kind(Adjectives__Phrases__has_ENUMERATIVE_meaning(aph)));
else if (Adjectives__Phrases__has_EORP_meaning(aph, NULL))
prn = Adjectives__Phrases__has_EORP_meaning(aph, NULL);
}
make_check = TRUE;
}
#line 1537 "inform7/Chapter 20/Dash.w"
;
if (make_check)
{
#line 1606 "inform7/Chapter 20/Dash.w"
LOGIF(MATCHING, "Property appears to be $Y\n", prn);
if (prn == NULL) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(target));
Problems__quote_wording(3, ParseTree__get_text(new_value));
Problems__Issue__handmade_problem(_p_(BelievedImpossible)); /* the parser seems not to allow these */
Problems__issue_problem_segment(
"You wrote %1, asking to change the object '%2'. This would "
"make sense if '%3' were an either/or property like 'open' "
"(or perhaps a named property value like 'blue') - but it "
"isn't, so the change makes no sense.");
Problems__issue_problem_end();
}
}
if ((target_wo) && (prn) &&
(World__Permissions__find(Instances__as_subject(target_wo), prn, TRUE) == NULL)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(target));
Problems__quote_property(3, prn);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is not allowed to have the property '%3'.");
Problems__issue_problem_end();
}
}
}
#line 1539 "inform7/Chapter 20/Dash.w"
;
}
#line 1516 "inform7/Chapter 20/Dash.w"
;
if (ph->type_data.token_sequence[0].construct != NEW_LOCAL_PT_CONSTRUCT)
{
#line 1640 "inform7/Chapter 20/Dash.w"
kind *kind_wanted, *kind_found;
LOGIF(MATCHING, "Check assignment of $P to $P\n", new_value, target);
switch(Lvalues__get_storage_form(target_spec)) {
case LOCAL_VARIABLE_VNT: Problems__quote_text(6, "the name of"); break;
case PROPERTY_VALUE_VNT: Problems__quote_text(6, "a property whose kind of value is"); break;
case NONLOCAL_VARIABLE_VNT: Problems__quote_text(6, "a variable whose kind of value is"); break;
case TABLE_ENTRY_VNT: Problems__quote_text(6, "a table entry whose kind of value is"); break;
case LIST_ENTRY_VNT: Problems__quote_text(6, "an entry in a list whose kind of value is"); break;
default: Problems__quote_text(6, "a stored value holding"); break;
}
kind_wanted = Specifications__to_kind(target);
kind_found = Specifications__to_kind(new_value);
parse_node *new_invl = new_value->down;
if (ParseTree__is(new_invl, INVOCATION_LIST_NT)) {
parse_node *new_inv;
LOOP_THROUGH_ALTERNATIVES(new_inv, new_invl)
if (Dash__test_flag(new_inv, PASSED_DASHFLAG)) break;
if (new_inv) kind_found = ParseTree__get_kind_resulting(new_inv);
}
LOGIF(MATCHING, "Kinds found: $u, wanted: $u\n", kind_found, kind_wanted);
if (((Kinds__Compare__eq(kind_wanted, K_understanding)) &&
(Kinds__Compare__eq(kind_found, K_understanding) == FALSE))
|| (Kinds__Compare__compatible(kind_found, kind_wanted) == NEVER_MATCH)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(target));
Problems__quote_kind(3, Specifications__to_kind(target));
Problems__quote_wording(4, ParseTree__get_text(new_value));
Problems__quote_kind(5, Specifications__to_kind(new_value));
Problems__Issue__handmade_problem(_p_(PM_ChangeToWrongValue));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is supposed to be "
"%6 %3, so it cannot be set equal to %4, whose kind is %5.");
Problems__issue_problem_end();
}
}
}
#line 1519 "inform7/Chapter 20/Dash.w"
;
}
}
}
#line 1067 "inform7/Chapter 20/Dash.w"
;
/* if this evaluates something, is it a value of the right kind? */
if (outcome != NEVER_MATCH)
{
#line 1694 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.e)");
int outcome_test = ALWAYS_MATCH;
if (kind_needed) {
LOGIF(MATCHING, "Checking returned $u against desired $u\n",
ParseTree__get_kind_resulting(inv), kind_needed);
outcome_test = Kinds__Compare__compatible(
ParseTree__get_kind_resulting(inv), kind_needed);
}
switch (outcome_test) {
case NEVER_MATCH: outcome = NEVER_MATCH; break;
case SOMETIMES_MATCH: outcome = Dash__worst_case(outcome, SOMETIMES_MATCH); break;
}
}
#line 1070 "inform7/Chapter 20/Dash.w"
;
/* are there any special rules about invoking this phrase? */
if (outcome != NEVER_MATCH)
{
#line 1711 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.f)");
if ((outcome != NEVER_MATCH) && (ParseTree__get_phrase_options_invoked(inv))) {
int cso = Phrases__Options__parse_invoked_options(
inv, (TEST_DASH_MODE(ISSUE_PROBLEMS_DMODE))?FALSE:TRUE);
if (cso == FALSE) outcome = NEVER_MATCH;
}
}
#line 1073 "inform7/Chapter 20/Dash.w"
;
if (outcome != NEVER_MATCH)
{
#line 1734 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.g)");
if ((Phrases__TypeData__is_a_say_phrase(ph)) &&
(Invocations__get_no_tokens(inv) == 1) &&
(Lvalues__get_storage_form(Invocations__get_token_as_parsed(inv, 0)) == PROPERTY_VALUE_VNT)) {
ParseTree__annotate_int(Invocations__get_token_as_parsed(inv, 0), record_as_self_ANNOT, TRUE);
Invocations__mark_to_save_self(inv);
}
}
#line 1074 "inform7/Chapter 20/Dash.w"
;
if (outcome != NEVER_MATCH)
{
#line 1750 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.h)");
if (ph) {
char *required = Phrases__TypeData__only_in(ph);
if (required) {
if (strcmp(required, "loop") == 0) {
LOGIF(MATCHING, "Required to be inside loop body\n");
if (Frames__Blocks__inside_a_loop_body() == FALSE) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_CantUseOutsideLoop));
Problems__issue_problem_segment(
"%1 makes sense only inside a 'while' or 'repeat' loop.");
Problems__issue_problem_end();
}
}
} else {
LOGIF(MATCHING, "Required to be inside block '%s'\n", required);
char *actual = Frames__Blocks__name_of_current_block();
if ((actual) && (strcmp(actual, "unless") == 0)) actual = "if";
if ((actual == NULL) || (strcmp(required, actual) != 0)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, required);
Problems__Issue__handmade_problem(_p_(PM_CantUseOutsideStructure));
Problems__issue_problem_segment(
"%1 makes sense only inside a '%2' block.");
Problems__issue_problem_end();
}
}
}
}
}
}
#line 1075 "inform7/Chapter 20/Dash.w"
;
if (outcome != NEVER_MATCH)
{
#line 1786 "inform7/Chapter 20/Dash.w"
if (no_deprecated_features) {
LOG_DASH("(4I.i)");
if ((ph) && (ph->type_data.now_deprecated)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(BelievedImpossible)); /* too moving a target to test */
Problems__issue_problem_segment(
"'%1' uses a phrase which is now deprecated: you should rephrase "
"to avoid the need for it. I'd normally allow this, but you have "
"the 'Use no deprecated features' option set.");
Problems__issue_problem_end();
}
}
}
}
#line 1076 "inform7/Chapter 20/Dash.w"
;
/* should we mark to create a let variable here? */
if ((outcome != NEVER_MATCH) && (consider_alternatives))
outcome = Dash__worst_case(outcome, Dash__set_up_any_local_required(inv));
}
/* the outcome is now definitely known */
if (outcome == NEVER_MATCH)
{
#line 1804 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.j) failure");
if (no_gross_problems_thrown > no_gross_problems_thrown_before)
Dash__set_flag(inv, GROSSLY_FAILED_DASHFLAG);
else if (no_interesting_problems_thrown > no_interesting_problems_thrown_before)
Dash__set_flag(inv, INTERESTINGLY_FAILED_DASHFLAG);
if ((consider_alternatives) && (TEST_DASH_MODE(ISSUE_PROBLEMS_DMODE)))
Dash__failed_one(inv, context, kind_needed);
}
#line 1084 "inform7/Chapter 20/Dash.w"
else
{
#line 1818 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4I.k) success");
Dash__set_flag(inv, PASSED_DASHFLAG);
if (qualified) {
Dash__set_flag(inv, UNPROVEN_DASHFLAG);
Invocations__mark_unproven(inv);
}
if (ph) {
wording NW = ph->ph_documentation_symbol;
if (Wordings__nonempty(NW))
Index__DocReferences__doc_mark_used(
Lexer__word_raw_text(Wordings__first_wn(NW)),
Wordings__first_wn(ParseTree__get_text(inv)));
}
}
#line 1085 "inform7/Chapter 20/Dash.w"
;
}
#line 822 "inform7/Chapter 20/Dash.w"
; break;
default:
{
#line 1837 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4S.a)");
LOG_INDENT;
outcome = Dash__typecheck_single_node(p, kind_needed, condition_context);
LOG_OUTDENT;
{
#line 1863 "inform7/Chapter 20/Dash.w"
if ((ParseTree__is(p, TABLE_ENTRY_VNT)) &&
(ParseTree__no_children(p) == 2) &&
(kind_needed) &&
(!(ParseTree__is(context, LVALUE_TR_CONTEXT_NT)))) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__Issue__sentence_problem(_p_(PM_InexplicitTableEntryAsValue),
"this form of table entry can only be used in certain special phrases",
"because it doesn't explicitly refer to a single value. (You can see "
"which phrases in the Phrasebook index: it's allowed wherever a 'table "
"entry' is wanted.)");
return NEVER_MATCH;
}
}
#line 1842 "inform7/Chapter 20/Dash.w"
;
LOG_DASH("(4S.b)");
for (parse_node *arg = p->down; arg; arg = arg->next)
outcome =
Dash__worst_case(outcome,
Dash__typecheck_recursive(arg, p, TRUE));
if ((outcome != NEVER_MATCH) && (p->down)) {
if (ParseTree__is(p, LIST_ENTRY_VNT))
{
#line 1879 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4S.c)");
kind *K1 = Specifications__to_kind(p->down);
kind *K2 = Specifications__to_kind(p->down->next);
if (Kinds__unary_construction_material(K1) == NULL) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__Issue__sentence_problem(_p_(PM_EntryOfNonList),
"that doesn't make sense to me as a list entry",
"since the entry is taken from something which isn't a list.");
return NEVER_MATCH;
}
if (Kinds__Compare__eq(K2, K_number) == FALSE) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__Issue__sentence_problem(_p_(PM_NonNumericListEntry),
"that doesn't make sense to me as a list entry",
"because the indication of which entry is not a number. "
"For instance, 'entry 3 of L' is allowed, but not 'entry "
"\"six\" of L'. (List entries are numbered 1, 2, 3, ...)");
return NEVER_MATCH;
}
}
#line 1852 "inform7/Chapter 20/Dash.w"
;
if (ParseTree__is(p, PROPERTY_VALUE_VNT))
{
#line 1905 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4S.d)");
parse_node *the_property = p->down;
kind *K1 = Specifications__to_kind(the_property);
if (Kinds__get_construct(K1) != CON_property)
{
#line 1933 "inform7/Chapter 20/Dash.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__quote_wording(3, ParseTree__get_text(the_property));
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend '%2' to be a property "
"of something, but there is no such property as '%3'.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 1908 "inform7/Chapter 20/Dash.w"
;
property *prn = Rvalues__to_property(the_property);
if (prn == NULL)
internal_error("null property name in type checking");
if (Properties__is_either_or(prn))
{
#line 1947 "inform7/Chapter 20/Dash.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__Issue__handmade_problem(_p_(PM_EitherOrAsValue));
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend '%2' to be the value "
"of a property of something, but that property has no value: it's "
"something which an object either is or is not.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 1912 "inform7/Chapter 20/Dash.w"
;
parse_node *the_owner = p->down->next;
kind *K2 = Specifications__to_kind(the_owner);
if ((K2 == NULL) || (Specifications__is_description(the_owner)))
{
#line 1961 "inform7/Chapter 20/Dash.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
int owner_quoted = TRUE;
if ((Specifications__to_kind(the_owner)) &&
(Descriptions__get_quantifier(the_owner) == NULL))
Problems__quote_kind(3, Specifications__to_kind(the_owner));
else if (Wordings__nonempty(ParseTree__get_text(the_owner)))
Problems__quote_wording(3, ParseTree__get_text(the_owner));
else owner_quoted = FALSE;
LOG("Owner tree is $T\n", the_owner);
Problems__Issue__handmade_problem(_p_(PM_PropertyOfKind2));
if (owner_quoted) {
if (Wordings__nonempty(ParseTree__get_text(p)))
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend '%2' to be a property, "
"but '%3' is not specific enough about who or what the owner is. ");
else
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend to look up a property "
"of something, but '%3' is not specific enough about who or what "
"the owner is. ");
} else {
if (Wordings__nonempty(ParseTree__get_text(p)))
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend '%2' to be a property, "
"but you're not specific enough about who or what the owner is. ");
else
Problems__issue_problem_segment(
"In the sentence %1, it looks as if you intend to look up a property "
"of something, but you're not specific enough about who or what "
"the owner is. ");
}
Problems__issue_problem_segment(
"%PSometimes this mistake is made because Inform mostly doesn't understand "
"the English language habit of referring to something indefinite by a "
"common noun - for instance, writing 'change the carrying capacity of "
"the container to 10' throws Inform because it doesn't understand "
"that 'the container' means one which has been discussed recently.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 1917 "inform7/Chapter 20/Dash.w"
;
inference_subject *owning_subject = InferenceSubjects__from_specification(the_owner);
if (owning_subject == NULL) owning_subject = Kinds__Behaviour__as_subject(K2);
if (World__Permissions__find(owning_subject, prn, TRUE) == NULL) {
if ((Kinds__Compare__le(K2, K_object) == FALSE) ||
((Rvalues__is_object(the_owner)) &&
(Rvalues__is_self_object_constant(the_owner) == FALSE)))
{
#line 2006 "inform7/Chapter 20/Dash.w"
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, prn->name);
Problems__quote_subject(3, owning_subject);
Problems__Issue__handmade_problem(_p_(PM_LookedUpForbiddenProperty));
Problems__issue_problem_segment(
"In the sentence %1, you seem to be looking up the '%2' property, "
"but '%3' is not allowed to have that property. ");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 1925 "inform7/Chapter 20/Dash.w"
;
}
}
#line 1854 "inform7/Chapter 20/Dash.w"
;
if (ParseTree__is(p, TABLE_ENTRY_VNT))
{
#line 2020 "inform7/Chapter 20/Dash.w"
LOG_DASH("(4S.e)");
if (ParseTree__no_children(p) == 4) {
kind *col_kind = Specifications__to_kind(p->down->next);
kind *col_contents_kind = Kinds__unary_construction_material(col_kind);
kind *key_kind = Specifications__to_kind(p->down->next->next);
LOGIF(MATCHING, "Kinds: col $u, contents $u, key $u\n",
col_kind, col_contents_kind, key_kind);
if ((Kinds__get_construct(col_kind) != CON_table_column) ||
(col_contents_kind == NULL)) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"that doesn't make sense to me as a table entry",
"since the entry is taken from something which isn't a table.");
return NEVER_MATCH;
}
if (Kinds__Compare__compatible(key_kind, col_contents_kind) == NEVER_MATCH) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, col_contents_kind);
Problems__quote_kind(3, key_kind);
Problems__Issue__handmade_problem(_p_(PM_TableCorrFruitless));
Problems__issue_problem_segment(
"In the sentence %1, you seem to be looking up a corresponding "
"entry in a table: but it's fruitless to go looking for %3 "
"in a column where each entry contains %2.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
}
}
#line 1856 "inform7/Chapter 20/Dash.w"
;
}
}
#line 824 "inform7/Chapter 20/Dash.w"
; break;
}
}
#line 800 "inform7/Chapter 20/Dash.w"
;
return outcome;
}
#line 537 "inform7/Chapter 20/Dash.w"
;
}
return NEVER_MATCH; /* to prevent compiler warnings: unreachable in fact */
}
#line 2078 "inform7/Chapter 20/Dash.w"
int structural_phrase_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 2084 "inform7/Chapter 20/Dash.w"
Problems__Issue__sentence_problem(_p_(PM_WrongContinue),
"this is a phrase which I don't recognise",
"and which isn't defined. Perhaps you wanted the phrase which "
"would skip to the next repetition of a loop, since that's "
"written 'continue' in some programming languages (such as C "
"and Inform 6)? If so, what you want is 'next'.");
}
#line 2079 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 2080 "inform7/Chapter 20/Dash.w"
#line 2096 "inform7/Chapter 20/Dash.w"
kind *Dash__fix_arithmetic_operand(parse_node *operand) {
if (ParseTree__is(operand->down, UNKNOWN_VNT)) return NULL;
if (ParseTree__get_type(operand) != RVALUE_CONTEXT_NT)
internal_error("arithmetic operand not an rvalue");
kind *expected = NULL;
parse_node *check = operand->down;
if (ParseTree__is(check, AMBIGUITY_NT)) check = check->down;
if (Rvalues__is_CONSTANT_construction(check, CON_property)) {
property *prn = Rvalues__to_property(check);
if (Properties__is_either_or(prn) == FALSE)
expected = Properties__Valued__kind(prn);
}
kind *K = ParseTree__get_kind_required_by_context(operand);
ParseTree__set_kind_required_by_context(operand, expected);
BEGIN_DASH_MODE;
DASH_MODE_EXIT(ISSUE_PROBLEMS_DMODE);
DASH_MODE_CREATE(NULL);
int rv = Dash__typecheck_recursive(operand, NULL, TRUE);
END_DASH_MODE;
ParseTree__set_kind_required_by_context(operand, K);
if (rv == NEVER_MATCH) return NULL;
return Specifications__to_kind(operand->down);
}
#line 2138 "inform7/Chapter 20/Dash.w"
int Dash__set_up_any_local_required(parse_node *inv) {
for (int i=0, N = Invocations__get_no_tokens(inv); i<N; i++) {
kind *K = Invocations__get_token_variable_kind(inv, i);
if (K) {
if ((i == 0) && (N >= 2) && (Kinds__Compare__eq(K, K_value)) &&
(Phrases__TypeData__is_a_let_assignment(ParseTree__get_phrase_invoked(inv))))
{
#line 2164 "inform7/Chapter 20/Dash.w"
parse_node *val = Invocations__get_token_as_parsed(inv, i);
wording W = ParseTree__get_text(val);
parse_node *initial_value = Invocations__get_token_as_parsed(inv, 1);
parse_node *iv_spec = ParseTree__get_phrase_invoked(inv)->type_data.token_sequence[1].to_match;
if (initial_value)
{
#line 2191 "inform7/Chapter 20/Dash.w"
kind *seems_to_be = NULL;
if ((Specifications__is_kind_like(iv_spec)) &&
(ParseTree__is(initial_value, CONSTANT_VNT))) {
kind *K = ParseTree__get_kind_of_value(initial_value);
if (Kinds__get_construct(K) == CON_description) {
kind *DK = Kinds__unary_construction_material(K);
if (Kinds__get_construct(DK) == CON_relation) seems_to_be = DK;
}
}
if (seems_to_be == NULL) seems_to_be = Specifications__to_kind(initial_value);
LOGIF(LOCAL_VARIABLES, "New variable $w from $P ($P) seems to be: $u\n",
W, initial_value, iv_spec, seems_to_be);
if (seems_to_be == NULL)
{
#line 2223 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(initial_value));
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"The phrase %1 tries to use 'let' to give a temporary name to a value, "
"but the value ('%2') is one that I can't understand.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 2204 "inform7/Chapter 20/Dash.w"
;
if ((Kinds__get_construct(seems_to_be) == CON_list_of) &&
(Kinds__Compare__eq(Kinds__unary_construction_material(seems_to_be), K_value)))
{
#line 2238 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
int pc = problem_count;
Lists__check_one(ParseTree__get_text(initial_value));
if (pc == problem_count) {
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_CantLetEmptyList));
Problems__issue_problem_segment(
"The phrase %1 tries to use 'let' to give a temporary name to the "
"empty list '{ }', but because it's empty, I can't tell what kind of "
"value the list should have. Try 'let X be a list of numbers' (or "
"whatever) instead.");
Problems__issue_problem_end();
}
return NEVER_MATCH;
}
#line 2208 "inform7/Chapter 20/Dash.w"
;
if (Kinds__Behaviour__definite(seems_to_be) == FALSE)
{
#line 2256 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"this isn't a definite kind",
"and is instead a general description which might apply to many "
"different kinds, so I can't see how to create this named value. "
"(For example, 'let R be a relation' is vague because it doesn't "
"make clear what R will relate - 'let R be a relation of numbers' "
"would be fine.)");
return NEVER_MATCH;
}
#line 2210 "inform7/Chapter 20/Dash.w"
;
LOGIF(MATCHING, "(4A.c.1) Local variable seems to have kind: $u\n", seems_to_be);
if (Kinds__Compare__le(K_person, K_thing)) LOGIF(MATCHING, "(4A.c.1) Obvs!\n");
K = seems_to_be;
if (Kinds__Compare__lt(K, K_object))
while (Kinds__Compare__eq(Kinds__Compare__super(K), K_object) == FALSE)
K = Kinds__Compare__super(K);
LOGIF(MATCHING, "(4A.c.1) Local variable inferred to have kind: $u\n", K);
}
#line 2169 "inform7/Chapter 20/Dash.w"
;
}
#line 2144 "inform7/Chapter 20/Dash.w"
;
int changed = FALSE;
K = Kinds__substitute(K, NULL, &changed);
if (changed) LOGIF(MATCHING, "(4A.c.1) Local var amended to $u\n", K);
Invocations__set_token_variable_kind(inv, i, K);
}
}
return ALWAYS_MATCH;
}
#line 2279 "inform7/Chapter 20/Dash.w"
int Dash__failed_one(parse_node *inv, parse_node *context, kind *kind_needed) {
parse_node *list[1];
list[0] = inv;
return Dash__failed(list, 1, context, kind_needed);
}
wording PM_BadIntermediateKind_wording = EMPTY_WORDING_INIT;
int Dash__failed(parse_node **list_of_possible_readings, int no_of_possible_readings,
parse_node *context, kind *kind_needed) {
if (Dash__problems_have_been_issued()) return NEVER_MATCH;
parse_node *first_inv_in_group = NULL;
parse_node *first_failing_interestingly = NULL;
parse_node *first_not_failing_grossly = NULL;
wording SW = EMPTY_WORDING;
int list_includes_lets = FALSE;
int nongross_count = 0;
{
#line 2317 "inform7/Chapter 20/Dash.w"
for (int ref=0; ref<no_of_possible_readings; ref++) {
parse_node *inv = list_of_possible_readings[ref];
if ((Dash__test_flag(inv, INTERESTINGLY_FAILED_DASHFLAG)) &&
(first_failing_interestingly == NULL)) first_failing_interestingly = inv;
if (first_inv_in_group == NULL) first_inv_in_group = inv;
phrase *ph = ParseTree__get_phrase_invoked(inv);
if (ph) {
if (Phrases__TypeData__is_a_let_assignment(ph)) list_includes_lets = TRUE;
if (Dash__test_flag(inv, GROSSLY_FAILED_DASHFLAG) == FALSE) {
first_not_failing_grossly = inv;
if (Phrases__TypeData__is_a_say_X_phrase(&(ph->type_data))) SW = ParseTree__get_text(inv);
nongross_count++;
}
}
}
}
#line 2297 "inform7/Chapter 20/Dash.w"
;
parse_node *most_likely_to_have_been_intended = NULL;
{
#line 2336 "inform7/Chapter 20/Dash.w"
if (first_failing_interestingly)
most_likely_to_have_been_intended = first_failing_interestingly;
else if ((nongross_count > 1) && (list_includes_lets))
most_likely_to_have_been_intended = first_not_failing_grossly;
else if (nongross_count == 1)
most_likely_to_have_been_intended = first_not_failing_grossly;
else if ((nongross_count == 0) && (first_inv_in_group))
most_likely_to_have_been_intended = first_inv_in_group;
}
#line 2300 "inform7/Chapter 20/Dash.w"
;
int pc_before = problem_count;
if (first_failing_interestingly)
{
#line 2348 "inform7/Chapter 20/Dash.w"
BEGIN_DASH_MODE;
DASH_MODE_ENTER(ISSUE_INTERESTING_PROBLEMS_DMODE);
DASH_MODE_CREATE(NULL);
Dash__typecheck_recursive(first_failing_interestingly, context, FALSE);
END_DASH_MODE;
}
#line 2304 "inform7/Chapter 20/Dash.w"
else if (most_likely_to_have_been_intended)
{
#line 2357 "inform7/Chapter 20/Dash.w"
int ec = problem_count;
BEGIN_DASH_MODE;
DASH_MODE_ENTER(ISSUE_PROBLEMS_DMODE);
DASH_MODE_CREATE(NULL);
for (int i=0; i<Invocations__get_no_tokens(most_likely_to_have_been_intended); i++) {
Dash__typecheck_recursive(Invocations__get_token(most_likely_to_have_been_intended, i), context, TRUE);
if (problem_count > ec) break;
}
if (problem_count == ec) {
LOGIF(MATCHING, "Try again in local problems mode\n");
BEGIN_DASH_MODE;
DASH_MODE_ENTER(ISSUE_LOCAL_PROBLEMS_DMODE);
DASH_MODE_CREATE(NULL);
for (int i=0; i<Invocations__get_no_tokens(most_likely_to_have_been_intended); i++) {
Dash__typecheck_recursive(Invocations__get_token(most_likely_to_have_been_intended, i), context, TRUE);
if (problem_count > ec) break;
}
END_DASH_MODE;
}
END_DASH_MODE;
if (problem_count == ec) {
kind *K = ParseTree__get_kind_resulting(most_likely_to_have_been_intended);
kind *W = kind_needed;
if ((K) && (W) && (Kinds__Compare__compatible(K, W) == NEVER_MATCH)) {
THIS_IS_AN_ORDINARY_PROBLEM;
wording PW = ParseTree__get_text(list_of_possible_readings[0]);
if (!(Wordings__eq(PM_BadIntermediateKind_wording, PW))) {
PM_BadIntermediateKind_wording = PW;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, PW);
Problems__quote_kind(3, K);
Problems__quote_kind(4, W);
Problems__Issue__handmade_problem(_p_(PM_BadIntermediateKind));
Problems__issue_problem_segment(
"In %1, the phrase '%2' doesn't seem to fit: I was hoping it would "
"be %4, but in fact it's %3.");
Problems__issue_problem_end();
}
return NEVER_MATCH;
}
if (problem_count == ec) {
LOGIF(MATCHING, "Try again in gross problems mode\n$T\n", most_likely_to_have_been_intended);
BEGIN_DASH_MODE;
DASH_MODE_ENTER(ISSUE_GROSS_PROBLEMS_DMODE);
DASH_MODE_CREATE(NULL);
Dash__typecheck_recursive(most_likely_to_have_been_intended, context, FALSE);
END_DASH_MODE;
}
if (problem_count == 0)
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"the ingredients in this phrase do not fit it",
"and I am confused enough by this that I can't give a very helpful "
"problem message. Sorry about that.");
}
}
#line 2306 "inform7/Chapter 20/Dash.w"
if (problem_count == pc_before) {
if (Wordings__nonempty(SW)) Preform__parse_nt_against_word_range(failed_text_substitution_diagnosis_NTM, SW, NULL, NULL);
else
{
#line 2415 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_AllInvsFailed));
Problems__quote_source(1, current_sentence);
Problems__issue_problem_segment(
"You wrote %1, which I tried to match against several possible phrase "
"definitions. None of them worked.");
Problems__issue_problem_end();
}
#line 2309 "inform7/Chapter 20/Dash.w"
;
}
return NEVER_MATCH;
}
#line 2426 "inform7/Chapter 20/Dash.w"
int failed_text_substitution_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 2433 "inform7/Chapter 20/Dash.w"
Problems__Issue__sentence_in_detail_problem(_p_(PM_SayAList), W,
"this asked to say 'a list of...'",
"which I read as being a general description applying to some "
"lists and not others, so it's not something which can be said. "
"(Maybe you meant 'the list of...' instead? That normally makes "
"a definite list of whatever matches the '...' part.)");
}
#line 2427 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 2443 "inform7/Chapter 20/Dash.w"
Problems__Issue__sentence_in_detail_problem(_p_(BelievedImpossible), W,
"this asked to say something which I do not recognise",
"either as a value or as one of the possible text substitutions.");
}
#line 2428 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 2429 "inform7/Chapter 20/Dash.w"
#line 2455 "inform7/Chapter 20/Dash.w"
void Dash__note_inv_token_text(parse_node *p, int new_name) {
inv_token_problem_token *itpt;
LOOP_OVER(itpt, inv_token_problem_token)
if (Wordings__eq(itpt->problematic_text, ParseTree__get_text(p))) {
if (new_name) itpt->new_name = TRUE;
return;
}
itpt = CREATE(inv_token_problem_token);
itpt->problematic_text = ParseTree__get_text(p);
itpt->new_name = new_name;
if (ParseTree__is(p, AMBIGUITY_NT)) p = p->down;
itpt->as_parsed = p; itpt->already_described = FALSE;
if ((Rvalues__is_CONSTANT_of_kind(p, K_number)) ||
(Rvalues__is_CONSTANT_of_kind(p, K_text))) itpt->already_described = TRUE;
}
#line 2476 "inform7/Chapter 20/Dash.w"
int condition_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1] | R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 2479 "inform7/Chapter 20/Dash.w"
int condition_problem_part_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 2483 "inform7/Chapter 20/Dash.w"
int condition_problem_part_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0;
{
#line 2494 "inform7/Chapter 20/Dash.w"
if (preform_lookahead_mode == FALSE) {
Problems__quote_wording(4, W);
Problems__issue_problem_segment("'%4' was okay; ");
}
}
#line 2485 "inform7/Chapter 20/Dash.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = INVALID_CP_BIT;
{
#line 2502 "inform7/Chapter 20/Dash.w"
if (preform_lookahead_mode == FALSE) {
Problems__quote_wording(4, W);
Problems__issue_problem_segment(
"'%4' only made sense as a value, which can't be used as a condition; ");
}
}
#line 2486 "inform7/Chapter 20/Dash.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = WHENWHILE_CP_BIT+INVALID_CP_BIT;
{
#line 2511 "inform7/Chapter 20/Dash.w"
if (preform_lookahead_mode == FALSE) {
Problems__quote_wording(4, W);
Problems__issue_problem_segment(
"'%4' did not make sense as a condition, but looked as if it might "
"be a way to specify a beginning or end for a scene - but such things "
"can't be divided by 'or'; ");
}
}
#line 2487 "inform7/Chapter 20/Dash.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = WHENWHILE_CP_BIT+INVALID_CP_BIT;
{
#line 2522 "inform7/Chapter 20/Dash.w"
if (preform_lookahead_mode == FALSE) {
Problems__quote_wording(4, W);
Problems__issue_problem_segment("'%4' did not make sense; ");
}
}
#line 2488 "inform7/Chapter 20/Dash.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = INVALID_CP_BIT;
{
#line 2522 "inform7/Chapter 20/Dash.w"
if (preform_lookahead_mode == FALSE) {
Problems__quote_wording(4, W);
Problems__issue_problem_segment("'%4' did not make sense; ");
}
}
#line 2489 "inform7/Chapter 20/Dash.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 2490 "inform7/Chapter 20/Dash.w"
#line 2532 "inform7/Chapter 20/Dash.w"
int Dash__typecheck_single_node(parse_node *p, kind *kind_expected, int condition_context) {
LOG_DASH("(5)");
LOGIF(MATCHING, "Kind expected: $u, condition expected: %d\n", kind_expected, condition_context);
int outcome = ALWAYS_MATCH; /* drops to |SOMETIMES_MATCH| if a need for run-time checking is realised */
if ((Rvalues__is_nothing_object_constant(p)) &&
(kind_expected) && (Kinds__Compare__lt(kind_expected, K_object)))
{
#line 2554 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__quote_kind(3, kind_expected);
Problems__Issue__handmade_problem(_p_(PM_NothingForSomething));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is literally no thing, and it consequently does "
"not count as %3.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 2539 "inform7/Chapter 20/Dash.w"
;
{
#line 2575 "inform7/Chapter 20/Dash.w"
LOG_DASH("(5.a)");
if (ParseTree__is(p, UNKNOWN_VNT)) {
THIS_IS_A_GROSS_PROBLEM;
LOG("(5.a) problem message:\nfound: $Texpected: $u", p, kind_expected);
if (Kinds__Compare__eq(kind_expected, K_stored_action))
{
#line 2618 "inform7/Chapter 20/Dash.w"
parse_node *spec = NULL;
kind *K = NULL, *K2 = NULL;
PL__Actions__Patterns__clear_validation_case();
Preform__parse_nt_against_word_range(action_pattern_NTM, ParseTree__get_text(p), NULL, NULL);
if (PL__Actions__Patterns__get_validation_case(&spec, &K, &K2)) {
Problems__Issue__handmade_problem(_p_(PM_UnknownTryAction1));
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__quote_wording(3, ParseTree__get_text(spec));
Problems__quote_kind(4, K);
Problems__quote_kind(5, K2);
Problems__issue_problem_segment(
"You wrote %1, but '%2' is not an action I can try. This looks as "
"if it might be because it contains something of the wrong kind. "
"My best try involved seeing if '%3' could be %4, which might have "
"made sense, but it turned out to be %5.");
Problems__issue_problem_end();
} else {
Problems__Issue__sentence_problem(_p_(PM_UnknownTryAction2),
"this is not an action I recognise",
"or else is malformed in a way I can't see how to sort out.");
}
return NEVER_MATCH;
}
#line 2581 "inform7/Chapter 20/Dash.w"
;
Problems__quote_source_eliding_begin(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
if (condition_context)
Problems__quote_text(3, "a condition");
else if (kind_expected == NULL)
Problems__quote_kind(3, K_value);
else
Problems__quote_kind(3, kind_expected);
int shape = NO_UTSHAPE;
if (current_sentence) {
Preform__parse_nt_against_word_range(unknown_text_shape_NTM, ParseTree__get_text(current_sentence), NULL, NULL);
shape = most_recent_result;
}
if (shape == NO_UTSHAPE) {
Preform__parse_nt_against_word_range(unknown_text_shape_NTM, ParseTree__get_text(p), NULL, NULL);
shape = most_recent_result;
}
int preceding = Wordings__first_wn(ParseTree__get_text(p)) - 1;
if ((preceding >= 0) && (current_sentence) &&
(((compiling_text_routines_mode) || (shape == SAY_UTSHAPE))) &&
((preceding == Wordings__first_wn(ParseTree__get_text(current_sentence)))
|| (Lexer__word(preceding) == COMMA_V)))
{
#line 2741 "inform7/Chapter 20/Dash.w"
Preform__parse_nt_against_word_range(unknown_text_substitution_problem_diagnosis_NTM, ParseTree__get_text(p), NULL, NULL);
}
#line 2606 "inform7/Chapter 20/Dash.w"
else if ((condition_context) && (shape == LIST_UTSHAPE))
{
#line 2752 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_CompoundConditionFailed));
Problems__issue_problem_segment(
"In the sentence %1, I was expecting that '%2' would be a condition. "
"It didn't make sense as one long phrase, but because it was divided up by "
"'and'/'or', I tried breaking it down into smaller conditions, but "
"that didn't work either. ");
Preform__parse_nt_against_word_range(condition_problem_diagnosis_NTM, ParseTree__get_text(p), NULL, NULL);
int dubious = most_recent_result;
if (dubious & INVALID_CP_BIT)
Problems__issue_problem_segment(
"so I ran out of ideas.");
else
Problems__issue_problem_segment(
"but that combination of conditions isn't allowed to be joined "
"together with 'and' or 'or', because that would just be too confusing. "
"%PFor example, 'if the player is carrying a container or a "
"supporter' has an obvious meaning in English, but Inform reads "
"it as two different conditions glued together: 'if the player is "
"carrying a container', and also 'a supporter'. The meaning of "
"the first is obvious. The second part is true if the current "
"item under discussion is a supporter - for instance, the noun of "
"the current action, or the item to which a definition applies. "
"Both of these conditions are useful in different circumstances, "
"but combining them in one condition like this makes a very "
"misleading line of text. So Inform disallows it.");
if (dubious & WHENWHILE_CP_BIT)
Problems__issue_problem_segment(
"%PI notice there's a 'when' or 'while' being used as the opening "
"word of one of those conditions, though; maybe that's the problem?");
Problems__issue_problem_end();
}
#line 2608 "inform7/Chapter 20/Dash.w"
else
{
#line 2910 "inform7/Chapter 20/Dash.w"
if (Kinds__Compare__eq(kind_expected, K_use_option)) {
Preform__parse_nt_against_word_range(unknown_use_option_diagnosis_NTM, ParseTree__get_text(p), NULL, NULL);
} else if (Kinds__get_construct(kind_expected) == CON_activity) {
Preform__parse_nt_against_word_range(unknown_activity_diagnosis_NTM, ParseTree__get_text(p), NULL, NULL);
} else {
Preform__parse_nt_against_word_range(unknown_value_problem_diagnosis_NTM, ParseTree__get_text(p), NULL, NULL);
}
}
#line 2610 "inform7/Chapter 20/Dash.w"
;
return NEVER_MATCH;
}
}
#line 2541 "inform7/Chapter 20/Dash.w"
;
{
#line 2924 "inform7/Chapter 20/Dash.w"
LOG_DASH("(5.b)");
if (Kinds__get_construct(kind_expected) != CON_property) {
parse_node *check = p;
if (ParseTree__is(check, AMBIGUITY_NT)) check = check->down;
if (Rvalues__is_CONSTANT_construction(check, CON_property)) {
property *prn = Rvalues__to_property(check);
{
#line 2945 "inform7/Chapter 20/Dash.w"
LOG_DASH("(5.b.2)");
if (kind_expected) {
LOG_DASH("(5.b.2a)");
if (Properties__is_value_property(prn)) {
LOG_DASH("(5.b.2b)");
kind *kind_if_coerced = Properties__Valued__kind(prn);
int verdict = Kinds__Compare__compatible(kind_if_coerced, kind_expected);
if (verdict != NEVER_MATCH) {
LOG_DASH("(5.b.2c)");
{
#line 2979 "inform7/Chapter 20/Dash.w"
parse_node *was = p->next_alternative;
parse_node *pr = ParseTree__duplicate(p);
pr->next_alternative = NULL;
parse_node *become = Lvalues__new_PROPERTY_VALUE(pr, Rvalues__new_self_object_constant());
ParseTree__copy(p, become);
p->next_alternative = was;
LOGIF(MATCHING, "(5.b) coercing PROPERTY to PROPERTY VALUE: $P\n", p);
}
#line 2954 "inform7/Chapter 20/Dash.w"
;
return verdict;
}
if ((Kinds__get_construct(kind_expected) == CON_description) &&
(Kinds__get_construct(kind_if_coerced) != CON_relation)) {
LOGIF(MATCHING, "(5.b.2) coercing to description\n");
parse_node *become = Specifications__from_kind(kind_if_coerced);
ParseTree__set_text(become, ParseTree__get_text(p));
ParseTree__copy_in_place(p, Descriptions__to_rvalue(become));
p->down = NULL;
} else {
LOGIF(MATCHING, "(5.b.2) declining to cast into property value form\n");
return verdict;
}
}
}
}
#line 2930 "inform7/Chapter 20/Dash.w"
;
}
}
}
#line 2542 "inform7/Chapter 20/Dash.w"
;
{
#line 2997 "inform7/Chapter 20/Dash.w"
LOG_DASH("(5.c)");
char *desired_to = NULL;
if (ParseTree__is(p, TEST_PROPOSITION_VNT)) desired_to = "be a condition";
if (Descriptions__is_complex(p)) desired_to = "be a description";
if (desired_to) {
if (Calculus__Propositions__Checker__type_check(Specifications__to_proposition(p),
Calculus__Propositions__Checker__tc_no_problem_reporting())
== NEVER_MATCH) {
LOGIF(MATCHING, "(5.c) on $P failed proposition type-checking: $D\n",
p, Specifications__to_proposition(p));
THIS_IS_A_GROSS_PROBLEM;
Calculus__Propositions__Checker__type_check(Specifications__to_proposition(p),
Calculus__Propositions__Checker__tc_problem_reporting(ParseTree__get_text(p), desired_to));
return NEVER_MATCH;
} else { LOG_DASH("(5.c) Okay!"); }
}
}
#line 2543 "inform7/Chapter 20/Dash.w"
;
{
#line 3020 "inform7/Chapter 20/Dash.w"
{
#line 3031 "inform7/Chapter 20/Dash.w"
LOG_DASH("(5.d.1)");
if ((Conditions__is_TEST_ACTION(p)) && (kind_expected) &&
(Kinds__Compare__compatible(K_stored_action, kind_expected))) {
action_pattern *ap = ParseTree__get_constant_action_pattern(p->down);
if (PL__Actions__Patterns__is_unspecific(ap)) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__Issue__handmade_problem(_p_(PM_ActionNotSpecific));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is too vague to describe a specific action. "
"%PIt has to be an exact instruction about what is being done, and "
"to what. For instance, 'taking the box' is fine, but 'dropping or "
"taking something openable' is not.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
if (PL__Actions__Patterns__is_overspecific(ap)) {
THIS_IS_A_GROSSER_THAN_GROSS_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__Issue__handmade_problem(_p_(PM_ActionTooSpecific));
Problems__issue_problem_segment(
"You wrote %1, but '%2' imposes too many restrictions on the "
"action to be carried out, by saying something about the "
"circumstances which you can't guarantee will be true. "
"%PSometimes this problem appears because I've misread text like "
"'in ...' as a clause saying that the action takes place in a "
"particular room, when in fact it was part of the name of one of "
"the items involved. If that's the problem, try using 'let' to "
"create a simpler name for it, and then rewrite the 'try' to use "
"that simpler name - the ambiguity should then vanish.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
ParseTree__copy_in_place(p, p->down);
p->down = NULL;
LOGIF(MATCHING, "Coerced to sa: $P\n", p);
return ALWAYS_MATCH;
}
if ((condition_context) &&
(ParseTree__is(p, CONSTANT_VNT))) {
kind *E = Specifications__to_kind(p);
if (Kinds__Compare__compatible(E, K_stored_action)) {
parse_node *val = ParseTree__duplicate(p);
ParseTree__copy_in_place(p, ParseTree__new(TEST_VALUE_VNT));
ParseTree__set_text(p, ParseTree__get_text(val));
p->down = val;
LOGIF(MATCHING, "Coerced back again to sa: $P\n", p);
return ALWAYS_MATCH;
}
}
}
#line 3020 "inform7/Chapter 20/Dash.w"
;
{
#line 3091 "inform7/Chapter 20/Dash.w"
LOG_DASH("(5.d.2)");
if ((Rvalues__is_CONSTANT_of_kind(p, K_text)) &&
(Kinds__Compare__eq(kind_expected, K_understanding))) {
ParseTree__set_kind_of_value(p, K_understanding);
}
}
#line 3021 "inform7/Chapter 20/Dash.w"
;
{
#line 3107 "inform7/Chapter 20/Dash.w"
LOG_DASH("(5.d.3)");
kind *domain = NULL;
if (Kinds__get_construct(kind_expected) == CON_description) {
domain = Kinds__unary_construction_material(kind_expected);
}
if ((domain) && (Specifications__is_description(p))) {
LOGIF(MATCHING, "(5.d.3) requiring description of $u\n", domain);
kind *K = Specifications__to_kind(p);
if (K == NULL) K = K_object;
LOGIF(MATCHING, "(5.d.3) finding description of $u\n", K);
int made_match = TRUE;
if (Kinds__Compare__compatible(K, domain) == NEVER_MATCH) made_match = FALSE;
{
#line 3153 "inform7/Chapter 20/Dash.w"
if (made_match == FALSE) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__quote_kind(3, K);
Problems__quote_kind(4, domain);
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"In the line %1, the text '%2' seems to be a description of %3, but "
"a description of %4 was required.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
}
#line 3119 "inform7/Chapter 20/Dash.w"
;
quantifier *q = Descriptions__get_quantifier(p);
if ((q) && (q != not_exists_quantifier) && (q != for_all_quantifier))
{
#line 3134 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__Issue__handmade_problem(_p_(PM_BadQuantifierInDescription));
Problems__issue_problem_segment(
"In %1 you wrote the description '%2' in the context of a value, "
"but descriptions used that way are not allowed to talk about "
"quantities. For example, it's okay to write 'an even number' "
"as a description value, but not 'three numbers' or 'most numbers'.");
Problems__issue_problem_end();
}
return NEVER_MATCH;
}
#line 3122 "inform7/Chapter 20/Dash.w"
;
parse_node *as_con = Descriptions__to_rvalue(p);
if (as_con == NULL)
{
#line 3173 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"In the line %1, the text '%2' is given where a description of a collection "
"of things or values was required. For instance, 'rooms which contain "
"something', or 'closed containers' - note that there is no need to say "
"'all' or 'every' in this context, as that is understood already.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 3125 "inform7/Chapter 20/Dash.w"
;
ParseTree__copy_in_place(p, as_con);
p->down = NULL;
return ALWAYS_MATCH;
}
}
#line 3022 "inform7/Chapter 20/Dash.w"
;
{
#line 3192 "inform7/Chapter 20/Dash.w"
if (ParseTree__is_lvalue(p)) {
kind *K = Specifications__to_kind(p);
if (K == NULL) {
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__Issue__handmade_problem(_p_(BelievedImpossible)); /* screened out at definition time */
Problems__issue_problem_segment(
"In the line %1, '%2' ought to be a value, but isn't - there must be "
"something fishy about the way it was created. %P"
"Usually this happens because it is one of the named items in "
"a phrase definition, but stood for a chunk of text which can't "
"be a value - for instance, 'To marvel at (feat - an action)' "
"doesn't make 'feat' a value. (Calling it a 'stored action' "
"would have been fine; and similarly, if you want something "
"which is either true or false, use 'truth state' not 'condition'.)");
Problems__issue_problem_end();
return NEVER_MATCH;
}
}
}
#line 3023 "inform7/Chapter 20/Dash.w"
;
}
#line 2544 "inform7/Chapter 20/Dash.w"
;
{
#line 3222 "inform7/Chapter 20/Dash.w"
int exceptional_case = FALSE;
{
#line 3240 "inform7/Chapter 20/Dash.w"
LOG_DASH("(5.e.2)");
if ((kind_expected) && (ParseTree__is_value(p))) {
if (ParseTree__is(p, PHRASE_TO_DECIDE_VALUE_VNT)) {
LOGIF(MATCHING, "(5.e.2) exempting phrase from return value checking for now\n");
} else {
switch (Kinds__Compare__compatible(
Specifications__to_kind(p),
kind_expected)) {
case NEVER_MATCH:
{
#line 3265 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
LOG("Offending subtree: $T\n", p);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__quote_kind(3, kind_expected);
if (ParseTree__is(p, LOCAL_VARIABLE_VNT)) {
local_variable *lvar = ParseTree__get_constant_local_variable(p);
Problems__quote_kind(4, LocalVariables__kind(lvar));
Problems__Issue__handmade_problem(_p_(PM_LocalMismatch));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is a temporary name for %4 (created by 'let' "
"or 'repeat'), whereas I was expecting to find %3 there.");
Problems__issue_problem_end();
} else if (Kinds__Compare__eq(kind_expected, K_sayable_value)) {
Problems__quote_kind(4, Specifications__to_kind(p));
Problems__Issue__handmade_problem(_p_(PM_AllSayInvsFailed));
if (Wordings__empty(ParseTree__get_text(p)))
Problems__issue_problem_segment(
"You wrote %1, but that only works for sayable values, that is, "
"values which I can display in text form. '%2' isn't one of those "
"values: it's %4, a kind which isn't sayable.");
else
Problems__issue_problem_segment(
"You wrote %1, but that only works for sayable values, that is, "
"values which I can display in text form. This isn't one of those "
"values: it's %4, a kind which isn't sayable.");
Problems__issue_problem_end();
} else {
LOG("Found: $u; Expected: $u\n", Specifications__to_kind(p),
kind_expected);
Problems__quote_kind(4, Specifications__to_kind(p));
Problems__Issue__handmade_problem(_p_(PM_TypeMismatch));
if (Wordings__empty(ParseTree__get_text(p)))
Problems__issue_problem_segment(
"You wrote %1, but that has the wrong kind of value: %4 rather than %3.");
else
Problems__issue_problem_segment(
"You wrote %1, but '%2' has the wrong kind of value: %4 rather than %3.");
Problems__issue_problem_end();
}
return NEVER_MATCH;
}
#line 3249 "inform7/Chapter 20/Dash.w"
;
case SOMETIMES_MATCH:
outcome = SOMETIMES_MATCH;
LOGIF(MATCHING, "dropping to sometimes level\n");
return outcome;
break;
case ALWAYS_MATCH: break;
}
}
exceptional_case = TRUE;
}
}
#line 3223 "inform7/Chapter 20/Dash.w"
;
if (exceptional_case == FALSE)
{
#line 3314 "inform7/Chapter 20/Dash.w"
LOG_DASH("(5.e.3)");
if ((kind_expected) || (condition_context)) {
int condition_found = FALSE;
if (ParseTree__is_condition(p)) condition_found = TRUE;
if (condition_found != condition_context) {
if ((Specifications__is_description(p)) && (kind_expected))
{
#line 3329 "inform7/Chapter 20/Dash.w"
if (Descriptions__is_complex(p)) {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__quote_kind(3, kind_expected);
Problems__quote_kind_of(4, p);
Problems__Issue__handmade_problem(_p_(PM_GenericDescription));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is used in a context where I'd expect to see "
"a (single) specific example of %3. Although what you wrote did "
"make sense as a description, it could refer to many different "
"values or to none, so it wasn't specific enough.");
Problems__issue_problem_end();
}
} else {
THIS_IS_AN_INTERESTING_PROBLEM {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__quote_kind(3, kind_expected);
Problems__quote_kind_of(4, p);
Problems__Issue__handmade_problem(_p_(PM_LiteralDescriptionAsValue));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is used in a context where I'd expect to see "
"a (single) specific example of %3, not a description.");
if ((Specifications__is_kind_like(p)) &&
(Kinds__Compare__eq(Specifications__to_kind(p), K_time)))
Problems__issue_problem_segment(
" %P(If you meant the current time, this is called 'time "
"of day' in Inform to avoid confusing it with the various "
"other meanings that the word 'time' can have.)");
Problems__issue_problem_end();
}
}
return NEVER_MATCH;
}
#line 3320 "inform7/Chapter 20/Dash.w"
else
{
#line 3368 "inform7/Chapter 20/Dash.w"
THIS_IS_AN_ORDINARY_PROBLEM;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(p));
Problems__quote_kind(3, kind_expected);
Problems__quote_kind_of(4, p);
Problems__Issue__handmade_problem(_p_(BelievedImpossible)); /* at any rate I haven't seen it lately */
Problems__issue_problem_segment(
"You wrote %1, but '%2' seems to be %4, whereas I was expecting to "
"find %3 there.");
Problems__issue_problem_end();
return NEVER_MATCH;
}
#line 3322 "inform7/Chapter 20/Dash.w"
;
}
}
}
#line 3224 "inform7/Chapter 20/Dash.w"
;
}
#line 2545 "inform7/Chapter 20/Dash.w"
;
return outcome;
}
#line 2647 "inform7/Chapter 20/Dash.w"
int unknown_text_shape_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = SAY_UTSHAPE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = LIST_UTSHAPE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = NO_UTSHAPE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 2651 "inform7/Chapter 20/Dash.w"
int unknown_text_substitution_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 2662 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_SayComma));
Problems__issue_problem_segment(
"In the line %1, I was expecting that '%2' would be something to "
"'say', but unexpectedly it began with a comma. The usual form is "
"just 'say \"text\"', perhaps with some substitutions in square "
"brackets within the quoted text, but no commas.");
Problems__issue_problem_end();
}
#line 2653 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 2673 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_SayUnicode));
Problems__issue_problem_segment(
"In the line %1, I was expecting that '%2' would be something to "
"'say', but it didn't look like any form of 'say' that I know. "
"So I tried to read '%2' as a Unicode character, which seemed "
"likely because of the word 'unicode', but that didn't work either. "
"%PUnicode characters can be written either using their decimal "
"numbers - for instance, 'Unicode 2041' - or with their standard "
"names - 'Unicode Latin small ligature oe'. For efficiency reasons "
"these names are only available if you ask for them; to make them "
"available, you need to 'Include Unicode Character Names by Graham "
"Nelson' or, if you really need more, 'Include Unicode Full "
"Character Names by Graham Nelson'.");
Problems__issue_problem_end();
}
#line 2654 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 2702 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_SayUnknownCondition));
Problems__issue_problem_segment(
"In the line %1, I was expecting that '%2' would be something to "
"'say', but it didn't look like any form of 'say' that I know. So "
"I tried to read '%2' as a value of some kind (because it's legal "
"to say values), but couldn't make sense of it that way either. "
"%PSometimes this happens because punctuation has gone wrong - "
"for instance, if you've omitted a semicolon or full stop at the "
"end of the 'say' phrase.");
Problems__issue_problem_segment(
"%PNames which end in 'condition' often represent the current "
"state of something which can be in any one of three or more "
"states. This will only be the case if you have explicitly said "
"so, with a line like 'The rocket is either dry, fuelled or launched.' - "
"in which case the value 'rocket condition' will always be one "
"of 'dry', 'fuelled' or 'launched'. Note that all of this only "
"applies to a list of three or more possibilities - a thing can "
"have any number of either/or properties. For instance, a "
"container is open or closed, but it also transparent or opaque. "
"Neither of these counts as its 'condition'.");
Problems__issue_problem_end();
}
#line 2655 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 2691 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_SayElseMisplaced));
Problems__issue_problem_segment(
"In the line %1, I was expecting that '%2' would be something to "
"'say', but unexpectedly I found an 'otherwise' (or 'else'). That "
"would be fine inside an '[if ...]' part of the text, but doesn't "
"make sense on its own.");
Problems__issue_problem_end();
}
#line 2656 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 2727 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_SayUnknown));
Problems__issue_problem_segment(
"In the line %1, I was expecting that '%2' would be something to "
"'say', but it didn't look like any form of 'say' that I know. So "
"I tried to read '%2' as a value of some kind (because it's legal "
"to say values), but couldn't make sense of it that way either. "
"%PSometimes this happens because punctuation has gone wrong - "
"for instance, if you've omitted a semicolon or full stop at the "
"end of the 'say' phrase.");
Problems__issue_problem_end();
}
#line 2657 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 2658 "inform7/Chapter 20/Dash.w"
#line 2787 "inform7/Chapter 20/Dash.w"
int unknown_value_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 2806 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_NumberOfTurns));
{
#line 2903 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment(
"In the sentence %1, I was expecting to read %3, but instead found some "
"text that I couldn't understand - '%2'. ");
}
#line 2807 "inform7/Chapter 20/Dash.w"
;
Problems__issue_problem_segment(
"%PPerhaps by 'turns' you meant the number of turns of play to date? "
"If so, try 'turn count' instead.");
Problems__issue_problem_end();
}
#line 2788 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 2816 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_OutOfPlay));
{
#line 2903 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment(
"In the sentence %1, I was expecting to read %3, but instead found some "
"text that I couldn't understand - '%2'. ");
}
#line 2817 "inform7/Chapter 20/Dash.w"
;
Problems__issue_problem_segment(
"%PPeople sometimes say that things or people removed from all "
"rooms are 'out of play', but Inform uses the adjective "
"'off-stage' - for instance, 'if the ball is off-stage'. "
"If you would like 'out of play' to work, you could always "
"write 'Definition: A thing is out of play if it is off-stage.' "
"Then the two would be equivalent.");
Problems__issue_problem_end();
}
#line 2789 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 2854 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_MidTextUnicode));
{
#line 2903 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment(
"In the sentence %1, I was expecting to read %3, but instead found some "
"text that I couldn't understand - '%2'. ");
}
#line 2855 "inform7/Chapter 20/Dash.w"
;
Problems__issue_problem_segment(
"%PMaybe you intended this to produce a Unicode character? "
"Unicode characters can be written either using their decimal "
"numbers - for instance, 'Unicode 2041' - or with their standard "
"names - 'Unicode Latin small ligature oe'. For efficiency reasons "
"these names are only available if you ask for them; to make them "
"available, you need to 'Include Unicode Character Names by Graham "
"Nelson' or, if you really need more, 'Include Unicode Full "
"Character Names by Graham Nelson'.");
Problems__issue_problem_end();
}
#line 2790 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 2870 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_UnknownCondition));
{
#line 2903 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment(
"In the sentence %1, I was expecting to read %3, but instead found some "
"text that I couldn't understand - '%2'. ");
}
#line 2871 "inform7/Chapter 20/Dash.w"
;
Problems__issue_problem_segment(
"%PNames which end in 'condition' often represent the current "
"state of something which can be in any one of three or more "
"states. Names like this only work if you've declared them, with "
"a line like 'The rocket is either dry, fuelled or launched.' - "
"in which case the value 'rocket condition' will always be one "
"of 'dry', 'fuelled' or 'launched'. Maybe you forgot to declare "
"something like this, or mis-spelled the name of the owner?");
Problems__issue_problem_end();
}
#line 2791 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 2896 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_Unknown));
{
#line 2903 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment(
"In the sentence %1, I was expecting to read %3, but instead found some "
"text that I couldn't understand - '%2'. ");
}
#line 2897 "inform7/Chapter 20/Dash.w"
;
Problems__issue_problem_end();
}
#line 2792 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 2793 "inform7/Chapter 20/Dash.w"
int unknown_use_option_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 2830 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_OptionlessOption));
{
#line 2903 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment(
"In the sentence %1, I was expecting to read %3, but instead found some "
"text that I couldn't understand - '%2'. ");
}
#line 2831 "inform7/Chapter 20/Dash.w"
;
Problems__issue_problem_segment(
"%PThe names of use options, on the rare occasions when they "
"appear as values, always end with the word 'option' - for "
"instance, we have to write 'American dialect option' not "
"'American dialect'. As your text here doesn't end with the "
"word 'option', perhaps you've forgotten this arcane rule?");
Problems__issue_problem_end();
}
#line 2795 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 2896 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_Unknown));
{
#line 2903 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment(
"In the sentence %1, I was expecting to read %3, but instead found some "
"text that I couldn't understand - '%2'. ");
}
#line 2897 "inform7/Chapter 20/Dash.w"
;
Problems__issue_problem_end();
}
#line 2796 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 2797 "inform7/Chapter 20/Dash.w"
int unknown_activity_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 2843 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_ActivityOf));
{
#line 2903 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment(
"In the sentence %1, I was expecting to read %3, but instead found some "
"text that I couldn't understand - '%2'. ");
}
#line 2844 "inform7/Chapter 20/Dash.w"
;
Problems__issue_problem_segment(
"%PActivity names rarely end with 'of': for instance, when we talk "
"about 'printing the name of something', properly speaking "
"the activity is called 'printing the name'. Maybe that's it?");
Problems__issue_problem_end();
}
#line 2799 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 2885 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_ActivityWithFor));
{
#line 2903 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment(
"In the sentence %1, I was expecting to read %3, but instead found some "
"text that I couldn't understand - '%2'. ");
}
#line 2886 "inform7/Chapter 20/Dash.w"
;
Problems__issue_problem_segment(
"%PWere you by any chance meaning to refer to an activity by name, "
"and used the word 'for' at the end of that name? If so, try removing "
"just the word 'for'.");
Problems__issue_problem_end();
}
#line 2800 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 2896 "inform7/Chapter 20/Dash.w"
Problems__Issue__handmade_problem(_p_(PM_Unknown));
{
#line 2903 "inform7/Chapter 20/Dash.w"
Problems__issue_problem_segment(
"In the sentence %1, I was expecting to read %3, but instead found some "
"text that I couldn't understand - '%2'. ");
}
#line 2897 "inform7/Chapter 20/Dash.w"
;
Problems__issue_problem_end();
}
#line 2801 "inform7/Chapter 20/Dash.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 2802 "inform7/Chapter 20/Dash.w"
#line 3392 "inform7/Chapter 20/Dash.w"
int Dash__reading_passed(parse_node *p) {
if (Dash__test_flag(p, PASSED_DASHFLAG)) return TRUE;
else if (Dash__test_flag(p, TESTED_DASHFLAG)) return FALSE;
return NOT_APPLICABLE;
}
char *Dash__verdict_to_text(parse_node *p) {
if (p == NULL) return "(no node)";
char *verdict = "untested";
if (Dash__test_flag(p, TESTED_DASHFLAG)) verdict = "failed";
if (Dash__test_flag(p, INTERESTINGLY_FAILED_DASHFLAG)) verdict = "interesting";
if (Dash__test_flag(p, GROSSLY_FAILED_DASHFLAG)) verdict = "gross";
if (Dash__test_flag(p, PASSED_DASHFLAG)) verdict = "proven";
if (Dash__test_flag(p, UNPROVEN_DASHFLAG)) verdict = "unproven";
return verdict;
}
char *Dash__quick_verdict_to_text(parse_node *p) {
if (p == NULL) return "?";
char *verdict = "-";
if (Dash__test_flag(p, TESTED_DASHFLAG)) verdict = "f";
if (Dash__test_flag(p, INTERESTINGLY_FAILED_DASHFLAG)) verdict = "i";
if (Dash__test_flag(p, GROSSLY_FAILED_DASHFLAG)) verdict = "g";
if (Dash__test_flag(p, PASSED_DASHFLAG)) verdict = "p";
if (Dash__test_flag(p, UNPROVEN_DASHFLAG)) verdict = "u";
return verdict;
}
#line 3423 "inform7/Chapter 20/Dash.w"
void Dash__set_flag(parse_node *p, int flag) {
if (p == NULL) internal_error("tried to set flag for null p");
int bm = ParseTree__int_annotation(p, epistemological_status_ANNOT);
ParseTree__annotate_int(p, epistemological_status_ANNOT, bm | flag);
}
void Dash__clear_flags(parse_node *p) {
if (p == NULL) internal_error("tried to clear flags for null p");
ParseTree__annotate_int(p, epistemological_status_ANNOT, 0);
}
void Dash__clear_flag(parse_node *p, int flag) {
if (p == NULL) internal_error("tried to clear flag for null p");
int bm = ParseTree__int_annotation(p, epistemological_status_ANNOT);
ParseTree__annotate_int(p, epistemological_status_ANNOT, bm & (~flag));
}
int Dash__test_flag(parse_node *p, int flag) {
int bm = (p)?(ParseTree__int_annotation(p, epistemological_status_ANNOT)):0;
if (bm & flag) return TRUE;
return FALSE;
}
#line 3449 "inform7/Chapter 20/Dash.w"
void Dash__experiment(wording W, int full) {
kind *K = NULL;
LOG("Beginning Dashperiment:\n");
parse_node *test_tree = NULL, *last_alt = NULL;
s_value_uncached_NTM->multiplicitous = TRUE;
s_value_uncached_NTM->watched = TRUE;
int n = 0;
while (Wordings__nonempty(W)) {
wording T = W;
if (Preform__parse_nt_against_word_range(phrase_with_comma_notation_NTM, W, NULL, NULL)) {
T = GET_RW(phrase_with_comma_notation_NTM, 1);
W = GET_RW(phrase_with_comma_notation_NTM, 2);
} else W = EMPTY_WORDING;
if (Preform__parse_nt_against_word_range(k_kind_NTM, T, NULL, NULL)) K = most_recent_result_p;
else if (Preform__parse_nt_against_word_range(s_value_uncached_NTM, T, NULL, NULL)) {
parse_node *p = most_recent_result_p;
if (last_alt) last_alt->next_alternative = p;
else test_tree = p;
last_alt = p;
n++;
} else LOG("Failed to parse: $w\n", T);
}
s_value_uncached_NTM->multiplicitous = FALSE;
s_value_uncached_NTM->watched = FALSE;
if (n > 1) {
parse_node *holder = ParseTree__new(AMBIGUITY_NT);
holder->down = test_tree;
test_tree = holder;
}
LOG("$m\n", test_tree);
if (K) {
LOG("Dash: value of kind $u\n", K);
if (full) Log__tracing_phrases(NULL);
int rv = Dash__check_value(test_tree, K);
char *trv = "ALWAYS";
if (rv == SOMETIMES_MATCH) trv = "SOMETIMES";
if (rv == NEVER_MATCH) trv = "NEVER";
LOG("Result: %s\n", trv);
if (full) Log__tracing_phrases(NULL);
LOG("$m\n", test_tree);
}
}
#line 93 "inform7/Chapter 21/Properties.w"
property *Properties__obtain(wording W, int valued) {
parse_node *p = SParser__parse_excerpt(PROPERTY_MC, W);
property *prn;
if (p == NULL) {
prn = Properties__create(W);
if (valued) {
Properties__Valued__make_setting_relation(prn, W);
prn->either_or = FALSE;
} else {
prn->either_or = TRUE;
}
} else {
prn = Rvalues__to_property(p);
if ((valued) && (prn->either_or))
internal_error("either/or property made into valued");
if ((valued == FALSE) && (prn->either_or == FALSE))
internal_error("valued property made into either/or");
}
return prn;
}
#line 117 "inform7/Chapter 21/Properties.w"
property *Properties__create(wording W) {
W = Articles__remove_article(W);
{
#line 140 "inform7/Chapter 21/Properties.w"
int unfortunate = FALSE;
if ((Preform__parse_nt_against_word_range(k_kind_NTM, W, NULL, NULL)) && (most_recent_result_p == K_value)) {
unfortunate = TRUE;
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"the single word 'value' cannot be used as the name of a property",
"because it has a much broader meaning already. Inform uses the "
"word 'value' to mean any number, time of day, name of something, "
"etcetera: and because of that very broadness, Inform cannot decide "
"what kind of value a simple 'value' might be. So 'A door has "
"a value' is not allowed; but 'A door has a number called the "
"room number' would be fine.");
}
if (Wordings__length(W) > MAX_WORDS_IN_ASSEMBLAGE-2) {
Problems__Issue__sentence_problem(_p_(PM_PropertyNameTooLong),
"this is too long a name for a single property to have",
"and would become unwieldy.");
W = Wordings__truncate(W, MAX_WORDS_IN_ASSEMBLAGE-2);
}
if (Preform__parse_nt_against_word_range(unsuitable_name_NTM, W, NULL, NULL)) {
unfortunate = TRUE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_PropertyNameUnsuitable));
Problems__issue_problem_segment(
"The sentence %1 seems to create a new property called '%2', but "
"this is not a good name, and I think I must have misread what "
"you wanted. Maybe the punctuation is wrong?");
Problems__issue_problem_end();
}
if (unfortunate) W = Feeds__feed_text("problem recovery name");
}
#line 119 "inform7/Chapter 21/Properties.w"
;
{
#line 176 "inform7/Chapter 21/Properties.w"
if (Preform__parse_nt_against_word_range(s_type_expression_or_value_NTM, W, NULL, NULL)) {
int okay = FALSE;
parse_node *spec = most_recent_result_p;
if (Specifications__is_kind_like(spec)) okay = TRUE;
if (Rvalues__is_CONSTANT_construction(spec, CON_table_column)) okay = TRUE;
if (Rvalues__is_CONSTANT_construction(spec, CON_property)) okay = TRUE;
if (Specifications__is_description(spec)) okay = TRUE;
if (ParseTree__is(spec, NONLOCAL_VARIABLE_VNT)) okay = TRUE;
if (okay == FALSE) {
LOG("Existing meaning: $P", spec);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_kind_of(3, spec);
Problems__Issue__handmade_problem(_p_(PM_PropertyNameClash));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is not free to be the name of a fresh "
"property: it already has a meaning (as %3).");
Problems__issue_problem_end();
}
}
}
#line 120 "inform7/Chapter 21/Properties.w"
;
property *prn = CREATE(property);
{
#line 202 "inform7/Chapter 21/Properties.w"
prn->name = W;
prn->ambiguous_name = Preform__parse_nt_against_word_range(name_looking_like_property_test_NTM, W, NULL, NULL);
prn->applicable_to = NULL;
prn->either_or = FALSE;
prn->translated = FALSE;
prn->do_not_compile = FALSE;
prn->indexed_already = FALSE;
prn->visited_on_traverse = -1;
prn->include_in_index = TRUE;
prn->metadata_table_offset = UNSET_TABLE_OFFSET;
Properties__EitherOr__initialise(prn);
Properties__Valued__initialise(prn);
}
#line 123 "inform7/Chapter 21/Properties.w"
;
{
#line 219 "inform7/Chapter 21/Properties.w"
if (Preform__parse_nt_against_word_range(k_kind_NTM, W, NULL, NULL))
Properties__Valued__make_coincide_with_kind(prn, most_recent_result_p);
}
#line 124 "inform7/Chapter 21/Properties.w"
;
Identifiers__compose(prn->original_name, 'p', prn->allocation_id, prn->name);
strcpy(prn->translated_name, prn->original_name);
{
#line 237 "inform7/Chapter 21/Properties.w"
if (Preform__parse_nt_against_word_range(notable_properties_NTM, W, NULL, NULL)) {
switch (most_recent_result) {
case 0: P_description = prn;
break;
case 1: P_specification = prn;
Properties__Valued__set_kind(prn, K_text);
prn->do_not_compile = TRUE;
prn->include_in_index = FALSE;
World__Permissions__grant(model_world, P_specification, TRUE);
break;
case 2: P_indefinite_appearance_text = prn;
Properties__Valued__set_kind(prn, K_text);
prn->do_not_compile = TRUE;
prn->include_in_index = FALSE;
World__Permissions__grant(global_constants,
P_indefinite_appearance_text, TRUE);
break;
case 3: P_variable_initial_value = prn;
prn->do_not_compile = TRUE;
Properties__Valued__set_kind(prn, K_value);
prn->include_in_index = FALSE;
World__Permissions__grant(nonlocal_variables, P_variable_initial_value, TRUE);
break;
}
}
Plugins__Call__new_property_notify(prn);
}
#line 128 "inform7/Chapter 21/Properties.w"
;
if (Wordings__nonempty(W))
{
#line 275 "inform7/Chapter 21/Properties.w"
Semantics__Nouns__ExcerptMeanings__register_noun(
PROPERTY_MC, W,
Rvalues__from_property(prn));
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(
PROPERTY_MC,
Preform__Nonparsing__merge(property_name_construction_NTM, 0,
WordAssemblages__from_wording(W)),
Rvalues__from_property(prn));
}
#line 130 "inform7/Chapter 21/Properties.w"
else Properties__exclude_from_index(prn);
LOGIF(PROPERTY_CREATIONS, "Created property: $Y = %s\n", prn, prn->translated_name);
return prn;
}
#line 228 "inform7/Chapter 21/Properties.w"
int notable_properties_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 233 "inform7/Chapter 21/Properties.w"
#line 269 "inform7/Chapter 21/Properties.w"
int property_name_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 271 "inform7/Chapter 21/Properties.w"
#line 287 "inform7/Chapter 21/Properties.w"
kind *Properties__to_kind(property *prn) {
if (prn == NULL) internal_error("took kind of null property");
kind *stored = prn->property_value_kind;
if (prn->either_or) stored = K_truth_state;
return Kinds__unary_construction(CON_property, stored);
}
#line 299 "inform7/Chapter 21/Properties.w"
int property_name_NTMR(wording W, int *X, void **XP) {
#line 300 "inform7/Chapter 21/Properties.w"
W = Articles__remove_the(W);
property *prn;
LOOP_OVER(prn, property)
if (Wordings__match(W, prn->name)) {
*XP = prn;
return Wordings__first_wn(W) + Wordings__length(prn->name) - 1;
}
return FALSE;
}
#line 313 "inform7/Chapter 21/Properties.w"
int either_or_property_name_NTMR(wording W, int *X, void **XP) {
#line 314 "inform7/Chapter 21/Properties.w"
W = Articles__remove_the(W);
property *prn;
LOOP_OVER(prn, property)
if (prn->either_or)
if (Wordings__match(W, prn->name)) {
*XP = prn;
return TRUE;
}
return FALSE;
}
int value_property_name_NTMR(wording W, int *X, void **XP) {
#line 326 "inform7/Chapter 21/Properties.w"
W = Articles__remove_the(W);
property *prn;
LOOP_OVER(prn, property)
if (prn->either_or == FALSE)
if (Wordings__match(W, prn->name)) {
*XP = prn;
return TRUE;
}
return FALSE;
}
#line 341 "inform7/Chapter 21/Properties.w"
int property_name_v_NTMR(wording W, int *X, void **XP) {
#line 342 "inform7/Chapter 21/Properties.w"
property *prn;
LOOP_OVER(prn, property)
if (Wordings__starts_with(W, prn->name)) {
*XP = prn;
return Wordings__first_wn(W) + Wordings__length(prn->name) - 1;
}
return FALSE;
}
#line 357 "inform7/Chapter 21/Properties.w"
int name_looking_like_property_test_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 359 "inform7/Chapter 21/Properties.w"
#line 364 "inform7/Chapter 21/Properties.w"
int ambiguous_property_name_NTMR(wording W, int *X, void **XP) {
#line 365 "inform7/Chapter 21/Properties.w"
property *prn;
LOOP_OVER(prn, property)
if (prn->ambiguous_name) {
if (Wordings__starts_with(W, prn->name)) {
*XP = prn;
return Wordings__first_wn(W) + Wordings__length(prn->name) - 1;
}
}
return FALSE;
}
#line 381 "inform7/Chapter 21/Properties.w"
int Properties__match_longest(wording W) {
int maxlen = -1;
property *prn;
LOOP_OVER(prn, property)
if (Wordings__starts_with(W, prn->name))
if (maxlen < Wordings__length(prn->name))
maxlen = Wordings__length(prn->name);
return maxlen;
}
#line 396 "inform7/Chapter 21/Properties.w"
property_permission *Properties__permission_list(property *prn) {
return prn->applicable_to;
}
void Properties__set_permission_list(property *prn, property_permission *pp) {
prn->applicable_to = pp;
}
#line 406 "inform7/Chapter 21/Properties.w"
void Properties__log(property *prn) {
Properties__log_basic_pname(prn);
if ((logging_to_I6_text) || (prn == NULL)) return;
if (prn->either_or) {
property *neg = Properties__EitherOr__get_negation(prn);
if (neg) { LOG("=~"); Properties__log_basic_pname(neg); }
} else {
LOG("=$u", Properties__Valued__kind(prn));
}
}
void Properties__log_basic_pname(property *prn) {
if (prn == NULL) { LOG("<null-property>"); return; }
if (Wordings__nonempty(prn->name)) { LOG("'$w'", prn->name); }
else { LOG("'%s'", prn->translated_name); }
}
#line 429 "inform7/Chapter 21/Properties.w"
int Properties__is_either_or(property *prn) {
return prn->either_or;
}
int Properties__is_value_property(property *prn) {
if (prn->either_or == FALSE) return TRUE;
return FALSE;
}
#line 443 "inform7/Chapter 21/Properties.w"
int Properties__can_be_compiled(property *prn) {
if ((prn == NULL) || (prn->do_not_compile)) return FALSE;
return TRUE;
}
#line 452 "inform7/Chapter 21/Properties.w"
int Properties__is_shown_in_index(property *prn) {
return prn->include_in_index;
}
void Properties__exclude_from_index(property *prn) {
prn->include_in_index = FALSE;
}
#line 462 "inform7/Chapter 21/Properties.w"
void Properties__set_indexed_already_flag(property *prn, int state) {
prn->indexed_already = state;
}
int Properties__get_indexed_already_flag(property *prn) {
return prn->indexed_already;
}
#line 472 "inform7/Chapter 21/Properties.w"
void Properties__offset_in_runtime_metadata_table_is(property *prn, int pos) {
prn->metadata_table_offset = pos;
}
int Properties__get_offset_in_runtime_metadata_table(property *prn) {
return prn->metadata_table_offset;
}
#line 489 "inform7/Chapter 21/Properties.w"
void Properties__set_translation(property *prn, char *t) {
if (prn == NULL) internal_error("translation set for null property");
int i; char *to = prn->translated_name;
for (i=0; ((t[i]) && (i<31)); i++) {
if ((isalpha(t[i])) || (isdigit(t[i])) || (t[i] == '_')) to[i] = t[i];
else to[i] = '_';
}
to[i] = 0;
prn->translated = TRUE;
}
char *Properties__get_translation(property *prn) {
if (prn == NULL) internal_error("I6 identifier requested for null property");
return prn->translated_name;
}
int Properties__has_been_translated(property *prn) {
return prn->translated;
}
#line 515 "inform7/Chapter 21/Properties.w"
void Properties__translates(wording W, parse_node *p2) {
property *prn = NULL;
if (Preform__parse_nt_against_word_range(property_name_NTM, W, NULL, NULL)) prn = most_recent_result_p;
char *text = Lexer__word_text(Wordings__first_wn(ParseTree__get_text(p2)));
{
#line 532 "inform7/Chapter 21/Properties.w"
if (prn == NULL) {
Problems__Issue__sentence_problem(_p_(PM_NonPropertyTranslated),
"this property does not exist",
"so cannot be translated.");
return;
}
if ((prn->translated) && (strcmp(text, prn->translated_name) != 0)) {
Problems__Issue__sentence_problem(_p_(PM_TranslatedTwice),
"this property has already been translated",
"so there must be some duplication somewhere.");
return;
}
}
#line 520 "inform7/Chapter 21/Properties.w"
;
Properties__set_translation(prn, text);
LOGIF(PROPERTY_TRANSLATIONS, "Property <$Y> translates as <%s>\n", prn, text);
if (prn->either_or)
{
#line 562 "inform7/Chapter 21/Properties.w"
property *neg = Properties__EitherOr__get_negation(prn);
if (neg) {
Properties__EitherOr__make_stored_in_negation(neg);
LOGIF(PROPERTY_TRANSLATIONS, "Storing this way round: $Y\n", prn);
}
}
#line 526 "inform7/Chapter 21/Properties.w"
;
}
#line 572 "inform7/Chapter 21/Properties.w"
void Properties__alias_translations(OUTPUT_STREAM) {
property *prn;
LOOP_OVER(prn, property)
if (strcmp(prn->translated_name, prn->original_name) != 0)
WRITE("Constant %s = %s;\n",
prn->original_name, prn->translated_name);
}
#line 586 "inform7/Chapter 21/Properties.w"
int property_traverse_count = 0;
void Properties__begin_traverse(void) {
property_traverse_count++;
}
int Properties__visited_in_traverse(property *prn) {
if (prn->visited_on_traverse == property_traverse_count) return TRUE;
prn->visited_on_traverse = property_traverse_count;
if (Properties__is_either_or(prn)) {
property *prnbar = Properties__EitherOr__get_negation(prn);
if (prnbar) prnbar->visited_on_traverse = property_traverse_count;
}
return FALSE;
}
#line 606 "inform7/Chapter 21/Properties.w"
possession_marker *Properties__get_possession_marker(property *prn) {
return &(prn->pom);
}
#line 617 "inform7/Chapter 21/Properties.w"
void Properties__compile_inferred_value(OUTPUT_STREAM, inference_subject *infs, property *prn) {
if ((prn == NULL) || (Properties__can_be_compiled(prn) == FALSE)) return;
while (infs) {
if (Properties__compile_property_value_inner(OUT, infs, prn)) return;
infs = InferenceSubjects__narrowest_broader_subject(infs);
}
if (Properties__is_either_or(prn))
Properties__EitherOr__compile_default_value(OUT, prn);
else
Properties__Valued__compile_default_value(OUT, prn);
}
#line 634 "inform7/Chapter 21/Properties.w"
int Properties__compile_property_value_inner(OUTPUT_STREAM, inference_subject *infs, property *prn) {
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
if (World__Inferences__get_inference_type(inf) == PROPERTY_INF) {
current_sentence = World__Inferences__where_inferred(inf);
int sense = (World__Inferences__get_certainty(inf) > 0)?TRUE:FALSE;
property *inferred_property = World__Inferences__get_property(inf);
if (Properties__is_either_or(prn)) {
if (inferred_property == prn) {
Properties__EitherOr__compile_value(OUT, inferred_property, sense);
return TRUE;
}
if (inferred_property == Properties__EitherOr__get_negation(prn)) {
Properties__EitherOr__compile_value(OUT, inferred_property, sense?FALSE:TRUE);
return TRUE;
}
} else {
if (inferred_property == prn) {
if (sense) {
parse_node *val = World__Inferences__get_property_value(inf);
if (val == NULL) internal_error("malformed property inference");
Properties__Valued__compile_value(OUT, inferred_property, val);
return TRUE;
} else {
internal_error("valued property with negative certainty");
}
}
}
}
}
return FALSE;
}
#line 57 "inform7/Chapter 21/Either-Or Properties.w"
property *Properties__EitherOr__obtain(wording W, inference_subject *infs) {
if (Preform__parse_nt_against_word_range(k_kind_NTM, W, NULL, NULL)) {
Problems__Issue__sentence_problem(_p_(PM_KindAdjectiveClash),
"this tries to create a new either/or adjective with the same name "
"as an existing kind",
"which isn't allowed. For example, 'A hopper can be a container.' is "
"not allowed because something either is, or is not, a 'container', "
"and that can never change during play. 'Container' is a kind, and "
"those are fixed. 'A hopper is a container' would be allowed, because "
"that makes a definite statement.");
}
property *prn = Properties__obtain(W, FALSE);
prn->either_or = TRUE;
kind *K = InferenceSubjects__domain(infs);
if (prn->adjectival_meaning_registered == NULL)
Properties__EitherOr__create_adjective_from_property(prn, W, K);
else
Properties__EitherOr__make_new_adjective_sense_from_property(prn, W, K);
return prn;
}
#line 89 "inform7/Chapter 21/Either-Or Properties.w"
property *Properties__EitherOr__new_nameless(char *I6_form) {
property *prn = Properties__create(EMPTY_WORDING);
prn->either_or = TRUE;
Properties__exclude_from_index(prn);
Properties__set_translation(prn, I6_form);
Properties__EitherOr__create_adjective_from_property(prn, EMPTY_WORDING, K_object);
return prn;
}
#line 101 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__initialise(property *prn) {
prn->negation = NULL;
prn->stored_in_negation = FALSE;
prn->implemented_as_attribute = NOT_APPLICABLE;
prn->adjectival_meaning_registered = NULL;
prn->adjectival_phrase_registered = NULL;
prn->eo_parsing_grammar = NULL;
}
#line 115 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__make_negations(property *prn, property *neg) {
if ((prn == NULL) || (prn->either_or == FALSE)) internal_error("non-EO property");
if ((neg == NULL) || (neg->either_or == FALSE)) internal_error("non-EO property");
if ((prn->negation) || (neg->negation)) {
if ((prn->negation != neg) || (neg->negation != prn)) {
Problems__quote_source(1, current_sentence);
Problems__quote_property(2, prn);
Problems__quote_property(3, neg);
if (prn->negation) {
Problems__quote_property(4, prn);
Problems__quote_property(5, prn->negation);
} else {
Problems__quote_property(4, neg);
Problems__quote_property(5, neg->negation);
}
Problems__Issue__handmade_problem(_p_(PM_BrokenNegationPair));
Problems__issue_problem_segment(
"In %1, you proposed to set up the properties '%2' and '%3' as "
"opposites of each other. But I can't allow that, because '%4' "
"already has an opposite in another context ('%5').");
Problems__issue_problem_end();
return;
}
return;
}
prn->negation = neg; neg->negation = prn;
Properties__EitherOr__make_stored_in_negation(neg);
}
property *Properties__EitherOr__get_negation(property *prn) {
if ((prn == NULL) || (prn->either_or == FALSE)) internal_error("non-EO property");
return prn->negation;
}
#line 153 "inform7/Chapter 21/Either-Or Properties.w"
int Properties__EitherOr__stored_in_negation(property *prn) {
if ((prn == NULL) || (prn->either_or == FALSE)) internal_error("non-EO property");
return prn->stored_in_negation;
}
void Properties__EitherOr__make_stored_in_negation(property *prn) {
if ((prn == NULL) || (prn->either_or == FALSE)) internal_error("non-EO property");
if (prn->negation == NULL) internal_error("singleton EO cannot store in negation");
prn->stored_in_negation = TRUE;
if (prn->negation) prn->negation->stored_in_negation = FALSE;
}
#line 169 "inform7/Chapter 21/Either-Or Properties.w"
grammar_verb *Properties__EitherOr__get_parsing_grammar(property *prn) {
if ((prn == NULL) || (prn->either_or == FALSE)) return NULL;
return prn->eo_parsing_grammar;
}
void Properties__EitherOr__set_parsing_grammar(property *prn, grammar_verb *gv) {
if ((prn == NULL) || (prn->either_or == FALSE)) internal_error("non-EO property");
prn->eo_parsing_grammar = gv;
}
adjectival_phrase *Properties__EitherOr__get_aph(property *prn) {
if ((prn == NULL) || (prn->either_or == FALSE)) internal_error("non-EO property");
return prn->adjectival_phrase_registered;
}
#line 187 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__assert(property *prn,
inference_subject *owner, int parity, int certainty) {
pcalc_prop *prop = Calculus__Atoms__unary_PREDICATE_from_aph(
Properties__EitherOr__get_aph(prn), (parity)?FALSE:TRUE);
Calculus__Propositions__Assert__assert_true_about(prop, owner, certainty);
}
#line 203 "inform7/Chapter 21/Either-Or Properties.w"
int Properties__EitherOr__implemented_as_attribute(property *prn) {
if ((prn == NULL) || (prn->either_or == FALSE)) internal_error("non-EO property");
if (prn->implemented_as_attribute == NOT_APPLICABLE) return TRUE;
return prn->implemented_as_attribute;
}
void Properties__EitherOr__implement_as_attribute(property *prn, int state) {
if ((prn == NULL) || (prn->either_or == FALSE)) internal_error("non-EO property");
prn->implemented_as_attribute = state;
if (prn->negation) prn->negation->implemented_as_attribute = state;
}
#line 225 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__compile_value(OUTPUT_STREAM, property *prn, int val) {
if (val) WRITE("true");
else WRITE("false");
}
void Properties__EitherOr__compile_default_value(OUTPUT_STREAM, property *prn) {
WRITE("false");
}
#line 242 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__create_adjective_from_property(property *prn, wording W, kind *K) {
adjective_meaning *am =
Adjectives__Meanings__new(EORP_KADJ, STORE_POINTER_property(prn), W);
Adjectives__Phrases__declare(am, W);
Adjectives__Meanings__set_domain_from_kind(am, K);
prn->adjectival_phrase_registered = Adjectives__Phrases__get_aph_from_am(am);
prn->adjectival_meaning_registered = am;
}
void Properties__EitherOr__make_new_adjective_sense_from_property(property *prn, wording W, kind *K) {
adjectival_phrase *aph = prn->adjectival_phrase_registered;
if (Adjectives__Phrases__applicable_to(aph, K)) return;
adjective_meaning *am =
Adjectives__Meanings__new(EORP_KADJ, STORE_POINTER_property(prn), W);
Adjectives__Phrases__declare(am, W);
Adjectives__Meanings__set_domain_from_kind(am, K);
}
#line 264 "inform7/Chapter 21/Either-Or Properties.w"
adjective_meaning *Properties__EitherOr__ADJ_parse(parse_node *q,
int sense, wording AW, wording DNW, wording CONW, wording CALLW) {
return NULL;
}
#line 273 "inform7/Chapter 21/Either-Or Properties.w"
int Properties__EitherOr__ADJ_compile(property *prn, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
#line 282 "inform7/Chapter 21/Either-Or Properties.w"
void Properties__EitherOr__ADJ_compiling_soon(adjective_meaning *am, property *prn, int T) {
if (am == NULL) internal_error("Unregistered adjectival either/or property in either/or atom");
if (Adjectives__Meanings__get_ready_flag(am)) return;
Adjectives__Meanings__set_ready_flag(am);
kind *K = Adjectives__Meanings__get_domain(am);
if (Kinds__Compare__le(K, K_object))
{
#line 302 "inform7/Chapter 21/Either-Or Properties.w"
if (Properties__EitherOr__stored_in_negation(prn)) {
property *neg = Properties__EitherOr__get_negation(prn);
char *identifier = Properties__get_translation(neg);
i6_schema *sch = Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Calculus__Schemas__modify(sch, "GetEitherOrProperty(*1, %s) == false", identifier);
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, FALSE);
Calculus__Schemas__modify(sch, "SetEitherOrProperty(*1, %s, true)", identifier);
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_FALSE_TASK, FALSE);
Calculus__Schemas__modify(sch, "SetEitherOrProperty(*1, %s)", identifier);
} else {
char *identifier = Properties__get_translation(prn);
i6_schema *sch = Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Calculus__Schemas__modify(sch, "GetEitherOrProperty(*1, %s)", identifier);
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, FALSE);
Calculus__Schemas__modify(sch, "SetEitherOrProperty(*1, %s)", identifier);
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_FALSE_TASK, FALSE);
Calculus__Schemas__modify(sch, "SetEitherOrProperty(*1, %s, true)", identifier);
}
}
#line 290 "inform7/Chapter 21/Either-Or Properties.w"
else
{
#line 330 "inform7/Chapter 21/Either-Or Properties.w"
if (Properties__EitherOr__stored_in_negation(prn)) {
property *neg = Properties__EitherOr__get_negation(prn);
i6_schema *sch = Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Calculus__Schemas__modify(sch, "GProperty(%k, *1, %s) == false", K,
Properties__get_translation(neg));
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, FALSE);
Calculus__Schemas__modify(sch, "WriteGProperty(%k, *1, %s)", K,
Properties__get_translation(neg));
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_FALSE_TASK, FALSE);
Calculus__Schemas__modify(sch, "WriteGProperty(%k, *1, %s, true)", K,
Properties__get_translation(neg));
} else {
i6_schema *sch = Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Calculus__Schemas__modify(sch, "GProperty(%k, *1, %s)", K,
Properties__get_translation(prn));
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, FALSE);
Calculus__Schemas__modify(sch, "WriteGProperty(%k, *1, %s, true)", K,
Properties__get_translation(prn));
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_FALSE_TASK, FALSE);
Calculus__Schemas__modify(sch, "WriteGProperty(%k, *1, %s)", K,
Properties__get_translation(prn));
}
}
#line 292 "inform7/Chapter 21/Either-Or Properties.w"
;
return;
}
#line 362 "inform7/Chapter 21/Either-Or Properties.w"
int Properties__EitherOr__ADJ_assert(property *prn,
inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) {
if (parity == FALSE) World__Inferences__draw_negated_property(infs_to_assert_on, prn, NULL);
else World__Inferences__draw_property(infs_to_assert_on, prn, NULL);
return TRUE;
}
#line 372 "inform7/Chapter 21/Either-Or Properties.w"
int Properties__EitherOr__ADJ_index(property *prn) {
property *neg = Properties__EitherOr__get_negation(prn);
INDEX("either/or property");
if (Properties__permission_list(prn)) {
INDEX(" of "); World__Permissions__index(prn);
} else if ((neg) && (Properties__permission_list(neg))) {
INDEX(" of "); World__Permissions__index(neg);
}
if (neg) {
INDEX(", opposite of </i>");
Wordings__index_raw(neg->name);
INDEX("<i>");
}
return TRUE;
}
#line 13 "inform7/Chapter 21/Valued Properties.w"
property *Properties__Valued__obtain(wording W) {
return Properties__obtain(W, TRUE);
}
#line 22 "inform7/Chapter 21/Valued Properties.w"
property *Properties__Valued__obtain_within_kind(wording W, kind *K) {
property *prn = NULL;
if (K == NULL) K = K_object;
K = Kinds__weaken(K);
if (Preform__parse_nt_against_word_range(property_name_NTM, W, NULL, NULL)) {
prn = most_recent_result_p;
kind *existing_kind = prn->property_value_kind;
switch(Kinds__Compare__compatible(K, existing_kind)) {
case SOMETIMES_MATCH:
if (Kinds__Compare__compatible(existing_kind, K) != ALWAYS_MATCH)
{
#line 48 "inform7/Chapter 21/Valued Properties.w"
Problems__Issue__sentence_problem(_p_(PM_BadKOVForRelationProperty),
"that property already exists and contains a kind of value incompatible with "
"what we need here",
"so you will need to give it a different name.");
return NULL;
}
#line 32 "inform7/Chapter 21/Valued Properties.w"
;
prn->property_value_kind = K; /* widen the kind of the property to make this fit */
break;
case NEVER_MATCH:
{
#line 48 "inform7/Chapter 21/Valued Properties.w"
Problems__Issue__sentence_problem(_p_(PM_BadKOVForRelationProperty),
"that property already exists and contains a kind of value incompatible with "
"what we need here",
"so you will need to give it a different name.");
return NULL;
}
#line 36 "inform7/Chapter 21/Valued Properties.w"
;
}
} else {
prn = Properties__obtain(W, TRUE);
prn->property_value_kind = K;
}
return prn;
}
#line 65 "inform7/Chapter 21/Valued Properties.w"
property *Properties__Valued__new_nameless(char *I6_form, kind *K) {
if (K == NULL) internal_error("new nameless property without kind");
property *prn = Properties__create(EMPTY_WORDING);
Properties__exclude_from_index(prn);
prn->either_or = FALSE;
Properties__set_translation(prn, I6_form);
prn->property_value_kind = K;
prn->setting_bp = Properties__SettingRelations__make_set_nameless_property_BP(prn);
prn->stored_bp = NULL;
return prn;
}
#line 80 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__initialise(property *prn) {
prn->property_value_kind = NULL;
prn->setting_bp = NULL;
prn->used_for_non_typesafe_relation = FALSE;
prn->also_a_type = FALSE;
Properties__Conditions__initialise(prn);
}
void Properties__Valued__make_setting_relation(property *prn, wording W) {
binary_predicate *bp = Properties__SettingRelations__find_set_property_BP(W);
if (bp == NULL) bp = Properties__SettingRelations__make_set_property_BP(W);
Properties__SettingRelations__fix_property_bp(bp);
Properties__SettingRelations__fix_property_bp(BinaryPredicates__get_reversal(bp));
prn->setting_bp = bp;
}
#line 100 "inform7/Chapter 21/Valued Properties.w"
kind *Properties__Valued__kind(property *prn) {
if ((prn == NULL) || (prn->either_or)) return NULL; /* for better type-checking Problems */
return prn->property_value_kind;
}
void Properties__Valued__set_kind(property *prn, kind *K) {
if ((prn == NULL) || (prn->either_or)) internal_error("non-value property");
if ((Kinds__Behaviour__definite(K) == FALSE) && (prn->do_not_compile == FALSE)) {
Problems__quote_wording(1, prn->name);
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(PM_PropertyIndefinite));
if (current_sentence) {
Problems__quote_source(3, current_sentence);
Problems__issue_problem_segment(
"In the sentence %3, I am unable to create the property '%1', because "
"it has too vague a kind ('%2'). I need to know exactly what kind of "
"value goes into each property: for instance, it's not enough to say "
"'A door has a list of values called the access list', because I don't "
"know what the entries in this list would have to be - 'A door has a "
"list of people called the access list' would be better.");
} else {
Problems__issue_problem_segment(
"I am unable to create the property '%1', because it has too vague "
"a kind ('%2'). I need to know exactly what kind of value goes into each "
"property: for instance, it's not enough to say 'A door has a list of values "
"called the access list', because I don't know what the entries in this "
"list would have to be - 'A door has a list of people called the access "
"list' would be better.");
}
Problems__issue_problem_end();
}
prn->property_value_kind = K;
}
#line 140 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__make_coincide_with_kind(property *prn, kind *K) {
Properties__Valued__set_kind(prn, K);
if (Kinds__Compare__eq(K, K_grammatical_gender)) P_grammatical_gender = prn;
prn->also_a_type = TRUE;
if (Kinds__Behaviour__name_can_coincide_with_property(K))
Instances__make_kind_coincident(K, prn);
}
int Properties__Valued__coincides_with_kind(property *prn) {
if ((prn == NULL) || (prn->either_or)) internal_error("non-value property");
return prn->also_a_type;
}
#line 156 "inform7/Chapter 21/Valued Properties.w"
binary_predicate *Properties__Valued__get_setting_bp(property *prn) {
if ((prn == NULL) || (prn->either_or)) internal_error("non-value property");
return prn->setting_bp;
}
#line 164 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__set_stored_relation(property *prn, binary_predicate *bp) {
if ((prn == NULL) || (prn->either_or)) internal_error("non-value property");
prn->stored_bp = bp;
}
binary_predicate *Properties__Valued__get_stored_relation(property *prn) {
if ((prn == NULL) || (prn->either_or)) internal_error("non-value property");
return prn->stored_bp;
}
#line 182 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__now_used_for_non_typesafe_relation(property *prn) {
if ((prn == NULL) || (prn->either_or)) internal_error("non-value property");
prn->used_for_non_typesafe_relation = TRUE;
}
int Properties__Valued__is_used_for_non_typesafe_relation(property *prn) {
if ((prn == NULL) || (prn->either_or)) internal_error("non-value property");
return prn->used_for_non_typesafe_relation;
}
#line 195 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__assert(property *prn, inference_subject *owner,
parse_node *val, int certainty) {
pcalc_prop *prop = Calculus__Propositions__Abstract__to_set_property(prn, val);
Calculus__Propositions__Assert__assert_true_about(prop, owner, certainty);
}
#line 208 "inform7/Chapter 21/Valued Properties.w"
void Properties__Valued__compile_value(OUTPUT_STREAM, property *prn, parse_node *val) {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
kind *K = Properties__Valued__kind(prn);
if (K) Specifications__Compiler__compile_constant_to_kind(OUT, val, K);
else Specifications__Compiler__compile(OUT, val);
END_COMPILATION_MODE;
}
void Properties__Valued__compile_default_value(OUTPUT_STREAM, property *prn) {
if (Properties__Valued__is_used_for_non_typesafe_relation(prn)) {
WRITE("0"); return;
}
kind *K = Properties__Valued__kind(prn);
current_sentence = NULL;
if (Kinds__Behaviour__compile_default_value(OUT, K, prn->name, "property") == FALSE) {
Problems__quote_wording(1, prn->name);
Problems__Issue__handmade_problem(_p_(PM_PropertyUninitialisable));
Problems__issue_problem_segment(
"I am unable to put any value into the property '%1', because "
"it seems to have a kind of value which has no actual values.");
Problems__issue_problem_end();
}
}
#line 20 "inform7/Chapter 21/Condition Properties.w"
void Properties__Conditions__initialise(property *prn) {
prn->condition_of = NULL;
prn->condition_anonymously_named = FALSE;
}
#line 28 "inform7/Chapter 21/Condition Properties.w"
property *Properties__Conditions__new(inference_subject *infs, wording NW, parse_node *set, int *already) {
int anon = FALSE;
wording W = NW;
*already = FALSE;
if (Wordings__empty(NW)) {
kind *common_kind = NULL;
int mixed_kind = FALSE, some_new = FALSE;
wording CKW = EMPTY_WORDING, NKW = EMPTY_WORDING;
for (parse_node *option = set; option; option = (option->down)?(option->down->next):NULL) {
wording PW = EMPTY_WORDING;
if (ParseTree__get_type(option) == AND_NT)
PW = ParseTree__get_text(option->down);
else
PW = ParseTree__get_text(option);
if (Preform__parse_nt_against_word_range(adjective_name_NTM, PW, NULL, NULL)) {
adjectival_phrase *aph = most_recent_result_p;
instance *I = Adjectives__Phrases__has_ENUMERATIVE_meaning(aph);
kind *K = (I)?Instances__to_kind(I):NULL;
if (common_kind == NULL) {
common_kind = K;
CKW = PW;
} else {
if (Kinds__Compare__eq(K, common_kind) == FALSE) {
mixed_kind = TRUE;
NKW = PW;
}
}
} else {
some_new = TRUE; NKW = PW;
}
}
if (common_kind) {
property *prn = Kinds__Behaviour__get_coinciding_property(common_kind);
if (Wordings__nonempty(NKW)) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, common_kind);
Problems__quote_wording(3, CKW);
Problems__quote_wording(4, NKW);
Problems__Issue__handmade_problem(_p_(PM_MixedExistingConstants));
Problems__issue_problem_segment(
"In %1, one of the values you supply as a possibility is '%3', "
"but this already has a meaning (as %2). This might be okay if "
"every other possibility was also %2, but '%4' isn't.");
Problems__issue_problem_end();
} else if (prn == NULL) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, common_kind);
Problems__Issue__handmade_problem(_p_(BelievedImpossible)); /* because it won't parse */
Problems__issue_problem_segment(
"In %1, every value you supply as a possibility is %2. "
"That would be okay if it were a property which is a condition "
"of something, but it isn't.");
Problems__issue_problem_end();
} else {
*already = TRUE;
return prn;
}
}
{
#line 119 "inform7/Chapter 21/Condition Properties.w"
int ct = 0;
property *prn;
LOOP_OVER(prn, property)
if ((prn->condition_of == infs) && (prn->condition_anonymously_named))
ct++;
feed_t id = Feeds__begin();
wording W2 = InferenceSubjects__get_name_text(infs);
if (Wordings__nonempty(W2)) Feeds__feed_wording(W2);
else Feeds__feed_text(" nameless ");
Feeds__feed_text(" condition ");
if (ct > 0) {
char numb[32];
sprintf(numb, " %d ", ct+1);
Feeds__feed_text(numb);
}
W = Feeds__end(id);
}
#line 86 "inform7/Chapter 21/Condition Properties.w"
;
anon = TRUE;
}
pcalc_prop *prop = Calculus__Propositions__Abstract__to_create_something(NULL, W);
prop = Calculus__Propositions__concatenate(prop,
Calculus__Propositions__Abstract__to_make_a_kind(K_value));
Calculus__Propositions__Assert__assert_true(prop, prevailing_mood);
property *prn = Properties__Valued__obtain(W);
prn->either_or = FALSE;
prn->condition_of = infs;
prn->condition_anonymously_named = anon;
return prn;
}
#line 139 "inform7/Chapter 21/Condition Properties.w"
inference_subject *Properties__Conditions__of_what(property *prn) {
if ((prn == NULL) || (prn->either_or)) return NULL;
return prn->condition_of; /* which will be null if not a condition property */
}
#line 23 "inform7/Chapter 21/Indefinite Appearance.w"
void Properties__Appearance__infer(inference_subject *infs, parse_node *spec) {
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_indefinite_appearance_text)
{
#line 40 "inform7/Chapter 21/Indefinite Appearance.w"
Problems__Issue__infs_contradiction_problem(_p_(PM_TwoAppearances),
World__Inferences__where_inferred(inf), current_sentence, infs,
"seems to have two different descriptions",
"perhaps because you intended the second description to apply to something "
"mentioned in between, but declared it in such a way that it was never the "
"subject of an assertion. For instance, 'The Forest Clearing is northeast of "
"the Woods.' makes the Forest Clearing the current room being discussed, but "
"'Northeast of the Woods is the Forest Clearing.' leaves the room under "
"discussion unchanged, because the Forest Clearing is not the subject of "
"the sentence.");
return;
}
#line 27 "inform7/Chapter 21/Indefinite Appearance.w"
;
prevailing_mood = CERTAIN_CE;
if ((InferenceSubjects__domain(infs)) &&
(InferenceSubjects__is_within(infs, Kinds__Behaviour__as_subject(K_object))))
prevailing_mood = LIKELY_CE;
Properties__Valued__assert(P_indefinite_appearance_text, infs, spec, prevailing_mood);
}
#line 63 "inform7/Chapter 21/Indefinite Appearance.w"
void Properties__Appearance__reallocate(inference_subject *infs) {
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
if (World__Inferences__get_property(inf) == P_indefinite_appearance_text) {
parse_node *txt = World__Inferences__get_property_value(inf);
current_sentence = World__Inferences__where_inferred(inf);
if (Plugins__Call__default_appearance(infs, txt) == FALSE) {
if ((P_description) &&
(World__Permissions__find(infs, P_description, TRUE))) {
Properties__Valued__assert(P_description, infs, txt, CERTAIN_CE);
} else Problems__Issue__inference_problem(_p_(PM_IndefiniteTextMeaningless),
infs, inf, "is not allowed",
"i.e., you can't write a double-quoted piece of text as a "
"sentence all by itself here. Some kinds or kinds of value "
"are allowed this - objects and scenes, for instance - but "
"most are not. (They would need to provide a 'description' "
"property.)");
}
}
}
}
#line 25 "inform7/Chapter 21/The Provision Relation.w"
void Properties__ProvisionRelation__REL_create_initial_stock(void) {
R_provision =
BinaryPredicates__make_pair(PROVISION_KBP,
BinaryPredicates__new_term(NULL), BinaryPredicates__new_term(NULL),
"provides", NULL, NULL, NULL, NULL,
Preform__Nonparsing__wording(relation_names_NTM, PROVISION_RELATION_NAME));
BinaryPredicates__set_index_details(R_provision, "value", "property");
}
#line 38 "inform7/Chapter 21/The Provision Relation.w"
void Properties__ProvisionRelation__REL_create_second_stock(void) {
}
#line 47 "inform7/Chapter 21/The Provision Relation.w"
int Properties__ProvisionRelation__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
if (Kinds__get_construct(kinds_of_terms[1]) == CON_property) return ALWAYS_MATCH;
Problems__quote_kind(4, kinds_of_terms[1]);
Problems__Issue__tcp_problem(_p_(PM_BadProvides), tck,
"that asks whether something provides something, and in Inform 'to provide' "
"means that an object (or value) has a property attached - for instance, "
"containers provide the property 'carrying capacity'. Here, though, we have "
"%4 rather than the name of a property.");
return NEVER_MATCH;
}
#line 65 "inform7/Chapter 21/The Provision Relation.w"
int Properties__ProvisionRelation__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
property *prn = Rvalues__to_property(spec1);
if ((infs0) && (prn)) {
World__Permissions__grant(infs0, prn, TRUE);
Instances__update_adjectival_forms(prn);
return TRUE;
}
return FALSE;
}
#line 82 "inform7/Chapter 21/The Provision Relation.w"
int Properties__ProvisionRelation__REL_compile(int task, binary_predicate *bp,
annotated_i6_schema *asch) {
if (task == TEST_ATOM_TASK) {
kind *K = Calculus__Deferrals__Cinders__kind_of_value_of_term(asch->pt0);
property *prn = Rvalues__to_property(asch->pt1.constant);
if (K) {
if (prn) {
if (Kinds__Compare__le(K, K_object))
{
#line 113 "inform7/Chapter 21/The Provision Relation.w"
if (Properties__is_value_property(prn))
Calculus__Schemas__modify(asch->schema, "WhetherProvides(*1, false, *2)");
else
Calculus__Schemas__modify(asch->schema, "WhetherProvides(*1, true, *2)");
}
#line 90 "inform7/Chapter 21/The Provision Relation.w"
else
{
#line 122 "inform7/Chapter 21/The Provision Relation.w"
if (World__Permissions__find(Kinds__Behaviour__as_subject(K), prn, TRUE))
Calculus__Schemas__modify(asch->schema, "true");
else
Calculus__Schemas__modify(asch->schema, "false");
}
#line 92 "inform7/Chapter 21/The Provision Relation.w"
;
return TRUE;
} else if (Kinds__Compare__le(K, K_object)) {
kind *PK = Calculus__Deferrals__Cinders__kind_of_value_of_term(asch->pt1);
if (Kinds__get_construct(PK) == CON_property) {
if (Kinds__Compare__eq(K_truth_state, Kinds__unary_construction_material(PK)))
Calculus__Schemas__modify(asch->schema, "WhetherProvides(*1, true, *2)");
else
Calculus__Schemas__modify(asch->schema, "WhetherProvides(*1, false, *2)");
return TRUE;
}
}
}
}
return FALSE;
}
#line 131 "inform7/Chapter 21/The Provision Relation.w"
int Properties__ProvisionRelation__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 87 "inform7/Chapter 21/Measurement Adjectives.w"
binary_predicate *Properties__Measurement__weak_comparison_bp(int shape) {
binary_predicate *operator = NULL; /* solely to placate gcc */
switch (shape) {
case MEASURE_T_OR_MORE: operator = R_numerically_greater_than_or_equal_to; break;
case MEASURE_T_EXACTLY: operator = R_equality; break;
case MEASURE_T_OR_LESS: operator = R_numerically_less_than_or_equal_to; break;
default: internal_error("unknown region for weak comparison");
}
return operator;
}
char *Properties__Measurement__strict_comparison(int shape) {
char *operator = NULL; /* solely to placate gcc */
switch (shape) {
case MEASURE_T_OR_MORE: operator = ">"; break;
case MEASURE_T_OR_LESS: operator = "<"; break;
default: internal_error("unknown region for strict comparison");
}
return operator;
}
#line 111 "inform7/Chapter 21/Measurement Adjectives.w"
measurement_definition *Properties__Measurement__retrieve(property *prn, int shape) {
measurement_definition *mdef;
LOOP_OVER(mdef, measurement_definition) {
Properties__Measurement__validate(mdef);
if ((Properties__Measurement__is_valid(mdef)) && (mdef->prop == prn) && (mdef->region_shape == shape))
return mdef;
}
return NULL;
}
void Properties__Measurement__read_property_details(measurement_definition *mdef,
property **prn, int *shape) {
if (prn) *prn = mdef->prop;
if (shape) *shape = mdef->region_shape;
}
#line 134 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__validate_definitions(void) {
measurement_definition *mdef;
LOOP_OVER(mdef, measurement_definition) Properties__Measurement__validate(mdef);
}
#line 142 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__validate(measurement_definition *mdef) {
if ((mdef->prop == NULL) && (Wordings__nonempty(mdef->name_of_property_to_compare)))
{
#line 152 "inform7/Chapter 21/Measurement Adjectives.w"
if (Preform__parse_nt_against_word_range(property_name_NTM, mdef->name_of_property_to_compare, NULL, NULL)) mdef->prop = most_recent_result_p;
else {
mdef->prop = NULL;
LOG("Validating mdef with headword $w... <$w>\n",
mdef->headword, mdef->name_of_property_to_compare);
Problems__Issue__definition_problem(_p_(PM_GradingUnknownProperty),
mdef->measurement_node,
"that definition involves an unknown property",
"assuming it was meant to be a definition in the form 'Definition: "
"a container is large if its carrying capacity is 10 or more.'");
return;
}
}
#line 144 "inform7/Chapter 21/Measurement Adjectives.w"
;
if (mdef->region_threshold_evaluated == FALSE)
{
#line 169 "inform7/Chapter 21/Measurement Adjectives.w"
mdef->region_kind = NULL;
if (Preform__parse_nt_against_word_range(s_literal_NTM, mdef->region_threshold_text, NULL, NULL))
mdef->region_kind = Rvalues__to_kind(most_recent_result_p);
if (mdef->region_kind) {
mdef->region_threshold = Rvalues__to_encoded_notation(most_recent_result_p);
if ((Kinds__Behaviour__is_quasinumerical(mdef->region_kind) == FALSE) &&
(mdef->region_shape != MEASURE_T_EXACTLY)) {
Problems__Issue__definition_problem(_p_(PM_GradingNonarithmeticKOV),
mdef->measurement_node,
"the property value given here has a kind which can't be "
"subject to numerical comparisons",
"so it doesn't make sense to talk about it being 'more' or "
"'less'.");
mdef->region_threshold = 0;
return;
}
if (Kinds__Compare__compatible(mdef->region_kind,
Properties__Valued__kind(mdef->prop)) != ALWAYS_MATCH) {
Problems__Issue__definition_problem(_p_(PM_GradingWrongKOV),
mdef->measurement_node,
"the property value given here is the wrong kind",
"and does not match the property being looked at.");
mdef->region_threshold = 0;
return;
}
} else {
LOG("Can't get literal from <$w>\n", mdef->region_threshold_text);
Problems__Issue__definition_problem(_p_(PM_GradingNonLiteral),
mdef->measurement_node,
"that definition is wrongly phrased",
"assuming it was meant to be a grading adjective like 'Definition: a "
"container is large if its carrying capacity is 10 or more.'");
return;
}
mdef->region_threshold_evaluated = TRUE;
}
#line 146 "inform7/Chapter 21/Measurement Adjectives.w"
;
}
#line 208 "inform7/Chapter 21/Measurement Adjectives.w"
int Properties__Measurement__is_valid(measurement_definition *mdef) {
if ((mdef->prop == NULL) || (mdef->region_threshold_evaluated == FALSE)) return FALSE;
return TRUE;
}
#line 229 "inform7/Chapter 21/Measurement Adjectives.w"
int measurement_adjective_definition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 242 "inform7/Chapter 21/Measurement Adjectives.w"
Problems__Issue__definition_problem(_p_(PM_GradingMisphrased),
Sentences__NPs__new_raw(W),
"that definition is wrongly phrased",
"assuming it was meant to be a grading adjective like 'Definition: a "
"container is large if its carrying capacity is 10 or more.'");
return FALSE;
}
#line 230 "inform7/Chapter 21/Measurement Adjectives.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[3]; *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[2]; *XP = NULL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 233 "inform7/Chapter 21/Measurement Adjectives.w"
int measurement_range_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = MEASURE_T_OR_MORE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = MEASURE_T_OR_LESS;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = MEASURE_T_EXACTLY;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 238 "inform7/Chapter 21/Measurement Adjectives.w"
#line 252 "inform7/Chapter 21/Measurement Adjectives.w"
adjective_meaning *Properties__Measurement__ADJ_parse(parse_node *q,
int sense, wording AW, wording DNW, wording CONW, wording CALLW) {
if (sense == 0) return NULL;
if (Preform__parse_nt_against_word_range(measurement_adjective_definition_NTM, CONW, NULL, NULL) == FALSE) return NULL;
int shape = most_recent_result;
wording PRW = GET_RW(measurement_adjective_definition_NTM, 1);
wording THRESW = GET_RW(measurement_range_NTM, 1);
property *prop = most_recent_result_p;
{
#line 275 "inform7/Chapter 21/Measurement Adjectives.w"
if (Wordings__length(AW) > 1) {
if (shape != MEASURE_T_EXACTLY)
Problems__Issue__definition_problem(_p_(PM_MultiwordGrading),
q, "a grading adjective must be a single word",
"as in 'Definition: a container is large if its carrying capacity is "
"10 or more.': 'fairly large' would not be allowed because it would "
"make no sense to talk about 'fairly larger' or 'fairly largest'.");
return NULL;
}
if (Wordings__nonempty(CALLW)) {
if (shape != MEASURE_T_EXACTLY)
Problems__Issue__definition_problem(_p_(PM_GradingCalled),
q, "callings are not allowed when defining grading adjectives",
"so 'Definition: a container is large if its carrying capacity is 10 "
"or more.' is fine, but so 'Definition: a container (called the bag) "
"is large if its carrying capacity is 10 or more.' is not - then again, "
"there's very little call for it.");
return NULL;
}
if (sense != 1) {
if (shape != MEASURE_T_EXACTLY)
Problems__Issue__definition_problem(_p_(PM_GradingUnless),
q, "'unless' is not allowed when defining grading adjectives",
"so 'Definition: a container is large if its carrying capacity is 10 "
"or more.' is fine, but so 'Definition: a container is modest unless "
"its carrying capacity is 10 or more.' is not - of course a similar "
"effect could be achieved by 'Definition: a container is modest if its "
"carrying capacity is 9 or less.'");
return NULL;
}
}
#line 262 "inform7/Chapter 21/Measurement Adjectives.w"
;
{
#line 326 "inform7/Chapter 21/Measurement Adjectives.w"
if (shape == MEASURE_T_EXACTLY) {
if (Preform__parse_nt_against_word_range(s_literal_NTM, THRESW, NULL, NULL) == FALSE) return NULL;
}
}
#line 263 "inform7/Chapter 21/Measurement Adjectives.w"
;
measurement_definition *mdef = CREATE(measurement_definition);
{
#line 333 "inform7/Chapter 21/Measurement Adjectives.w"
mdef->measurement_node = q;
mdef->headword = Wordings__first_word(AW);
mdef->region_threshold = 0;
mdef->region_threshold_text = THRESW;
mdef->region_threshold_evaluated = FALSE;
mdef->prop = prop;
mdef->property_schema_written = FALSE;
mdef->region_shape = shape;
mdef->name_of_property_to_compare = PRW;
mdef->superlative = EMPTY_WORDING; /* but it may be set below */
mdef->headword_as_adjective = NULL; /* but it will certainly be set below */
}
#line 266 "inform7/Chapter 21/Measurement Adjectives.w"
;
if (shape != MEASURE_T_EXACTLY)
{
#line 351 "inform7/Chapter 21/Measurement Adjectives.w"
mdef->superlative = Inflections__make_superlative(mdef->headword);
{
#line 359 "inform7/Chapter 21/Measurement Adjectives.w"
TEMPORARY_STREAM;
WRITE_TO(TEMP, " To decide which object is %s ( S - description of objects ) ",
Lexer__word_text(Wordings__first_wn(mdef->superlative)));
Sentences__make_node(
Feeds__feed_text(STREAM_TEXT(TEMP)),
':');
CLOSE_TEMPORARY_STREAM;
}
#line 352 "inform7/Chapter 21/Measurement Adjectives.w"
;
{
#line 370 "inform7/Chapter 21/Measurement Adjectives.w"
TEMPORARY_STREAM;
WRITE_TO(TEMP, " (- {-primitive-definition:extremal%s",
Properties__Measurement__strict_comparison(mdef->region_shape));
Wordings__to_stream(TEMP, mdef->name_of_property_to_compare);
WRITE_TO(TEMP, "} -) ");
Sentences__make_node(
Feeds__feed_text(STREAM_TEXT(TEMP)),
'.');
CLOSE_TEMPORARY_STREAM;
}
#line 353 "inform7/Chapter 21/Measurement Adjectives.w"
;
Sentences__RuleSubtrees__register_recently_lexed_phrases();
}
#line 267 "inform7/Chapter 21/Measurement Adjectives.w"
;
{
#line 383 "inform7/Chapter 21/Measurement Adjectives.w"
adjective_meaning *am = Adjectives__Meanings__new(MEASUREMENT_KADJ,
STORE_POINTER_measurement_definition(mdef), ParseTree__get_text(q));
mdef->headword_as_adjective = am;
Adjectives__Phrases__declare(am, AW);
Adjectives__Meanings__pass_task_to_support_routine(am, TEST_ADJECTIVE_TASK);
Adjectives__Meanings__set_domain_text(am, DNW);
}
#line 268 "inform7/Chapter 21/Measurement Adjectives.w"
;
return mdef->headword_as_adjective;
}
#line 393 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__ADJ_compiling_soon(adjective_meaning *am,
measurement_definition *mdef, int T) {
if ((mdef->prop) && (mdef->region_threshold_evaluated) &&
(mdef->property_schema_written == FALSE)) {
i6_schema *sch = Adjectives__Meanings__set_i6_schema(
mdef->headword_as_adjective, TEST_ADJECTIVE_TASK, FALSE);
Calculus__Schemas__modify(sch, "MADJ_Test_%d(*1)", mdef->allocation_id);
mdef->property_schema_written = TRUE;
}
}
int Properties__Measurement__ADJ_compile(measurement_definition *mdef,
int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
int Properties__Measurement__ADJ_assert(measurement_definition *mdef,
inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) {
Properties__Measurement__validate(mdef);
if ((Properties__Measurement__is_valid(mdef)) && (mdef->prop) && (parity == TRUE)) {
parse_node *val = NULL;
if (Preform__parse_nt_against_word_range(s_literal_NTM, mdef->region_threshold_text, NULL, NULL)) val = most_recent_result_p;
else internal_error("literal unreadable");
World__Inferences__draw_property(infs_to_assert_on, mdef->prop, val);
return TRUE;
}
return FALSE;
}
int Properties__Measurement__ADJ_index(measurement_definition *mdef) {
return FALSE;
}
#line 429 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__compile_MADJ_routines(OUTPUT_STREAM) {
measurement_definition *mdef;
LOOP_OVER(mdef, measurement_definition)
if (mdef->property_schema_written) {
OUT = Routines__begin_numbered(OUT, "MADJ_Test_%d", mdef->allocation_id);
local_variable *lv = LocalVariables__add_call_parameter(
Frames__current_stack_frame(),
EMPTY_WORDING,
Adjectives__Meanings__get_domain(mdef->headword_as_adjective));
parse_node *var = Lvalues__new_LOCAL_VARIABLE(EMPTY_WORDING, lv);
parse_node *evaluated_prop = Lvalues__new_PROPERTY_VALUE(
Rvalues__from_property(mdef->prop), var);
parse_node *val = NULL;
if (Preform__parse_nt_against_word_range(s_literal_NTM, mdef->region_threshold_text, NULL, NULL)) val = most_recent_result_p;
else internal_error("literal unreadable");
pcalc_prop *prop = Calculus__Atoms__binary_PREDICATE_new(
Properties__Measurement__weak_comparison_bp(mdef->region_shape),
Calculus__Terms__new_constant(evaluated_prop),
Calculus__Terms__new_constant(val));
if (Calculus__Propositions__Checker__type_check(prop,
Calculus__Propositions__Checker__tc_problem_reporting(
mdef->region_threshold_text,
"be giving the boundary of the definition")) == ALWAYS_MATCH) {
WRITE("if (");
Calculus__Deferrals__compile_test_of_proposition(OUT, NULL, prop);
WRITE(") rtrue;\n");
}
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
}
}
#line 466 "inform7/Chapter 21/Measurement Adjectives.w"
void Properties__Measurement__create_comparatives(void) {
measurement_definition *mdef;
LOOP_OVER(mdef, measurement_definition) {
Properties__Measurement__validate(mdef);
if ((Properties__Measurement__is_valid(mdef)) && (mdef->region_shape != MEASURE_T_EXACTLY)) {
wording H = mdef->headword; /* word number of, e.g., "tall" */
wording comparative_form = Inflections__make_comparative(H); /* "taller" */
vocabulary_entry *quiddity =
Lexer__word(Wordings__first_wn(Inflections__make_quiddity(H))); /* "tallness" */
i6_schema *schema_to_compare_property_values;
{
#line 486 "inform7/Chapter 21/Measurement Adjectives.w"
char *identifier = Properties__get_translation(mdef->prop);
char *operation = Properties__Measurement__strict_comparison(mdef->region_shape);
schema_to_compare_property_values =
Calculus__Schemas__new("(*1.%s %s *2.%s)", identifier, operation, identifier);
}
#line 477 "inform7/Chapter 21/Measurement Adjectives.w"
;
{
#line 501 "inform7/Chapter 21/Measurement Adjectives.w"
binary_predicate *bp;
bp = BinaryPredicates__make_pair(PROPERTY_COMPARISON_KBP,
BinaryPredicates__new_term(NULL), BinaryPredicates__new_term(NULL),
Vocabulary__get_exemplar(quiddity, FALSE), NULL, NULL, NULL,
schema_to_compare_property_values, WordAssemblages__lit_1(quiddity));
BinaryPredicates__set_comparison_details(bp, mdef->region_shape, mdef->prop);
Prepositions__register_comparative(comparative_form, bp);
}
#line 478 "inform7/Chapter 21/Measurement Adjectives.w"
;
}
}
}
#line 21 "inform7/Chapter 21/Comparative Relations.w"
void Properties__ComparativeRelations__REL_create_initial_stock(void) {
}
#line 35 "inform7/Chapter 21/Comparative Relations.w"
void Properties__ComparativeRelations__REL_create_second_stock(void) {
Properties__Measurement__create_comparatives();
}
#line 45 "inform7/Chapter 21/Comparative Relations.w"
int Properties__ComparativeRelations__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
if ((kinds_required[0]) &&
(Kinds__Compare__compatible(kinds_of_terms[0], kinds_required[0]) == NEVER_MATCH)) {
LOG("Term 0 is $u not $u\n", kinds_of_terms[0], kinds_required[0]);
Calculus__Propositions__Checker__issue_bp_typecheck_error(bp,
kinds_of_terms[0], kinds_of_terms[1], tck);
return NEVER_MATCH;
}
property *prn = Kinds__Behaviour__get_coinciding_property(kinds_of_terms[1]);
if ((prn) && (prn != bp->comparative_property)) {
if (tck->log_to_I6_text)
LOG("Comparative misapplied to $Y not $Y\n", prn, bp->comparative_property);
Problems__quote_property(4, bp->comparative_property);
Problems__quote_property(5, prn);
Problems__Issue__tcp_problem(_p_(PM_ComparativeMisapplied), tck,
"that ought to make a comparison of %4 not %5.");
return NEVER_MATCH;
}
return ALWAYS_MATCH;
}
#line 72 "inform7/Chapter 21/Comparative Relations.w"
int Properties__ComparativeRelations__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
return FALSE;
}
#line 82 "inform7/Chapter 21/Comparative Relations.w"
int Properties__ComparativeRelations__REL_compile(int task, binary_predicate *bp,
annotated_i6_schema *asch) {
if (task == TEST_ATOM_TASK)
{
#line 98 "inform7/Chapter 21/Comparative Relations.w"
kind *st[2];
st[0] = Calculus__Deferrals__Cinders__kind_of_value_of_term(asch->pt0);
st[1] = Calculus__Deferrals__Cinders__kind_of_value_of_term(asch->pt1);
if ((Kinds__Compare__eq(st[0], st[1]) == FALSE) &&
(Kinds__Behaviour__name_can_coincide_with_property(st[1]))) {
property *prn = Kinds__Behaviour__get_coinciding_property(st[1]);
if (prn) {
Calculus__Schemas__modify(asch->schema,
"*1.%s %s *2", Properties__get_translation(prn),
Properties__Measurement__strict_comparison(bp->comparison_sign));
return TRUE;
}
}
}
#line 85 "inform7/Chapter 21/Comparative Relations.w"
;
return FALSE;
}
#line 115 "inform7/Chapter 21/Comparative Relations.w"
int Properties__ComparativeRelations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 13 "inform7/Chapter 21/Same Property Relation.w"
void Properties__SameRelations__REL_create_initial_stock(void) {
}
#line 33 "inform7/Chapter 21/Same Property Relation.w"
void Properties__SameRelations__REL_create_second_stock(void) {
property *prn;
LOOP_OVER(prn, property) {
if (Properties__is_value_property(prn)) {
vocabulary_entry *rel_name;
char *i6_pname = Properties__get_translation(prn);
{
#line 71 "inform7/Chapter 21/Same Property Relation.w"
char i7_name[510];
sprintf(i7_name, "same-");
Wordings__to_string_abbreviated(500, i7_name + Platform__strlen(i7_name), prn->name);
STREAM_FLUSH(dl);
sprintf(i7_name + Platform__strlen(i7_name), "-as");
for (int i=0; i7_name[i]; i++) if (i7_name[i] == ' ') i7_name[i] = '-';
wording I7W = Feeds__feed_text_expanding_strings(i7_name);
rel_name = Lexer__word(Wordings__first_wn(I7W));
}
#line 39 "inform7/Chapter 21/Same Property Relation.w"
;
binary_predicate *bp = BinaryPredicates__make_pair(PROPERTY_SAME_KBP,
BinaryPredicates__new_term(NULL), BinaryPredicates__new_term(NULL),
Vocabulary__get_exemplar(rel_name, FALSE), NULL, NULL,
Calculus__Schemas__new("*1.%s = *2.%s", i6_pname, i6_pname),
Calculus__Schemas__new("*1.%s == *2.%s", i6_pname, i6_pname),
WordAssemblages__lit_1(rel_name));
bp->same_property = prn;
Prepositions__register_same_property_as(bp);
}
}
}
#line 84 "inform7/Chapter 21/Same Property Relation.w"
int Properties__SameRelations__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
return DECLINE_TO_MATCH;
}
#line 92 "inform7/Chapter 21/Same Property Relation.w"
int Properties__SameRelations__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
return FALSE;
}
#line 102 "inform7/Chapter 21/Same Property Relation.w"
int Properties__SameRelations__REL_compile(int task,
binary_predicate *bp, annotated_i6_schema *asch) {
return FALSE;
}
#line 110 "inform7/Chapter 21/Same Property Relation.w"
property *Properties__SameRelations__bp_get_same_as_property(binary_predicate *bp) {
return bp->same_property;
}
#line 117 "inform7/Chapter 21/Same Property Relation.w"
int Properties__SameRelations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 12 "inform7/Chapter 21/Setting Property Relation.w"
void Properties__SettingRelations__REL_create_initial_stock(void) {
}
#line 23 "inform7/Chapter 21/Setting Property Relation.w"
binary_predicate *Properties__SettingRelations__make_set_property_BP(wording W) {
binary_predicate *bp = BinaryPredicates__make_pair(PROPERTY_SETTING_KBP,
BinaryPredicates__new_term(Kinds__Behaviour__as_subject(K_object)),
BinaryPredicates__new_term(NULL),
"set-property", NULL, NULL, NULL, NULL, WordAssemblages__lit_0());
bp->property_pending_text = W;
bp->reversal->property_pending_text = W;
return bp;
}
#line 38 "inform7/Chapter 21/Setting Property Relation.w"
binary_predicate *Properties__SettingRelations__find_set_property_BP(wording W) {
binary_predicate *bp;
LOOP_OVER(bp, binary_predicate)
if (Wordings__match(W, bp->property_pending_text))
if (bp->right_way_round)
return bp;
return NULL;
}
#line 51 "inform7/Chapter 21/Setting Property Relation.w"
void Properties__SettingRelations__fix_property_bp(binary_predicate *bp) {
binary_predicate *bpr = bp->reversal;
wording W = bp->property_pending_text;
if (Wordings__nonempty(W)) {
bp->property_pending_text = EMPTY_WORDING;
bpr->property_pending_text = EMPTY_WORDING;
current_sentence = bp->bp_created_at;
Preform__parse_nt_against_word_range(relation_property_name_NTM, W, NULL, NULL);
if (most_recent_result == FALSE) return; /* a problem was issued */
property *prn = most_recent_result_p;
bp->set_property = prn; bpr->set_property = prn;
if (bp->right_way_round) Properties__SettingRelations__set_property_BP_schemas(bp, prn);
else Properties__SettingRelations__set_property_BP_schemas(bpr, prn);
}
}
#line 74 "inform7/Chapter 21/Setting Property Relation.w"
int relation_property_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 82 "inform7/Chapter 21/Setting Property Relation.w"
*X = FALSE;
Problems__Issue__sentence_problem(_p_(PM_RelationWithEitherOrProperty),
"verbs can only set properties with values",
"not either/or properties like this one.");
}
#line 75 "inform7/Chapter 21/Setting Property Relation.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 90 "inform7/Chapter 21/Setting Property Relation.w"
*X = FALSE;
Problems__Issue__sentence_problem(_p_(PM_RelationWithBadProperty),
"that doesn't seem to be a property",
"perhaps because you haven't defined it yet?");
}
#line 77 "inform7/Chapter 21/Setting Property Relation.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 78 "inform7/Chapter 21/Setting Property Relation.w"
#line 99 "inform7/Chapter 21/Setting Property Relation.w"
binary_predicate *Properties__SettingRelations__make_set_nameless_property_BP(property *prn) {
binary_predicate *bp = Properties__SettingRelations__make_set_property_BP(EMPTY_WORDING);
binary_predicate *bpr = bp->reversal;
bp->set_property = prn; bpr->set_property = prn;
Properties__SettingRelations__set_property_BP_schemas(bp, prn);
return bp;
}
#line 112 "inform7/Chapter 21/Setting Property Relation.w"
void Properties__SettingRelations__REL_create_second_stock(void) {
binary_predicate *bp;
LOOP_OVER(bp, binary_predicate)
if (Wordings__nonempty(bp->property_pending_text))
Properties__SettingRelations__fix_property_bp(bp);
}
#line 126 "inform7/Chapter 21/Setting Property Relation.w"
void Properties__SettingRelations__set_property_BP_schemas(binary_predicate *bp, property *prn) {
bp->test_function =
Calculus__Schemas__new("*1.%s == *2", Properties__get_translation(prn));
bp->make_true_function =
Calculus__Schemas__new("*1.%s = *2", Properties__get_translation(prn));
BinaryPredicates__set_term_domain(&(bp->term_details[1]),
Properties__Valued__kind(prn));
}
#line 148 "inform7/Chapter 21/Setting Property Relation.w"
int Properties__SettingRelations__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
property *prn = bp->set_property;
kind *val_kind = Properties__Valued__kind(prn);
{
#line 169 "inform7/Chapter 21/Setting Property Relation.w"
int safe = FALSE;
int compatible = Kinds__Compare__compatible(kinds_of_terms[1], val_kind);
if (compatible == ALWAYS_MATCH) safe = TRUE;
if (compatible == SOMETIMES_MATCH) {
if ((Kinds__Compare__le(val_kind, K_object) == FALSE) ||
(Kinds__Compare__eq(val_kind, K_direction)) ||
(Kinds__Compare__eq(val_kind, K_room)) ||
(Kinds__Compare__eq(val_kind, K_container)) ||
(Kinds__Compare__eq(val_kind, K_supporter))) safe = TRUE;
}
if (safe == FALSE) {
LOG("Property value given as $u not $u\n", kinds_of_terms[1], val_kind);
Problems__quote_kind(4, kinds_of_terms[1]);
Problems__quote_kind(5, val_kind);
Problems__quote_property(6, prn);
if (Kinds__get_construct(kinds_of_terms[1]) == CON_property)
Problems__Issue__tcp_problem(_p_(PM_PropertiesEquated), tck,
"that seems to say that two different properties are the same - "
"like saying 'The indefinite article is the printed name': that "
"might be true for some things, some of the time, but it makes no "
"sense in a general statement like this one.");
else if (prn == NULL)
Problems__Issue__tcp_problem(_p_(PM_UnknownPropertyType), tck,
"that tries to set the value of an unknown property to %4.");
else
Problems__Issue__tcp_problem(_p_(PM_PropertyType), tck,
"that tries to set the value of the '%6' property to %4 - which "
"must be wrong because this property has to be %5.");
return NEVER_MATCH;
}
}
#line 152 "inform7/Chapter 21/Setting Property Relation.w"
;
{
#line 204 "inform7/Chapter 21/Setting Property Relation.w"
if (Kinds__Behaviour__has_properties(kinds_of_terms[0]) == FALSE) {
LOG("Property value for impossible domain $u\n", kinds_of_terms[0]);
Problems__quote_kind(4, kinds_of_terms[0]);
Problems__quote_property(5, prn);
Problems__Issue__tcp_problem(_p_(BelievedImpossible), tck,
"that tries to set the property '%5' for %4. Values of that kind "
"are not allowed to have properties. (Some kinds of value are, "
"some aren't - see the Kinds index for details. It's a matter "
"of what is practical in terms of how much memory is needed.)");
return NEVER_MATCH;
}
}
#line 153 "inform7/Chapter 21/Setting Property Relation.w"
;
return ALWAYS_MATCH;
}
#line 219 "inform7/Chapter 21/Setting Property Relation.w"
int Properties__SettingRelations__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
World__Inferences__draw_property(infs0, bp->set_property, spec1);
return TRUE;
}
#line 230 "inform7/Chapter 21/Setting Property Relation.w"
int Properties__SettingRelations__REL_compile(int task,
binary_predicate *bp, annotated_i6_schema *asch) {
kind *K = Calculus__Deferrals__Cinders__kind_of_value_of_term(asch->pt0);
if (Kinds__Compare__le(K, K_object)) return FALSE;
property *prn = bp->set_property;
switch (task) {
case TEST_ATOM_TASK:
Calculus__Schemas__modify(asch->schema,
"GProperty(%k, *1, %s) == *2", K, Properties__get_translation(prn));
break;
case NOW_ATOM_FALSE_TASK:
break;
case NOW_ATOM_TRUE_TASK:
Calculus__Schemas__modify(asch->schema,
"WriteGProperty(%k, *1, %s, *2)", K, Properties__get_translation(prn));
break;
}
return TRUE;
}
#line 255 "inform7/Chapter 21/Setting Property Relation.w"
int Properties__SettingRelations__bp_sets_a_property(binary_predicate *bp) {
if ((bp->set_property) || (Wordings__nonempty(bp->property_pending_text))) return TRUE;
return FALSE;
}
#line 263 "inform7/Chapter 21/Setting Property Relation.w"
int Properties__SettingRelations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 102 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__allocate_attributes(void) {
int slots_given_away = 0;
property *prn;
LOOP_OVER(prn, property) {
if ((Properties__is_either_or(prn)) &&
(Properties__EitherOr__stored_in_negation(prn) == FALSE)) {
int make_attribute = NOT_APPLICABLE;
{
#line 123 "inform7/Chapter 21/Properties of Objects.w"
property_permission *pp;
LOOP_OVER_PERMISSIONS_FOR_PROPERTY(pp, prn) {
inference_subject *infs = World__Permissions__get_subject(pp);
if ((InferenceSubjects__is_an_object(infs) == FALSE) &&
(InferenceSubjects__is_a_kind_of_object(infs) == FALSE))
make_attribute = FALSE;
}
}
#line 109 "inform7/Chapter 21/Properties of Objects.w"
;
{
#line 141 "inform7/Chapter 21/Properties of Objects.w"
if (Properties__has_been_translated(prn)) make_attribute = TRUE;
}
#line 110 "inform7/Chapter 21/Properties of Objects.w"
;
{
#line 154 "inform7/Chapter 21/Properties of Objects.w"
if (make_attribute == NOT_APPLICABLE) {
if (slots_given_away++ < ATTRIBUTE_SLOTS_TO_GIVE_AWAY)
make_attribute = TRUE;
else
make_attribute = FALSE;
}
}
#line 111 "inform7/Chapter 21/Properties of Objects.w"
;
Properties__EitherOr__implement_as_attribute(prn, make_attribute);
}
}
}
#line 166 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_attributes(OUTPUT_STREAM) {
{
#line 176 "inform7/Chapter 21/Properties of Objects.w"
property *prn;
LOOP_OVER(prn, property)
if ((Properties__is_either_or(prn)) &&
(Properties__EitherOr__stored_in_negation(prn) == FALSE))
if ((Properties__EitherOr__implemented_as_attribute(prn)) &&
(Properties__has_been_translated(prn) == FALSE))
WRITE("Attribute %s;\n", Properties__get_translation(prn));
}
#line 167 "inform7/Chapter 21/Properties of Objects.w"
;
{
#line 203 "inform7/Chapter 21/Properties of Objects.w"
property *FBNA = NULL;
property *prn;
LOOP_OVER(prn, property)
if ((Properties__is_either_or(prn)) &&
(Properties__EitherOr__stored_in_negation(prn) == FALSE))
if (Properties__EitherOr__implemented_as_attribute(prn) == FALSE) {
FBNA = prn; break;
}
if (FBNA) WRITE("Constant FBNA_PROP_NUMBER = %s;\n", Properties__get_translation(FBNA));
else WRITE("Constant FBNA_PROP_NUMBER = MAX_POSITIVE_NUMBER; ! No actual FBNA\n");
}
#line 168 "inform7/Chapter 21/Properties of Objects.w"
;
{
#line 228 "inform7/Chapter 21/Properties of Objects.w"
WRITE("Object property_numberspace_forcer\n"); INDENT;
property *prn;
LOOP_OVER(prn, property)
if ((Properties__is_either_or(prn)) &&
(Properties__EitherOr__stored_in_negation(prn) == FALSE))
if (Properties__EitherOr__implemented_as_attribute(prn) == FALSE)
WRITE("with %s false\n", Properties__get_translation(prn));
OUTDENT; WRITE(";\n");
}
#line 169 "inform7/Chapter 21/Properties of Objects.w"
;
}
#line 250 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__begin_sequencing_objects(void) {
int i, nc = NUMBER_CREATED(instance);
if (objects_in_compilation_list == NULL) {
objects_in_compilation_list = (instance **)
(Memory__I7_calloc(nc, sizeof(instance *), OBJECT_COMPILATION_MREASON));
}
for (i=0; i<nc; i++) objects_in_compilation_list[i] = NULL;
first_object_in_compilation_list = NULL;
last_object_in_compilation_list = NULL;
}
void Properties__ObjectImplementation__place_this_object_next(instance *I) {
if (last_object_in_compilation_list == NULL)
first_object_in_compilation_list = I;
else
objects_in_compilation_list[last_object_in_compilation_list->allocation_id] = I;
last_object_in_compilation_list = I;
}
#line 273 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__place_objects_in_definition_sequence(void) {
Properties__ObjectImplementation__begin_sequencing_objects();
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
Properties__ObjectImplementation__place_this_object_next(I);
}
#line 300 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_all(OUTPUT_STREAM) {
instance *I;
Properties__ObjectImplementation__compile_subject(OUT,
Kinds__Behaviour__as_subject(K_object));
Properties__ObjectImplementation__compile_class_definitions(OUT, Kinds__Behaviour__as_subject(K_object));
LOOP_OVER_OBJECTS_IN_COMPILATION_SEQUENCE(I)
Properties__ObjectImplementation__compile_subject(OUT,
Instances__as_subject(I));
PL__Naming__compile_small_names(OUT);
}
void Properties__ObjectImplementation__compile_class_definitions(OUTPUT_STREAM, inference_subject *within) {
inference_subject *subj;
LOOP_OVER(subj, inference_subject)
if ((InferenceSubjects__narrowest_broader_subject(subj) == within) &&
(InferenceSubjects__is_a_kind_of_object(subj))) {
Properties__ObjectImplementation__compile_subject(OUT, subj);
Properties__ObjectImplementation__compile_class_definitions(OUT, subj);
}
}
#line 324 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_subject(OUTPUT_STREAM, inference_subject *subj) {
LOGIF(OBJECT_COMPILATION, "Compiling object definition for $j\n", subj);
int words_used = 0;
kind *K = InferenceSubjects__as_kind(subj);
if (K) Plugins__Call__estimate_property_usage(K, &words_used);
{
#line 354 "inform7/Chapter 21/Properties of Objects.w"
{
#line 373 "inform7/Chapter 21/Properties of Objects.w"
if (K) {
WRITE("Class %s ", Kinds__Behaviour__I6_classname(K));
} else {
instance *I = InferenceSubjects__as_object_instance(subj);
if (Plugins__Call__compile_object_header(OUT, I) == FALSE) {
WRITE("Object ");
int i; for (i=0; i<PL__Spatial__get_definition_depth(I); i++) WRITE("-> ");
WRITE("%s \"\"", Instances__identifier(I));
}
}
WRITE("\n");
}
#line 354 "inform7/Chapter 21/Properties of Objects.w"
;
INDENT;
{
#line 389 "inform7/Chapter 21/Properties of Objects.w"
inference_subject *sup = InferenceSubjects__narrowest_broader_subject(subj);
kind *S = InferenceSubjects__as_kind(sup);
if (Kinds__Compare__le(S, K_object)) {
WRITE("class %s\n", Kinds__Behaviour__I6_classname(S));
words_used++;
}
}
#line 356 "inform7/Chapter 21/Properties of Objects.w"
;
{
#line 401 "inform7/Chapter 21/Properties of Objects.w"
if (subj) Config__Inclusions__compile_inclusions_for_subject(OUT, subj);
}
#line 357 "inform7/Chapter 21/Properties of Objects.w"
;
Properties__begin_traverse();
{
#line 412 "inform7/Chapter 21/Properties of Objects.w"
inference *inf;
KNOWLEDGE_LOOP(inf, subj, PROPERTY_INF) {
property *prn = World__Inferences__get_property(inf);
current_sentence = World__Inferences__where_inferred(inf);
LOGIF(OBJECT_COMPILATION, "Compiling property $Y\n", prn);
words_used += Properties__ObjectImplementation__compile_property_within_object_body(OUT, subj, prn);
}
}
#line 359 "inform7/Chapter 21/Properties of Objects.w"
;
{
#line 424 "inform7/Chapter 21/Properties of Objects.w"
inference_subject *infs;
for (infs = subj; infs; infs = InferenceSubjects__narrowest_broader_subject(infs)) {
property_permission *pp;
LOOP_OVER_PERMISSIONS_FOR_INFS(pp, infs) {
property *prn = World__Permissions__get_property(pp);
if ((infs == subj) ||
(Kinds__Behaviour__uses_pointer_values(Properties__Valued__kind(prn))))
words_used += Properties__ObjectImplementation__compile_property_within_object_body(OUT, subj, prn);
}
}
}
#line 360 "inform7/Chapter 21/Properties of Objects.w"
;
OUTDENT;
WRITE(";\n\n");
}
#line 329 "inform7/Chapter 21/Properties of Objects.w"
;
if (K) {
World__Compile__set_rough_memory_usage(K, words_used);
int nw = 0;
inference_subject *infs;
for (infs = subj;
infs; infs = InferenceSubjects__narrowest_broader_subject(infs)) {
kind *K2 = InferenceSubjects__as_kind(infs);
if (K2) nw += World__Compile__get_rough_memory_usage(K2);
}
nw += 16;
wording KW = Kinds__Behaviour__get_name(K, FALSE);
VirtualMachines__note_usage("object", KW, NULL, nw, 0, TRUE);
LOGIF(OBJECT_COMPILATION, "Rough size estimate: %d words\n", nw);
}
LOGIF(OBJECT_COMPILATION, "Compilation of $j complete\n", subj);
}
#line 439 "inform7/Chapter 21/Properties of Objects.w"
int Properties__ObjectImplementation__compile_property_within_object_body(OUTPUT_STREAM, inference_subject *know, property *prn) {
int storage_cost = 0;
if ((Properties__visited_in_traverse(prn) == FALSE) &&
(Properties__can_be_compiled(prn))) {
if ((Properties__is_either_or(prn)) && (Properties__EitherOr__stored_in_negation(prn)))
prn = Properties__EitherOr__get_negation(prn);
TEMPORARY_STREAM;
Properties__compile_inferred_value(TEMP, know, prn);
{
#line 469 "inform7/Chapter 21/Properties of Objects.w"
if ((Properties__is_either_or(prn)) && (Properties__EitherOr__implemented_as_attribute(prn))) {
int value = FALSE;
if (strcmp(STREAM_TEXT(TEMP), "true") == 0) value = TRUE;
char *name = Properties__get_translation(prn);
if (Properties__EitherOr__stored_in_negation(prn)) {
name = Properties__get_translation(Properties__EitherOr__get_negation(prn));
value = (value)?FALSE:TRUE;
}
WRITE("has %s%s\n", (value)?"":"~", name);
} else {
WRITE("with %s ", Properties__get_translation(prn));
STREAM_COPY(OUT, TEMP);
WRITE("\n");
storage_cost = 2;
}
}
#line 447 "inform7/Chapter 21/Properties of Objects.w"
;
CLOSE_TEMPORARY_STREAM;
}
return storage_cost;
}
#line 494 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_has_property(OUTPUT_STREAM, property *prn) {
if (Properties__EitherOr__implemented_as_attribute(prn)) {
if (Properties__EitherOr__stored_in_negation(prn))
WRITE(" hasnt %s", Properties__get_translation(Properties__EitherOr__get_negation(prn)));
else
WRITE(" has %s", Properties__get_translation(prn));
} else {
if (Properties__EitherOr__stored_in_negation(prn))
WRITE(".%s == false", Properties__get_translation(Properties__EitherOr__get_negation(prn)));
else
WRITE(".%s == true", Properties__get_translation(prn));
}
}
#line 527 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__property_metadata_array(OUTPUT_STREAM) {
WRITE("Array property_metadata -->\n"); INDENT;
int pos = 0;
property *prn;
LOOP_OVER(prn, property) {
if ((Properties__is_either_or(prn)) && (Properties__EitherOr__stored_in_negation(prn))) continue;
char *run_time_id = Properties__get_translation(prn);
Properties__offset_in_runtime_metadata_table_is(prn, pos);
WRITE("! offset %d: property %s\n", pos, run_time_id);
{
#line 546 "inform7/Chapter 21/Properties of Objects.w"
WRITE("\"");
if (Wordings__nonempty(prn->name)) Wordings__to_stream(OUT, prn->name);
else WRITE("<nameless>");
WRITE("\" ");
pos++;
}
#line 536 "inform7/Chapter 21/Properties of Objects.w"
;
{
#line 568 "inform7/Chapter 21/Properties of Objects.w"
property *equiv;
LOOP_OVER(equiv, property)
if (strcmp(Properties__get_translation(equiv), run_time_id) == 0) {
{
#line 578 "inform7/Chapter 21/Properties of Objects.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__lt(K, K_object))
if (World__Permissions__find(Kinds__Behaviour__as_subject(K), equiv, FALSE)) {
WRITE("%s ", Kinds__Behaviour__I6_classname(K));
pos++;
}
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (World__Permissions__find(Instances__as_subject(I), equiv, FALSE)) {
WRITE("%s ", Instances__identifier(I));
pos++;
}
}
#line 571 "inform7/Chapter 21/Properties of Objects.w"
;
{
#line 595 "inform7/Chapter 21/Properties of Objects.w"
if (World__Permissions__find(Kinds__Behaviour__as_subject(K_object), equiv, FALSE)) {
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__eq(Kinds__Compare__super(K), K_object)) {
WRITE("%s ", Kinds__Behaviour__I6_classname(K));
pos++;
}
}
}
#line 572 "inform7/Chapter 21/Properties of Objects.w"
;
}
}
#line 537 "inform7/Chapter 21/Properties of Objects.w"
;
WRITE("NULL\n"); pos++;
}
OUTDENT; WRITE(";\n");
}
#line 614 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__CreatePropertyOffsets_routine(OUTPUT_STREAM) {
OUT = Routines__begin(OUT, "CreatePropertyOffsets");
LocalVariables__add_internal_local_c("i", "loop counter");
WRITE("for (i=0: i<attributed_property_offsets_SIZE: i++)"); INDENT;
WRITE("attributed_property_offsets-->i = -1;\n"); OUTDENT;
WRITE("for (i=0: i<valued_property_offsets_SIZE: i++)"); INDENT;
WRITE("valued_property_offsets-->i = -1;\n"); OUTDENT;
property *prn;
LOOP_OVER(prn, property) {
int offset = Properties__get_offset_in_runtime_metadata_table(prn);
if (offset == UNSET_TABLE_OFFSET) continue;
char *name = Properties__get_translation(prn);
if (Properties__is_either_or(prn))
{
#line 636 "inform7/Chapter 21/Properties of Objects.w"
if (Properties__EitherOr__stored_in_negation(prn) == FALSE) {
if (Properties__EitherOr__implemented_as_attribute(prn))
WRITE("attributed_property_offsets-->%s = %d;\n", name, offset);
else
WRITE("valued_property_offsets-->%s = %d;\n", name, offset);
}
}
#line 626 "inform7/Chapter 21/Properties of Objects.w"
else
{
#line 646 "inform7/Chapter 21/Properties of Objects.w"
WRITE("valued_property_offsets-->%s = %d;\n", name, offset);
}
#line 627 "inform7/Chapter 21/Properties of Objects.w"
;
}
OUT = Routines__end(OUT);
}
#line 659 "inform7/Chapter 21/Properties of Objects.w"
void Properties__ObjectImplementation__compile_stub_properties(OUTPUT_STREAM) {
property *prn;
LOOP_OVER(prn, property) {
char *name = Properties__get_translation(prn);
if ((Properties__is_either_or(prn) == TRUE)
&& (Properties__EitherOr__stored_in_negation(prn))) continue;
WRITE("#ifndef %s; Constant %s = 0; #endif;\n", name, name);
}
}
#line 37 "inform7/Chapter 21/Properties of Values.w"
property_of_value_storage *Properties__ValueImplementation__get_storage(void) {
property_of_value_storage *povs = CREATE(property_of_value_storage);
povs->storage_table_id = -1;
povs->storage_column_id = 0;
latest_povs = povs;
return povs;
}
void Properties__ValueImplementation__pp_set_table_storage(int t, int i) {
if (latest_povs) {
latest_povs->storage_table_id = t;
latest_povs->storage_column_id = i;
}
}
#line 68 "inform7/Chapter 21/Properties of Values.w"
int KOV_representatives_compiled = FALSE;
void Properties__ValueImplementation__compile_properties(OUTPUT_STREAM, kind *K) {
if (KOV_representatives_compiled == FALSE) {
{
#line 86 "inform7/Chapter 21/Properties of Values.w"
WRITE("Class VPH_Class;\n");
}
#line 71 "inform7/Chapter 21/Properties of Values.w"
;
{
#line 95 "inform7/Chapter 21/Properties of Values.w"
WRITE("Array KOV_representatives --> 0 ");
int vph = 0;
int k_id;
for (k_id=1; k_id<next_free_data_type_ID; k_id++) {
int written = FALSE;
kind *K;
LOOP_OVER_BASE_KINDS(K)
if ((Kinds__RunTime__weak_id(K) == k_id) &&
(Properties__ValueImplementation__kind_has_a_vph(K) > 0)) {
WRITE("ValuePropertyHolder_%d ", k_id);
written = TRUE;
break;
}
if (written) vph++; else WRITE("0 ");
}
WRITE(";\n");
if (vph == 0) WRITE("VPH_Class UnusedVPH with value_range 0;\n");
}
#line 72 "inform7/Chapter 21/Properties of Values.w"
;
KOV_representatives_compiled = TRUE;
}
if (Properties__ValueImplementation__kind_has_a_vph(K)) {
{
#line 116 "inform7/Chapter 21/Properties of Values.w"
Properties__ValueImplementation__kind_no_permitted_properties(OUT, FALSE, K);
}
#line 76 "inform7/Chapter 21/Properties of Values.w"
;
{
#line 135 "inform7/Chapter 21/Properties of Values.w"
property *prn;
property_permission *pp;
TRAVERSE_PERMITTED_COMPILABLE_PROPERTIES(prn, pp, K) {
WRITE("! Storage for property %s of kind %s\n",
Properties__get_translation(prn), Kinds__Behaviour__get_name_in_template_code(K));
WRITE("Array KOVP_%d_P%d table ",
Kinds__RunTime__weak_id(K), prn->allocation_id);
int i; for (i=0; i<COL_HSIZE; i++) WRITE("0 ");
instance *nc;
LOOP_OVER_INSTANCES(nc, K) {
WRITE("(");
Properties__compile_inferred_value(OUT,
Instances__as_subject(nc), prn);
WRITE(") ");
}
WRITE(";\n");
}
}
#line 77 "inform7/Chapter 21/Properties of Values.w"
;
}
}
#line 156 "inform7/Chapter 21/Properties of Values.w"
int Properties__ValueImplementation__kind_has_a_vph(kind *K) {
if ((Kinds__Compare__le(K, K_object) == FALSE) &&
(Properties__ValueImplementation__kind_no_permitted_properties(NULL, TRUE, K) > 0))
return TRUE;
return FALSE;
}
#line 182 "inform7/Chapter 21/Properties of Values.w"
int Properties__ValueImplementation__kind_no_permitted_properties(OUTPUT_STREAM, int count_only, kind *K) {
int count = 0;
if (count_only == FALSE)
{
#line 232 "inform7/Chapter 21/Properties of Values.w"
WRITE("VPH_Class ValuePropertyHolder_%d\n", Kinds__RunTime__weak_id(K));
INDENT;
int r = 0;
if ((Kinds__Behaviour__has_properties(K)) &&
(Kinds__Compare__le(K, K_object) == FALSE))
r = Kinds__Behaviour__get_highest_valid_value_as_integer(K);
WRITE("with value_range %d\n", r);
}
#line 185 "inform7/Chapter 21/Properties of Values.w"
;
property *prn;
property_permission *pp;
TRAVERSE_PERMITTED_COMPILABLE_PROPERTIES(prn, pp, K) {
count++;
if (count_only)
{
#line 207 "inform7/Chapter 21/Properties of Values.w"
if ((problem_count == 0) &&
(Properties__has_been_translated(prn)) &&
(Properties__is_either_or(prn))) {
current_sentence = World__Permissions__where_granted(pp);
Problems__quote_source(1, current_sentence);
Problems__quote_property(2, prn);
Problems__quote_kind(3, K);
Problems__Issue__handmade_problem(_p_(PM_AnomalousProperty));
Problems__issue_problem_segment(
"Sorry, but I'm going to have to disallow the sentence %1, even "
"though it asks for something reasonable. A very small number "
"of either-or properties with meanings special to Inform, like '%2', "
"are restricted so that only kinds of object can have them. Since "
"%3 isn't a kind of object, it can't be said to be %2. %P"
"Probably you only need to call the property something else. The "
"built-in meaning would only make sense if it were a kind of object "
"in any case, so nothing is lost. Sorry for the inconvenience, all "
"the same; there are good implementation reasons.");
Problems__issue_problem_end();
}
}
#line 190 "inform7/Chapter 21/Properties of Values.w"
;
if (count_only == FALSE)
{
#line 251 "inform7/Chapter 21/Properties of Values.w"
WRITE("with %s ", Properties__get_translation(prn));
property_of_value_storage *povs =
RETRIEVE_POINTER_property_of_value_storage(World__Permissions__get_storage_data(pp));
if (povs->storage_table_id >= 0)
WRITE("tab_%d_%d", povs->storage_table_id, povs->storage_column_id);
else
WRITE("KOVP_%d_P%d", Kinds__RunTime__weak_id(K), prn->allocation_id);
WRITE("\n");
}
#line 191 "inform7/Chapter 21/Properties of Values.w"
;
}
if (count_only == FALSE)
{
#line 263 "inform7/Chapter 21/Properties of Values.w"
OUTDENT;
WRITE(";\n");
}
#line 193 "inform7/Chapter 21/Properties of Values.w"
;
return count;
}
#line 137 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__begin(void) {
model_world = InferenceSubjects__new_fundamental(NULL, "model-world");
nonlocal_variables = InferenceSubjects__new_fundamental(model_world, "global-variables");
global_constants = InferenceSubjects__new_fundamental(model_world, "global-constants");
relations = InferenceSubjects__new_fundamental(model_world, "relations");
}
inference_subject *InferenceSubjects__new_fundamental(inference_subject *from, char *lname) {
inference_subject *infs = CREATE(inference_subject);
InferenceSubjects__infs_initialise(infs, NULL_GENERAL_POINTER, FUND_SUB, LIKELY_CE, from, lname);
return infs;
}
#line 154 "inform7/Chapter 22/Inference Subjects.w"
inference_subject *InferenceSubjects__new(inference_subject *from, int KOI,
general_pointer gp, int cert) {
inference_subject *infs = CREATE(inference_subject);
InferenceSubjects__infs_initialise(infs, gp, KOI, cert, from, NULL);
return infs;
}
#line 164 "inform7/Chapter 22/Inference Subjects.w"
int no_roots = 0;
void InferenceSubjects__infs_initialise(inference_subject *infs,
general_pointer gp, int KOI, int cert, inference_subject *from, char *lname) {
if ((from == NULL) && (++no_roots > 1)) {
InferenceSubjects__log_infs_hierarchy();
internal_error("subject tree now disconnected");
}
if (from == infs) internal_error("made sub-subject of itself");
infs->infs_created_at = current_sentence;
infs->represents = gp;
infs->kind_of_infs = KOI;
infs->inf_list = NULL;
infs->imp_list = NULL;
infs->broader_than = from;
infs->default_certainty = cert;
infs->permissions_list = NULL;
infs->infs_name_in_log = lname;
infs->alias_variable = NULL;
Assertions__Assemblies__initialise_assemblies_data(&(infs->assemblies));
int i;
for (i=0; i<MAX_PLUGINS; i++) infs->plugin_subj[i] = NULL;
Plugins__Call__new_subject_notify(infs);
}
#line 194 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__renew(inference_subject *infs,
inference_subject *from, int KOI, general_pointer gp, int cert) {
InferenceSubjects__infs_initialise(infs, gp, KOI, cert, from, NULL);
}
#line 204 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__alias_to_nonlocal_variable(inference_subject *infs, nonlocal_variable *q) {
infs->alias_variable = q;
}
int InferenceSubjects__aliased_but_diverted(inference_subject *infs) {
if (infs->alias_variable) {
inference_subject *vs =
Instances__as_subject(
Rvalues__to_object_instance(
NonlocalVariables__get_initial_value(
infs->alias_variable)));
if ((vs) && (vs != infs)) return TRUE;
}
return FALSE;
}
#line 228 "inform7/Chapter 22/Inference Subjects.w"
int InferenceSubjects__is_within(inference_subject *smaller, inference_subject *larger) {
while (smaller) {
if (smaller == larger) return TRUE;
smaller = smaller->broader_than;
}
return FALSE;
}
int InferenceSubjects__is_strictly_within(inference_subject *subj, inference_subject *larger) {
if (subj == NULL) return FALSE;
return InferenceSubjects__is_within(subj->broader_than, larger);
}
#line 245 "inform7/Chapter 22/Inference Subjects.w"
inference_subject *InferenceSubjects__narrowest_broader_subject(inference_subject *narrow) {
if (narrow == NULL) return NULL;
return narrow->broader_than;
}
#line 256 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__falls_within(inference_subject *narrow, inference_subject *broad) {
if (InferenceSubjects__is_within(broad, narrow->broader_than) == FALSE)
internal_error("subject breadth change leads to inconsistency");
narrow->broader_than = broad;
}
#line 266 "inform7/Chapter 22/Inference Subjects.w"
parse_node *InferenceSubjects__where_created(inference_subject *infs) {
if (infs == NULL) internal_error("null INFS");
return infs->infs_created_at;
}
int InferenceSubjects__get_default_certainty(inference_subject *infs) {
return infs->default_certainty;
}
assemblies_data *InferenceSubjects__get_assemblies_data(inference_subject *infs) {
if (infs == NULL) internal_error("tried to fetch assembly data for null subject");
return &(infs->assemblies);
}
inference *InferenceSubjects__get_inferences(inference_subject *infs) {
return (infs)?(infs->inf_list):NULL;
}
void InferenceSubjects__set_inferences(inference_subject *infs, inference *inf) {
if (infs == NULL) internal_error("null INFS");
infs->inf_list = inf;
}
implication *InferenceSubjects__get_implications(inference_subject *infs) {
return infs->imp_list;
}
void InferenceSubjects__set_implications(inference_subject *infs, implication *imp) {
infs->imp_list = imp;
}
property_permission **InferenceSubjects__get_permissions(inference_subject *infs) {
return &(infs->permissions_list);
}
#line 306 "inform7/Chapter 22/Inference Subjects.w"
inference_subject *InferenceSubjects__from_specification(parse_node *spec) {
inference_subject *infs = NULL;
if (Specifications__is_kind_like(spec)) {
kind *K = Specifications__to_kind(spec);
infs = Kinds__Behaviour__as_subject(K);
} else {
instance *I = Rvalues__to_object_instance(spec);
if (I) infs = Instances__as_subject(I);
else {
instance *nc = Rvalues__to_instance(spec);
if (nc) infs = Instances__as_subject(nc);
}
}
return infs;
}
#line 332 "inform7/Chapter 22/Inference Subjects.w"
parse_node *InferenceSubjects__as_constant(inference_subject *infs) {
kind *K = InferenceSubjects__domain(infs);
if (K) return Specifications__from_kind(K);
instance *I = InferenceSubjects__as_object_instance(infs);
if (I) return Rvalues__from_instance(I);
instance *nc = InferenceSubjects__as_nc(infs);
if (nc) return Rvalues__from_instance(nc);
return NULL;
}
#line 348 "inform7/Chapter 22/Inference Subjects.w"
instance *InferenceSubjects__as_instance(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == INST_SUB)) {
instance *nc = RETRIEVE_POINTER_instance(infs->represents);
return nc;
}
return NULL;
}
instance *InferenceSubjects__as_object_instance(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == INST_SUB)) {
instance *nc = RETRIEVE_POINTER_instance(infs->represents);
if (Kinds__Compare__le(Instances__to_kind(nc), K_object))
return nc;
}
return NULL;
}
kind *InferenceSubjects__as_nonobject_kind(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == KIND_SUB)) {
kind *K = Kinds__base_construction(
RETRIEVE_POINTER_kind_constructor(infs->represents));
if (Kinds__Compare__lt(K, K_object)) return NULL;
return K;
}
return NULL;
}
kind *InferenceSubjects__as_kind(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == KIND_SUB)) {
kind *K = Kinds__base_construction(
RETRIEVE_POINTER_kind_constructor(infs->represents));
return K;
}
return NULL;
}
nonlocal_variable *InferenceSubjects__as_nlv(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == VARI_SUB))
return RETRIEVE_POINTER_nonlocal_variable(infs->represents);
return NULL;
}
binary_predicate *InferenceSubjects__as_bp(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == RELN_SUB))
return RETRIEVE_POINTER_binary_predicate(infs->represents);
return NULL;
}
instance *InferenceSubjects__as_nc(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == INST_SUB))
return RETRIEVE_POINTER_instance(infs->represents);
return NULL;
}
#line 405 "inform7/Chapter 22/Inference Subjects.w"
int InferenceSubjects__is_an_object(inference_subject *infs) {
if (InferenceSubjects__as_object_instance(infs)) return TRUE;
return FALSE;
}
int InferenceSubjects__is_a_kind_of_object(inference_subject *infs) {
if ((infs) && (infs->kind_of_infs == KIND_SUB)) {
kind *K = Kinds__base_construction(
RETRIEVE_POINTER_kind_constructor(infs->represents));
if (Kinds__Compare__lt(K, K_object)) return TRUE;
}
return FALSE;
}
#line 423 "inform7/Chapter 22/Inference Subjects.w"
kind *InferenceSubjects__domain(inference_subject *infs) {
return InferenceSubjects__as_kind(infs);
}
#line 430 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__log(inference_subject *infs) {
if (infs == NULL) { LOG("<null infs>"); return; }
if (infs->infs_name_in_log) { LOG("infs<%s>", infs->infs_name_in_log); return; }
wording W = InferenceSubjects__get_name_text(infs);
kind *K = InferenceSubjects__as_nonobject_kind(infs);
if (K) { LOG("infs'$u'-k", K); return; }
if (Wordings__nonempty(W)) { LOG("infs'$w'", W); return; }
binary_predicate *bp = InferenceSubjects__as_bp(infs);
if (bp) { LOG("infs'%s'", BinaryPredicates__get_log_name(bp)); }
LOG("infs%d", infs->allocation_id);
}
void InferenceSubjects__log_knowledge_about(inference_subject *infs) {
inference *inf;
LOG("Inferences drawn about $j:\n", infs); LOG_INDENT;
for (inf = InferenceSubjects__get_inferences(infs); inf; inf = inf->next) LOG("$I\n", inf);
LOG_OUTDENT;
}
#line 459 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__log_infs_hierarchy(void) {
LOG("Subjects hierarchy:\n");
InferenceSubjects__log_subjects_hierarchically(NULL, 0);
}
void InferenceSubjects__log_subjects_hierarchically(inference_subject *infs, int count) {
if (count > 20) { LOG("*** Pruning: too deep ***\n"); return; }
if (infs) LOG("$j\n", infs);
inference_subject *narrower;
LOOP_OVER(narrower, inference_subject)
if (narrower->broader_than == infs) {
LOG_INDENT;
InferenceSubjects__log_subjects_hierarchically(narrower, count+1);
LOG_OUTDENT;
}
}
#line 481 "inform7/Chapter 22/Inference Subjects.w"
wording InferenceSubjects__get_name_text(inference_subject *infs) {
if (infs == NULL) internal_error("null INFS");
wording W = EMPTY_WORDING;
switch (infs->kind_of_infs) {
case FUND_SUB: break;
case KIND_SUB: W = Kinds__Behaviour__get_name_text(infs); break;
case INST_SUB: W = Instances__SUBJ_get_name_text(infs); break;
case VARI_SUB: W = NonlocalVariables__SUBJ_get_name_text(infs); break;
case RELN_SUB: W = BinaryPredicates__SUBJ_get_name_text(infs); break;
}
LOOP_THROUGH_WORDING(i, W)
if (Lexer__word(i) == STROKE_V) {
W = Wordings__up_to(W, i-1);
break;
}
return W;
}
#line 505 "inform7/Chapter 22/Inference Subjects.w"
general_pointer InferenceSubjects__new_permission_granted(inference_subject *infs) {
if (infs == NULL) internal_error("null INFS");
switch (infs->kind_of_infs) {
case FUND_SUB: break;
case KIND_SUB: return Kinds__Behaviour__new_permission_granted(infs);
case INST_SUB: return Instances__SUBJ_new_permission_granted(infs);
case VARI_SUB: return NonlocalVariables__SUBJ_new_permission_granted(infs);
case RELN_SUB: return BinaryPredicates__SUBJ_new_permission_granted(infs);
}
return NULL_GENERAL_POINTER;
}
#line 523 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__make_adj_const_domain(inference_subject *infs,
instance *nc, property *prn) {
if (infs == NULL) internal_error("null INFS");
switch (infs->kind_of_infs) {
case FUND_SUB: break;
case KIND_SUB: Kinds__Behaviour__make_adj_const_domain(infs, nc, prn); break;
case INST_SUB: Instances__SUBJ_make_adj_const_domain(infs, nc, prn); break;
case VARI_SUB: NonlocalVariables__SUBJ_make_adj_const_domain(infs, nc, prn); break;
case RELN_SUB: BinaryPredicates__SUBJ_make_adj_const_domain(infs, nc, prn); break;
}
}
#line 540 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__complete_model(inference_subject *infs) {
if (infs == NULL) internal_error("null INFS");
switch (infs->kind_of_infs) {
case FUND_SUB: break;
case KIND_SUB: Kinds__Behaviour__complete_model(infs); break;
case INST_SUB: Instances__SUBJ_complete_model(infs); break;
case VARI_SUB: NonlocalVariables__SUBJ_complete_model(infs); break;
case RELN_SUB: BinaryPredicates__SUBJ_complete_model(infs); break;
}
}
#line 555 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__check_model(inference_subject *infs) {
if (infs == NULL) internal_error("null INFS");
switch (infs->kind_of_infs) {
case FUND_SUB: break;
case KIND_SUB: Kinds__Behaviour__check_model(infs); break;
case INST_SUB: Instances__SUBJ_check_model(infs); break;
case VARI_SUB: NonlocalVariables__SUBJ_check_model(infs); break;
case RELN_SUB: BinaryPredicates__SUBJ_check_model(infs); break;
}
}
#line 575 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__write_element_of_condition(inference_subject *infs, char *cond) {
if (infs == NULL) internal_error("null INFS");
cond[0] = 0;
switch (infs->kind_of_infs) {
case FUND_SUB: break;
case KIND_SUB: Kinds__Behaviour__write_element_of_condition(infs, cond); break;
case INST_SUB: Instances__SUBJ_write_element_of_condition(infs, cond); break;
case VARI_SUB: NonlocalVariables__SUBJ_write_element_of_condition(infs, cond); break;
case RELN_SUB: BinaryPredicates__SUBJ_write_element_of_condition(infs, cond); break;
}
}
#line 597 "inform7/Chapter 22/Inference Subjects.w"
void InferenceSubjects__compile_all(OUTPUT_STREAM) {
inference_subject *infs;
LOOP_OVER(infs, inference_subject)
World__Inferences__verify_prop_states(infs);
int koi;
for (koi=1; koi<=MAX_SUB; koi++) {
int done = FALSE;
switch (koi) {
case FUND_SUB: break;
case KIND_SUB: done = Kinds__Behaviour__compile_all(OUT); break;
case INST_SUB: done = Instances__SUBJ_compile_all(OUT); break;
case VARI_SUB: done = NonlocalVariables__SUBJ_compile_all(OUT); break;
case RELN_SUB: done = BinaryPredicates__SUBJ_compile_all(OUT); break;
}
if (done) continue;
inference_subject *infs;
LOOP_OVER(infs, inference_subject)
if (infs->kind_of_infs == koi) {
switch (infs->kind_of_infs) {
case FUND_SUB: break;
case KIND_SUB: Kinds__Behaviour__compile(OUT, infs); break;
case INST_SUB: Instances__SUBJ_compile(OUT, infs); break;
case VARI_SUB: NonlocalVariables__SUBJ_compile(OUT, infs); break;
case RELN_SUB: BinaryPredicates__SUBJ_compile(OUT, infs); break;
}
}
}
}
#line 114 "inform7/Chapter 22/Property Permissions.w"
property_permission *World__Permissions__find(inference_subject *infs,
property *prn, int allow_inheritance) {
property *prnbar = NULL;
if (Properties__is_either_or(prn)) prnbar = Properties__EitherOr__get_negation(prn);
if (prn)
while (infs) {
property_permission *pp;
LOOP_OVER_PERMISSIONS_FOR_INFS(pp, infs)
if ((pp->property_granted == prn) || (pp->property_granted == prnbar))
return pp;
infs = (allow_inheritance)?(InferenceSubjects__narrowest_broader_subject(infs)):NULL;
}
return NULL;
}
#line 141 "inform7/Chapter 22/Property Permissions.w"
property_permission *World__Permissions__grant(inference_subject *infs, property *prn,
int allow_inheritance) {
property_permission *new_pp = World__Permissions__find(infs, prn, allow_inheritance);
if (new_pp == NULL) {
LOGIF(PROPERTY_PROVISION, "Allowing $j to provide $Y\n", infs, prn);
{
#line 157 "inform7/Chapter 22/Property Permissions.w"
new_pp = CREATE(property_permission);
new_pp->where_granted = current_sentence;
new_pp->pp_storage_data = InferenceSubjects__new_permission_granted(infs);
}
#line 146 "inform7/Chapter 22/Property Permissions.w"
;
{
#line 164 "inform7/Chapter 22/Property Permissions.w"
new_pp->property_owner = infs;
property_permission **ppl = InferenceSubjects__get_permissions(infs);
if (*ppl == NULL) *ppl = new_pp;
else {
property_permission *pp = *ppl;
while (pp->next_for_this_owner) pp = pp->next_for_this_owner;
pp->next_for_this_owner = new_pp;
}
new_pp->next_for_this_owner = NULL;
}
#line 147 "inform7/Chapter 22/Property Permissions.w"
;
{
#line 177 "inform7/Chapter 22/Property Permissions.w"
new_pp->property_granted = prn;
property_permission *pp = Properties__permission_list(prn);
if (pp == NULL) {
Properties__set_permission_list(prn, new_pp);
} else {
while (pp->next_for_this_property != NULL) pp = pp->next_for_this_property;
pp->next_for_this_property = new_pp;
}
new_pp->next_for_this_property = NULL;
}
#line 148 "inform7/Chapter 22/Property Permissions.w"
;
{
#line 190 "inform7/Chapter 22/Property Permissions.w"
int i;
for (i=0; i<MAX_PLUGINS; i++) new_pp->plugin_pp[i] = NULL;
Plugins__Call__new_permission_notify(new_pp);
}
#line 149 "inform7/Chapter 22/Property Permissions.w"
;
}
return new_pp;
}
#line 199 "inform7/Chapter 22/Property Permissions.w"
property *World__Permissions__get_property(property_permission *pp) {
return pp->property_granted;
}
inference_subject *World__Permissions__get_subject(property_permission *pp) {
return pp->property_owner;
}
general_pointer World__Permissions__get_storage_data(property_permission *pp) {
return pp->pp_storage_data;
}
parse_node *World__Permissions__where_granted(property_permission *pp) {
return pp->where_granted;
}
#line 219 "inform7/Chapter 22/Property Permissions.w"
void World__Permissions__index(property *prn) {
int ac = 0, s;
for (s = 1; s <= 2; s++) {
property_permission *pp;
LOOP_OVER_PERMISSIONS_FOR_PROPERTY(pp, prn) {
wording W = InferenceSubjects__get_name_text(World__Permissions__get_subject(pp));
if (Wordings__nonempty(W)) {
if (s == 1) ac++;
else {
INDEX("</i>");
Wordings__index_raw(W);
INDEX("<i>");
ac--;
if (ac == 1) INDEX(" or ");
if (ac > 1) INDEX(", ");
}
}
}
}
}
#line 97 "inform7/Chapter 22/Inferences.w"
int inference_timer = 0;
inference *World__Inferences__create_inference(int type, int certitude) {
PROTECTED_MODEL_PROCEDURE;
if (certitude == UNKNOWN_CE) certitude = CERTAIN_CE;
inference *new_i;
new_i = CREATE(inference);
new_i->inference_timestamp = inference_timer++;
new_i->inference_type = type;
new_i->certainty = certitude;
new_i->infs_ref1 = NULL; new_i->infs_ref2 = NULL;
new_i->spec_ref1 = NULL; new_i->spec_ref2 = NULL;
new_i->inferred_property = NULL;
new_i->inferred_property_value = NULL;
new_i->inferred_from = current_sentence;
new_i->added_in_construction = model_world_under_construction;
new_i->next = NULL;
return new_i;
}
#line 120 "inform7/Chapter 22/Inferences.w"
inference *World__Inferences__create_property_inference(inference_subject *infs,
property *prn, parse_node *val) {
PROTECTED_MODEL_PROCEDURE;
inference *i = World__Inferences__create_inference(PROPERTY_INF, prevailing_mood);
if (prevailing_mood == UNKNOWN_CE)
i->certainty = InferenceSubjects__get_default_certainty(infs);
i->inferred_property = prn;
i->inferred_property_value = val;
if (prn == NULL) internal_error("null property inference");
return i;
}
inference *World__Inferences__create_relation_inference(inference_subject *infs0, inference_subject *infs1) {
PROTECTED_MODEL_PROCEDURE;
inference *i = World__Inferences__create_inference(ARBITRARY_RELATION_INF, prevailing_mood);
i->infs_ref1 = World__Inferences__divert_infs(infs0);
i->infs_ref2 = World__Inferences__divert_infs(infs1);
return i;
}
inference *World__Inferences__create_relation_inference_spec(parse_node *spec0, parse_node *spec1) {
PROTECTED_MODEL_PROCEDURE;
inference *i = World__Inferences__create_inference(ARBITRARY_RELATION_INF, prevailing_mood);
i->spec_ref1 = spec0;
i->spec_ref2 = spec1;
if ((spec0 == NULL) || (spec1 == NULL)) internal_error("malformed specified relation");
return i;
}
#line 158 "inform7/Chapter 22/Inferences.w"
void World__Inferences__draw_property(inference_subject *infs,
property *prn, parse_node *val) {
inference *i = World__Inferences__create_property_inference(infs, prn, val);
World__Inferences__join_inference(i, infs);
}
void World__Inferences__draw_negated_property(inference_subject *infs,
property *prn, parse_node *val) {
inference *i = World__Inferences__create_property_inference(infs, prn, val);
i->certainty = -i->certainty;
World__Inferences__join_inference(i, infs);
}
void World__Inferences__draw_relation(binary_predicate *bp,
inference_subject *infs0, inference_subject *infs1) {
inference *i = World__Inferences__create_relation_inference(infs0, infs1);
World__Inferences__join_inference(i, BinaryPredicates__as_subject(bp));
}
void World__Inferences__draw_relation_spec(binary_predicate *bp,
parse_node *spec0, parse_node *spec1) {
inference *i = World__Inferences__create_relation_inference_spec(spec0, spec1);
World__Inferences__join_inference(i, BinaryPredicates__as_subject(bp));
}
#line 187 "inform7/Chapter 22/Inferences.w"
void World__Inferences__draw(int type, inference_subject *about,
int certitude, inference_subject *infs0, inference_subject *infs1) {
inference *i = World__Inferences__create_inference(type, certitude);
i->infs_ref1 = World__Inferences__divert_infs(infs0); i->infs_ref2 = World__Inferences__divert_infs(infs1);
World__Inferences__join_inference(i, about);
}
#line 199 "inform7/Chapter 22/Inferences.w"
int World__Inferences__get_timestamp(inference *i) {
return i->inference_timestamp;
}
int World__Inferences__get_inference_type(inference *i) {
return i->inference_type;
}
parse_node *World__Inferences__where_inferred(inference *i) {
return i->inferred_from;
}
int World__Inferences__get_certainty(inference *i) {
return i->certainty;
}
void World__Inferences__set_certainty(inference *i, int ce) {
i->certainty = ce;
}
int World__Inferences__added_in_construction(inference *i) {
return i->added_in_construction;
}
property *World__Inferences__get_property(inference *i) {
return i->inferred_property;
}
parse_node *World__Inferences__get_property_value(inference *i) {
return i->inferred_property_value;
}
parse_node *World__Inferences__set_property_value_kind(inference *i, kind *K) {
ParseTree__set_kind_of_value(i->inferred_property_value, K);
return i->inferred_property_value;
}
#line 241 "inform7/Chapter 22/Inferences.w"
void World__Inferences__get_references(inference *i,
inference_subject **infs1, inference_subject **infs2) {
if (infs1) *infs1 = i->infs_ref1; if (infs2) *infs2 = i->infs_ref2;
}
void World__Inferences__get_references_spec(inference *i,
parse_node **spec1, parse_node **spec2) {
*spec1 = i->spec_ref1; *spec2 = i->spec_ref2;
}
instance *World__Inferences__get_reference_as_object(inference *i) {
return InferenceSubjects__as_object_instance(i->infs_ref1);
}
#line 271 "inform7/Chapter 22/Inferences.w"
int World__Inferences__get_EO_state(inference_subject *infs, property *prn) {
if ((prn == NULL) || (infs == NULL)) return UNKNOWN_CE;
inference_subject *k;
property *prnbar = NULL;
if (Properties__is_either_or(prn)) prnbar = Properties__EitherOr__get_negation(prn);
for (k = infs; k; k = InferenceSubjects__narrowest_broader_subject(k)) {
inference *inf;
KNOWLEDGE_LOOP(inf, k, PROPERTY_INF) {
property *known = World__Inferences__get_property(inf);
int c = World__Inferences__get_certainty(inf);
if (known) {
if ((prn == known) && (c != UNKNOWN_CE)) return c;
if ((prnbar == known) && (c != UNKNOWN_CE)) return -c;
}
}
}
return UNKNOWN_CE;
}
int World__Inferences__get_EO_state_without_inheritance(inference_subject *infs, property *prn, parse_node **where) {
if ((prn == NULL) || (infs == NULL)) return UNKNOWN_CE;
property *prnbar = NULL;
if (Properties__is_either_or(prn)) prnbar = Properties__EitherOr__get_negation(prn);
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
property *known = World__Inferences__get_property(inf);
int c = World__Inferences__get_certainty(inf);
if (known) {
if ((prn == known) && (c != UNKNOWN_CE)) {
if (where) *where = World__Inferences__where_inferred(inf);
return c;
}
if ((prnbar == known) && (c != UNKNOWN_CE)) {
if (where) *where = World__Inferences__where_inferred(inf);
return -c;
}
}
}
return UNKNOWN_CE;
}
void World__Inferences__verify_prop_states(inference_subject *infs) {
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
property *prn = World__Inferences__get_property(inf);
parse_node *val = World__Inferences__get_property_value(inf);
kind *PK = Properties__Valued__kind(prn);
kind *VK = Specifications__to_kind(val);
if (Kinds__Compare__compatible(VK, PK) != ALWAYS_MATCH) {
LOG("Property value given as $u not $u\n", VK, PK);
current_sentence = inf->inferred_from;
Problems__quote_source(1, current_sentence);
Problems__quote_property(2, prn);
Problems__quote_kind(3, VK);
Problems__quote_kind(4, PK);
Problems__Issue__handmade_problem(_p_(PM_LateInferenceProblem));
Problems__issue_problem_segment(
"You wrote %1, but that tries to set the value of the '%2' "
"property to %3 - which must be wrong because this property "
"has to be %4.");
Problems__issue_problem_end();
}
}
}
parse_node *World__Inferences__get_prop_state(inference_subject *infs, property *prn) {
if ((prn == NULL) || (infs == NULL)) return NULL;
inference_subject *k;
for (k = infs; k; k = InferenceSubjects__narrowest_broader_subject(k)) {
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, k, PROPERTY_INF) {
property *known = World__Inferences__get_property(inf);
if (known == prn) return World__Inferences__get_property_value(inf);
}
}
return NULL;
}
parse_node *World__Inferences__get_prop_state_at(inference_subject *infs, property *prn,
parse_node **where) {
if ((prn == NULL) || (infs == NULL)) return NULL;
inference_subject *k;
for (k = infs; k; k = InferenceSubjects__narrowest_broader_subject(k)) {
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, k, PROPERTY_INF) {
property *known = World__Inferences__get_property(inf);
if (known == prn) {
if (where) *where = World__Inferences__where_inferred(inf);
return World__Inferences__get_property_value(inf);
}
}
}
return NULL;
}
parse_node *World__Inferences__get_prop_state_without_inheritance(inference_subject *infs,
property *prn, parse_node **where) {
if ((prn == NULL) || (infs == NULL)) return NULL;
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
property *known = World__Inferences__get_property(inf);
if (known == prn) {
if (where) *where = World__Inferences__where_inferred(inf);
return World__Inferences__get_property_value(inf);
}
}
return NULL;
}
#line 385 "inform7/Chapter 22/Inferences.w"
void World__Inferences__index(inference_subject *infs, int brief) {
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_specification) {
parse_node *spec = World__Inferences__get_property_value(inf);
Index__dequote(Lexer__word_raw_text(Wordings__first_wn(ParseTree__get_text(spec))));
INDEX("<br>");
}
property *prn;
LOOP_OVER(prn, property) Properties__set_indexed_already_flag(prn, FALSE);
int c;
for (c = CERTAIN_CE; c >= IMPOSSIBLE_CE; c--) {
char *cert = "Text only put here to stop gcc -O2 wrongly reporting an error";
if (c == UNKNOWN_CE) continue;
switch(c) {
case CERTAIN_CE: cert = "Always"; break;
case LIKELY_CE: cert = "Usually"; break;
case UNLIKELY_CE: cert = "Usually not"; break;
case IMPOSSIBLE_CE: cert = "Never"; break;
case INITIALLY_CE: cert = "Initially"; break;
}
World__Inferences__index_provided(infs, TRUE, c, cert, brief);
}
World__Inferences__index_provided(infs, FALSE, LIKELY_CE, "Can have", brief);
}
#line 417 "inform7/Chapter 22/Inferences.w"
int World__Inferences__has_or_can_have(inference_subject *infs, property *prn) {
if (Properties__is_either_or(prn)) {
int has = World__Inferences__get_EO_state(infs, prn);
if ((has == UNKNOWN_CE) && (World__Permissions__find(infs, prn, TRUE))) {
if (Properties__EitherOr__stored_in_negation(prn))
return LIKELY_CE;
else
return UNLIKELY_CE;
}
return has;
}
if (World__Permissions__find(infs, prn, TRUE)) return LIKELY_CE;
return UNKNOWN_CE;
}
void World__Inferences__index_provided(inference_subject *infs, int bool, int c, char *cert, int brief) {
int f = TRUE;
property *prn;
LOOP_OVER(prn, property) {
if (Properties__is_shown_in_index(prn) == FALSE) continue;
if (Properties__get_indexed_already_flag(prn)) continue;
if (Properties__is_either_or(prn) != bool) continue;
int state = World__Inferences__has_or_can_have(infs, prn);
if (state != c) continue;
int inherited_state = World__Inferences__has_or_can_have(
InferenceSubjects__narrowest_broader_subject(infs), prn);
if ((state == inherited_state) && (brief)) continue;
if (f) { INDEX("<i>%s</i> ", cert); f = FALSE; }
else INDEX(", ");
Wordings__index_raw(prn->name);
Properties__set_indexed_already_flag(prn, TRUE);
if (Properties__is_either_or(prn)) {
property *prnbar = Properties__EitherOr__get_negation(prn);
if (prnbar) {
INDEX(" <i>not</i> ");
Wordings__index_raw(prnbar->name);
Properties__set_indexed_already_flag(prnbar, TRUE);
}
} else {
kind *K = Properties__Valued__kind(prn);
if (K) {
INDEX(" (<i>"); Kinds__Textual__write(ifl, K); INDEX("</i>)");
}
}
}
if (f == FALSE) INDEX(".<br>");
}
#line 472 "inform7/Chapter 22/Inferences.w"
void World__Inferences__index_specific(inference_subject *infs) {
property *prn; int k = 0;
LOOP_OVER(prn, property)
if (Properties__is_shown_in_index(prn))
if (Properties__is_either_or(prn)) {
if (World__Permissions__find(infs, prn, TRUE)) {
parse_node *P = NULL;
int S = World__Inferences__get_EO_state_without_inheritance(infs, prn, &P);
property *prnbar = Properties__EitherOr__get_negation(prn);
if ((prnbar) && (S < 0)) continue;
if (S != UNKNOWN_CE) {
k++;
if (k == 1) HTML__open_para(ifl, 1, "hanging");
else INDEX("; ");
if (S < 0) INDEX("not ");
Wordings__index_raw(prn->name);
if (P) Index__link(Wordings__first_wn(ParseTree__get_text(P)));
}
}
}
if (k > 0) INDEX("</p>");
LOOP_OVER(prn, property)
if (Properties__is_shown_in_index(prn))
if (Properties__is_either_or(prn) == FALSE)
if (World__Permissions__find(infs, prn, TRUE)) {
parse_node *P = NULL;
parse_node *S = World__Inferences__get_prop_state_without_inheritance(infs, prn, &P);
if ((S) && (Wordings__nonempty(ParseTree__get_text(S)))) {
HTML__open_para(ifl, 1, "hanging");
Wordings__index_raw(prn->name);
INDEX(": <font color=\"#000080\">");
Wordings__index_raw(ParseTree__get_text(S));
INDEX("</font>");
if (P) Index__link(Wordings__first_wn(ParseTree__get_text(P)));
INDEX("</p>");
}
}
}
#line 547 "inform7/Chapter 22/Inferences.w"
int World__Inferences__measure_property(property *P) {
if (P) return 1 + P->allocation_id;
return 0;
}
int World__Inferences__measure_inf(inference *I) {
if (I) return 1 + I->allocation_id;
return 0;
}
int World__Inferences__measure_infs(inference_subject *IS) {
if (IS) return 1 + IS->allocation_id;
return 0;
}
int World__Inferences__measure_pn(parse_node *N) {
if (N) return 1 + N->allocation_id;
return 0;
}
int World__Inferences__compare_inferences(inference *i1, inference *i2) {
if (i1 == i2) return CI_IDENTICAL;
if (i1 == NULL) return CI_DIFFER_IN_EXISTENCE;
if (i2 == NULL) return -CI_DIFFER_IN_EXISTENCE;
int c = i1->inference_type - i2->inference_type;
if (c > 0) return CI_DIFFER_IN_TYPE; if (c < 0) return -CI_DIFFER_IN_TYPE;
property *pr1 = i1->inferred_property;
property *pr2 = i2->inferred_property;
if ((pr1) && (Properties__is_either_or(pr1)) &&
(pr2) && (Properties__is_either_or(pr2)) &&
((pr1 == Properties__EitherOr__get_negation(pr2)) ||
(pr2 == Properties__EitherOr__get_negation(pr1)))) pr2 = pr1;
c = World__Inferences__measure_property(pr1) - World__Inferences__measure_property(pr2);
if (c > 0) return CI_DIFFER_IN_PROPERTY; if (c < 0) return -CI_DIFFER_IN_PROPERTY;
c = World__Inferences__measure_infs(i1->infs_ref2) - World__Inferences__measure_infs(i2->infs_ref2);
if (c > 0) return CI_DIFFER_IN_INFS2; if (c < 0) return -CI_DIFFER_IN_INFS2;
c = World__Inferences__measure_infs(i1->infs_ref1) - World__Inferences__measure_infs(i2->infs_ref1);
if (c > 0) return CI_DIFFER_IN_INFS1; if (c < 0) return -CI_DIFFER_IN_INFS1;
c = World__Inferences__measure_pn(i1->spec_ref2) - World__Inferences__measure_pn(i2->spec_ref2);
if (c > 0) return CI_DIFFER_IN_INFS2; if (c < 0) return -CI_DIFFER_IN_INFS2;
c = World__Inferences__measure_pn(i1->spec_ref1) - World__Inferences__measure_pn(i2->spec_ref1);
if (c > 0) return CI_DIFFER_IN_INFS1; if (c < 0) return -CI_DIFFER_IN_INFS1;
c = World__Inferences__measure_inf(i1) - World__Inferences__measure_inf(i2);
parse_node *val1 = i1->inferred_property_value;
parse_node *val2 = i2->inferred_property_value;
if ((i1->inferred_property != i2->inferred_property) ||
((val1) && (val2) && (Rvalues__compare_CONSTANT(val1, val2) == FALSE))) {
if (c > 0) return CI_DIFFER_IN_PROPERTY_VALUE;
if (c < 0) return -CI_DIFFER_IN_PROPERTY_VALUE;
}
if (c > 0) return CI_DIFFER_IN_COPY_ONLY; if (c < 0) return -CI_DIFFER_IN_COPY_ONLY;
return CI_IDENTICAL;
}
int infs_diversion = TRUE;
void World__Inferences__diversion_on(void) {
infs_diversion = TRUE;
}
void World__Inferences__diversion_off(void) {
infs_diversion = FALSE;
}
inference_subject *World__Inferences__divert_infs(inference_subject *infs) {
if (infs_diversion)
if ((I_yourself) && (player_VAR) &&
(infs == Instances__as_subject(I_yourself))) {
parse_node *val = NonlocalVariables__get_initial_value(player_VAR);
inference_subject *divert = InferenceSubjects__from_specification(val);
if (divert) return divert;
}
return infs;
}
#line 612 "inform7/Chapter 22/Inferences.w"
void World__Inferences__join_inference(inference *i, inference_subject *infs) {
PROTECTED_MODEL_PROCEDURE;
if (i == NULL) internal_error("joining null inference");
if (infs == NULL) internal_error("joining to null inference subject");
infs = World__Inferences__divert_infs(infs);
int inserted = FALSE;
inference *list, *prev;
for (prev = NULL, list = InferenceSubjects__get_inferences(infs);
(list) && (inserted == FALSE); prev = list, list = list->next) {
int c = World__Inferences__compare_inferences(i, list);
int d = c; if (d < 0) d = -d;
int icl = i->certainty; if (icl < 0) icl = -icl;
int lcl = list->certainty; if (lcl < 0) lcl = -lcl;
int affinity_threshold;
{
#line 676 "inform7/Chapter 22/Inferences.w"
switch (list->inference_type) {
case PROPERTY_INF: affinity_threshold = CI_DIFFER_IN_PROPERTY_VALUE; break;
case ARBITRARY_RELATION_INF: affinity_threshold = CI_DIFFER_IN_COPY_ONLY; break;
default: affinity_threshold = CI_DIFFER_IN_INFS1; break;
}
}
#line 630 "inform7/Chapter 22/Inferences.w"
;
if (d >= affinity_threshold) {
{
#line 686 "inform7/Chapter 22/Inferences.w"
if (icl != lcl)
{
#line 701 "inform7/Chapter 22/Inferences.w"
if (lcl > icl) {
World__Inferences__report_inference(i, infs, "discarded (we already know better)");
} else {
i->next = list->next;
if (prev == NULL) InferenceSubjects__set_inferences(infs, i); else prev->next = i;
World__Inferences__report_inference(i, infs, "replaced existing less certain one");
}
}
#line 686 "inform7/Chapter 22/Inferences.w"
else {
int contradiction_flag = FALSE;
{
#line 722 "inform7/Chapter 22/Inferences.w"
switch (list->inference_type) {
case PROPERTY_INF:
if (d == CI_DIFFER_IN_PROPERTY_VALUE) contradiction_flag = TRUE;
break;
default:
if (Plugins__Call__inferences_contradict(list, i, d)) contradiction_flag = TRUE;
break;
}
if (list->certainty == -i->certainty) contradiction_flag = (contradiction_flag)?FALSE:TRUE;
}
#line 689 "inform7/Chapter 22/Inferences.w"
;
if (contradiction_flag) {
if (icl == CERTAIN_CE)
{
#line 736 "inform7/Chapter 22/Inferences.w"
World__Inferences__report_inference(i, infs, "contradiction");
World__Inferences__report_inference(list, infs, "with");
if ((list->inference_type != PROPERTY_INF) &&
(list->inference_type != ARBITRARY_RELATION_INF) &&
(Plugins__Call__explain_contradiction(list, i, d, infs))) return;
if (i->inference_type == PROPERTY_INF) {
if (i->inferred_property == P_variable_initial_value)
Problems__Issue__two_sentences_problem(_p_(PM_VariableContradiction),
list->inferred_from,
"this looks like a contradiction",
"because the initial value of this variable seems to be being set "
"in each of these sentences, but with a different outcome.");
else {
if (Properties__is_value_property(i->inferred_property)) {
binary_predicate *bp =
Properties__Valued__get_stored_relation(i->inferred_property);
if (bp) {
if (Wordings__match(ParseTree__get_text(current_sentence), ParseTree__get_text(list->inferred_from))) {
Problems__quote_source(1, current_sentence);
Problems__quote_relation(3, bp);
Problems__quote_subject(4, infs);
Problems__quote_spec(5, i->inferred_property_value);
Problems__quote_spec(6, list->inferred_property_value);
Problems__Issue__handmade_problem(_p_(PM_RelationContradiction2));
Problems__issue_problem_segment(
"I'm finding a contradiction at the sentence %1, "
"because it means I can't set up %3. "
"On the one hand, %4 should relate to %5, but on the other "
"hand to %6, and this is a relation which doesn't allow "
"such clashes.");
Problems__issue_problem_end();
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, list->inferred_from);
Problems__quote_relation(3, bp);
Problems__quote_subject(4, infs);
Problems__quote_spec(5, i->inferred_property_value);
Problems__quote_spec(6, list->inferred_property_value);
Problems__Issue__handmade_problem(_p_(PM_RelationContradiction));
Problems__issue_problem_segment(
"I'm finding a contradiction at the sentences %1 and %2, "
"because between them they set up rival versions of %3. "
"On the one hand, %4 should relate to %5, but on the other "
"hand to %6, and this is a relation which doesn't allow "
"such clashes.");
Problems__issue_problem_end();
}
return;
}
}
Problems__Issue__two_sentences_problem(_p_(PM_PropertyContradiction),
list->inferred_from,
"this looks like a contradiction",
"because the same property seems to be being set in each of these sentences, "
"but with a different outcome.");
}
} else if (i->inference_type == IS_ROOM_INF) {
Problems__Issue__two_sentences_problem(_p_(PM_WhenIsARoomNotARoom),
list->inferred_from,
"this looks like a contradiction",
"because apparently something would have to be both a room and not a "
"room at the same time.");
} else
Problems__Issue__two_sentences_problem(_p_(PM_Contradiction),
list->inferred_from,
"this looks like a contradiction",
"which might be because I have misunderstood what was meant to be the subject "
"of one or both of those sentences.");
return;
}
#line 691 "inform7/Chapter 22/Inferences.w"
;
if ((icl == LIKELY_CE) && (InferenceSubjects__get_default_certainty(infs) == LIKELY_CE))
{
#line 813 "inform7/Chapter 22/Inferences.w"
i->next = list->next;
if (prev == NULL) InferenceSubjects__set_inferences(infs, i); else prev->next = i;
World__Inferences__report_inference(i, infs, "replaced existing also only likely one");
return;
}
#line 693 "inform7/Chapter 22/Inferences.w"
;
}
World__Inferences__report_inference(i, infs, "redundant");
}
}
#line 632 "inform7/Chapter 22/Inferences.w"
;
return;
}
if (c<0)
{
#line 649 "inform7/Chapter 22/Inferences.w"
if (prev == NULL) InferenceSubjects__set_inferences(infs, i); else prev->next = i;
i->next = list; inserted = TRUE;
}
#line 636 "inform7/Chapter 22/Inferences.w"
;
}
if (inserted == FALSE)
{
#line 649 "inform7/Chapter 22/Inferences.w"
if (prev == NULL) InferenceSubjects__set_inferences(infs, i); else prev->next = i;
i->next = list; inserted = TRUE;
}
#line 638 "inform7/Chapter 22/Inferences.w"
;
World__Inferences__report_inference(i, infs, "drawn");
if (i->inference_type == PROPERTY_INF)
Plugins__Call__property_value_notify(
i->inferred_property, i->inferred_property_value);
}
#line 824 "inform7/Chapter 22/Inferences.w"
void World__Inferences__report_inference(inference *i, inference_subject *infs, char *what_happened) {
LOGIF(INFERENCES, ":::: %s: $j - $I\n", what_happened, infs, i);
}
#line 831 "inform7/Chapter 22/Inferences.w"
void World__Inferences__log_kind(int it) {
switch(it) {
case ARBITRARY_RELATION_INF: LOG("ARBITRARY_RELATION_INF"); break;
case PROPERTY_INF: LOG("PROPERTY_INF"); break;
default: Plugins__Call__log_inference_type(it); break;
}
}
void World__Inferences__log(inference *in) {
if (in == NULL) { LOG("<null-inference>"); return; }
World__Inferences__log_kind(in->inference_type);
LOG("-");
switch(in->certainty) {
case IMPOSSIBLE_CE: LOG("Impossible "); break;
case UNLIKELY_CE: LOG("Unlikely "); break;
case UNKNOWN_CE: LOG("<No information> "); break;
case LIKELY_CE: LOG("Likely "); break;
case CERTAIN_CE: LOG("Certain "); break;
default: LOG("<unknown-certainty>"); break;
}
if (in->inferred_property) LOG("($w)", in->inferred_property->name);
if (in->inferred_property_value) LOG("-1:$P", in->inferred_property_value);
if (in->infs_ref1) LOG("-1:$j", in->infs_ref1);
if (in->infs_ref2) LOG("-2:$j", in->infs_ref2);
if (in->spec_ref1) LOG("-s1:$P", in->spec_ref1);
if (in->spec_ref2) LOG("-s2:$P", in->spec_ref2);
}
#line 54 "inform7/Chapter 22/Complete Model World.w"
void World__complete(void) {
Properties__ObjectImplementation__place_objects_in_definition_sequence();
model_world_under_construction = TRUE;
{
#line 73 "inform7/Chapter 22/Complete Model World.w"
inference_subject *infs;
LOOP_OVER(infs, inference_subject) {
InferenceSubjects__complete_model(infs);
Properties__Appearance__reallocate(infs);
}
LOOP_OVER(infs, inference_subject)
Assertions__Implications__consider_all(infs);
Plugins__Call__complete_model(2);
Plugins__Call__complete_model(3);
}
#line 59 "inform7/Chapter 22/Complete Model World.w"
;
{
#line 87 "inform7/Chapter 22/Complete Model World.w"
inference_subject *infs;
LOOP_OVER(infs, inference_subject) {
InferenceSubjects__check_model(infs);
{
#line 117 "inform7/Chapter 22/Complete Model World.w"
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
property *prn = World__Inferences__get_property(inf);
if (Wordings__nonempty(prn->name))
if (World__Permissions__find(infs, prn, TRUE) == NULL)
Problems__Issue__inference_problem(_p_(PM_PropertyNotPermitted),
infs, inf, "is not allowed to exist",
"because you haven't said it is. What properties something can "
"have depends on what kind of thing it is: see the Index for "
"details.");
}
}
#line 90 "inform7/Chapter 22/Complete Model World.w"
;
{
#line 134 "inform7/Chapter 22/Complete Model World.w"
inference *narrow;
KNOWLEDGE_LOOP(narrow, infs, PROPERTY_INF) {
if (World__Inferences__added_in_construction(narrow) == FALSE) {
property *prn = World__Inferences__get_property(narrow);
int sign = 1;
if (World__Inferences__get_certainty(narrow) < 0) sign = -1;
{
#line 152 "inform7/Chapter 22/Complete Model World.w"
inference_subject *boss = InferenceSubjects__narrowest_broader_subject(infs);
while (boss) {
inference *wide;
KNOWLEDGE_LOOP(wide, boss, PROPERTY_INF)
if (World__Inferences__added_in_construction(wide) == FALSE)
if (prn == World__Inferences__get_property(wide))
{
#line 172 "inform7/Chapter 22/Complete Model World.w"
int abcw = World__Inferences__get_certainty(wide); if (abcw < 0) abcw = -abcw;
if (abcw == CERTAIN_CE) {
int clash = FALSE;
int wide_sign = 1; if (World__Inferences__get_certainty(wide) < 0) wide_sign = -1;
if (Properties__is_either_or(prn) == FALSE) {
parse_node *narrow_val = World__Inferences__get_property_value(narrow);
parse_node *wide_val = World__Inferences__get_property_value(wide);
if (Rvalues__compare_CONSTANT(narrow_val, wide_val) == FALSE) {
LOG("Clash of $P and $P\n $I\n $I\n",
narrow_val, wide_val, narrow, wide);
clash = TRUE;
}
}
if (sign != wide_sign) clash = (clash)?FALSE:TRUE;
if (clash) {
int abcn = World__Inferences__get_certainty(narrow); if (abcn < 0) abcn = -abcn;
if (abcn == CERTAIN_CE)
{
#line 198 "inform7/Chapter 22/Complete Model World.w"
LOG("Checking infs $j compatible with infs $j for property $Y:\n $I\n $I\n",
infs, boss, prn, narrow, wide);
Problems__Issue__infs_contradiction_problem(_p_(PM_InstanceContradiction),
World__Inferences__where_inferred(narrow), World__Inferences__where_inferred(wide), infs,
"therefore has to have two contradictory states of the same property at once",
"which is impossible. When a kind's definition says that something is 'always' "
"true, there is no way to override that for particular things of the kind.");
}
#line 189 "inform7/Chapter 22/Complete Model World.w"
else
World__Inferences__set_certainty(narrow, IMPOSSIBLE_CE);
}
}
}
#line 158 "inform7/Chapter 22/Complete Model World.w"
;
boss = InferenceSubjects__narrowest_broader_subject(boss);
}
}
#line 140 "inform7/Chapter 22/Complete Model World.w"
;
if ((Properties__is_either_or(prn)) && (Properties__EitherOr__get_negation(prn))) {
prn = Properties__EitherOr__get_negation(prn);
sign = -sign;
{
#line 152 "inform7/Chapter 22/Complete Model World.w"
inference_subject *boss = InferenceSubjects__narrowest_broader_subject(infs);
while (boss) {
inference *wide;
KNOWLEDGE_LOOP(wide, boss, PROPERTY_INF)
if (World__Inferences__added_in_construction(wide) == FALSE)
if (prn == World__Inferences__get_property(wide))
{
#line 172 "inform7/Chapter 22/Complete Model World.w"
int abcw = World__Inferences__get_certainty(wide); if (abcw < 0) abcw = -abcw;
if (abcw == CERTAIN_CE) {
int clash = FALSE;
int wide_sign = 1; if (World__Inferences__get_certainty(wide) < 0) wide_sign = -1;
if (Properties__is_either_or(prn) == FALSE) {
parse_node *narrow_val = World__Inferences__get_property_value(narrow);
parse_node *wide_val = World__Inferences__get_property_value(wide);
if (Rvalues__compare_CONSTANT(narrow_val, wide_val) == FALSE) {
LOG("Clash of $P and $P\n $I\n $I\n",
narrow_val, wide_val, narrow, wide);
clash = TRUE;
}
}
if (sign != wide_sign) clash = (clash)?FALSE:TRUE;
if (clash) {
int abcn = World__Inferences__get_certainty(narrow); if (abcn < 0) abcn = -abcn;
if (abcn == CERTAIN_CE)
{
#line 198 "inform7/Chapter 22/Complete Model World.w"
LOG("Checking infs $j compatible with infs $j for property $Y:\n $I\n $I\n",
infs, boss, prn, narrow, wide);
Problems__Issue__infs_contradiction_problem(_p_(PM_InstanceContradiction),
World__Inferences__where_inferred(narrow), World__Inferences__where_inferred(wide), infs,
"therefore has to have two contradictory states of the same property at once",
"which is impossible. When a kind's definition says that something is 'always' "
"true, there is no way to override that for particular things of the kind.");
}
#line 189 "inform7/Chapter 22/Complete Model World.w"
else
World__Inferences__set_certainty(narrow, IMPOSSIBLE_CE);
}
}
}
#line 158 "inform7/Chapter 22/Complete Model World.w"
;
boss = InferenceSubjects__narrowest_broader_subject(boss);
}
}
#line 144 "inform7/Chapter 22/Complete Model World.w"
;
}
}
}
}
#line 91 "inform7/Chapter 22/Complete Model World.w"
;
}
Plugins__Call__complete_model(4);
}
#line 60 "inform7/Chapter 22/Complete Model World.w"
;
model_world_under_construction = FALSE;
model_world_constructed = TRUE;
}
#line 210 "inform7/Chapter 22/Complete Model World.w"
void World__complete_additions(void) {
Plugins__Call__complete_model(5);
}
#line 16 "inform7/Chapter 22/Compile Model World.w"
int *rough_array_memory_used = NULL; /* in words, not bytes; for kinds only */
void World__Compile__set_rough_memory_usage(kind *K, int words_used) {
if (K == NULL) return;
if (rough_array_memory_used == NULL)
internal_error("rough_array_memory_used unallocated");
rough_array_memory_used[Kinds__get_construct(K)->allocation_id] = words_used;
}
int World__Compile__get_rough_memory_usage(kind *K) {
if (K == NULL) return 0;
if (rough_array_memory_used == NULL)
internal_error("rough_array_memory_used unallocated");
return rough_array_memory_used[Kinds__get_construct(K)->allocation_id];
}
#line 36 "inform7/Chapter 22/Compile Model World.w"
void World__Compile__compile(OUTPUT_STREAM) {
Plugins__Call__compile_model_tables(OUT);
{
#line 46 "inform7/Chapter 22/Compile Model World.w"
int nc = NUMBER_CREATED(kind_constructor), i;
rough_array_memory_used = (int *)
(Memory__I7_calloc(nc, sizeof(int), COMPILATION_SIZE_MREASON));
for (i=0; i<nc; i++) rough_array_memory_used[i] = 0;
}
#line 38 "inform7/Chapter 22/Compile Model World.w"
;
InferenceSubjects__compile_all(OUT);
{
#line 54 "inform7/Chapter 22/Compile Model World.w"
Memory__I7_free(rough_array_memory_used, COMPILATION_SIZE_MREASON);
rough_array_memory_used = NULL;
}
#line 40 "inform7/Chapter 22/Compile Model World.w"
;
}
#line 93 "inform7/Chapter 23/Text Literals.w"
int wn_quote_suppressed = -1;
void Strings__TextLiterals__suppress_quote_expansion(wording W) {
wn_quote_suppressed = Wordings__first_wn(W);
}
#line 102 "inform7/Chapter 23/Text Literals.w"
literal_text *Strings__TextLiterals__lt_new(int w1, int colour) {
literal_text *x = CREATE(literal_text);
x->left_node = NULL;
x->right_node = NULL;
x->node_colour = colour;
x->lt_position = w1;
x->as_boxed_quotation = FALSE;
x->bibliographic_conventions = FALSE;
x->unescaped = FALSE;
x->unexpanded = FALSE;
x->small_block_array_needed = FALSE;
if ((wn_quote_suppressed >= 0) && (w1 == wn_quote_suppressed)) x->unexpanded = TRUE;
return x;
}
#line 121 "inform7/Chapter 23/Text Literals.w"
int Strings__TextLiterals__lt_cmp(int w1, literal_text *lt) {
if (lt == NULL) return 1;
if (lt->lt_position < 0) return 1;
return strcmp(Lexer__word_text(w1), Lexer__word_text(lt->lt_position));
}
#line 130 "inform7/Chapter 23/Text Literals.w"
void Strings__TextLiterals__mark_as_unescaped(literal_text *lt) {
if (lt) lt->unescaped = TRUE;
}
#line 137 "inform7/Chapter 23/Text Literals.w"
literal_text *Strings__TextLiterals__compile_literal(OUTPUT_STREAM, wording W) {
int w1 = Wordings__first_wn(W);
if (divert_constant_text_bibliographically) {
HTML__compile_bibliographic_text(OUT, Lexer__word_text(w1));
return NULL;
}
if (strcmp(Lexer__word_text(w1), "\"\"") == 0) {
WRITE("EMPTY_TEXT_VALUE");
return NULL;
}
if (z_node == NULL)
{
#line 159 "inform7/Chapter 23/Text Literals.w"
z_node = Strings__TextLiterals__lt_new(-1, BLACK_NODE); z_node->left_node = z_node; z_node->right_node = z_node;
root_of_literal_text = Strings__TextLiterals__lt_new(-1, BLACK_NODE);
root_of_literal_text->left_node = z_node;
root_of_literal_text->right_node = z_node;
}
#line 147 "inform7/Chapter 23/Text Literals.w"
;
{
#line 167 "inform7/Chapter 23/Text Literals.w"
literal_text *x = root_of_literal_text, *p = x, *g = p, *gg = g;
int went_left = FALSE; /* redundant assignment to appease |gcc -O2| */
do {
gg = g; g = p; p = x;
int sgn = Strings__TextLiterals__lt_cmp(w1, x);
if (sgn == 0)
{
#line 191 "inform7/Chapter 23/Text Literals.w"
if (encode_constant_text_bibliographically) x->bibliographic_conventions = TRUE;
if (OUT) {
WRITE("TX_L_%d", x->allocation_id);
x->small_block_array_needed = TRUE;
}
return x;
}
#line 172 "inform7/Chapter 23/Text Literals.w"
;
if (sgn < 0) { went_left = TRUE; x = x->left_node; }
if (sgn > 0) { went_left = FALSE; x = x->right_node; }
if ((x->left_node->node_colour == RED_NODE) &&
(x->right_node->node_colour == RED_NODE))
{
#line 201 "inform7/Chapter 23/Text Literals.w"
x->node_colour = RED_NODE;
x->left_node->node_colour = BLACK_NODE;
x->right_node->node_colour = BLACK_NODE;
if (p->node_colour == RED_NODE)
{
#line 210 "inform7/Chapter 23/Text Literals.w"
g->node_colour = RED_NODE;
int left_of_g = FALSE, left_of_p = FALSE;
if (Strings__TextLiterals__lt_cmp(w1, g) < 0) left_of_g = TRUE;
if (Strings__TextLiterals__lt_cmp(w1, p) < 0) left_of_p = TRUE;
if (left_of_g != left_of_p) p = Strings__TextLiterals__rotate(w1, g);
x = Strings__TextLiterals__rotate(w1, gg);
x->node_colour = BLACK_NODE;
}
#line 204 "inform7/Chapter 23/Text Literals.w"
;
root_of_literal_text->right_node->node_colour = BLACK_NODE;
}
#line 177 "inform7/Chapter 23/Text Literals.w"
;
} while (x != z_node);
x = Strings__TextLiterals__lt_new(w1, RED_NODE);
x->left_node = z_node; x->right_node = z_node;
if (went_left == TRUE) p->left_node = x; else p->right_node = x;
literal_text *new_x = x;
{
#line 201 "inform7/Chapter 23/Text Literals.w"
x->node_colour = RED_NODE;
x->left_node->node_colour = BLACK_NODE;
x->right_node->node_colour = BLACK_NODE;
if (p->node_colour == RED_NODE)
{
#line 210 "inform7/Chapter 23/Text Literals.w"
g->node_colour = RED_NODE;
int left_of_g = FALSE, left_of_p = FALSE;
if (Strings__TextLiterals__lt_cmp(w1, g) < 0) left_of_g = TRUE;
if (Strings__TextLiterals__lt_cmp(w1, p) < 0) left_of_p = TRUE;
if (left_of_g != left_of_p) p = Strings__TextLiterals__rotate(w1, g);
x = Strings__TextLiterals__rotate(w1, gg);
x->node_colour = BLACK_NODE;
}
#line 204 "inform7/Chapter 23/Text Literals.w"
;
root_of_literal_text->right_node->node_colour = BLACK_NODE;
}
#line 184 "inform7/Chapter 23/Text Literals.w"
;
x = new_x;
{
#line 191 "inform7/Chapter 23/Text Literals.w"
if (encode_constant_text_bibliographically) x->bibliographic_conventions = TRUE;
if (OUT) {
WRITE("TX_L_%d", x->allocation_id);
x->small_block_array_needed = TRUE;
}
return x;
}
#line 186 "inform7/Chapter 23/Text Literals.w"
;
}
#line 148 "inform7/Chapter 23/Text Literals.w"
;
}
#line 223 "inform7/Chapter 23/Text Literals.w"
literal_text *Strings__TextLiterals__rotate(int w1, literal_text *y) {
literal_text *c, *gc;
if (Strings__TextLiterals__lt_cmp(w1, y) < 0) c = y->left_node; else c = y->right_node;
if (Strings__TextLiterals__lt_cmp(w1, c) < 0) {
gc = c->left_node; c->left_node = gc->right_node; gc->right_node = c;
} else {
gc = c->right_node; c->right_node = gc->left_node; gc->left_node = c;
}
if (Strings__TextLiterals__lt_cmp(w1, y) < 0) y->left_node = gc; else y->right_node = gc;
return gc;
}
#line 245 "inform7/Chapter 23/Text Literals.w"
int extent_of_runtime_quotations_array = 1; /* start at 1 to avoid 0 length */
void Strings__TextLiterals__compile_quotation(OUTPUT_STREAM, wording W) {
literal_text *lt = Strings__TextLiterals__compile_literal(OUT, W);
if (lt) lt->as_boxed_quotation = TRUE;
else
Problems__Issue__sentence_problem(_p_(PM_EmptyQuotationBox),
"a boxed quotation can't be empty",
"though I suppose you could make it consist of just a few spaces "
"to get a similar effect if you really needed to.");
extent_of_runtime_quotations_array++;
}
#line 261 "inform7/Chapter 23/Text Literals.w"
literal_text *Strings__TextLiterals__compile_literal_from_text(OUTPUT_STREAM, char *p) {
return Strings__TextLiterals__compile_literal(OUT, Feeds__feed_text(p));
}
#line 273 "inform7/Chapter 23/Text Literals.w"
void Strings__TextLiterals__compile(OUTPUT_STREAM) {
Strings__TextLiterals__traverse_lts(OUT, root_of_literal_text);
}
void Strings__TextLiterals__traverse_lts(OUTPUT_STREAM, literal_text *lt) {
if (lt->left_node != z_node) Strings__TextLiterals__traverse_lts(OUT, lt->left_node);
if (lt->lt_position >= 0) {
if (lt->as_boxed_quotation == FALSE)
{
#line 291 "inform7/Chapter 23/Text Literals.w"
WRITE("Constant TX_PS_%d = \"", lt->allocation_id);
if (existing_story_file) { /* to prevent trouble when no story file is really being made */
WRITE("--");
} else {
int options = CT_DEQUOTE + CT_EXPAND_APOSTROPHES;
if (lt->unescaped) options = CT_DEQUOTE;
if (lt->bibliographic_conventions)
options += CT_RECOGNISE_APOSTROPHE_SUBSTITUTION + CT_RECOGNISE_UNICODE_SUBSTITUTION;
if (lt->unexpanded) options = CT_DEQUOTE;
CompiledText__from_ISO_string(OUT, Lexer__word_text(lt->lt_position), options);
}
WRITE("\";\n");
if (lt->small_block_array_needed) {
WRITE("Array TX_L_%d --> ", lt->allocation_id);
WRITE("CONSTANT_PACKED_TEXT_STORAGE TX_PS_%d", lt->allocation_id);
WRITE(";\n");
}
}
#line 281 "inform7/Chapter 23/Text Literals.w"
else
{
#line 312 "inform7/Chapter 23/Text Literals.w"
OUT = Routines__begin_numbered(OUT, "TX_L_%d", lt->allocation_id);
WRITE("box\n\""); INDENT;
CompiledText__from_ISO_string(OUT, Lexer__word_text(lt->lt_position),
CT_DEQUOTE + CT_BOX_QUOTATION + CT_RECOGNISE_UNICODE_SUBSTITUTION);
WRITE("\";\n");
OUTDENT;
OUT = Routines__end(OUT);
}
#line 283 "inform7/Chapter 23/Text Literals.w"
;
}
if (lt->right_node != z_node) Strings__TextLiterals__traverse_lts(OUT, lt->right_node);
}
#line 323 "inform7/Chapter 23/Text Literals.w"
void Strings__TextLiterals__compile_small_block(OUTPUT_STREAM, literal_text *lt) {
}
#line 329 "inform7/Chapter 23/Text Literals.w"
literal_text *Strings__TextLiterals__compile_literal_sb(OUTPUT_STREAM, wording W) {
literal_text *lt = NULL;
if (TEST_COMPILATION_MODE(CONSTANT_CMODE)) {
text_stream *BC = Kinds__RunTime__begin_block_constant(OUT, K_text);
lt = Strings__TextLiterals__compile_literal(NULL, W);
WRITE_TO(BC, "PACKED_TEXT_STORAGE ");
if (lt == NULL) WRITE_TO(BC, "EMPTY_TEXT_PACKED");
else WRITE_TO(BC, "TX_PS_%d", lt->allocation_id);
Kinds__RunTime__end_block_constant(K_text);
} else {
lt = Strings__TextLiterals__compile_literal(OUT, W);
}
return lt;
}
#line 66 "inform7/Chapter 23/Text Substitutions.w"
text_substitution *Strings__TextSubstitutions__new_text_substitution(wording W,
ph_stack_frame *phsf, rule *R, int marker) {
text_substitution *ts = CREATE(text_substitution);
if (no_further_text_subs)
{
#line 100 "inform7/Chapter 23/Text Substitutions.w"
if (divert_constant_text_bibliographically)
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"text substitutions can't be used in bibliographic data",
"such as the title or author of a work of IF.");
else
internal_error("Too late for further text substitutions");
}
#line 69 "inform7/Chapter 23/Text Substitutions.w"
;
ts->unsubstituted_text = Wordings__first_word(W);
ts->sentence_using_this = current_sentence;
ts->local_names_existed_at_usage_time = FALSE;
if (R) {
ts->parked_stack_frame = NULL;
} else {
ph_stack_frame new_frame = Frames__new();
ts->parked_stack_frame = Frames__boxed_frame(&new_frame);
if (phsf) LocalVariables__copy(ts->parked_stack_frame, phsf);
}
ts->responding_to_rule = R;
ts->responding_to_marker = marker;
ts->dont_need_after_all = FALSE;
ts->tr_done_already = FALSE;
ts->ts_sb_needed = FALSE;
if ((phrase_being_compiled) &&
(LocalVariables__count(Frames__current_stack_frame()) > 0))
ts->local_names_existed_at_usage_time = TRUE;
sprintf(ts->ts_identifier, "TX_S_%d", ts->allocation_id);
LOGIF(TEXT_SUBSTITUTIONS, "Requesting text routine %d %08x $w %08x\n",
ts->allocation_id, (int) phsf, W, R);
return ts;
}
#line 110 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__allow_no_further_text_subs(void) {
no_further_text_subs = TRUE;
}
#line 118 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__text_substitution_name(OUTPUT_STREAM, text_substitution *ts) {
WRITE("%s", ts->ts_identifier);
ts->ts_sb_needed = TRUE;
}
#line 132 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__text_substitution_cue(OUTPUT_STREAM, wording W) {
if (adopted_rule_for_compilation) {
Rules__log(adopted_rule_for_compilation);
}
ph_stack_frame *phsf = NULL;
if (adopted_rule_for_compilation) {
{
#line 158 "inform7/Chapter 23/Text Substitutions.w"
text_substitution *ts = Strings__TextSubstitutions__new_text_substitution(W, phsf,
adopted_rule_for_compilation, adopted_marker_for_compilation);
if (TEST_COMPILATION_MODE(CONSTANT_CMODE)) {
text_stream *BC = Kinds__RunTime__begin_block_constant(OUT, K_text);
WRITE_TO(BC, "CONSTANT_PACKED_TEXT_STORAGE R_%s", ts->ts_identifier);
Kinds__RunTime__end_block_constant(K_text);
} else {
Strings__TextSubstitutions__text_substitution_name(OUT, ts);
}
}
#line 138 "inform7/Chapter 23/Text Substitutions.w"
;
} else {
if (TEST_COMPILATION_MODE(PERMIT_LOCALS_IN_TEXT_CMODE)) {
if (phsf == NULL) phsf = Frames__current_stack_frame();
WRITE("(");
LocalVariables__compile_storage(OUT, phsf);
phsf = Frames__boxed_frame(phsf);
WRITE("TEXT_TY_ExpandIfPerishable(");
Frames__compile_allocation(OUT, K_text);
WRITE(",");
}
{
#line 158 "inform7/Chapter 23/Text Substitutions.w"
text_substitution *ts = Strings__TextSubstitutions__new_text_substitution(W, phsf,
adopted_rule_for_compilation, adopted_marker_for_compilation);
if (TEST_COMPILATION_MODE(CONSTANT_CMODE)) {
text_stream *BC = Kinds__RunTime__begin_block_constant(OUT, K_text);
WRITE_TO(BC, "CONSTANT_PACKED_TEXT_STORAGE R_%s", ts->ts_identifier);
Kinds__RunTime__end_block_constant(K_text);
} else {
Strings__TextSubstitutions__text_substitution_name(OUT, ts);
}
}
#line 149 "inform7/Chapter 23/Text Substitutions.w"
;
if (TEST_COMPILATION_MODE(PERMIT_LOCALS_IN_TEXT_CMODE))
WRITE("))");
}
}
#line 172 "inform7/Chapter 23/Text Substitutions.w"
text_substitution *current_ts_being_compiled = NULL;
void Strings__TextSubstitutions__append_text_substitution_proviso(void) {
if (it_is_not_worth_adding) return;
if ((current_ts_being_compiled) &&
(current_ts_being_compiled->local_names_existed_at_usage_time)) {
Frames__log(Frames__current_stack_frame());
Problems__quote_wording(9, current_ts_being_compiled->unsubstituted_text);
Problems__issue_problem_segment(
" %PIt may be worth adding that this problem arose in text "
"which both contains substitutions and is also being used as "
"a value - being put into a variable, or used as one of the "
"ingredients in a phrase other than 'say'. Because that means "
"it needs to be used in places outside its immediate context, "
"it is not allowed to refer to any 'let' values or phrase "
"options - those are temporary things, long gone by the time it "
"would need to be printed.");
}
}
#line 206 "inform7/Chapter 23/Text Substitutions.w"
text_substitution *latest_ts_compiled = NULL;
int Strings__TextSubstitutions__compilation_coroutine(OUTPUT_STREAM, int in_response_mode) {
Strings__compile_response_launchers(OUT);
int N = 0;
compiling_text_routines_mode = TRUE;
while (TRUE) {
text_substitution *ts;
if (latest_ts_compiled == NULL) ts = FIRST_OBJECT(text_substitution);
else ts = NEXT_OBJECT(latest_ts_compiled, text_substitution);
if (ts == NULL) break;
latest_ts_compiled = ts;
int responding = FALSE;
if (ts->responding_to_rule) responding = TRUE;
if ((ts->dont_need_after_all == FALSE) && (responding == in_response_mode) &&
(ts->tr_done_already == FALSE)) {
Strings__TextSubstitutions__compile_single_substitution(OUT, ts);
}
N++;
}
compiling_text_routines_mode = FALSE;
return N;
}
#line 236 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__compile_single_substitution(OUTPUT_STREAM, text_substitution *ts) {
LOGIF(TEXT_SUBSTITUTIONS, "Compiling text routine %d %08x $w\n",
ts->allocation_id, (int) (ts->parked_stack_frame), ts->unsubstituted_text);
current_ts_being_compiled = ts;
ts->tr_done_already = TRUE;
char ts_name[32];
sprintf(ts_name, "R_%s", ts->ts_identifier);
OUT = Routines__begin(OUT, ts_name);
ph_stack_frame *phsf = ts->parked_stack_frame;
if ((ts->responding_to_rule) && (ts->responding_to_marker >= 0)) {
response_message *resp = Rules__rule_defines_response(
ts->responding_to_rule, ts->responding_to_marker);
if (resp) phsf = Strings__frame_for_response(resp);
}
if (phsf) LocalVariables__copy(Frames__current_stack_frame(), phsf);
LocalVariables__monitor_local_parsing(Frames__current_stack_frame());
{
#line 277 "inform7/Chapter 23/Text Substitutions.w"
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(IMPLY_NEWLINES_IN_SAY_CMODE);
WRITE("#ifdef DEBUG; if (suppress_text_substitution) { print \"");
Wordings__to_stream_raw_within_i6_literal(OUT, ts->unsubstituted_text);
WRITE("\"; rtrue; }\n");
WRITE("#endif; ! DEBUG\n");
parse_node *ts_code_block = ParseTree__new(ROUTINE_NT);
ts_code_block->down = ParseTree__new(INVOCATION_LIST_NT);
ParseTree__set_text(ts_code_block->down, ts->unsubstituted_text);
ParseTree__annotate_int(ts_code_block->down, from_text_substitution_ANNOT, TRUE);
Sentences__RuleSubtrees__parse_routine_structure(ts_code_block);
Routines__Compile__code_block(OUT, 0, ts_code_block->down, TRUE);
END_COMPILATION_MODE;
}
#line 254 "inform7/Chapter 23/Text Substitutions.w"
;
WRITE("rtrue;\n");
int makes_local_references =
LocalVariables__local_parsed_recently(Frames__current_stack_frame());
OUT = Routines__end_retrieving(OUT,
(makes_local_references)?(phsf):NULL);
if (ts->ts_sb_needed) {
WRITE("Array %s --> %s %s;\n",
ts->ts_identifier,
(makes_local_references)?
"CONSTANT_PERISHABLE_TEXT_STORAGE":"CONSTANT_PACKED_TEXT_STORAGE",
ts_name);
}
current_ts_being_compiled = NULL;
}
#line 297 "inform7/Chapter 23/Text Substitutions.w"
void Strings__TextSubstitutions__compile_text_routines_in_response_mode(OUTPUT_STREAM) {
latest_ts_compiled = NULL;
Strings__TextSubstitutions__compilation_coroutine(OUT, TRUE);
latest_ts_compiled = NULL;
}
#line 34 "inform7/Chapter 23/Responses.w"
void Strings__response_launcher_name(OUTPUT_STREAM, response_message *resp) {
WRITE("TX_R_%d", resp->allocation_id);
}
#line 42 "inform7/Chapter 23/Responses.w"
void Strings__compile_response_constant(OUTPUT_STREAM, rule *R, int marker) {
WRITE("R_%d_RESP_%c", R->allocation_id, 'A'+marker);
}
#line 65 "inform7/Chapter 23/Responses.w"
response_message *Strings__response_cue(OUTPUT_STREAM, rule *owner, int marker,
wording W, ph_stack_frame *phsf, int via_I6) {
response_message *resp = CREATE(response_message);
resp->original_stack_frame = Frames__boxed_frame(phsf);
resp->responding_rule = owner;
resp->response_marker = marker;
resp->original_text = Strings__TextSubstitutions__new_text_substitution(W, phsf, owner, marker);
resp->launcher_compiled = FALSE;
resp->via_I6 = via_I6;
resp->via_I6_routine_compiled = FALSE;
if (OUT) Strings__response_launcher_name(OUT, resp);
return resp;
}
#line 85 "inform7/Chapter 23/Responses.w"
void Strings__compile_response_launchers(OUTPUT_STREAM) {
response_message *resp;
LOOP_OVER(resp, response_message) {
if (resp->launcher_compiled == FALSE) {
resp->launcher_compiled = TRUE;
{
#line 101 "inform7/Chapter 23/Responses.w"
WRITE("Array TX_R_%d --> CONSTANT_PACKED_TEXT_STORAGE TX_R_%d_R;\n",
resp->allocation_id, resp->allocation_id);
OUT = Routines__begin_numbered(OUT, "TX_R_%d_R", resp->allocation_id);
WRITE("ResponseViaActivity(");
Strings__compile_response_constant(OUT,
resp->responding_rule, resp->response_marker);
WRITE(");\n");
OUT = Routines__end(OUT);
}
#line 90 "inform7/Chapter 23/Responses.w"
;
if ((resp->via_I6) && (resp->via_I6_routine_compiled == FALSE))
{
#line 129 "inform7/Chapter 23/Responses.w"
char rname[33];
sprintf(rname, "%sM", Rules__get_I6_definition(resp->responding_rule));
OUT = Routines__begin(OUT, rname);
LocalVariables__add_named_call("code");
LocalVariables__add_named_call("val");
LocalVariables__add_named_call("val2");
LocalVariables__add_internal_local("s");
LocalVariables__add_internal_local("s2");
LocalVariables__add_internal_local("s3");
LocalVariables__add_internal_local("str");
LocalVariables__add_internal_local("f");
WRITE("if ((code >= 'a') && (code <= 'z')) { f = true; code = code - 'a' + 'A'; }\n");
WRITE("s = noun; s2 = second; s3 = parsed_number;\n");
WRITE("noun = val; second = val2; parsed_number = val;\n");
WRITE("switch (code) {\n"); INDENT;
response_message *r2;
LOOP_OVER(r2, response_message) {
if (r2->responding_rule == resp->responding_rule) {
WRITE("'%c': str = ", 'A'+r2->response_marker);
Strings__response_launcher_name(OUT, r2);
WRITE(";\n");
r2->via_I6_routine_compiled = TRUE;
}
}
OUTDENT; WRITE("}\n");
WRITE("if ((str) && (f == false)) { TEXT_TY_Say(str); }\n");
WRITE("noun = s; second = s2; parsed_number = s3;\n");
WRITE("return str;\n");
OUT = Routines__end(OUT);
}
#line 92 "inform7/Chapter 23/Responses.w"
;
}
}
}
#line 165 "inform7/Chapter 23/Responses.w"
void Strings__compile_responses(OUTPUT_STREAM) {
{
#line 179 "inform7/Chapter 23/Responses.w"
rule *R;
int tally = 0;
LOOP_OVER(R, rule) {
int marker;
for (marker = 0; marker < 26; marker++) {
response_message *resp = Rules__rule_defines_response(R, marker);
if (resp) {
WRITE("Constant ");
Strings__compile_response_constant(OUT, R, marker);
WRITE(" = %d;\n", ++tally);
}
}
}
WRITE("Constant NO_RESPONSES = %d;\n", tally);
}
#line 166 "inform7/Chapter 23/Responses.w"
;
{
#line 198 "inform7/Chapter 23/Responses.w"
WRITE("Array ResponseTexts -->\n"); INDENT;
rule *R;
LOOP_OVER(R, rule) {
int marker;
for (marker = 0; marker < 26; marker++) {
response_message *resp = Rules__rule_defines_response(R, marker);
if (resp) {
text_substitution *ts = resp->original_text;
wording W = Rules__get_response_value(R, marker);
if (Wordings__nonempty(W)) { /* i.e., if the rule gives us a better text */
current_sentence = Rules__get_response_sentence(R, marker);
ts = Strings__TextSubstitutions__new_text_substitution(W,
NULL, R, marker);
resp->original_text->dont_need_after_all = TRUE;
}
Strings__TextSubstitutions__text_substitution_name(OUT, ts);
WRITE(" ");
}
}
}
OUTDENT; WRITE("0 0;\n");
}
#line 167 "inform7/Chapter 23/Responses.w"
;
{
#line 225 "inform7/Chapter 23/Responses.w"
OUT = Routines__begin(OUT, "PrintResponse");
LocalVariables__add_named_call("R");
response_message *resp;
LOOP_OVER(resp, response_message) {
WRITE("if (R == ");
Strings__compile_response_constant(OUT,
resp->responding_rule,
resp->response_marker);
WRITE(") print (RulePrintingRule) ");
Rules__compile(OUT, resp->responding_rule);
WRITE(", \" response (%c)\";\n", 'A' + resp->response_marker);
}
OUT = Routines__end(OUT);
}
#line 168 "inform7/Chapter 23/Responses.w"
;
{
#line 243 "inform7/Chapter 23/Responses.w"
OUT = Routines__begin(OUT, "STANDARD_RESPONSE_ISSUING_R");
WRITE("RegardingSingleObject(); TEXT_TY_Say(ResponseTexts-->(parameter_value-1));\n");
OUT = Routines__end(OUT);
}
#line 169 "inform7/Chapter 23/Responses.w"
;
{
#line 252 "inform7/Chapter 23/Responses.w"
WRITE("Array ResponseDivisions -->\n"); INDENT;
extension_file *group_ef = NULL;
{
#line 263 "inform7/Chapter 23/Responses.w"
rule *R;
int tally = 0, contiguous_match = FALSE, no_cms = 0;
LOOP_OVER(R, rule)
for (int marker = 0; marker < 26; marker++)
if (Rules__rule_defines_response(R, marker)) {
tally++;
extension_file *ef = SourceFiles__get_extension_corresponding(
Lexer__file_of_origin(Wordings__first_wn(R->name)));
if (ef == group_ef)
{
#line 279 "inform7/Chapter 23/Responses.w"
if (contiguous_match == FALSE) {
contiguous_match = TRUE;
if (no_cms++ == 0) {
WRITE("\"");
extension_identifier *eid = Extensions__Files__get_eid(ef);
if (eid == NULL) WRITE("source text");
else Extensions__IDs__write_to_I6_file(OUT, eid);
WRITE("\"");
} else {
WRITE("EMPTY_TEXT_PACKED");
}
WRITE(" %d ", tally);
}
}
#line 271 "inform7/Chapter 23/Responses.w"
else
{
#line 296 "inform7/Chapter 23/Responses.w"
if (contiguous_match) {
WRITE("%d\n", tally-1);
contiguous_match = FALSE;
}
}
#line 272 "inform7/Chapter 23/Responses.w"
;
}
{
#line 296 "inform7/Chapter 23/Responses.w"
if (contiguous_match) {
WRITE("%d\n", tally-1);
contiguous_match = FALSE;
}
}
#line 274 "inform7/Chapter 23/Responses.w"
;
}
#line 254 "inform7/Chapter 23/Responses.w"
;
LOOP_OVER(group_ef, extension_file)
{
#line 263 "inform7/Chapter 23/Responses.w"
rule *R;
int tally = 0, contiguous_match = FALSE, no_cms = 0;
LOOP_OVER(R, rule)
for (int marker = 0; marker < 26; marker++)
if (Rules__rule_defines_response(R, marker)) {
tally++;
extension_file *ef = SourceFiles__get_extension_corresponding(
Lexer__file_of_origin(Wordings__first_wn(R->name)));
if (ef == group_ef)
{
#line 279 "inform7/Chapter 23/Responses.w"
if (contiguous_match == FALSE) {
contiguous_match = TRUE;
if (no_cms++ == 0) {
WRITE("\"");
extension_identifier *eid = Extensions__Files__get_eid(ef);
if (eid == NULL) WRITE("source text");
else Extensions__IDs__write_to_I6_file(OUT, eid);
WRITE("\"");
} else {
WRITE("EMPTY_TEXT_PACKED");
}
WRITE(" %d ", tally);
}
}
#line 271 "inform7/Chapter 23/Responses.w"
else
{
#line 296 "inform7/Chapter 23/Responses.w"
if (contiguous_match) {
WRITE("%d\n", tally-1);
contiguous_match = FALSE;
}
}
#line 272 "inform7/Chapter 23/Responses.w"
;
}
{
#line 296 "inform7/Chapter 23/Responses.w"
if (contiguous_match) {
WRITE("%d\n", tally-1);
contiguous_match = FALSE;
}
}
#line 274 "inform7/Chapter 23/Responses.w"
;
}
#line 256 "inform7/Chapter 23/Responses.w"
;
WRITE("0 0 0;\n");
OUTDENT;
}
#line 170 "inform7/Chapter 23/Responses.w"
;
Strings__TextSubstitutions__compile_text_routines_in_response_mode(OUT);
}
#line 304 "inform7/Chapter 23/Responses.w"
ph_stack_frame *Strings__frame_for_response(response_message *resp) {
if (resp == NULL) return NULL;
return resp->original_stack_frame;
}
#line 313 "inform7/Chapter 23/Responses.w"
void Strings__assert_response_value(rule *R, int marker, wording W) {
Rules__now_rule_needs_response(R, marker, W);
}
#line 321 "inform7/Chapter 23/Responses.w"
void Strings__index_response(rule *R, int marker, response_message *resp) {
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;");
INDEX("<span style=\"color: #ffffff; ");
INDEX("font-family: 'Courier New', Courier, monospace; background-color: #8080ff;\">");
INDEX("&nbsp;&nbsp;%c&nbsp;&nbsp;</span> ", 'A' + marker);
INDEX("<span style=\"color: #000066;\">");
Wordings__index_raw(resp->original_text->unsubstituted_text);
INDEX("</span>");
INDEX("&nbsp;&nbsp;");
char S[2*MAX_PASTEABLE_RULE_NAME_LENGTH + 50];
Wordings__to_string_raw_truncated(S, MAX_PASTEABLE_RULE_NAME_LENGTH, R->name);
sprintf(S+Platform__strlen(S), " response (%c)", 'A' + marker);
HTML__Javascript__paste(ifl, S);
INDEX("&nbsp;<i>name</i>");
INDEX("&nbsp;");
Wordings__to_string_raw_truncated(S, MAX_PASTEABLE_RULE_NAME_LENGTH, R->name);
sprintf(S+Platform__strlen(S), " response (%c) is \"New text.\".", 'A' + marker);
HTML__Javascript__paste(ifl, S);
INDEX("&nbsp;<i>set</i>");
}
#line 345 "inform7/Chapter 23/Responses.w"
int Strings__get_marker_from_response_spec(parse_node *rs) {
if (Rvalues__is_CONSTANT_of_kind(rs, K_response)) {
wording SW = ParseTree__get_text(rs);
if ((Wordings__length(SW) >= 2) && (Preform__parse_nt_against_word_range(response_letter_NTM, Wordings__one_word(Wordings__last_wn(SW)-1), NULL, NULL)))
return most_recent_result;
}
return -1;
}
#line 368 "inform7/Chapter 23/Responses.w"
void Strings__compile_general(OUTPUT_STREAM, parse_node *str) {
wording SW = ParseTree__get_text(str);
if (ParseTree__int_annotation(str, explicit_literal_ANNOT)) {
text_stream *S = ParseTree__get_constant_text(str);
if (S) {
STREAM_COPY(OUT, S);
} else {
WRITE("%d", ParseTree__int_annotation(str, constant_number_ANNOT));
}
return;
}
if (Wordings__empty(SW)) internal_error("Text no longer available for CONSTANT/TEXT");
if (TEST_COMPILATION_MODE(COMPILE_TEXT_TO_QUOT_CMODE)) {
Strings__TextLiterals__compile_quotation(OUT, SW);
} else if (divert_constant_text_bibliographically) {
HTML__compile_bibliographic_text(OUT, Lexer__word_text(Wordings__first_wn(SW)));
} else
{
#line 394 "inform7/Chapter 23/Responses.w"
if ((Wordings__length(SW) >= 2) && (Preform__parse_nt_against_word_range(response_letter_NTM, Wordings__one_word(Wordings__last_wn(SW)-1), NULL, NULL)))
{
#line 401 "inform7/Chapter 23/Responses.w"
int code = most_recent_result;
if ((rule_being_compiled == NULL) ||
(Rules__rule_is_named(rule_being_compiled) == FALSE)) {
Problems__Issue__sentence_problem(_p_(PM_ResponseContextWrong),
"lettered responses can only be used in named rules",
"not in any of the other contexts in which quoted text can appear.");
return;
}
if (Rules__rule_defines_response(rule_being_compiled, code)) {
Problems__Issue__sentence_problem(_p_(PM_ResponseDuplicated),
"this duplicates a response letter",
"which is not allowed: if a bracketed letter like (A) is used to mark "
"some text as a response, then it can only occur once in its rule.");
return;
}
ph_stack_frame *phsf = Frames__current_stack_frame();
WRITE("(");
LocalVariables__compile_storage(OUT, phsf);
response_message *resp =
Strings__response_cue(OUT, rule_being_compiled, code, SW,
Frames__boxed_frame(phsf), FALSE);
Rules__now_rule_defines_response(rule_being_compiled, code, resp);
WRITE(")");
}
#line 395 "inform7/Chapter 23/Responses.w"
else
{
#line 428 "inform7/Chapter 23/Responses.w"
if (ParseTree__int_annotation(str, text_unescaped_ANNOT)) {
literal_text *lt = Strings__TextLiterals__compile_literal_sb(OUT, SW);
Strings__TextLiterals__mark_as_unescaped(lt);
} else if (Vocabulary__test_flags(Wordings__first_wn(SW), TEXTWITHSUBS_MC)) {
Strings__TextSubstitutions__text_substitution_cue(OUT, SW);
} else {
Strings__TextLiterals__compile_literal_sb(OUT, SW);
}
}
#line 396 "inform7/Chapter 23/Responses.w"
;
}
#line 384 "inform7/Chapter 23/Responses.w"
;
}
#line 60 "inform7/Chapter 24/List Constants.w"
int s_literal_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *XP = Rvalues__from_wording_of_list(Lists__kind_of_ll(Lists__empty_literal_list(Wordings__last_word(W)), FALSE), W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *XP = Rvalues__from_wording_of_list(Lists__kind_of_ll(RP[1], FALSE), W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 63 "inform7/Chapter 24/List Constants.w"
int literal_list_contents_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = Lists__add_to_ll(RP[1], RP[2], W, R[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = Lists__add_to_ll(RP[1], Lists__empty_literal_list(W), W, R[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 67 "inform7/Chapter 24/List Constants.w"
int literal_list_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE; *XP = Specifications__new_UNKNOWN(W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 71 "inform7/Chapter 24/List Constants.w"
#line 76 "inform7/Chapter 24/List Constants.w"
literal_list *Lists__empty_literal_list(wording W) {
literal_list *ll = Lists__find_list_at(Wordings__first_wn(W));
if (ll == NULL) {
ll = CREATE(literal_list);
ll->list_compiled = FALSE;
}
ll->unbraced_text = W; ll->entry_kind = K_value;
ll->listed_within_code = FALSE;
ll->kinds_known_to_be_inconsistent = FALSE;
ll->first_llist_entry = NULL;
ll->list_text = NULL;
Kinds__RunTime__ensure_basic_heap_present();
return ll;
}
#line 99 "inform7/Chapter 24/List Constants.w"
literal_list *Lists__find_list_at(int incipit) {
literal_list *ll;
LOOP_OVER(ll, literal_list)
if (Wordings__first_wn(ll->unbraced_text) == incipit)
return ll;
return NULL;
}
#line 112 "inform7/Chapter 24/List Constants.w"
literal_list *Lists__add_to_ll(parse_node *spec, literal_list *ll, wording W, int bad) {
llist_entry *lle = CREATE(llist_entry);
lle->next_llist_entry = ll->first_llist_entry;
ll->first_llist_entry = lle;
lle->llist_entry_value = spec;
literal_list *ll2 = Lists__find_list_at(Wordings__first_wn(W));
if (ll2) ll = ll2;
ll->unbraced_text = W;
if (bad) ll->kinds_known_to_be_inconsistent = TRUE;
return ll;
}
#line 131 "inform7/Chapter 24/List Constants.w"
kind *Lists__kind_of_ll(literal_list *ll, int issue_problems) {
parse_node *cs = current_sentence;
if (issue_problems) {
if (ll->list_text == NULL)
ll->list_text = Sentences__NPs__new_raw(ll->unbraced_text);
current_sentence = ll->list_text;
}
kind *K = K_value;
llist_entry *lle;
for (lle = ll->first_llist_entry; lle; lle = lle->next_llist_entry) {
parse_node *spec = lle->llist_entry_value;
if (!ParseTree__is(spec, UNKNOWN_VNT)) {
if (Conditions__is_TEST_ACTION(spec))
Dash__check_value_silently(spec, K_stored_action);
else
Dash__check_value_silently(spec, NULL);
}
spec = NonlocalVariables__substitute_constants(spec);
kind *E = NULL;
{
#line 163 "inform7/Chapter 24/List Constants.w"
if (ParseTree__is(spec, UNKNOWN_VNT)) {
if (issue_problems)
{
#line 197 "inform7/Chapter 24/List Constants.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(spec));
Problems__Issue__handmade_problem(_p_(PM_BadConstantListEntry));
Problems__issue_problem_segment(
"The constant list %1 contains an entry '%2' which isn't any "
"form of constant I'm able to read.");
Problems__issue_problem_segment(
"%PNote that lists have to be written with spaces after commas, "
"so I like '{2, 4}' but not '{2,4}', for instance.");
Problems__issue_problem_end();
}
#line 164 "inform7/Chapter 24/List Constants.w"
;
ll->kinds_known_to_be_inconsistent = TRUE;
E = K;
} else if ((ParseTree__is(spec, CONSTANT_VNT) == FALSE) &&
(Lvalues__is_constant_NONLOCAL_VARIABLE(spec) == FALSE)) {
if (issue_problems)
{
#line 211 "inform7/Chapter 24/List Constants.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(spec));
Problems__quote_spec(3, spec);
Problems__Issue__handmade_problem(_p_(PM_NonconstantConstantListEntry));
Problems__issue_problem_segment(
"The constant list %1 contains an entry '%2' which does make sense, "
"but isn't a constant (it's %3). Only constants can appear as entries in "
"constant lists, i.e., in lists written in braces '{' and '}'.");
Problems__issue_problem_end();
}
#line 169 "inform7/Chapter 24/List Constants.w"
;
ll->kinds_known_to_be_inconsistent = TRUE;
E = K;
} else {
E = Specifications__to_kind(spec);
if (E == NULL) {
if (issue_problems)
{
#line 197 "inform7/Chapter 24/List Constants.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(spec));
Problems__Issue__handmade_problem(_p_(PM_BadConstantListEntry));
Problems__issue_problem_segment(
"The constant list %1 contains an entry '%2' which isn't any "
"form of constant I'm able to read.");
Problems__issue_problem_segment(
"%PNote that lists have to be written with spaces after commas, "
"so I like '{2, 4}' but not '{2,4}', for instance.");
Problems__issue_problem_end();
}
#line 175 "inform7/Chapter 24/List Constants.w"
;
ll->kinds_known_to_be_inconsistent = TRUE;
}
}
}
#line 150 "inform7/Chapter 24/List Constants.w"
;
if (Kinds__Compare__eq(K, K_value)) K = E;
else
{
#line 186 "inform7/Chapter 24/List Constants.w"
kind *previous_K = K;
K = Kinds__Compare__max(E, K);
if (Kinds__Compare__eq(K, K_value)) {
if (issue_problems)
{
#line 224 "inform7/Chapter 24/List Constants.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(spec));
Problems__quote_kind(3, E);
Problems__quote_kind(4, previous_K);
Problems__Issue__handmade_problem(_p_(PM_IncompatibleConstantListEntry));
Problems__issue_problem_segment(
"The constant list %1 contains an entry '%2' whose kind is '%3', but "
"that's not compatible with the kind I had established from looking at "
"earlier entries ('%4').");
Problems__issue_problem_end();
}
#line 189 "inform7/Chapter 24/List Constants.w"
;
ll->kinds_known_to_be_inconsistent = TRUE;
break;
}
}
#line 152 "inform7/Chapter 24/List Constants.w"
;
}
if (ll->kinds_known_to_be_inconsistent) K = K_value;
ll->entry_kind = K;
current_sentence = cs;
return Kinds__unary_construction(CON_list_of, K);
}
#line 240 "inform7/Chapter 24/List Constants.w"
kind *Lists__kind_of_list_at(wording W) {
int incipit = Wordings__first_wn(W);
literal_list *ll = Lists__find_list_at(incipit+1);
if (ll) return Lists__kind_of_ll(ll, FALSE);
return NULL;
}
void Lists__check_one(wording W) {
int incipit = Wordings__first_wn(W);
literal_list *ll = Lists__find_list_at(incipit+1);
if (ll) Lists__kind_of_ll(ll, TRUE);
}
#line 256 "inform7/Chapter 24/List Constants.w"
void Lists__check(OUTPUT_STREAM) {
if (problem_count == 0) {
literal_list *ll;
LOOP_OVER(ll, literal_list)
Lists__kind_of_ll(ll, TRUE);
}
}
#line 269 "inform7/Chapter 24/List Constants.w"
void Lists__compile_literal_list(OUTPUT_STREAM, wording W) {
int incipit = Wordings__first_wn(W);
literal_list *ll = Lists__find_list_at(incipit+1);
if (ll) {
kind *K = Lists__kind_of_ll(ll, FALSE);
text_stream *BC = Kinds__RunTime__begin_block_constant(OUT, K);
WRITE_TO(BC, "LIST_CONST_%d 0", incipit+1);
Kinds__RunTime__end_block_constant(K);
}
}
#line 283 "inform7/Chapter 24/List Constants.w"
void Lists__compile(OUTPUT_STREAM) {
literal_list *ll;
if (problem_count == 0)
LOOP_OVER(ll, literal_list)
if (ll->list_compiled == FALSE) {
ll->list_compiled = TRUE;
current_sentence = ll->list_text;
Lists__kind_of_ll(ll, TRUE);
if (problem_count == 0)
{
#line 305 "inform7/Chapter 24/List Constants.w"
WRITE("Array LIST_CONST_%d --> ", Wordings__first_wn(ll->unbraced_text));
llist_entry *lle;
int n = 0;
for (lle = ll->first_llist_entry; lle; lle = lle->next_llist_entry) n++;
Kinds__RunTime__compile_block_value_header(OUT, Lists__kind_of_ll(ll, FALSE), TRUE, n+2);
Kinds__RunTime__compile_strong_id(OUT, ll->entry_kind);
WRITE(" %d ", n);
for (lle = ll->first_llist_entry; lle; lle = lle->next_llist_entry) {
parse_node *spec = lle->llist_entry_value;
WRITE("(");
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__Compiler__compile_constant_to_kind(OUT, spec, ll->entry_kind);
END_COMPILATION_MODE;
WRITE(") ");
}
WRITE(";\n");
}
#line 292 "inform7/Chapter 24/List Constants.w"
;
}
}
#line 329 "inform7/Chapter 24/List Constants.w"
void Lists__compile_default_list(OUTPUT_STREAM, char *identifier, kind *K) {
WRITE("Array %s -->\n", identifier);
Kinds__RunTime__compile_block_value_header(OUT, K, TRUE, 2);
Kinds__RunTime__compile_strong_id(OUT, Kinds__unary_construction_material(K));
WRITE(" 0;\n");
}
#line 64 "inform7/Chapter 25/Table Columns.w"
table_column *Tables__Columns__new_table_column(wording W) {
table_column *tc = CREATE(table_column);
tc->name = W;
tc->kind_stored_in_column = NULL;
tc->table_from_which_kind_inferred = NULL;
tc->listed_in_predicate = Tables__Relations__make_listed_in_predicate(tc);
if (Wordings__nonempty(W)) { /* as always happens except when recovering from a problem */
Semantics__Nouns__ExcerptMeanings__register_noun(TABLE_COLUMN_MC, tc->name,
Rvalues__from_table_column(tc));
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(TABLE_COLUMN_MC,
Preform__Nonparsing__merge(table_column_name_construction_NTM, 0,
WordAssemblages__from_wording(W)),
Rvalues__from_table_column(tc));
}
return tc;
}
#line 84 "inform7/Chapter 25/Table Columns.w"
void Tables__Columns__log(table_column *tc) {
LOG("'$w'/", tc->name);
if (tc->kind_stored_in_column == NULL) LOG("unknown");
else LOG("$u", tc->kind_stored_in_column);
}
#line 102 "inform7/Chapter 25/Table Columns.w"
kind *Tables__Columns__get_kind(table_column *tc) {
return tc->kind_stored_in_column;
}
kind *Tables__Columns__to_kind(table_column *tc) {
return Kinds__unary_construction(CON_table_column, tc->kind_stored_in_column);
}
void Tables__Columns__set_kind(table_column *tc, table *t, kind *K) {
if (Kinds__get_construct(K) == CON_description)
{
#line 125 "inform7/Chapter 25/Table Columns.w"
Problems__quote_kind(4, K);
Problems__quote_kind(5, K);
Problems__quote_table(6, t);
Problems__Issue__table_problem(_p_(PM_TableColumnDescription),
t, tc, NULL,
"In %1, you've written the heading of the column '%2' to say that each entry "
"should be %4. But descriptions aren't allowed as table entries - tables "
"have to hold values, not descriptions of values.");
}
#line 112 "inform7/Chapter 25/Table Columns.w"
;
tc->kind_stored_in_column = K;
tc->table_from_which_kind_inferred = t;
LOGIF(TABLES, "Table column $C contains kind $u, according to $B\n",
tc, tc->kind_stored_in_column, t);
if (Kinds__Compare__eq(K, K_understanding))
Tables__Relations__supply_kind_for_listed_in_tc(tc->listed_in_predicate, K_snippet);
else Tables__Relations__supply_kind_for_listed_in_tc(tc->listed_in_predicate, K);
}
#line 137 "inform7/Chapter 25/Table Columns.w"
binary_predicate *Tables__Columns__get_listed_in_predicate(table_column *tc) {
return tc->listed_in_predicate;
}
#line 149 "inform7/Chapter 25/Table Columns.w"
int Tables__Columns__get_id(table_column *tc) {
return 100 + tc->allocation_id;
}
void Tables__Columns__compile_run_time_support(OUTPUT_STREAM) {
OUT = Routines__begin(OUT, "TC_KOV");
LocalVariables__add_named_call("tc");
WRITE("switch (tc) {\n"); INDENT;
table_column *tc;
LOOP_OVER(tc, table_column) {
WRITE("%d: return ", Tables__Columns__get_id(tc));
Kinds__RunTime__compile_strong_id(OUT, Tables__Columns__get_kind(tc));
WRITE("; ! ");
Wordings__to_stream(OUT, tc->name);
WRITE(": ");
Kinds__Textual__write(OUT, Tables__Columns__get_kind(tc));
WRITE("\n");
}
OUTDENT; WRITE("}\n");
WRITE("return UNKNOWN_TY;\n");
OUT = Routines__end(OUT);
}
#line 178 "inform7/Chapter 25/Table Columns.w"
table_column_usage Tables__Columns__add_to_table(wording W, table *t) {
wording EXPW = EMPTY_WORDING;
table_column_usage tcu;
table_column *tc = Tables__Columns__find_table_column(W, t, &EXPW);
for (int i=0; i<t->no_columns; i++)
if (t->columns[i].column_identity == tc) {
Problems__quote_wording(4, W);
Problems__Issue__table_problem(_p_(PM_DuplicateColumnName),
t, NULL, NULL,
"In %1, the column name %4 cannot be used, because there's already "
"a column of the same name. (You can't have two columns with the "
"same name in the same table.)");
}
tcu.column_identity = tc;
tcu.entries = Sentences__NPs__new_raw(W);
tcu.kind_declaration_text = EXPW;
tcu.actual_constant_entries = 0;
tcu.observed_constant_cell = NULL;
tcu.kind_name_entries = 0;
tcu.observed_kind_cell = NULL;
return tcu;
}
#line 219 "inform7/Chapter 25/Table Columns.w"
int table_column_heading_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 256 "inform7/Chapter 25/Table Columns.w"
*X = NEW_TC_PROBLEM;
Problems__Issue__table_problem(_p_(PM_TableColumnBracketed),
table_being_examined, NULL, table_cell_node,
"In %1, the column name %3 cannot be used, because it is in brackets. "
"(Perhaps you intended to use the brackets to give the kind of the "
"entries, but forgot to put a name before the opening bracket.)");
}
#line 220 "inform7/Chapter 25/Table Columns.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = EXISTING_TC; *XP = RP[1]; k1_NTMV = Wordings__first_wn(table_column_heading_NTM->range_result[1]); k2_NTMV = Wordings__last_wn(table_column_heading_NTM->range_result[1]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1]; if (R[1] != NEW_TC_PROBLEM) *X = NEW_TC_WITH_KIND; k1_NTMV = Wordings__first_wn(table_column_heading_NTM->range_result[1]); k2_NTMV = Wordings__last_wn(table_column_heading_NTM->range_result[1]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = EXISTING_TC; *XP = RP[1]; k1_NTMV = -1; k2_NTMV = -1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 225 "inform7/Chapter 25/Table Columns.w"
int table_column_heading_unbracketed_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 236 "inform7/Chapter 25/Table Columns.w"
*X = NEW_TC_PROBLEM;
Problems__quote_wording(4, W);
Problems__Issue__table_problem(_p_(PM_TableColumnArticle),
table_being_examined, NULL, table_cell_node,
"In %1, the column name %3 cannot be used, because there would be too "
"much ambiguity arising from its ordinary meaning as an article. (It "
"would be quite awkward talking about the '%4 entry', for example.)");
}
#line 227 "inform7/Chapter 25/Table Columns.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = NEW_TC_TOPIC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = NEW_TC_WITHOUT_KIND;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 247 "inform7/Chapter 25/Table Columns.w"
*X = NEW_TC_PROBLEM;
Problems__Issue__table_problem(_p_(PM_TableColumnAlready),
table_being_examined, NULL, table_cell_node,
"In %1, the column name %3 cannot be used, because it already means "
"something else.");
}
#line 230 "inform7/Chapter 25/Table Columns.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = NEW_TC_WITHOUT_KIND;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 232 "inform7/Chapter 25/Table Columns.w"
#line 268 "inform7/Chapter 25/Table Columns.w"
int table_column_name_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 270 "inform7/Chapter 25/Table Columns.w"
#line 276 "inform7/Chapter 25/Table Columns.w"
table_column *Tables__Columns__find_table_column(wording W, table *t, wording *EXPW) {
table_cell_node = Sentences__NPs__new_raw(W);
table_cell_row = -1;
table_cell_col = -1;
table_being_examined = t;
*EXPW = EMPTY_WORDING;
Preform__parse_nt_against_word_range(table_column_heading_NTM, W, NULL, NULL);
table_column *tc = NULL;
kind *K = NULL;
switch (most_recent_result) {
case EXISTING_TC:
*EXPW = Wordings__new(k1_NTMV, k2_NTMV);
tc = Rvalues__to_table_column(most_recent_result_p);
break;
case NEW_TC_TOPIC: K = K_understanding; break;
case NEW_TC_WITH_KIND: *EXPW = Wordings__new(k1_NTMV, k2_NTMV); break;
case NEW_TC_WITHOUT_KIND: break;
case NEW_TC_PROBLEM: return NULL;
}
{
#line 307 "inform7/Chapter 25/Table Columns.w"
if ((K == NULL) && (Wordings__nonempty(*EXPW)) && (Preform__parse_nt_against_word_range(k_kind_articled_NTM, *EXPW, NULL, NULL))) {
K = most_recent_result_p; *EXPW = EMPTY_WORDING;
}
}
#line 295 "inform7/Chapter 25/Table Columns.w"
;
if (tc == NULL)
{
#line 314 "inform7/Chapter 25/Table Columns.w"
W = GET_RW(table_column_heading_unbracketed_NTM, 1);
if (Assertions__Creator__vet_name(W)) tc = Tables__Columns__new_table_column(W);
else return NULL;
}
#line 296 "inform7/Chapter 25/Table Columns.w"
;
if (K) Tables__Columns__set_kind(tc, t, K);
return tc;
}
#line 323 "inform7/Chapter 25/Table Columns.w"
void Tables__Columns__check_explicit_headings(table *t, int i, table_column_usage *tcu) {
kind *K = Tables__Columns__get_kind(tcu->column_identity);
if (Wordings__nonempty(tcu->kind_declaration_text)) {
kind *EK = NULL;
if (Preform__parse_nt_against_word_range(k_kind_articled_NTM, tcu->kind_declaration_text, NULL, NULL)) {
EK = most_recent_result_p;
LOGIF(TABLES, "$B col %d '$w' claims $u\n", t, i, tcu->kind_declaration_text, EK);
if (K == NULL)
Tables__Columns__set_kind(tcu->column_identity, t, EK);
else if (!(Kinds__Compare__eq(K, EK)))
{
#line 343 "inform7/Chapter 25/Table Columns.w"
Problems__quote_kind(4, EK);
Problems__quote_kind(5, K);
Problems__quote_table(6, tcu->column_identity->table_from_which_kind_inferred);
Problems__Issue__table_problem(_p_(PM_TableColumnInconsistent),
t, tcu->column_identity, tcu->entries,
"In %1, you've written the heading of the column %3 to say that each entry "
"should be %4. But a column with the same name also appears in %6, and each "
"entry there is %5. Inform doesn't allow this - the same column name always "
"has to have the same kind of entry, whichever tables it appears in.");
}
#line 333 "inform7/Chapter 25/Table Columns.w"
;
} else
{
#line 356 "inform7/Chapter 25/Table Columns.w"
Problems__Issue__table_problem(_p_(PM_TableColumnBrackets),
t, tcu->column_identity, tcu->entries,
"In %1, I can't use the column heading %3. Brackets are only allowed in "
"table column names when giving the kind of value which will be stored in "
"the column. So 'poems (text)' is legal, but not 'poems (chiefly lyrical)'.");
}
#line 334 "inform7/Chapter 25/Table Columns.w"
;
} else {
LOGIF(TABLES, "Column %d has no explicit kind named in $B\n", i, t);
}
}
#line 368 "inform7/Chapter 25/Table Columns.w"
void Tables__Columns__note_kind(table *t, int i, table_column_usage *tcu,
parse_node *cell, kind *K, int generic) {
if (generic) {
tcu->kind_name_entries++;
if (tcu->observed_kind_cell == NULL) tcu->observed_kind_cell = cell;
if (tcu->kind_name_entries == 2)
{
#line 439 "inform7/Chapter 25/Table Columns.w"
int quoted_col = i + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_number(5, &table_cell_row);
Problems__quote_source(6, tcu->observed_kind_cell);
Problems__Issue__table_problem(_p_(PM_TableKindTwice),
t, tcu->column_identity, cell,
"In %1, column %4 (%2), the entry %3 (row %5) is the name of a kind. "
"This isn't a specific value. You're allowed to write in the name "
"of a kind like this if the column starts out with blank entries - to "
"tell me what might eventually go there - but only once; and "
"this is the second time. (The first was %6.)");
}
#line 374 "inform7/Chapter 25/Table Columns.w"
else if (tcu->actual_constant_entries > 0)
{
#line 421 "inform7/Chapter 25/Table Columns.w"
int quoted_col = i + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_number(5, &table_cell_row);
Problems__quote_source(6, tcu->observed_constant_cell);
Problems__Issue__table_problem(_p_(PM_TableKindBelowValue),
t, tcu->column_identity, cell,
"In %1, column %4 (%2), the entry %3 (row %5) is the name of a kind. "
"This isn't a specific value. You're allowed to write in the name "
"of a kind like this if the column otherwise has blank entries - to "
"tell Inform what might eventually go there - but here the column "
"already contains a genuine value higher up: %6. %P"
"So the kind name has to go. You can either let me deduce the kind by "
"myself, working it out from the actual values in the column, or you "
"can put the kind in brackets after the column's name, at the top.)");
}
#line 376 "inform7/Chapter 25/Table Columns.w"
else {
kind *CK = Tables__Columns__get_kind(tcu->column_identity);
if (CK == NULL) {
Tables__Columns__set_kind(tcu->column_identity, t, K);
return;
} else if (Kinds__Compare__eq(K, CK) == FALSE)
{
#line 502 "inform7/Chapter 25/Table Columns.w"
Problems__quote_table(6, tcu->column_identity->table_from_which_kind_inferred);
Problems__quote_wording(7, tcu->column_identity->name);
Problems__quote_kind(4, K);
Problems__quote_kind(5, CK);
Problems__Issue__table_problem(_p_(PM_TableColumnIncompatible),
t, tcu->column_identity, cell,
"In %1, the column '%2' is declared as holding %4, but when the same "
"column appeared in table %6, the contents were said there to be %5. %P"
"The entries under a given column name must be values of the same "
"kind as each other, and this applies even to columns in different tables "
"if they have the same name.");
}
#line 383 "inform7/Chapter 25/Table Columns.w"
;
}
} else {
tcu->actual_constant_entries++;
if (tcu->observed_constant_cell == NULL) tcu->observed_constant_cell = cell;
if (tcu->kind_name_entries > 0)
{
#line 454 "inform7/Chapter 25/Table Columns.w"
int quoted_col = i + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_number(5, &table_cell_row);
Problems__quote_source(6, tcu->observed_kind_cell);
Problems__Issue__table_problem(_p_(PM_TableValueBelowKind),
t, tcu->column_identity, cell,
"In %1, column %4 (%2), the entry %3 (row %5) is a genuine, non-blank "
"entry: it's a specific value. That's fine, of course - the whole "
"idea of a table is to contain values - but this is a column which "
"already contains a name of a kind: %6. %P"
"Names of kinds are only allowed at the top of otherwise blank columns: "
"they tell me what might eventually go there. So the kind name has to go. "
"You can replace it with a blank '--', and then either let me deduce the "
"kind by myself, working it out from the actual values in the column, or "
"you can put the kind in brackets after the column's name, at the top.)");
}
#line 389 "inform7/Chapter 25/Table Columns.w"
;
}
kind *CK = Kinds__weaken(Tables__Columns__get_kind(tcu->column_identity));
K = Kinds__weaken(K);
if (CK == NULL) {
Tables__Columns__set_kind(tcu->column_identity, t, K);
} else {
int allow_refinement = TRUE;
if (Kinds__Compare__eq(CK, K_understanding)) {
CK = K_text; /* make sure the entries are texts... */
allow_refinement = FALSE; /* ...and don't allow any change to the kind */
}
if (Kinds__Compare__eq(K, CK) == FALSE) {
kind *max_K = Kinds__Compare__accumulative_max(K, CK);
if (Kinds__Behaviour__definite(max_K) == FALSE) {
Problems__quote_kind(4, K);
Problems__quote_kind(5, CK);
if (t == tcu->column_identity->table_from_which_kind_inferred)
{
#line 473 "inform7/Chapter 25/Table Columns.w"
int quoted_col = i + 1; /* i.e., counting from 1 */
Problems__quote_number(6, &quoted_col);
Problems__quote_number(7, &table_cell_row);
Problems__Issue__table_problem(_p_(PM_TableIncompatibleEntry),
t, tcu->column_identity, cell,
"In %1, column %6 (%2), the entry %3 (row %7) doesn't fit what I know "
"about '%2' - it's %4, whereas I think every entry ought to be %5.");
}
#line 407 "inform7/Chapter 25/Table Columns.w"
else
{
#line 484 "inform7/Chapter 25/Table Columns.w"
int quoted_col = i + 1; /* i.e., counting from 1 */
Problems__quote_table(6, tcu->column_identity->table_from_which_kind_inferred);
Problems__quote_wording(7, tcu->column_identity->name);
Problems__quote_number(8, &quoted_col);
Problems__quote_number(9, &table_cell_row);
Problems__Issue__table_problem(_p_(PM_TableIncompatibleEntry2),
t, tcu->column_identity, cell,
"In %1, column %8 (%2), the entry %3 (row %9) has the wrong kind to be in "
"the '%2' column - it's %4, whereas I think every entry ought to be %5. %P"
"The entries under a given column name must be blanks or values of the same "
"kind as each other, and this applies even to columns in different tables "
"if they have the same name. Compare the table %6, where there's also a "
"column called '%7'.");
}
#line 409 "inform7/Chapter 25/Table Columns.w"
;
allow_refinement = FALSE;
}
if (allow_refinement)
Tables__Columns__set_kind(tcu->column_identity, t, max_K);
}
}
}
#line 517 "inform7/Chapter 25/Table Columns.w"
void Tables__Columns__approve_kind(table *t, int i, table_column_usage *tcu) {
kind *K = Tables__Columns__get_kind(tcu->column_identity);
LOGIF(TABLES, "Column %d '$w' has kind $u with data:\n$T",
i, tcu->column_identity->name, K, tcu->entries);
if ((Kinds__get_construct(K) == CON_list_of) &&
(Kinds__Compare__eq(Kinds__unary_construction_material(K), K_value))) {
Problems__Issue__table_problem(_p_(PM_TableColumnEmptyLists),
t, NULL, tcu->entries,
"In %1, the column %3 seems to consist only of empty lists. "
"This means that I can't tell what kind of value it should hold - "
"are they to be lists of numbers, for instance, or lists of texts, "
"or some other possibility? Either one of the entries must contain a "
"non-empty list - so that I can deduce the answer by looking at what "
"is in it - or else the column heading must say, e.g., by calling it "
"'exceptions (list of texts)' with the kind of value in brackets after "
"the name.");
}
if (K == NULL) {
int quoted_col = i + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__Issue__table_problem(_p_(PM_TableKindlessColumn),
t, tcu->column_identity, NULL,
"Column %4 (%2) of %1 contains no values and doesn't tell me "
"anything about its kind%|, "
"which means that I don't know how to deal with it. You should "
"either put a value into the column somewhere, or else write "
"the kind in as part of the heading: '%2 (a number)', say.");
Tables__Columns__set_kind(tcu->column_identity, t, K_number);
}
}
#line 78 "inform7/Chapter 25/Tables.w"
sentence_handler TABLE_SH_handler = { TABLE_NT, -1, 0, NULL };
#line 85 "inform7/Chapter 25/Tables.w"
void Tables__traverse_to_create(void) {
ParseTree__traverse(Tables__visit_to_create);
}
void Tables__visit_to_create(parse_node *p) {
if (ParseTree__get_type(p) == TABLE_NT)
Tables__create_table(p);
}
#line 100 "inform7/Chapter 25/Tables.w"
void Tables__traverse_to_stock(void) {
int phase;
for (phase = 1; phase <= 3; phase++) {
table *t;
LOOP_OVER(t, table) {
current_sentence = t->table_created_at->source_table;
Tables__stock_table(t, phase);
}
}
}
#line 116 "inform7/Chapter 25/Tables.w"
void Tables__check_tables_for_kind_clashes(void) {
table *t;
LOOP_OVER(t, table) {
if ((Wordings__nonempty(t->table_name_text)) && (Preform__parse_nt_against_word_range(k_kind_articled_NTM, t->table_name_text, NULL, NULL)) &&
(Kinds__Compare__lt(most_recent_result_p, K_object))) {
Problems__quote_table(1, t);
Problems__quote_wording(2, t->table_name_text);
Problems__Issue__handmade_problem(_p_(PM_TableCoincidesWithKind));
Problems__issue_problem_segment(
"The name %1 will have to be disallowed because '%2' is also the "
"name of a kind, or of the plural of a kind. (For instance, writing "
"'Table of Rooms' is disallowed - it could lead to great confusion.)");
Problems__issue_problem_end();
}
}
}
#line 138 "inform7/Chapter 25/Tables.w"
table *Tables__new_table_structure(void) {
table *t = CREATE(table);
t->table_no_text = EMPTY_WORDING;
t->table_name_text = EMPTY_WORDING;
t->headline_fragment = NULL;
t->blank_rows = 0;
t->blank_rows_text = EMPTY_WORDING;
t->blank_rows_for_each_text = EMPTY_WORDING;
t->fill_in_blanks = FALSE;
t->first_column_by_definition = FALSE;
t->kind_defined_in_this_table = NULL;
t->where_used_to_define = NULL;
t->contains_property_values_at_run_time = FALSE;
t->preserve_row_order_at_run_time = FALSE;
t->amendment_of = NULL;
t->has_been_amended = FALSE;
sprintf(t->tab_I6_identifier, "TB%d_raw", t->allocation_id); /* should never be seen */
t->approximate_array_space_needed = 0;
t->disable_block_constant_correction = FALSE;
t->no_columns = 0;
t->table_created_at = NULL;
Tables__add_table_contribution(t, current_sentence);
return t;
}
#line 166 "inform7/Chapter 25/Tables.w"
void Tables__add_table_contribution(table *t, parse_node *src) {
table_contribution *tc = CREATE(table_contribution);
tc->source_table = src;
tc->next = NULL;
table_contribution *ltc = t->table_created_at;
while ((ltc) && (ltc->next)) ltc = ltc->next;
if (ltc) ltc->next = tc; else t->table_created_at = tc;
}
#line 178 "inform7/Chapter 25/Tables.w"
void Tables__log(table *t) {
LOG("{%s}", t->tab_I6_identifier);
}
#line 185 "inform7/Chapter 25/Tables.w"
int Tables__get_no_columns(table *t) {
return t->no_columns;
}
int Tables__get_no_rows(table *t) {
parse_node *PN; int c=0;
for (PN=t->columns[0].entries->down; PN; PN=PN->next) c++;
c += t->blank_rows;
return c;
}
#line 199 "inform7/Chapter 25/Tables.w"
int Tables__expand_block_constants(table *t) {
if (t->amendment_of) return FALSE;
if (t->disable_block_constant_correction) return FALSE;
return TRUE;
}
kind *Tables__kind_of_ith_column(table *t, int i) {
if ((i<0) || (i>=t->no_columns))
internal_error("tcdt for column out of range");
return Tables__Columns__get_kind(t->columns[i].column_identity);
}
#line 214 "inform7/Chapter 25/Tables.w"
char *Tables__identifier(table *t) {
return t->tab_I6_identifier;
}
parse_node *Tables__get_headline(table *t) {
return t->headline_fragment;
}
#line 253 "inform7/Chapter 25/Tables.w"
int table_header_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TABLE_IS_CONTINUED; nameforms_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TABLE_IS_AMENDED; nameforms_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TABLE_IS_REPLACED; nameforms_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = TABLE_IS_NEW; nameforms_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 258 "inform7/Chapter 25/Tables.w"
int table_new_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TABLE_HAS_NUMBER_AND_NAME;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TABLE_HAS_ONLY_NUMBER;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TABLE_HAS_ONLY_NAME;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 268 "inform7/Chapter 25/Tables.w"
*X = TABLE_HAS_ONLY_NAME; /* for recovery */
Problems__Issue__sentence_problem(_p_(PM_TableMisnamed),
"this isn't allowed as the name of a Table",
"since a table is required either to have a number, or to be a table 'of' "
"something (or both). For example: 'Table 5', 'Table of Blue Meanies', and "
"'Table 2 - Submarine Hues' are all allowed, but 'Table concerning "
"Pepperland' is not.");
}
#line 263 "inform7/Chapter 25/Tables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 264 "inform7/Chapter 25/Tables.w"
#line 281 "inform7/Chapter 25/Tables.w"
int table_names_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 284 "inform7/Chapter 25/Tables.w"
#line 291 "inform7/Chapter 25/Tables.w"
int table_footer_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; each_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; each_NTMV = NOT_APPLICABLE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; each_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 295 "inform7/Chapter 25/Tables.w"
#line 306 "inform7/Chapter 25/Tables.w"
void Tables__create_table(parse_node *PN) {
wording W = ParseTree__get_text(PN);
int connection = TABLE_IS_NEW; /* i.e., no connection with existing tables */
table *t = Tables__new_table_structure();
wording HW = Wordings__up_to(W, Wordings__last_word_of_formatted_text(W, FALSE));
if (Wordings__length(HW) == 1)
{
#line 341 "inform7/Chapter 25/Tables.w"
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"this table does not strictly speaking start a paragraph",
"and I'm afraid we need to speak strictly here. Even a comment coming before "
"the start of the table is too much.");
return;
}
#line 312 "inform7/Chapter 25/Tables.w"
;
t->headline_fragment = Sentences__NPs__new_raw(HW);
current_sentence = t->headline_fragment;
{
#line 350 "inform7/Chapter 25/Tables.w"
LOGIF(TABLES, "Parsing table headline $w\n", HW);
Preform__parse_nt_against_word_range(table_header_NTM, HW, NULL, NULL);
connection = most_recent_result;
switch (nameforms_NTMV) {
case TABLE_HAS_ONLY_NUMBER:
t->table_no_text = GET_RW(table_new_name_NTM, 1);
break;
case TABLE_HAS_ONLY_NAME:
t->table_name_text = GET_RW(table_new_name_NTM, 1);
break;
case TABLE_HAS_NUMBER_AND_NAME:
t->table_no_text = GET_RW(table_new_name_NTM, 1);
t->table_name_text = GET_RW(table_new_name_NTM, 2);
break;
}
}
#line 316 "inform7/Chapter 25/Tables.w"
;
{
#line 370 "inform7/Chapter 25/Tables.w"
if (Preform__parse_nt_against_word_range(s_type_expression_or_value_NTM, t->table_name_text, NULL, NULL)) {
Problems__quote_wording_as_source(1, t->table_name_text);
Problems__Issue__handmade_problem(_p_(PM_TableNameAmbiguous));
Problems__issue_problem_segment(
"The table name %1 will have to be disallowed as it is text which "
"already has a meaning to Inform. For instance, creating the 'Table "
"of Seven' would be disallowed because of the possible confusion "
"with the number 'seven'.");
Problems__issue_problem_end();
DESTROY(t, table);
return;
}
}
#line 317 "inform7/Chapter 25/Tables.w"
;
table *existing_table_with_same_name = NULL;
{
#line 401 "inform7/Chapter 25/Tables.w"
if ((Wordings__nonempty(t->table_name_text)) && (Wordings__nonempty(t->table_no_text))) {
table *t2;
LOOP_OVER(t2, table)
if ((TABLE_NAMES_MATCH(t2, t)) && (TABLE_NUMBERS_MATCH(t2, t)))
existing_table_with_same_name = t2;
} else if (Wordings__nonempty(t->table_name_text)) {
table *t2;
LOOP_OVER(t2, table)
if (TABLE_NAMES_MATCH(t2, t)) {
if ((Wordings__nonempty(t->table_no_text)) && (!(TABLE_NUMBERS_MATCH(t2, t))))
continue;
existing_table_with_same_name = t2;
}
} else if (Wordings__nonempty(t->table_no_text)) {
table *t2;
LOOP_OVER(t2, table)
if (TABLE_NUMBERS_MATCH(t2, t))
existing_table_with_same_name = t2;
}
}
#line 320 "inform7/Chapter 25/Tables.w"
;
if (connection != TABLE_IS_NEW)
{
#line 424 "inform7/Chapter 25/Tables.w"
if (existing_table_with_same_name == NULL) {
Problems__quote_table(1, t);
Problems__Issue__handmade_problem(_p_(PM_TableNotContinuation));
Problems__issue_problem_segment(
"It looks as if %1 is meant to be related to an existing table, "
"but I can't find one if it is. %P"
"Perhaps you've put the new part before the original? The original "
"has to be earlier in the source text.");
Problems__issue_problem_end();
DESTROY(t, table);
return;
}
}
#line 321 "inform7/Chapter 25/Tables.w"
else
{
#line 440 "inform7/Chapter 25/Tables.w"
if (existing_table_with_same_name) {
Problems__quote_table(1, t);
Problems__quote_table(2, existing_table_with_same_name);
Problems__quote_wording(3, HW);
Problems__Issue__handmade_problem(_p_(PM_TableNameDuplicate));
Problems__issue_problem_segment(
"I can't create %1 because its name overlaps with one that already "
"exists: %2. %P"
"It's possible to continue the existing one, if you just want to "
"add more rows, by writing '%3 (continued)' here.");
Problems__issue_problem_end();
DESTROY(t, table);
return;
}
}
#line 322 "inform7/Chapter 25/Tables.w"
;
Identifiers__compose(t->tab_I6_identifier, 'T', t->allocation_id, t->table_name_text);
if (connection == TABLE_IS_NEW) {
{
#line 458 "inform7/Chapter 25/Tables.w"
if (Wordings__nonempty(t->table_no_text)) {
LOGIF(TABLES, "Registering table by number: table $w\n", t->table_no_text);
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(TABLE_MC,
Preform__Nonparsing__merge(table_names_construction_NTM, 0,
WordAssemblages__from_wording(t->table_no_text)),
Rvalues__from_table(t));
}
if (Wordings__nonempty(t->table_name_text)) {
LOGIF(TABLES, "Registering table by name: table of $w\n", t->table_name_text);
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(TABLE_MC,
Preform__Nonparsing__merge(table_names_construction_NTM, 1,
WordAssemblages__from_wording(t->table_name_text)),
Rvalues__from_table(t));
}
}
#line 326 "inform7/Chapter 25/Tables.w"
;
LOGIF(TABLES, "Created: $B\n", t);
}
{
#line 476 "inform7/Chapter 25/Tables.w"
if (Preform__parse_nt_against_word_range(table_footer_NTM, W, NULL, NULL)) {
W = GET_RW(table_footer_NTM, 1);
switch (each_NTMV) {
case TRUE: t->blank_rows_for_each_text = GET_RW(table_footer_NTM, 2); break;
case FALSE: t->blank_rows = most_recent_result; break;
case NOT_APPLICABLE: t->blank_rows = 1; t->blank_rows_text = GET_RW(table_footer_NTM, 2); break;
}
}
}
#line 330 "inform7/Chapter 25/Tables.w"
;
int row_count = 0;
{
#line 492 "inform7/Chapter 25/Tables.w"
int pos = Wordings__last_wn(HW)+1;
while (pos <= Wordings__last_wn(W)) {
int col_count = 0;
int row_end = Wordings__last_word_of_formatted_text(Wordings__from(W, pos), FALSE);
LOGIF(TABLES, "Row %d is $w\n", row_count, Wordings__new(pos, row_end));
while (pos <= row_end) {
int cell_end = Wordings__last_word_of_formatted_text(Wordings__new(pos, row_end), TRUE);
LOGIF(TABLES, "Cell (%d, %d) is $w\n", row_count, col_count, Wordings__new(pos, cell_end));
if (row_count == 0)
{
#line 518 "inform7/Chapter 25/Tables.w"
current_sentence = PN;
wording CW = Wordings__new(pos, cell_end);
if (col_count == MAX_COLUMNS_PER_TABLE) {
parse_node *overflow = Sentences__NPs__new_raw(CW);
int limit = MAX_COLUMNS_PER_TABLE;
Problems__quote_number(4, &limit);
Problems__Issue__table_problem(_p_(PM_TableTooManyColumns),
t, NULL, overflow,
"There are %4 columns in %1 already, and that's the absolute limit, "
"so the column %3 can't be added.");
}
if (col_count < MAX_COLUMNS_PER_TABLE) {
LOGIF(TABLES, "Creating col %d from '$w'\n", t->no_columns, CW);
t->columns[t->no_columns] = Tables__Columns__add_to_table(CW, t);
if (t->columns[t->no_columns].column_identity) /* i.e., no Problem occurred */
t->no_columns++;
}
}
#line 500 "inform7/Chapter 25/Tables.w"
else
{
#line 539 "inform7/Chapter 25/Tables.w"
wording CW = Wordings__new(pos, cell_end);
parse_node *cell = Sentences__NPs__new_raw(CW);
if (col_count >= t->no_columns) {
current_sentence = PN;
Problems__quote_number(4, &(row_count));
int given_col = col_count + 1; /* i.e., counting from 1 rather than 0 */
Problems__quote_number(5, &(given_col));
Problems__quote_number(6, &(t->no_columns));
Problems__Issue__table_problem(_p_(PM_TableRowFull),
t, NULL, cell,
"In row %4 of the table %1, the entry %3 won't fit, because its row "
"is already full. (This entry would be in column %5 and the table has "
"only %6.)");
} else {
ParseTree__annotate_int(cell, table_cell_unspecified_ANNOT, FALSE);
ParseTree__graft(cell, t->columns[col_count].entries);
}
}
#line 501 "inform7/Chapter 25/Tables.w"
;
col_count++;
pos = cell_end + 1;
}
{
#line 560 "inform7/Chapter 25/Tables.w"
while (col_count < t->no_columns) { /* which can only happen on data rows */
parse_node *cell = Sentences__NPs__new_raw_empty();
ParseTree__annotate_int(cell, table_cell_unspecified_ANNOT, TRUE);
ParseTree__graft(cell, t->columns[col_count].entries);
col_count++;
}
}
#line 505 "inform7/Chapter 25/Tables.w"
;
row_count++;
}
if ((row_count < 2) && (t->blank_rows == 0)) {
Problems__Issue__table_problem(_p_(PM_TableWithoutRows),
t, NULL, PN, "%1 has no rows.");
return;
}
}
#line 332 "inform7/Chapter 25/Tables.w"
;
if (connection != TABLE_IS_NEW)
{
#line 570 "inform7/Chapter 25/Tables.w"
table *old_t = existing_table_with_same_name;
Tables__add_table_contribution(old_t, t->headline_fragment);
int new_to_old[MAX_COLUMNS_PER_TABLE], old_to_new[MAX_COLUMNS_PER_TABLE];
{
#line 592 "inform7/Chapter 25/Tables.w"
int i, j;
for (j=0; j<old_t->no_columns; j++) old_to_new[j] = -1;
for (i=0; i<t->no_columns; i++) new_to_old[i] = -1;
for (i=0; i<t->no_columns; i++)
for (j=0; j<old_t->no_columns; j++)
if (t->columns[i].column_identity == old_t->columns[j].column_identity) {
new_to_old[i] = j; old_to_new[j] = i;
}
LOGIF(TABLES, "Column correspondence table:\n old->new: ");
for (j=0; j<old_t->no_columns; j++)
LOGIF(TABLES, "%d ($w) ", old_to_new[j],
old_t->columns[j].column_identity->name);
LOGIF(TABLES, "\n new->old: ");
for (i=0; i<t->no_columns; i++)
LOGIF(TABLES, "%d ($w) ", new_to_old[i],
t->columns[i].column_identity->name);
LOGIF(TABLES, "\n");
}
#line 573 "inform7/Chapter 25/Tables.w"
;
switch (connection) {
case TABLE_IS_CONTINUED:
{
#line 614 "inform7/Chapter 25/Tables.w"
{
#line 694 "inform7/Chapter 25/Tables.w"
int i, missing = 0;
for (i=0; i<t->no_columns; i++)
if (new_to_old[i] == -1)
missing++;
if (missing > 0) {
for (i=0; i<t->no_columns; i++)
LOG("nto[%d] = %d, otn[%d] = %d\n", i, new_to_old[i], i, old_to_new[i]);
current_sentence = t->table_created_at->source_table;
Problems__quote_table(1, t);
Problems__quote_table(2, old_t);
if (missing == 1) Problems__quote_text(3, "a column");
else Problems__quote_text(3, "columns");
Problems__Issue__handmade_problem(_p_(PM_TableContinuationAddsCols));
Problems__issue_problem_segment(
"The table %1 won't work as a continuation, because it contains "
"%3 not found in the original %2.");
Problems__issue_problem_end();
{
#line 769 "inform7/Chapter 25/Tables.w"
Problems__issue_problem_begin("****");
Problems__issue_problem_segment("The old table has columns: "); {
TEMPORARY_STREAM;
int j;
for (j=0; j<old_t->no_columns; j++) {
if (j > 0) WRITE_TO(TEMP, ", ");
Wordings__to_stream_raw(TEMP, old_t->columns[j].column_identity->name);
}
WRITE_TO(TEMP, ". ");
Problems__issue_problem_segment(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
Problems__issue_problem_end();
Problems__issue_problem_begin("****");
Problems__issue_problem_segment("The new table has columns: "); {
TEMPORARY_STREAM;
int i;
for (i=0; i<t->no_columns; i++) {
if (i > 0) WRITE_TO(TEMP, ", ");
Wordings__to_stream_raw(TEMP, t->columns[i].column_identity->name);
}
WRITE_TO(TEMP, ".");
Problems__issue_problem_segment(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
Problems__issue_problem_end();
}
#line 711 "inform7/Chapter 25/Tables.w"
;
DESTROY(t, table);
return;
}
}
#line 614 "inform7/Chapter 25/Tables.w"
;
{
#line 637 "inform7/Chapter 25/Tables.w"
old_t->blank_rows += t->blank_rows;
if (Wordings__nonempty(t->blank_rows_for_each_text)) {
if (Wordings__nonempty(old_t->blank_rows_for_each_text)) {
current_sentence = t->table_created_at->source_table;
Problems__quote_table(1, t);
Problems__quote_table(2, old_t);
Problems__quote_wording(3, old_t->blank_rows_for_each_text);
Problems__quote_wording(4, t->blank_rows_for_each_text);
Problems__Issue__handmade_problem(_p_(PM_TableContinuationContradicts));
Problems__issue_problem_segment(
"The table %1 says that it should have a blank row for each "
"%4, but the original %2 already says it has a blank for each "
"%3. It can only be specified once.");
Problems__issue_problem_end();
}
old_t->blank_rows_for_each_text = t->blank_rows_for_each_text;
}
}
#line 615 "inform7/Chapter 25/Tables.w"
;
if (row_count >= 2) {
int j;
for (j=0; j<old_t->no_columns; j++)
if (old_to_new[j] >= 0) {
ParseTree__graft(t->columns[old_to_new[j]].entries->down,
old_t->columns[j].entries);
} else {
int i;
for (i=1; i<row_count; i++) { /* from 1 to omit the column headings */
parse_node *blank = Sentences__NPs__new_raw_empty();
ParseTree__annotate_int(blank, table_cell_unspecified_ANNOT, TRUE);
ParseTree__graft(blank, old_t->columns[j].entries);
}
}
}
DESTROY(t, table);
}
#line 575 "inform7/Chapter 25/Tables.w"
; break;
case TABLE_IS_AMENDED:
{
#line 684 "inform7/Chapter 25/Tables.w"
{
#line 745 "inform7/Chapter 25/Tables.w"
int mismatch = FALSE;
if (t->no_columns != old_t->no_columns) mismatch = TRUE;
int j;
for (j=0; j<old_t->no_columns; j++)
if (old_to_new[j] != j)
mismatch = TRUE;
if (mismatch) {
current_sentence = t->table_created_at->source_table;
Problems__quote_table(1, t);
Problems__quote_table(2, old_t);
Problems__Issue__handmade_problem(_p_(PM_TableAmendmentMisfit));
Problems__issue_problem_segment(
"Columns in %1 do not exactly match the original %2. I can only "
"make changes to rows in an existing table if the amended versions "
"have the same columns and in the same order.");
Problems__issue_problem_end();
{
#line 769 "inform7/Chapter 25/Tables.w"
Problems__issue_problem_begin("****");
Problems__issue_problem_segment("The old table has columns: "); {
TEMPORARY_STREAM;
int j;
for (j=0; j<old_t->no_columns; j++) {
if (j > 0) WRITE_TO(TEMP, ", ");
Wordings__to_stream_raw(TEMP, old_t->columns[j].column_identity->name);
}
WRITE_TO(TEMP, ". ");
Problems__issue_problem_segment(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
Problems__issue_problem_end();
Problems__issue_problem_begin("****");
Problems__issue_problem_segment("The new table has columns: "); {
TEMPORARY_STREAM;
int i;
for (i=0; i<t->no_columns; i++) {
if (i > 0) WRITE_TO(TEMP, ", ");
Wordings__to_stream_raw(TEMP, t->columns[i].column_identity->name);
}
WRITE_TO(TEMP, ".");
Problems__issue_problem_segment(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
Problems__issue_problem_end();
}
#line 761 "inform7/Chapter 25/Tables.w"
;
DESTROY(t, table);
return;
}
}
#line 684 "inform7/Chapter 25/Tables.w"
;
t->amendment_of = old_t;
old_t->has_been_amended = TRUE;
LOGIF(TABLES, "Amendment table created pro tem\n");
}
#line 576 "inform7/Chapter 25/Tables.w"
; break;
case TABLE_IS_REPLACED:
{
#line 658 "inform7/Chapter 25/Tables.w"
{
#line 721 "inform7/Chapter 25/Tables.w"
int j, missing = 0;
for (j=0; j<old_t->no_columns; j++)
if (old_to_new[j] == -1)
missing++;
if (missing > 0) {
current_sentence = t->table_created_at->source_table;
Problems__quote_table(1, t);
Problems__quote_table(2, old_t);
if (missing == 1) Problems__quote_text(3, "a column");
else Problems__quote_text(3, "columns");
Problems__Issue__handmade_problem(_p_(PM_TableReplacementMissesCols));
Problems__issue_problem_segment(
"The table %1 won't work as a replacement, because it's missing "
"%3 found in the original %2.");
Problems__issue_problem_end();
{
#line 769 "inform7/Chapter 25/Tables.w"
Problems__issue_problem_begin("****");
Problems__issue_problem_segment("The old table has columns: "); {
TEMPORARY_STREAM;
int j;
for (j=0; j<old_t->no_columns; j++) {
if (j > 0) WRITE_TO(TEMP, ", ");
Wordings__to_stream_raw(TEMP, old_t->columns[j].column_identity->name);
}
WRITE_TO(TEMP, ". ");
Problems__issue_problem_segment(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
Problems__issue_problem_end();
Problems__issue_problem_begin("****");
Problems__issue_problem_segment("The new table has columns: "); {
TEMPORARY_STREAM;
int i;
for (i=0; i<t->no_columns; i++) {
if (i > 0) WRITE_TO(TEMP, ", ");
Wordings__to_stream_raw(TEMP, t->columns[i].column_identity->name);
}
WRITE_TO(TEMP, ".");
Problems__issue_problem_segment(STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
Problems__issue_problem_end();
}
#line 736 "inform7/Chapter 25/Tables.w"
;
DESTROY(t, table);
return;
}
}
#line 658 "inform7/Chapter 25/Tables.w"
;
{
#line 674 "inform7/Chapter 25/Tables.w"
old_t->blank_rows = t->blank_rows;
old_t->blank_rows_text = t->blank_rows_text;
old_t->blank_rows_for_each_text = t->blank_rows_for_each_text;
}
#line 659 "inform7/Chapter 25/Tables.w"
;
int j;
for (j=0; j<old_t->no_columns; j++)
if (old_to_new[j] >= 0) /* and if this isn't true, we've issued a Problem already */
old_t->columns[j].entries->down
= t->columns[old_to_new[j]].entries->down;
int i;
for (i=0; i<t->no_columns; i++)
if (new_to_old[i] == -1)
old_t->columns[old_t->no_columns++] = t->columns[i]; /* old table must have room */
DESTROY(t, table);
}
#line 577 "inform7/Chapter 25/Tables.w"
; break;
default: internal_error("unknown form of table connection");
}
}
#line 335 "inform7/Chapter 25/Tables.w"
;
}
#line 804 "inform7/Chapter 25/Tables.w"
void Tables__stock_table(table *t, int phase) {
LOGIF(TABLES, "Stocking $B (%d cols): phase %d\n", t, t->no_columns, phase);
table_being_examined = t;
int i = 0;
if (t->first_column_by_definition) i = 1;
for (; i<t->no_columns; i++) {
table_column_usage *tcu = &(t->columns[i]);
switch (phase) {
case 1:
tcu->kind_name_entries = 0;
tcu->actual_constant_entries = 0;
tcu->observed_constant_cell = NULL;
Tables__Columns__check_explicit_headings(t, i, tcu);
break;
case 2: {
int row_count;
parse_node *PN;
for (PN = t->columns[i].entries->down, row_count = 1; PN; PN = PN->next, row_count++)
if (Wordings__nonempty(ParseTree__get_text(PN))) /* if there's anything written there at all */
Tables__stock_table_cell(t, PN, row_count, i);
break;
}
case 3: Tables__Columns__approve_kind(t, i, tcu);
break;
}
}
}
#line 858 "inform7/Chapter 25/Tables.w"
int table_cell_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 885 "inform7/Chapter 25/Tables.w"
*X = BLANK_TABLE_ENTRY;
*XP = Specifications__new_UNKNOWN(W);
}
#line 859 "inform7/Chapter 25/Tables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 891 "inform7/Chapter 25/Tables.w"
*X = KIND_TABLE_ENTRY;
parse_node *new = Specifications__from_kind(RP[1]);
ParseTree__set_text(new, W);
*XP = new;
}
#line 860 "inform7/Chapter 25/Tables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = NAMED_CONSTANT_ENTRY; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 927 "inform7/Chapter 25/Tables.w"
*X = PROBLEMATIC_TABLE_ENTRY;
nonlocal_variable *q = Lvalues__get_nonlocal_variable_if_any(RP[1]);
if (q == NULL) internal_error("no such variable");
inference_subject *infs = NonlocalVariables__get_alias(q);
if (infs) {
int quoted_col = table_cell_col + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_wording(5,
table_being_examined->columns[table_cell_col].column_identity->name);
Problems__quote_number(6, &table_cell_row);
Problems__quote_subject(7, infs);
Problems__Issue__table_problem(_p_(PM_TablePlayerEntry),
table_being_examined, NULL, table_cell_node,
"In %1, the entry %3 in column %4 (%5) of row %6 is the name of a value "
"which varies, not a constant, and can't be stored as a table entry. %P"
"This variable is usually set to the constant value '%7', so you might "
"want to write that instead.");
} else {
int quoted_col = table_cell_col + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_wording(5,
table_being_examined->columns[table_cell_col].column_identity->name);
Problems__quote_number(6, &table_cell_row);
Problems__Issue__table_problem(_p_(PM_TableVariableEntry),
table_being_examined, NULL, table_cell_node,
"In %1, the entry %3 in column %4 (%5) of row %6 is the name of a value "
"which varies, not a constant, so it can't be stored as a table entry.");
}
}
#line 862 "inform7/Chapter 25/Tables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 899 "inform7/Chapter 25/Tables.w"
*X = TOPIC_TABLE_ENTRY;
parse_node *new = Specifications__from_kind(K_text);
ParseTree__set_text(new, W);
*XP = new;
}
#line 864 "inform7/Chapter 25/Tables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 959 "inform7/Chapter 25/Tables.w"
*X = PROBLEMATIC_TABLE_ENTRY;
{
#line 965 "inform7/Chapter 25/Tables.w"
int quoted_col = table_cell_col + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_wording(5,
table_being_examined->columns[table_cell_col].column_identity->name);
Problems__quote_number(6, &table_cell_row);
Problems__Issue__table_problem(_p_(PM_TableUnknownEntry),
table_being_examined, NULL, table_cell_node,
"In %1, I'm reading the text %3 in column %4 (%5) of row %6, but I don't "
"know what this means. %PThis should usually be a value, like a number "
"or a piece of text, or a blank entry marker '--', but in some circumstances "
"it can also be an action (such as 'taking the box'), or a kind (such as "
"'a number') to show what sort of values will go into an otherwise blank "
"row.");
}
#line 960 "inform7/Chapter 25/Tables.w"
;
}
#line 865 "inform7/Chapter 25/Tables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 866 "inform7/Chapter 25/Tables.w"
int table_cell_blank_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 869 "inform7/Chapter 25/Tables.w"
int table_cell_value_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = ACTION_TABLE_ENTRY; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = ACTION_TABLE_ENTRY; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 907 "inform7/Chapter 25/Tables.w"
*X = PROBLEMATIC_TABLE_ENTRY;
int quoted_col = table_cell_col + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_wording(5,
table_being_examined->columns[table_cell_col].column_identity->name);
Problems__quote_number(6, &table_cell_row);
Problems__Issue__table_problem(_p_(PM_NonconstantActionInTable),
table_being_examined, NULL, table_cell_node,
"In %1, I'm reading the text %3 in column %4 (%5) of row %6, but this is "
"an action involving a variable, that is, a value that might vary in play. "
"%PThis often happens if the action mentions 'the player', for example, "
"because 'the player' is a variable. If 'the player' is the person "
"carrying out the action, simply leave those words out; if 'the player' "
"is involved in some other way, try using 'yourself' instead.");
}
#line 873 "inform7/Chapter 25/Tables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 907 "inform7/Chapter 25/Tables.w"
*X = PROBLEMATIC_TABLE_ENTRY;
int quoted_col = table_cell_col + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_wording(5,
table_being_examined->columns[table_cell_col].column_identity->name);
Problems__quote_number(6, &table_cell_row);
Problems__Issue__table_problem(_p_(PM_NonconstantActionInTable),
table_being_examined, NULL, table_cell_node,
"In %1, I'm reading the text %3 in column %4 (%5) of row %6, but this is "
"an action involving a variable, that is, a value that might vary in play. "
"%PThis often happens if the action mentions 'the player', for example, "
"because 'the player' is a variable. If 'the player' is the person "
"carrying out the action, simply leave those words out; if 'the player' "
"is involved in some other way, try using 'yourself' instead.");
}
#line 874 "inform7/Chapter 25/Tables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = INSTANCE_TABLE_ENTRY; *XP = Rvalues__from_instance(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = SPEC_TABLE_ENTRY; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 877 "inform7/Chapter 25/Tables.w"
int list_of_double_quotes_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 881 "inform7/Chapter 25/Tables.w"
#line 982 "inform7/Chapter 25/Tables.w"
void Tables__stock_table_cell(table *t, parse_node *cell, int row_count, int col_count) {
current_sentence = cell;
int topic_exception = FALSE;
table_cell_node = cell;
table_cell_row = row_count;
table_cell_col = col_count;
{
#line 1001 "inform7/Chapter 25/Tables.w"
Preform__parse_nt_against_word_range(table_cell_NTM, ParseTree__get_text(cell), NULL, NULL);
parse_node *spec = most_recent_result_p;
switch (most_recent_result) {
case BLANK_TABLE_ENTRY:
ParseTree__annotate_int(cell, table_cell_unspecified_ANNOT, TRUE);
return;
case SPEC_TABLE_ENTRY:
Assertions__Refiner__noun_from_value(cell, spec);
break;
case NAMED_CONSTANT_ENTRY:
topic_exception = TRUE;
Assertions__Refiner__noun_from_value(cell, spec);
break;
case INSTANCE_TABLE_ENTRY:
Assertions__Refiner__noun_from_value(cell, spec);
break;
case KIND_TABLE_ENTRY:
ParseTree__annotate_int(cell, table_cell_unspecified_ANNOT, TRUE);
kind *K = Specifications__to_kind(spec);
Tables__Columns__note_kind(t, col_count, &(t->columns[col_count]), cell,
K, TRUE);
return;
case ACTION_TABLE_ENTRY:
Assertions__Refiner__noun_from_value(cell, spec);
break;
case TOPIC_TABLE_ENTRY:
Assertions__Refiner__noun_from_value(cell, spec);
topic_exception = TRUE;
break;
case PROBLEMATIC_TABLE_ENTRY:
return;
}
}
#line 989 "inform7/Chapter 25/Tables.w"
;
parse_node *evaluation = ParseTree__get_evaluation(cell);
LOGIF(TABLES, "Cell evaluates to: $P\n", evaluation);
if (topic_exception == FALSE)
{
#line 1037 "inform7/Chapter 25/Tables.w"
if ((Specifications__is_kind_like(evaluation)) ||
(Specifications__is_description(evaluation))) {
LOG("Evaluation is $P\n", evaluation);
int quoted_col = table_cell_col + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_wording(5,
table_being_examined->columns[table_cell_col].column_identity->name);
Problems__quote_number(6, &table_cell_row);
Problems__Issue__table_problem(_p_(PM_TableDescriptionEntry),
t, NULL, cell,
"In %1, the entry %3 in column %4 (%5) of row %6 is a general description "
"of things with no definite value, and can't be stored as a table entry.");
return;
}
if (ParseTree__is(evaluation, CONSTANT_VNT) == FALSE) {
LOG("Evaluation is $P\n", evaluation);
{
#line 965 "inform7/Chapter 25/Tables.w"
int quoted_col = table_cell_col + 1; /* i.e., counting from 1 */
Problems__quote_number(4, &quoted_col);
Problems__quote_wording(5,
table_being_examined->columns[table_cell_col].column_identity->name);
Problems__quote_number(6, &table_cell_row);
Problems__Issue__table_problem(_p_(PM_TableUnknownEntry),
table_being_examined, NULL, table_cell_node,
"In %1, I'm reading the text %3 in column %4 (%5) of row %6, but I don't "
"know what this means. %PThis should usually be a value, like a number "
"or a piece of text, or a blank entry marker '--', but in some circumstances "
"it can also be an action (such as 'taking the box'), or a kind (such as "
"'a number') to show what sort of values will go into an otherwise blank "
"row.");
}
#line 1053 "inform7/Chapter 25/Tables.w"
;
}
}
#line 993 "inform7/Chapter 25/Tables.w"
;
Tables__Columns__note_kind(t, col_count, &(t->columns[col_count]), cell, Specifications__to_kind(evaluation), FALSE);
}
#line 1060 "inform7/Chapter 25/Tables.w"
void Tables__complete(void) {
{
#line 1069 "inform7/Chapter 25/Tables.w"
table *t;
LOOP_OVER(t, table)
if (t->amendment_of)
Tables__amend_table(t->amendment_of, t);
}
#line 1061 "inform7/Chapter 25/Tables.w"
;
{
#line 1077 "inform7/Chapter 25/Tables.w"
table *t;
LOOP_OVER(t, table)
if (t->amendment_of == FALSE) {
current_sentence = t->table_created_at->source_table;
wording W = t->blank_rows_text;
int N = -1;
if (Wordings__nonempty(W)) {
if (Preform__parse_nt_against_word_range(s_named_constant_NTM, W, NULL, NULL)) {
parse_node *val = NonlocalVariables__substitute_constants(most_recent_result_p);
N = Rvalues__to_int(val);
}
if (N >= 0) t->blank_rows = N;
else {
Problems__quote_wording(4, t->blank_rows_text);
Problems__Issue__table_problem(_p_(PM_TableUnknownBlanks),
t, NULL, current_sentence,
"%1 asked to have '%4' extra blank rows, but that would "
"only make sense for a literal number like '15' or a "
"name for a constant number. (The number must of course "
"be 0 or more.)");
}
}
}
}
#line 1062 "inform7/Chapter 25/Tables.w"
;
{
#line 1104 "inform7/Chapter 25/Tables.w"
table *t;
LOOP_OVER(t, table)
if (t->amendment_of == FALSE) {
current_sentence = t->table_created_at->source_table;
if (Wordings__nonempty(t->blank_rows_for_each_text)) {
kind *K = NULL;
if (Preform__parse_nt_against_word_range(k_kind_NTM, t->blank_rows_for_each_text, NULL, NULL)) {
K = most_recent_result_p;
t->blank_rows += Instances__count(K);
} else {
Problems__quote_wording(4, t->blank_rows_for_each_text);
Problems__Issue__table_problem(_p_(PM_TableKindlessBlanks),
t, NULL, current_sentence,
"%1 asked to have extra blank rows for each '%4', but that "
"isn't a kind, so I can't see how many blank rows to make.");
}
}
}
}
#line 1063 "inform7/Chapter 25/Tables.w"
;
}
#line 1137 "inform7/Chapter 25/Tables.w"
void Tables__amend_table(table *main_table, table *amendments) {
LOGIF(TABLES, "Amending table $B according to $B\n", main_table, amendments);
parse_node *leftmost_amend_cell = NULL;
int amend_row = 1, amendment_problem_opened = FALSE;
for (amend_row = 1, leftmost_amend_cell = amendments->columns[0].entries->down;
leftmost_amend_cell;
amend_row++, leftmost_amend_cell = leftmost_amend_cell->next)
{
#line 1169 "inform7/Chapter 25/Tables.w"
int col, matches_in_last_round = 0;
{
#line 1190 "inform7/Chapter 25/Tables.w"
parse_node *leftmost_cell;
for (leftmost_cell = main_table->columns[0].entries->down;
leftmost_cell;
leftmost_cell = leftmost_cell->next) {
ParseTree__annotate_int(leftmost_cell, row_amendable_ANNOT, TRUE);
matches_in_last_round++;
}
}
#line 1170 "inform7/Chapter 25/Tables.w"
;
for (col = 0; col < main_table->no_columns; col++) {
parse_node *amend_cell;
{
#line 1201 "inform7/Chapter 25/Tables.w"
int i;
for (i = 1, amend_cell = amendments->columns[col].entries->down;
amend_cell && (i < amend_row); i++, amend_cell = amend_cell->next) ;
if (amend_cell == NULL) internal_error("columns in amendments aren't equal in length");
}
#line 1173 "inform7/Chapter 25/Tables.w"
;
if (ParseTree__int_annotation(amend_cell, table_cell_unspecified_ANNOT) == FALSE) {
int only_row_left = -1;
{
#line 1216 "inform7/Chapter 25/Tables.w"
parse_node *amend_key = ParseTree__get_evaluation(amend_cell);
LOGIF(TABLES, "Amend row %d, col %d, key $P: $T\n", amend_row, col, amend_key, amend_cell);
if (ParseTree__is(amend_key, CONSTANT_VNT) == FALSE)
internal_error("bad key in amendments table"); /* code above should make this impossible */
int matches = 0;
{
#line 1235 "inform7/Chapter 25/Tables.w"
int row;
parse_node *leftmost_cell;
parse_node *main_cell;
for (row = 1,
main_cell = main_table->columns[col].entries->down,
leftmost_cell = main_table->columns[0].entries->down;
main_cell;
row++,
main_cell = main_cell->next,
leftmost_cell = leftmost_cell->next) {
parse_node *main_value = ParseTree__get_evaluation(main_cell);
if (ParseTree__int_annotation(leftmost_cell, row_amendable_ANNOT))
{
#line 1254 "inform7/Chapter 25/Tables.w"
LOG("Key in row %d is $P\n", row, main_value);
if ((ParseTree__is(main_value, CONSTANT_VNT)) &&
(Rvalues__compare_CONSTANT(amend_key, main_value))) {
matches++;
only_row_left = row;
} else {
ParseTree__annotate_int(leftmost_cell, row_amendable_ANNOT, FALSE);
}
}
#line 1247 "inform7/Chapter 25/Tables.w"
;
}
}
#line 1222 "inform7/Chapter 25/Tables.w"
;
if (matches == 0)
{
#line 1267 "inform7/Chapter 25/Tables.w"
{
#line 1293 "inform7/Chapter 25/Tables.w"
if (amendment_problem_opened == FALSE) {
amendment_problem_opened = TRUE;
current_sentence = amendments->table_created_at->source_table;
Problems__quote_table(1, main_table);
Problems__quote_table(2, amendments);
Problems__Issue__handmade_problem(_p_(PM_TableAmendmentMismatch));
Problems__issue_problem_segment(
"I'm currently trying to amend rows in %1 according to the instructions "
"in %2. To do that, I have to match each amendment row in turn, which "
"I do by trying to match up entries in the leftmost column(s).");
Problems__issue_problem_end();
Problems__issue_problem_begin("****");
Problems__issue_problem_segment("But I ran into problems:");
Problems__issue_problem_end();
}
}
#line 1267 "inform7/Chapter 25/Tables.w"
;
int quoted_col = col + 1; /* i.e., counting from 1, not 0 */
Problems__quote_number(1, &amend_row);
Problems__quote_number(2, &quoted_col);
Problems__quote_source(3, amend_cell);
Problems__quote_wording(4, main_table->columns[col].column_identity->name);
Problems__quote_table(5, main_table);
Problems__quote_number(6, &matches_in_last_round);
if (matches_in_last_round > 2) Problems__quote_text(7, "any");
else Problems__quote_text(7, "either");
Problems__issue_problem_begin("****");
if (col == 0)
Problems__issue_problem_segment(
"(Amendment %1). I can't match this to any row - there's nothing with "
"an entry of %3 in the lefthand column (%4).");
else
Problems__issue_problem_segment(
"(Amendment %1). I can't decide which row this should replace. "
"It matches %6 rows until I get up to column %2 (%4), but then "
"it reads %3, which is different from %7 of them.");
Problems__issue_problem_end();
break; /* to move on to the next row in the amendments */
}
#line 1223 "inform7/Chapter 25/Tables.w"
;
if (matches > 1) {
if (col < main_table->no_columns - 1) /* i.e., if we haven't reached the final column */
only_row_left = -1; /* because there's no single row left */
}
matches_in_last_round = matches;
}
#line 1176 "inform7/Chapter 25/Tables.w"
;
if (only_row_left >= 0) {
Tables__splice_table_row(main_table, amendments, only_row_left, amend_row);
break;
}
}
}
}
#line 1144 "inform7/Chapter 25/Tables.w"
;
}
#line 1313 "inform7/Chapter 25/Tables.w"
void Tables__splice_table_row(table *table_to, table *table_from, int row_to, int row_from) {
int i;
for (i=0; i<table_to->no_columns; i++) {
parse_node *cell_to, *cell_from;
int row;
for (row = 1, cell_to = table_to->columns[i].entries->down;
cell_to && (row < row_to); cell_to = cell_to->next, row++) ;
for (row = 1, cell_from = table_from->columns[i].entries->down;
cell_from && (row < row_from); cell_from = cell_from->next, row++) ;
if ((cell_to) && (cell_from)) {
Assertions__Refiner__copy_noun_details(cell_to, cell_from);
ParseTree__annotate_int(cell_to, table_cell_unspecified_ANNOT,
ParseTree__int_annotation(cell_from, table_cell_unspecified_ANNOT));
} else internal_error("bad table row splice");
}
}
#line 1337 "inform7/Chapter 25/Tables.w"
void Tables__index(void) {
INDEX("<p>");
int m = Tables__index_tables_in(NULL, 0);
INDEX("</p><p>"); Index__extra_link(2);
if (m > 0) INDEX("Show tables inside extensions too</p>");
else INDEX("Show tables inside extensions (there are none in the main text)</p>");
Index__extra_div_open(2, 1, "e0e0e0");
extension_file *ef; int efc = 0;
LOOP_OVER(ef, extension_file) Tables__index_tables_in(ef, efc++);
Index__extra_div_close("e0e0e0");
INDEX("</p>");
}
#line 1354 "inform7/Chapter 25/Tables.w"
int Tables__index_tables_in(extension_file *ef, int efc) {
int tc = 0; table *t;
LOOP_OVER(t, table) if (Tables__table_within(t, ef)) tc++;
if (tc > 0) {
if (ef) {
if (efc > 0) INDEX("<br>");
INDEX("<i>");
Wordings__index_raw(ef->title_text);
INDEX("</i></p><p>");
}
HTML__begin_plain_html_table(ifl);
LOOP_OVER(t, table)
if (Tables__table_within(t, ef))
{
#line 1377 "inform7/Chapter 25/Tables.w"
HTML__first_html_column_spaced(ifl, 0);
INDEX("<b>");
Wordings__index_raw(ParseTree__get_text(t->headline_fragment));
INDEX("</b>");
table_contribution *tc; int ntc = 0;
for (tc = t->table_created_at; tc; tc = tc->next) {
if (ntc++ > 0) INDEX(" +");
Index__link(Wordings__first_wn(ParseTree__get_text(tc->source_table)));
}
HTML__next_html_column_spaced(ifl, 0);
int rc = Tables__get_no_rows(t);
INDEX("<i><small>");
if (t->first_column_by_definition) {
INDEX("%d definition%s", rc,
(rc == 1)?"":"s");
} else {
INDEX("%d column%s x %d row%s",
t->no_columns, (t->no_columns == 1)?"":"s",
rc, (rc == 1)?"":"s");
}
if (t->blank_rows > 0) {
INDEX(" (%d blank", t->blank_rows);
if (Wordings__nonempty(t->blank_rows_for_each_text)) {
INDEX(", one for each ");
Wordings__index_raw(t->blank_rows_for_each_text);
}
INDEX(")");
}
INDEX("</small></i>");
HTML__end_html_row(ifl);
int col;
for (col = 0; col < t->no_columns; col++) {
HTML__first_html_column(ifl, 0);
INDEX("&nbsp;&nbsp;col %d:&nbsp;&nbsp;", col+1);
wording CW = t->columns[col].column_identity->name;
if ((t->first_column_by_definition) && (col == 0)) {
parse_node *PN = t->where_used_to_define;
Wordings__index_raw(ParseTree__get_text(PN));
Index__link(Wordings__first_wn(ParseTree__get_text(PN)));
} else {
if (t->first_column_by_definition) INDEX("<i>sets</i> ");
Wordings__index_raw(CW);
INDEX("&nbsp;");
TEMPORARY_STREAM;
Wordings__to_stream_raw(TEMP, CW);
if (t->first_column_by_definition == FALSE) WRITE_TO(TEMP, " entry");
HTML__Javascript__paste(ifl, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
}
HTML__next_html_column(ifl, 0);
if ((t->first_column_by_definition) && (col == 0)) {
parse_node *cell;
int row;
for (row = 1, cell = t->columns[0].entries->down; cell; cell = cell->next, row++) {
if (row > 1) INDEX(", ");
Wordings__index_raw(ParseTree__get_text(cell));
Index__link(Wordings__first_wn(ParseTree__get_text(cell)));
}
} else if (t->first_column_by_definition) {
Kinds__Textual__write(ifl,
Tables__Columns__get_kind(
t->columns[col].column_identity));
INDEX(" property");
} else {
INDEX("of ");
Kinds__Textual__write_plural(ifl,
Tables__Columns__get_kind(
t->columns[col].column_identity));
}
HTML__end_html_row(ifl);
}
}
#line 1367 "inform7/Chapter 25/Tables.w"
;
HTML__end_html_table(ifl);
}
return tc;
}
#line 1453 "inform7/Chapter 25/Tables.w"
int Tables__table_within(table *t, extension_file *ef) {
if (t->amendment_of) return FALSE;
heading *at_heading = Wordings__heading_of(ParseTree__get_text(t->table_created_at->source_table));
extension_file *at_ef = Sentences__Headings__get_extension_containing(at_heading);
if (ef == at_ef) return TRUE;
return FALSE;
}
#line 16 "inform7/Chapter 25/Runtime Support for Tables.w"
void Tables__Support__compile(OUTPUT_STREAM) {
{
#line 27 "inform7/Chapter 25/Runtime Support for Tables.w"
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
int blanks_array_hwm = 0; /* the high water mark of storage used in the blanks array */
table *t;
LOOP_OVER(t, table)
if (t->amendment_of == FALSE)
{
#line 39 "inform7/Chapter 25/Runtime Support for Tables.w"
int words_used = 0;
current_sentence = t->table_created_at->source_table;
{
#line 63 "inform7/Chapter 25/Runtime Support for Tables.w"
WRITE("Array %s ", t->tab_I6_identifier);
if (t->no_columns == 1) {
WRITE("--> 1 tab_%d_%d", t->allocation_id, 0);
} else {
WRITE("table ");
int j;
for (j=0; j<t->no_columns; j++)
WRITE(" tab_%d_%d", t->allocation_id, j);
}
WRITE(";\n");
words_used += t->no_columns + 1;
}
#line 41 "inform7/Chapter 25/Runtime Support for Tables.w"
;
int j;
for (j=0; j<t->no_columns; j++)
{
#line 87 "inform7/Chapter 25/Runtime Support for Tables.w"
WRITE("Array tab_%d_%d table ", t->allocation_id, j);
table_column *tc = t->columns[j].column_identity;
LOGIF(TABLES, "Compiling column: $C\n", tc);
kind *K = Tables__Columns__get_kind(tc);
int bits = 0; /* bitmap of some properties of the column */
{
#line 153 "inform7/Chapter 25/Runtime Support for Tables.w"
if (Kinds__Behaviour__can_exchange(K)) bits += TB_COLUMN_CANEXCHANGE;
if ((Kinds__Behaviour__uses_signed_comparisons(K)) ||
(Kinds__FloatingPoint__uses_floating_point(K))) bits += TB_COLUMN_SIGNED;
if (Kinds__FloatingPoint__uses_floating_point(K)) bits += TB_COLUMN_REAL;
if (Kinds__Behaviour__uses_pointer_values(K)) bits += TB_COLUMN_ALLOCATED;
if (Kinds__Compare__eq(K, K_understanding)) bits = TB_COLUMN_TOPIC;
if (Kinds__Behaviour__requires_blanks_bitmap(K) == FALSE) bits += TB_COLUMN_NOBLANKBITS;
if (t->preserve_row_order_at_run_time) bits += TB_COLUMN_DONTSORTME;
WRITE("$%04x ", Tables__Columns__get_id(tc) + bits);
if (bits & TB_COLUMN_NOBLANKBITS) WRITE("NULL "); else WRITE("%d ", blanks_array_hwm);
words_used += 2;
}
#line 94 "inform7/Chapter 25/Runtime Support for Tables.w"
;
int e = 0; /* which bit we're up to within the current byte of the blanks array */
parse_node *cell;
for (cell = t->columns[j].entries->down; cell; cell = cell->next) {
{
#line 173 "inform7/Chapter 25/Runtime Support for Tables.w"
current_sentence = cell;
WRITE("(");
if (ParseTree__int_annotation(cell, table_cell_unspecified_ANNOT)) {
{
#line 211 "inform7/Chapter 25/Runtime Support for Tables.w"
WRITE(" ");
if (t->fill_in_blanks == FALSE) WRITE("TABLE_NOVALUE");
else Kinds__Behaviour__compile_default_value(OUT, K, EMPTY_WORDING, "table entry");
}
#line 176 "inform7/Chapter 25/Runtime Support for Tables.w"
;
} else {
if (bits & TB_COLUMN_TOPIC)
PL__Parsing__compile_understanding(OUT, ParseTree__get_text(cell), TRUE);
else {
parse_node *val = ParseTree__get_evaluation(cell);
if (Specifications__is_kind_like(val)) WRITE("nothing");
else if (val == NULL) internal_error("Valueless cell");
else Specifications__Compiler__compile_constant_to_kind(OUT, val, K);
}
}
WRITE(") ");
words_used++;
}
#line 100 "inform7/Chapter 25/Runtime Support for Tables.w"
;
{
#line 122 "inform7/Chapter 25/Runtime Support for Tables.w"
if ((bits & TB_COLUMN_NOBLANKBITS) == 0) {
e++; if ((e % 8) == 0) blanks_array_hwm++;
}
}
#line 101 "inform7/Chapter 25/Runtime Support for Tables.w"
;
words_used++;
}
int blank_count = t->blank_rows;
if ((blank_count == 0) && (t->columns[j].entries->down == NULL)) blank_count = 1;
int br;
for (br = 0; br < blank_count; br++) {
{
#line 211 "inform7/Chapter 25/Runtime Support for Tables.w"
WRITE(" ");
if (t->fill_in_blanks == FALSE) WRITE("TABLE_NOVALUE");
else Kinds__Behaviour__compile_default_value(OUT, K, EMPTY_WORDING, "table entry");
}
#line 108 "inform7/Chapter 25/Runtime Support for Tables.w"
;
{
#line 122 "inform7/Chapter 25/Runtime Support for Tables.w"
if ((bits & TB_COLUMN_NOBLANKBITS) == 0) {
e++; if ((e % 8) == 0) blanks_array_hwm++;
}
}
#line 109 "inform7/Chapter 25/Runtime Support for Tables.w"
;
words_used++;
}
{
#line 129 "inform7/Chapter 25/Runtime Support for Tables.w"
if ((bits & TB_COLUMN_NOBLANKBITS) == 0) {
if ((e % 8) != 0) blanks_array_hwm++; /* pad out a partial byte with zero bits */
}
}
#line 112 "inform7/Chapter 25/Runtime Support for Tables.w"
;
WRITE(";\n");
}
#line 43 "inform7/Chapter 25/Runtime Support for Tables.w"
;
t->approximate_array_space_needed = words_used;
}
#line 33 "inform7/Chapter 25/Runtime Support for Tables.w"
;
END_COMPILATION_MODE;
}
#line 17 "inform7/Chapter 25/Runtime Support for Tables.w"
;
{
#line 218 "inform7/Chapter 25/Runtime Support for Tables.w"
WRITE("Array TB_Blanks -> ");
table *t;
LOOP_OVER(t, table)
if (t->amendment_of == FALSE) {
WRITE("\n ! For table %s\n ", t->tab_I6_identifier);
current_sentence = t->table_created_at->source_table;
int j;
for (j=0; j<t->no_columns; j++) {
table_column *tc = t->columns[j].column_identity;
if (Kinds__Behaviour__requires_blanks_bitmap(Tables__Columns__get_kind(tc)) == FALSE)
continue;
int current_bit = 1, byte_so_far = 0;
{
#line 241 "inform7/Chapter 25/Runtime Support for Tables.w"
parse_node *cell;
for (cell = t->columns[j].entries->down; cell; cell = cell->next) {
if ((ParseTree__int_annotation(cell, table_cell_unspecified_ANNOT))
&& (t->fill_in_blanks == FALSE))
byte_so_far += current_bit;
current_bit = current_bit*2;
if (current_bit == 256)
{
#line 263 "inform7/Chapter 25/Runtime Support for Tables.w"
WRITE("$%02x ", byte_so_far);
byte_so_far = 0; current_bit = 1;
}
#line 247 "inform7/Chapter 25/Runtime Support for Tables.w"
;
}
}
#line 230 "inform7/Chapter 25/Runtime Support for Tables.w"
;
{
#line 253 "inform7/Chapter 25/Runtime Support for Tables.w"
int k;
for (k = 0; k < t->blank_rows; k++) {
byte_so_far += current_bit;
current_bit = current_bit*2;
if (current_bit == 256)
{
#line 263 "inform7/Chapter 25/Runtime Support for Tables.w"
WRITE("$%02x ", byte_so_far);
byte_so_far = 0; current_bit = 1;
}
#line 257 "inform7/Chapter 25/Runtime Support for Tables.w"
;
}
}
#line 231 "inform7/Chapter 25/Runtime Support for Tables.w"
;
if (current_bit != 1)
{
#line 263 "inform7/Chapter 25/Runtime Support for Tables.w"
WRITE("$%02x ", byte_so_far);
byte_so_far = 0; current_bit = 1;
}
#line 232 "inform7/Chapter 25/Runtime Support for Tables.w"
;
WRITE(" ! Column %d\n ", j);
}
}
WRITE("\n ! End of table\n NULL NULL;\n");
}
#line 18 "inform7/Chapter 25/Runtime Support for Tables.w"
;
{
#line 272 "inform7/Chapter 25/Runtime Support for Tables.w"
WRITE("Array TableOfTables --> TheEmptyTable ");
table *t;
LOOP_OVER(t, table)
if (t->amendment_of == FALSE)
WRITE("%s ", t->tab_I6_identifier);
WRITE("0 0;\n");
}
#line 19 "inform7/Chapter 25/Runtime Support for Tables.w"
;
Tables__Columns__compile_run_time_support(OUT);
{
#line 282 "inform7/Chapter 25/Runtime Support for Tables.w"
table *t;
LOOP_OVER(t, table)
if (t->amendment_of == FALSE)
VirtualMachines__note_usage("table",
ParseTree__get_text(t->headline_fragment),
NULL, t->approximate_array_space_needed, 0, FALSE);
}
#line 21 "inform7/Chapter 25/Runtime Support for Tables.w"
;
}
#line 293 "inform7/Chapter 25/Runtime Support for Tables.w"
void Tables__Support__compile_print_table_names(OUTPUT_STREAM) {
table *t;
WRITE(" TheEmptyTable: print \"(the empty table)\"; return;\n");
LOOP_OVER(t, table)
if (t->amendment_of == FALSE) {
WRITE(" %s: print \"", t->tab_I6_identifier);
Wordings__to_stream_raw(OUT, ParseTree__get_text(t->headline_fragment));
WRITE("\"; return;\n");
}
}
#line 312 "inform7/Chapter 25/Runtime Support for Tables.w"
int rankings_table_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 314 "inform7/Chapter 25/Runtime Support for Tables.w"
#line 323 "inform7/Chapter 25/Runtime Support for Tables.w"
void Tables__Support__compile_max_score(OUTPUT_STREAM) {
table *t;
LOOP_OVER(t, table) {
if ((Preform__parse_nt_against_word_range(rankings_table_name_NTM, t->table_name_text, NULL, NULL)) &&
(t->no_columns >= 2) &&
(Kinds__Compare__eq(Tables__kind_of_ith_column(t, 0), K_number)) &&
(Kinds__Compare__eq(Tables__kind_of_ith_column(t, 1), K_text))) {
parse_node *PN = t->columns[0].entries->down;
while ((PN != NULL) && (PN->next != NULL)) PN = PN->next;
WRITE("Constant RANKING_TABLE = %s;\n", t->tab_I6_identifier);
if ((PN != NULL) && (max_score_VAR) &&
(NonlocalVariables__has_initial_value_set(max_score_VAR) == FALSE))
Assertions__PropertyKnowledge__initialise_global_variable(
max_score_VAR, ParseTree__get_evaluation(PN));
}
}
if (NonlocalVariables__has_initial_value_set(max_score_VAR)) {
WRITE("Global MAX_SCORE = ");
NonlocalVariables__compile_initial_value(OUT, max_score_VAR);
WRITE(";\n");
}
}
#line 30 "inform7/Chapter 25/Tables of Definitions.w"
int defined_by_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 38 "inform7/Chapter 25/Tables of Definitions.w"
*X = FALSE;
{
#line 44 "inform7/Chapter 25/Tables of Definitions.w"
Problems__Issue__sentence_problem(_p_(PM_TableDefiningTheImpossible),
"you can only use 'defined by' to set up values and things",
"as created with sentences like 'The tree species are defined by Table 1.' "
"or 'Some men are defined by the Table of Eligible Bachelors.'");
}
#line 39 "inform7/Chapter 25/Tables of Definitions.w"
;
}
#line 33 "inform7/Chapter 25/Tables of Definitions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 34 "inform7/Chapter 25/Tables of Definitions.w"
#line 52 "inform7/Chapter 25/Tables of Definitions.w"
int defined_by_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 59 "inform7/Chapter 25/Tables of Definitions.w"
*X = TRUE; *XP = RP[1];
if (!(Rvalues__is_CONSTANT_of_kind(RP[1], K_table)))
return FALSE;
}
#line 53 "inform7/Chapter 25/Tables of Definitions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 66 "inform7/Chapter 25/Tables of Definitions.w"
*X = FALSE;
Problems__Issue__sentence_problem(_p_(PM_TableUndefined),
"you can only use 'defined by' in terms of a table",
"which lists the value names in the first column.");
}
#line 54 "inform7/Chapter 25/Tables of Definitions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 55 "inform7/Chapter 25/Tables of Definitions.w"
#line 94 "inform7/Chapter 25/Tables of Definitions.w"
sentence_handler DEFINED_BY_SH_handler =
{ SENTENCE_NT, DEFINED_BY_VB, 0, Tables__Defining__kind_defined_by_table };
#line 102 "inform7/Chapter 25/Tables of Definitions.w"
void Tables__Defining__kind_defined_by_table(parse_node *pn) {
wording LTW = ParseTree__get_text(pn->down->next->next);
wording SPW = ParseTree__get_text(pn->down->next);
LOGIF(TABLES, "Traverse %d: I now want to define <$w> by table <$w>\n",
traverse, SPW, LTW);
Preform__parse_nt_against_word_range(defined_by_sentence_object_NTM, LTW, NULL, NULL); if (most_recent_result == FALSE) return;
table *t = Rvalues__to_table(most_recent_result_p);
if (traverse == 1) {
int abstract = NOT_APPLICABLE;
kind *K = NULL;
{
#line 129 "inform7/Chapter 25/Tables of Definitions.w"
Preform__parse_nt_against_word_range(defined_by_sentence_subject_NTM, SPW, NULL, NULL); if (most_recent_result == FALSE) return;
parse_node *what = most_recent_result_p;
if (Specifications__is_kind_like(what)) {
K = Specifications__to_kind(what);
if (Kinds__Compare__le(K, K_object)) abstract = FALSE;
else {
abstract = TRUE;
t->contains_property_values_at_run_time = TRUE;
t->fill_in_blanks = TRUE;
t->preserve_row_order_at_run_time = TRUE;
t->disable_block_constant_correction = TRUE;
}
} else if (Specifications__object_exactly_described_if_any(what)) {
{
#line 167 "inform7/Chapter 25/Tables of Definitions.w"
Problems__Issue__sentence_problem(_p_(PM_TableDefiningObject),
"you can only use 'defined by' to set up values and things",
"as created with sentences like 'The tree species are defined by Table 1.' "
"or 'Some men are defined by the Table of Eligible Bachelors.' - trying to "
"define a single specific object, as here, is not allowed.");
}
#line 142 "inform7/Chapter 25/Tables of Definitions.w"
return;
} else if (Specifications__is_description(what)) {
{
#line 208 "inform7/Chapter 25/Tables of Definitions.w"
if (Calculus__Propositions__contains_quantifier(
Specifications__to_proposition(what))) {
Problems__Issue__sentence_problem(_p_(PM_TableOfQuantifiedKind),
"you can't use 'defined by' a table while also talking about the "
"number of things to be defined",
"since that could too easily lead to contradictions. (So 'Six doors are "
"defined by the Table of Portals' is not allowed - suppose there are ten "
"rows in the Table, making ten doors?)");
return;
}
}
#line 145 "inform7/Chapter 25/Tables of Definitions.w"
;
abstract = FALSE;
K = Specifications__to_kind(what);
} else {
LOG("Error at: $T", what);
{
#line 44 "inform7/Chapter 25/Tables of Definitions.w"
Problems__Issue__sentence_problem(_p_(PM_TableDefiningTheImpossible),
"you can only use 'defined by' to set up values and things",
"as created with sentences like 'The tree species are defined by Table 1.' "
"or 'Some men are defined by the Table of Eligible Bachelors.'");
}
#line 150 "inform7/Chapter 25/Tables of Definitions.w"
;
return;
}
if ((t) && (t->has_been_amended) && (Kinds__Compare__le(K, K_object))) {
Problems__Issue__sentence_problem(_p_(PM_TableCantDefineAndAmend),
"you can't use 'defined by' to define objects using a table "
"which is amended by another table",
"since that could too easily lead to ambiguities about what "
"the property values are.");
return;
}
t->first_column_by_definition = TRUE;
t->where_used_to_define = pn->down->next;
}
#line 114 "inform7/Chapter 25/Tables of Definitions.w"
;
{
#line 176 "inform7/Chapter 25/Tables of Definitions.w"
if ((Kinds__Compare__le(K, K_object) == FALSE) &&
(Kinds__Behaviour__has_named_constant_values(K) == FALSE)) {
LOG("K is $u\n", K);
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(PM_TableOfBuiltInKind));
Problems__issue_problem_segment(
"You wrote %1, but this would mean making each of the names in "
"the first column %2 that's new. This is a kind which can't have "
"entirely new values, so I can't make these definitions.");
Problems__issue_problem_end();
return;
}
if ((Kinds__Behaviour__has_named_constant_values(K)) &&
(Kinds__Behaviour__is_uncertainly_defined(K) == FALSE)) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(PM_TableOfExistingKind));
Problems__issue_problem_segment(
"You wrote %1, but this would mean making each of the names in "
"the first column %2 that's new. That looks reasonable, since this is a "
"kind which does have named values, but one of the restrictions on "
"definitions-by-table is that all of the values of the kind have "
"to be made by the table: you can't have some defined in ordinary "
"sentences and others in the table.");
Problems__issue_problem_end();
return;
}
}
#line 115 "inform7/Chapter 25/Tables of Definitions.w"
;
K = Kinds__weaken(K);
if (!(Kinds__Compare__le(K, K_object))) Kinds__Behaviour__set_defined_by_table(K, t);
t->kind_defined_in_this_table = K;
Tables__Columns__set_kind(t->columns[0].column_identity, t, K);
{
#line 243 "inform7/Chapter 25/Tables of Definitions.w"
parse_node *name_entry;
int objections = 0, blank_objections = 0, row_count;
for (name_entry = t->columns[0].entries->down, row_count = 1; name_entry;
name_entry=name_entry->next, row_count++) {
wording NW = ParseTree__get_text(name_entry);
LOGIF(TABLES, "So I want to create: <$w>\n", NW);
if (Preform__parse_nt_against_word_range(table_cell_blank_NTM, NW, NULL, NULL))
{
#line 283 "inform7/Chapter 25/Tables of Definitions.w"
if (blank_objections == 0) {
Problems__quote_number(4, &row_count);
Problems__Issue__table_problem(_p_(PM_TableWithBlankNames),
t, NULL, name_entry,
"%1 is being used to create values, so that the first column needs "
"to contain names for these new things. It's not allowed to contain "
"blanks, but row %4 does (see %3).");
}
objections++; blank_objections++; continue;
}
#line 250 "inform7/Chapter 25/Tables of Definitions.w"
;
parse_node *evaluation = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, ParseTree__get_text(name_entry), NULL, NULL))
evaluation = most_recent_result_p;
Assertions__Refiner__noun_from_value(name_entry, evaluation);
if (Specifications__is_kind_like(evaluation))
{
#line 299 "inform7/Chapter 25/Tables of Definitions.w"
Problems__quote_number(4, &row_count);
Problems__Issue__table_problem(_p_(PM_TableEntryGeneric),
t, NULL, name_entry,
"In row %4 of %1, the entry %3 is the name of a kind of value, "
"so it can't be the name of a new object.");
objections++; continue;
}
#line 256 "inform7/Chapter 25/Tables of Definitions.w"
;
if ((evaluation) && (ParseTree__is(evaluation, UNKNOWN_VNT) == FALSE))
{
#line 309 "inform7/Chapter 25/Tables of Definitions.w"
LOG("Existing meaning was: $P\n", evaluation);
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, name_entry);
Problems__quote_kind_of(3, evaluation);
Problems__quote_kind(4, K);
Problems__quote_number(5, &row_count);
Problems__Issue__handmade_problem(_p_(PM_TableCreatedClash));
Problems__issue_problem_segment(
"You wrote %1, and row %5 of the first column of that table is %2, which "
"I ought to create as a new value of %4. But I can't do that: it already "
"has a meaning (as %3).");
Problems__issue_problem_end();
objections++; continue;
}
#line 258 "inform7/Chapter 25/Tables of Definitions.w"
;
Assertions__Creator__tabular_definitions(t);
Sentences__NPs__annotate_by_articles(name_entry);
Problems__Buffer__redirect_problem_sentence(current_sentence, name_entry, pn->down->next);
Assertions__Copular__make_assertion(name_entry, pn->down->next);
Problems__Buffer__redirect_problem_sentence(NULL, NULL, NULL);
ParseTree__set_text(name_entry, NW);
evaluation = NULL;
if (Preform__parse_nt_against_word_range(k_kind_NTM, NW, NULL, NULL))
evaluation = Specifications__from_kind(most_recent_result_p);
else if (Preform__parse_nt_against_word_range(s_type_expression_NTM, ParseTree__get_text(name_entry), NULL, NULL))
evaluation = most_recent_result_p;
Assertions__Refiner__noun_from_value(name_entry, evaluation);
Assertions__Creator__tabular_definitions(NULL);
if (ParseTree__get_subject(name_entry) == NULL)
{
#line 326 "inform7/Chapter 25/Tables of Definitions.w"
LOG("Eval is $P\n", evaluation);
Problems__quote_source(4, name_entry);
Problems__quote_number(5, &row_count);
Problems__Issue__table_problem(_p_(PM_TableDefiningNothing),
t, NULL, name_entry,
"In row %5 of %1, the entry %4 seems not to have defined "
"a thing there, so perhaps the first column did not consist "
"of new names?");
objections++; continue;
}
#line 275 "inform7/Chapter 25/Tables of Definitions.w"
;
}
if (objections > 0) return;
}
#line 121 "inform7/Chapter 25/Tables of Definitions.w"
;
}
{
#line 345 "inform7/Chapter 25/Tables of Definitions.w"
int i;
for (i=1; i<t->no_columns; i++) {
property *P = NULL;
{
#line 365 "inform7/Chapter 25/Tables of Definitions.w"
Preform__parse_nt_against_word_range(unfortunate_table_column_property_NTM, t->columns[i].column_identity->name, NULL, NULL);
P = Properties__Valued__obtain(t->columns[i].column_identity->name);
if (Properties__Valued__kind(P) == NULL) {
kind *CK = Tables__Columns__get_kind(t->columns[i].column_identity);
if ((Kinds__get_construct(CK) == CON_rule) ||
(Kinds__get_construct(CK) == CON_rulebook)) {
kind *K1 = NULL, *K2 = NULL;
Kinds__binary_construction_material(CK, &K1, &K2);
if ((Kinds__Compare__eq(K1, K_value)) && (Kinds__Compare__eq(K1, K_value))) {
CK = Kinds__binary_construction(
Kinds__get_construct(CK), K_action_name, K_nil);
Tables__Columns__set_kind(t->columns[i].column_identity, t, CK);
}
}
if (CK) Properties__Valued__set_kind(P, CK);
}
}
#line 348 "inform7/Chapter 25/Tables of Definitions.w"
;
if (traverse == 1)
Calculus__Propositions__Assert__assert_true_about(
Calculus__Propositions__Abstract__to_provide_property(P),
Kinds__Behaviour__as_subject(t->kind_defined_in_this_table),
prevailing_mood);
if (t->contains_property_values_at_run_time)
{
#line 412 "inform7/Chapter 25/Tables of Definitions.w"
if (traverse == 1)
Properties__ValueImplementation__pp_set_table_storage(t->allocation_id, i);
}
#line 355 "inform7/Chapter 25/Tables of Definitions.w"
else
{
#line 419 "inform7/Chapter 25/Tables of Definitions.w"
parse_node *name_entry, *data_entry;
for (name_entry = t->columns[0].entries->down,
data_entry = t->columns[i].entries->down;
name_entry && data_entry;
name_entry = name_entry->next,
data_entry = data_entry->next) {
Problems__Buffer__redirect_problem_sentence(current_sentence, name_entry, data_entry);
{
#line 436 "inform7/Chapter 25/Tables of Definitions.w"
inference_subject *subj = ParseTree__get_subject(name_entry);
if (traverse == 2) {
if ((Wordings__nonempty(ParseTree__get_text(data_entry))) &&
(Preform__parse_nt_against_word_range(table_cell_blank_NTM, ParseTree__get_text(data_entry), NULL, NULL) == FALSE)) {
parse_node *val = ParseTree__get_evaluation(data_entry);
if (ParseTree__is(val, UNKNOWN_VNT)) {
if (problem_count == 0) internal_error("misevaluated cell");
} else {
Assertions__Refiner__noun_from_value(data_entry, val);
Assertions__PropertyKnowledge__assert_property_value_from_property_subtree_infs(
P, subj, data_entry);
}
}
}
}
#line 426 "inform7/Chapter 25/Tables of Definitions.w"
;
}
Problems__Buffer__redirect_problem_sentence(current_sentence, NULL, NULL);
}
#line 356 "inform7/Chapter 25/Tables of Definitions.w"
;
}
}
#line 123 "inform7/Chapter 25/Tables of Definitions.w"
;
}
#line 387 "inform7/Chapter 25/Tables of Definitions.w"
int unfortunate_table_column_property_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 393 "inform7/Chapter 25/Tables of Definitions.w"
*X = NEW_TC_PROBLEM;
Problems__quote_wording(3, W);
Problems__Issue__table_problem(_p_(PM_TableColumnLocation),
table_being_examined, NULL, table_cell_node,
"In %1, the column name %3 cannot be used, because there would be too "
"much ambiguity arising from its ordinary meaning referring to the "
"physical position of something.");
}
#line 388 "inform7/Chapter 25/Tables of Definitions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 389 "inform7/Chapter 25/Tables of Definitions.w"
#line 12 "inform7/Chapter 25/Listed-In Relations.w"
void Tables__Relations__REL_create_initial_stock(void) {
}
#line 28 "inform7/Chapter 25/Listed-In Relations.w"
binary_predicate *Tables__Relations__make_listed_in_predicate(table_column *tc) {
binary_predicate *bp = BinaryPredicates__make_pair(LISTED_IN_KBP,
BinaryPredicates__new_term(NULL),
BinaryPredicates__new_term(Kinds__Behaviour__as_subject(K_table)),
"listed_in", "lists-in", NULL, NULL,
Calculus__Schemas__new("(ct_1=ExistsTableRowCorr(ct_0=*2,%d,*1))",
Tables__Columns__get_id(tc)),
WordAssemblages__lit_0());
bp->a_listed_in_predicate = TRUE;
return bp;
}
#line 48 "inform7/Chapter 25/Listed-In Relations.w"
void Tables__Relations__supply_kind_for_listed_in_tc(binary_predicate *bp, kind *K) {
BinaryPredicates__set_term_domain(&(bp->term_details[0]), K);
BinaryPredicates__set_term_domain(&(bp->reversal->term_details[1]), K);
}
#line 57 "inform7/Chapter 25/Listed-In Relations.w"
void Tables__Relations__REL_create_second_stock(void) {
}
#line 63 "inform7/Chapter 25/Listed-In Relations.w"
int Tables__Relations__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
return DECLINE_TO_MATCH;
}
#line 72 "inform7/Chapter 25/Listed-In Relations.w"
int Tables__Relations__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
return FALSE;
}
#line 84 "inform7/Chapter 25/Listed-In Relations.w"
int Tables__Relations__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) {
if (task == TEST_ATOM_TASK) LocalVariables__add_table_lookup();
return FALSE;
}
#line 92 "inform7/Chapter 25/Listed-In Relations.w"
int Tables__Relations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
WRITE("the listed in relation");
return TRUE;
}
#line 131 "inform7/Chapter 26/Equations.w"
sentence_handler EQUATION_SH_handler = { EQUATION_NT, -1, 0, NULL };
#line 134 "inform7/Chapter 26/Equations.w"
void Equations__traverse_to_create(void) {
ParseTree__traverse(Equations__visit_to_create);
}
void Equations__visit_to_create(parse_node *p) {
if (ParseTree__get_type(p) == EQUATION_NT)
Equations__new(ParseTree__get_text(p), FALSE);
}
#line 145 "inform7/Chapter 26/Equations.w"
int equation_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 3;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 2;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 210 "inform7/Chapter 26/Equations.w"
*X = 0;
Problems__Issue__sentence_problem(_p_(PM_EquationMisnumbered),
"the top line of this equation declaration seems not to be a "
"legal equation number or name",
"and should read something like 'Equation 6', or 'Equation - "
"Newton's Second Law', or 'Equation 41 - Coulomb's Law'.");
}
#line 149 "inform7/Chapter 26/Equations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 150 "inform7/Chapter 26/Equations.w"
#line 161 "inform7/Chapter 26/Equations.w"
equation *Equations__new(wording W, int anonymous) {
equation *eqn;
LOOP_OVER(eqn, equation)
if (eqn->equation_created_at == current_sentence)
return eqn;
eqn = CREATE(equation);
eqn->equation_created_at = current_sentence;
eqn->where_text = EMPTY_WORDING;
eqn->usage_text = EMPTY_WORDING;
eqn->parsed_equation = NULL;
eqn->symbol_list = NULL;
eqn->examined_already = FALSE;
Identifiers__compose(eqn->eqn_I6_identifier, 'Q', eqn->allocation_id,
eqn->equation_name_text);
wording NO = EMPTY_WORDING, NA = EMPTY_WORDING;
if (anonymous == FALSE) {
{
#line 220 "inform7/Chapter 26/Equations.w"
int i = Wordings__last_word_of_formatted_text(W, FALSE);
wording TW = Wordings__up_to(W, i);
W = Wordings__from(W, i+1);
if (Preform__parse_nt_against_word_range(equation_name_NTM, TW, NULL, NULL)) {
switch (most_recent_result) {
case 0: return NULL;
case 1: NO = GET_RW(equation_name_NTM, 1); break;
case 2: NA = GET_RW(equation_name_NTM, 1); break;
case 3: NO = GET_RW(equation_name_NTM, 1);
NA = GET_RW(equation_name_NTM, 2); break;
}
} else internal_error("malformed equation sentence");
}
#line 180 "inform7/Chapter 26/Equations.w"
;
{
#line 249 "inform7/Chapter 26/Equations.w"
if (Wordings__nonempty(NO))
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(EQUATION_MC,
Preform__Nonparsing__merge(equation_names_construction_NTM, 0,
WordAssemblages__from_wording(NO)),
Rvalues__from_equation(eqn));
if (Wordings__nonempty(NA)) {
if (Preform__parse_nt_against_word_range(s_type_expression_or_value_NTM, NA, NULL, NULL)) {
Problems__quote_wording_as_source(1, NA);
Problems__Issue__handmade_problem(_p_(PM_EquationMisnamed));
Problems__issue_problem_segment(
"The equation name %1 will have to be disallowed as it is text "
"which already has a meaning to Inform. For instance, creating "
"an equation called 'Equation - 2 + 2' would be disallowed "
"because Inform would read '2 + 2' as arithmetic, not a name.");
Problems__issue_problem_end();
} else {
Semantics__Nouns__ExcerptMeanings__register_noun(EQUATION_MC,
NA, Rvalues__from_equation(eqn));
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(EQUATION_MC,
Preform__Nonparsing__merge(equation_names_construction_NTM, 0,
WordAssemblages__from_wording(NA)),
Rvalues__from_equation(eqn));
}
}
}
#line 181 "inform7/Chapter 26/Equations.w"
;
if (Preform__parse_nt_against_word_range(equation_where_NTM, W, NULL, NULL)) {
W = GET_RW(equation_where_NTM, 1);
Equations__set_wherewithal(eqn, GET_RW(equation_where_NTM, 2));
}
}
eqn->equation_no_text = NO;
eqn->equation_name_text = NA;
if (Preform__parse_nt_against_word_range(text_ending_in_comma_NTM, W, NULL, NULL)) W = GET_RW(text_ending_in_comma_NTM, 1);
eqn->equation_text = W;
return eqn;
}
#line 198 "inform7/Chapter 26/Equations.w"
int text_ending_in_comma_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 200 "inform7/Chapter 26/Equations.w"
#line 242 "inform7/Chapter 26/Equations.w"
int equation_names_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 245 "inform7/Chapter 26/Equations.w"
#line 281 "inform7/Chapter 26/Equations.w"
void Equations__set_wherewithal(equation *eqn, wording W) {
eqn->where_text = W;
}
#line 290 "inform7/Chapter 26/Equations.w"
void Equations__traverse_to_stock(void) {
equation *eqn;
LOOP_OVER(eqn, equation) {
current_sentence = eqn->equation_created_at;
Equations__examine(eqn);
}
}
#line 305 "inform7/Chapter 26/Equations.w"
void Equations__examine(equation *eqn) {
if (eqn->examined_already) return;
eqn->examined_already = TRUE;
if (Equations__eqn_declare_symbols(eqn) == FALSE) return;
Equations__eqn_declare_standard_symbols();
eqn->parsed_equation = Equations__eqn_parse(eqn);
if (eqn->parsed_equation == NULL) return;
if (Equations__eqn_typecheck(eqn) == FALSE) Equations__log_equation_node(eqn->parsed_equation);
}
#line 325 "inform7/Chapter 26/Equations.w"
int equation_where_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 327 "inform7/Chapter 26/Equations.w"
#line 332 "inform7/Chapter 26/Equations.w"
int Equations__eqn_declare_symbols(equation *eqn) {
if (Wordings__empty(eqn->where_text)) return TRUE;
int result = Equations__eqn_declare_variables_inner(eqn, eqn->where_text, FALSE);
int changed = TRUE;
while (changed) {
changed = FALSE;
for (equation_symbol *ev = eqn->symbol_list; ev; ev = ev->next)
if (ev->var_kind == NULL) {
if (ev->next == NULL) {
Problems__Issue__equation_symbol_problem(_p_(BelievedImpossible),
eqn, eqn->where_text,
"each symbol in a equation has to be declared with a kind of "
"value or else an actual value. So '...where N = 1701.' or "
"'...where N, M are numbers.' would be fine.");
result = FALSE;
} else {
ev->var_kind = ev->next->var_kind;
ev->var_const = ev->next->var_const;
changed = TRUE;
}
}
}
return result;
}
#line 372 "inform7/Chapter 26/Equations.w"
equation *equation_being_declared = NULL;
int equation_declared_temporarily = FALSE;
int eq_symbol_wn = -1;
#line 388 "inform7/Chapter 26/Equations.w"
int equation_where_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; eq_symbol_wn = Wordings__first_wn(W); return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 392 "inform7/Chapter 26/Equations.w"
int equation_where_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 396 "inform7/Chapter 26/Equations.w"
int equation_where_setting_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; if (!preform_lookahead_mode) Equations__eqn_dec_var(equation_being_declared, Wordings__one_word(eq_symbol_wn), R[1], RP[1]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 399 "inform7/Chapter 26/Equations.w"
int equation_where_setting_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = EQW_IDENTIFIES_KIND; *XP = RP[2]; eq_symbol_wn = R[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = EQW_IDENTIFIES_VALUE; *XP = RP[2]; eq_symbol_wn = R[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 417 "inform7/Chapter 26/Equations.w"
*X = EQW_IDENTIFIES_PROBLEM;
if (!preform_lookahead_mode)
Problems__Issue__equation_symbol_problem(_p_(PM_EquationSymbolNonValue),
equation_being_declared, Wordings__one_word(R[1]),
"this has neither a kind of value nor an actual value.");
}
#line 403 "inform7/Chapter 26/Equations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 426 "inform7/Chapter 26/Equations.w"
*X = EQW_IDENTIFIES_PROBLEM;
if (!preform_lookahead_mode)
Problems__Issue__equation_symbol_problem(_p_(PM_EquationSymbolEqualsKOV),
equation_being_declared, Wordings__one_word(R[1]),
"'is' should be used, not '=', for a kind of value rather "
"than an actual value.");
}
#line 404 "inform7/Chapter 26/Equations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = EQW_IDENTIFIES_VALUE; *XP = RP[2]; eq_symbol_wn = R[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 417 "inform7/Chapter 26/Equations.w"
*X = EQW_IDENTIFIES_PROBLEM;
if (!preform_lookahead_mode)
Problems__Issue__equation_symbol_problem(_p_(PM_EquationSymbolNonValue),
equation_being_declared, Wordings__one_word(R[1]),
"this has neither a kind of value nor an actual value.");
}
#line 406 "inform7/Chapter 26/Equations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = EQW_IDENTIFIES_NOTHING; eq_symbol_wn = R[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 408 "inform7/Chapter 26/Equations.w"
int equation_symbol_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 436 "inform7/Chapter 26/Equations.w"
*X = -1;
if (!preform_lookahead_mode)
Problems__Issue__equation_symbol_problem(_p_(PM_EquationSymbolMalformed),
equation_being_declared, W,
"a symbol in a equation has to be a sequence of one to ten "
"letters optionally followed by a number from 0 to 99, so "
"'G', 'm', 'pi' and 'KE1' are all legal symbol names. But "
"this one is not.");
}
#line 411 "inform7/Chapter 26/Equations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 448 "inform7/Chapter 26/Equations.w"
*X = -1;
if (!preform_lookahead_mode)
Problems__Issue__sentence_problem(_p_(PM_EquationSymbolMisdeclared),
"the symbols here are not declared properly",
"and should each be declared with a kind of value or else an "
"actual value.");
}
#line 412 "inform7/Chapter 26/Equations.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 413 "inform7/Chapter 26/Equations.w"
#line 463 "inform7/Chapter 26/Equations.w"
int Equations__eqn_declare_variables_inner(equation *eqn, wording W, int temp) {
equation_being_declared = eqn;
equation_declared_temporarily = temp;
int pc = problem_count;
Preform__parse_nt_against_word_range(equation_where_list_NTM, W, NULL, NULL);
if (problem_count > pc) return FALSE;
return TRUE;
}
int Equations__eqn_dec_var(equation *eqn, wording W, int X, void *XP) {
parse_node *spec = NULL;
kind *K = NULL;
int temp = equation_declared_temporarily;
if ((X == EQW_IDENTIFIES_PROBLEM) || (Wordings__empty(W))) return FALSE;
if (X != EQW_IDENTIFIES_NOTHING)
{
#line 499 "inform7/Chapter 26/Equations.w"
spec = NULL;
if (X == EQW_IDENTIFIES_KIND) {
K = XP;
if (temp) {
Problems__Issue__equation_symbol_problem(_p_(PM_EquationSymbolVague), eqn, W,
"when an equation is named for use in a 'let' "
"phrase, any variables listed under 'where...' have "
"to be given definite values, not just vaguely said "
"to have particular kinds. Otherwise, I can't do any "
"calculation with them.");
return FALSE;
}
}
if (X == EQW_IDENTIFIES_VALUE) {
spec = XP;
K = Specifications__to_kind(spec);
}
if ((K) && (Kinds__Behaviour__is_quasinumerical(K) == FALSE)) {
Problems__Issue__equation_symbol_problem(_p_(PM_EquationSymbolNonNumeric), eqn, W,
"this has a kind of value on which arithmetic cannot be done, "
"so it can have no place in an equation.");
return FALSE;
}
}
#line 478 "inform7/Chapter 26/Equations.w"
;
if (temp)
{
#line 528 "inform7/Chapter 26/Equations.w"
for (equation_symbol *ev = eqn->symbol_list; ev; ev = ev->next)
if (Wordings__match_cs(W, ev->name)) {
if (Kinds__Compare__eq(K, ev->var_kind) == FALSE) {
Problems__Issue__equation_symbol_problem(_p_(PM_EquationSymbolBadSub), eqn, W,
"you're using 'where' to substitute something into this "
"symbol which has the wrong kind of value.");
}
ev->temp_constant = TRUE;
ev->var_const = spec;
return TRUE;
}
Problems__Issue__equation_symbol_problem(_p_(PM_EquationSymbolSpurious), eqn, W,
"when 'where' is used to supply values to plug into a "
"named equation as part of a 'let' phrase, you can only "
"supply values for symbols actually used in that equation. "
"This one doesn't seem to occur there.");
return FALSE;
}
#line 480 "inform7/Chapter 26/Equations.w"
else Equations__eqn_add_symbol(eqn, W, K, spec);
return TRUE;
}
#line 550 "inform7/Chapter 26/Equations.w"
void Equations__eqn_remove_temp_variables(equation *eqn) {
for (equation_symbol *ev = eqn->symbol_list; ev; ev = ev->next)
if (ev->temp_constant) {
ev->var_const = NULL;
ev->temp_constant = FALSE;
}
}
#line 571 "inform7/Chapter 26/Equations.w"
void Equations__declare_local_variables(equation *eqn) {
LocalVariables__make_available_to_equation(eqn);
}
/* which calls the following for each current local variable in turn: */
void Equations__declare_local(equation *eqn, wording W, kind *K) {
if ((Equations__equation_symbol_legal(W)) && (Kinds__Behaviour__is_quasinumerical(K)))
Equations__eqn_add_symbol(eqn, W, K, NULL);
}
#line 585 "inform7/Chapter 26/Equations.w"
void Equations__eqn_declare_standard_symbols(void) {
if (standard_equation_symbols) return;
wording TCW = Feeds__feed_text("e pi");
LOOP_THROUGH_WORDING(i, TCW) {
wording V = Wordings__one_word(i);
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, V, NULL, NULL)) {
parse_node *spec = most_recent_result_p;
Equations__eqn_add_symbol(NULL, V, K_real_number, spec);
}
}
phrase *ph;
LOOP_OVER(ph, phrase) {
wording W = Phrases__Usage__get_equation_form(&(ph->usage_data));
if (Wordings__nonempty(W)) {
equation_symbol *ev = Equations__eqn_add_symbol(NULL, W, K_real_number, NULL);
ev->function_notated = ph;
}
}
}
#line 610 "inform7/Chapter 26/Equations.w"
equation_symbol *Equations__eqn_add_symbol(equation *eqn, wording W, kind *K, parse_node *spec) {
W = Wordings__first_word(W);
equation_symbol **list_head = &standard_equation_symbols;
if (eqn) list_head = &(eqn->symbol_list);
equation_symbol *ev;
for (ev = *list_head; ev; ev = ev->next)
if (Wordings__match_cs(W, ev->name))
return ev;
ev = CREATE(equation_symbol);
ev->var_kind = K;
ev->function_notated = NULL;
ev->var_const = spec;
ev->next = NULL;
if (*list_head == NULL) *list_head = ev;
else {
equation_symbol *f = *list_head;
while ((f) && (f->next)) f = f->next;
f->next = ev;
}
ev->name = W;
ev->temp_constant = FALSE;
return ev;
}
#line 639 "inform7/Chapter 26/Equations.w"
int valid_equation_symbol_NTMR(wording W, int *X, void **XP) {
#line 640 "inform7/Chapter 26/Equations.w"
if (Equations__equation_symbol_legal(W)) { *X = Wordings__first_wn(W); return TRUE; }
return FALSE;
}
#line 647 "inform7/Chapter 26/Equations.w"
int Equations__equation_symbol_legal(wording W) {
if (Wordings__length(W) == 1) {
char *p = Lexer__word_raw_text(Wordings__first_wn(W));
int j, letters = 0, digits = 0, name_legal = TRUE;
for (j=0; p[j]; j++) {
char c = p[j];
if (Platform__isdigit(c)) digits++;
else if (Platform__isalpha(c)) { letters++; if (digits > 0) name_legal = FALSE; }
else name_legal = FALSE;
if (j >= 13) break;
}
if ((letters > 10) || (digits > 2)) name_legal = FALSE;
return name_legal;
}
return FALSE;
}
#line 669 "inform7/Chapter 26/Equations.w"
equation_node *Equations__enode_new(int t) {
equation_node *enode = CREATE(equation_node);
enode->eqn_type = t;
enode->eqn_operation = -1;
enode->enode_arity = 0;
enode->leaf_constant = NULL;
enode->leaf_symbol = NULL;
enode->enode_operands[0] = NULL;
enode->gK_before = Kinds__FloatingPoint__new_gk(K_value); /* unknown for now */
enode->gK_after = Kinds__FloatingPoint__new_gk(K_value); /* unknown for now */
enode->enode_promotion = FALSE;
enode->rational_n = 0;
enode->rational_m = 0;
return enode;
}
#line 689 "inform7/Chapter 26/Equations.w"
equation_node *Equations__enode_new_op(int op) {
equation_node *enode = Equations__enode_new(OPERATION_EQN);
enode->eqn_operation = op;
return enode;
}
equation_node *Equations__enode_new_symbol(equation_symbol *ev) {
equation_node *enode = Equations__enode_new(SYMBOL_EQN);
enode->leaf_symbol = ev;
return enode;
}
equation_node *Equations__enode_new_constant(parse_node *spec) {
equation_node *enode = Equations__enode_new(CONSTANT_EQN);
enode->leaf_constant = spec;
return enode;
}
#line 711 "inform7/Chapter 26/Equations.w"
void Equations__log_equation_node(equation_node *tok) {
Equations__log_equation_node_inner(tok, 0);
}
void Equations__log_equation_node_inner(equation_node *tok, int d) {
for (int i=0; i<d; i++) if (i+1<d) LOG(" "); else LOG("+---");
if (tok == NULL) { LOG("<NULL>\n"); return; }
if (tok->eqn_type == OPERATION_EQN) {
switch (tok->eqn_operation) {
case PLUS_OPERATION: LOG("<add>"); break;
case MINUS_OPERATION: LOG("<subtract>"); break;
case DIVIDE_OPERATION: LOG("<divide>"); break;
case TIMES_OPERATION: LOG("<multiply>"); break;
case IMPLICIT_TIMES_OPERATION: LOG("<implicitly multiply>"); break;
case IMPLICIT_APPLICATION_OPERATION: LOG("<apply function>"); break;
case EQUALS_OPERATION: LOG("<set equal>"); break;
case ROOT_OPERATION: LOG("<square root>"); break;
case REALROOT_OPERATION: LOG("<real square root>"); break;
case CUBEROOT_OPERATION: LOG("<cube root>"); break;
case POWER_OPERATION: LOG("<to the power>"); break;
case UNARY_MINUS_OPERATION: LOG("<unary subtraction>"); break;
default: LOG("<op-%d>", tok->eqn_operation); break;
}
} else if (tok->eqn_type == SYMBOL_EQN) LOG("<symbol-$w>", tok->leaf_symbol->name);
else if (tok->eqn_type == CONSTANT_EQN) LOG("<constant-$P>", tok->leaf_constant);
else if (tok->eqn_type == OPEN_BRACKET_EQN) LOG("<open-bracket>");
else if (tok->eqn_type == CLOSE_BRACKET_EQN) LOG("<close-bracket>");
else if (tok->eqn_type == END_EQN) LOG("<end>");
else { LOG("<bad-eqn>\n"); return; }
LOG(" : ");
Kinds__FloatingPoint__log_gk(tok->gK_before);
LOG(", ");
Kinds__FloatingPoint__log_gk(tok->gK_after);
LOG("\n");
if (tok->eqn_type == OPERATION_EQN)
for (int i=0; i<tok->enode_arity; i++)
Equations__log_equation_node_inner(tok->enode_operands[i], d+1);
}
#line 763 "inform7/Chapter 26/Equations.w"
equation_node *Equations__eqn_parse(equation *eqn) {
wording W = eqn->equation_text;
Equations__enode_sr_start(); /* start the shift-reduce parser */
equation_node *previous_token = NULL;
int enode_count = 0; /* number of tokens shipped so far */
int bl = 0; /* bracket nesting level */
int wn = Wordings__first_wn(W), i = 0; char *p = NULL;
while ((wn <= Wordings__last_wn(W)) || (p)) {
if (p == NULL) { i = 0; p = Lexer__word_raw_text(wn++); }
/* we are now at character |i| in string |p|, while |wn| is the next word */
equation_node *token = NULL;
{
#line 798 "inform7/Chapter 26/Equations.w"
char c = p[i];
if (Platform__isalpha(c))
{
#line 810 "inform7/Chapter 26/Equations.w"
char text_of_symbol[16];
int j; /* the length of the symbol name we try to break off */
for (j=0; (j<14) && (isalnum(p[i+j])) && (token == NULL); j++)
text_of_symbol[j] = p[i+j];
text_of_symbol[j] = 0;
for (equation_symbol *ev = standard_equation_symbols; ev; ev = ev->next)
{
#line 838 "inform7/Chapter 26/Equations.w"
if (Text__compare_raw_word_by_strcmp(Wordings__first_wn(ev->name), text_of_symbol)) {
token = Equations__enode_new_symbol(ev);
i += j;
break;
}
}
#line 816 "inform7/Chapter 26/Equations.w"
;
if (token == NULL)
for (j=1; (j<15) && (isalnum(p[i+j-1])) && (token == NULL); j++) {
/* copy the first |j| characters into a C string: */
int k; for (k=0; k<j; k++) text_of_symbol[k] = p[i+k];
text_of_symbol[j] = 0;
/* try to identify this as one of the declared symbols: */
equation_symbol *ev;
for (ev = eqn->symbol_list; ev; ev = ev->next)
{
#line 838 "inform7/Chapter 26/Equations.w"
if (Text__compare_raw_word_by_strcmp(Wordings__first_wn(ev->name), text_of_symbol)) {
token = Equations__enode_new_symbol(ev);
i += j;
break;
}
}
#line 825 "inform7/Chapter 26/Equations.w"
;
}
if (token == NULL) {
Problems__Issue__equation_problem(_p_(PM_EquationTokenUnrecognised), eqn, text_of_symbol,
"the symbol '%3' is one that I don't recognise. It doesn't "
"seem to be declared after the equation - for instance, "
"by adding 'where %3 is a number'.");
return NULL;
}
}
#line 799 "inform7/Chapter 26/Equations.w"
else if (Platform__isdigit(c))
{
#line 849 "inform7/Chapter 26/Equations.w"
int j; /* again the length of the number we try to break off */
if ((p[i] == '0') && (isdigit(p[i+1]))) {
Problems__Issue__equation_problem(_p_(PM_EquationLeadingZero), eqn, "",
"a number in an equation isn't allowed to begin with a "
"'0' digit, so an equation like 'M = 007+Q' is against the rules.");
return NULL;
}
char text_of_number[32];
{
#line 876 "inform7/Chapter 26/Equations.w"
text_of_number[0] = ' ';
for (j=1; (j<30) && (isdigit(p[i])); j++) text_of_number[j] = p[i++];
if (p[i] == '.') {
text_of_number[j++] = p[i++];
while ((j<30) && (isdigit(p[i]))) text_of_number[j++] = p[i++];
}
if ((Literals__ismultiplicationsign(p[i])) && (p[i+1] == '1') && (p[i+2] == '0') && (p[i+3] == '^')) {
text_of_number[j++] = p[i++];
text_of_number[j++] = p[i++];
text_of_number[j++] = p[i++];
text_of_number[j++] = p[i++];
while ((j<30) && (isdigit(p[i]))) text_of_number[j++] = p[i++];
}
text_of_number[j++] = ' ';
text_of_number[j] = 0;
}
#line 858 "inform7/Chapter 26/Equations.w"
;
/* now sneakily add this to the word stream, and let the S-parser read it: */
wording NW = Feeds__feed_text(text_of_number);
parse_node *spec = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, NW, NULL, NULL)) spec = most_recent_result_p;
else {
Problems__Issue__equation_problem(_p_(BelievedImpossible), eqn, "",
"there's a literal number in that equation which doesn't make "
"sense to me.");
return NULL;
}
/* this can only go wrong if there was an overflow, and a problem will have been issued for that: */
if (ParseTree__is(spec, CONSTANT_VNT) == FALSE) return NULL;
token = Equations__enode_new_constant(spec);
}
#line 800 "inform7/Chapter 26/Equations.w"
else
{
#line 895 "inform7/Chapter 26/Equations.w"
switch (c) {
case '=': token = Equations__enode_new_op(EQUALS_OPERATION); break;
case '+': token = Equations__enode_new_op(PLUS_OPERATION); break;
case '-':
if ((previous_token == NULL) ||
(previous_token->eqn_type == OPERATION_EQN) ||
(previous_token->eqn_type == OPEN_BRACKET_EQN))
token = Equations__enode_new_op(UNARY_MINUS_OPERATION);
else
token = Equations__enode_new_op(MINUS_OPERATION); break;
case '/': token = Equations__enode_new_op(DIVIDE_OPERATION); break;
case '*': token = Equations__enode_new_op(TIMES_OPERATION); break;
case '^': token = Equations__enode_new_op(POWER_OPERATION); break;
case '(': token = Equations__enode_new(OPEN_BRACKET_EQN); bl++; break;
case ')': token = Equations__enode_new(CLOSE_BRACKET_EQN); bl--; break;
default: {
char symbol[2]; symbol[0] = c; symbol[1] = 0;
Problems__Issue__equation_problem(_p_(PM_EquationOperatorUnrecognised), eqn, symbol,
"the symbol '%3' is one that I don't recognise. I was "
"expecting an arithmetic sign, '+', '-', '*','/', or '^', "
"or else '=' or a bracket '(' or ')'.");
LOG("Bad operator '%c'\n", c); return NULL;
}
}
i++;
}
#line 801 "inform7/Chapter 26/Equations.w"
;
}
#line 777 "inform7/Chapter 26/Equations.w"
;
{
#line 927 "inform7/Chapter 26/Equations.w"
if (Equations__application_is_implied(previous_token, token)) {
if (Equations__enode_sr_token(eqn, Equations__enode_new_op(IMPLICIT_APPLICATION_OPERATION)) == FALSE)
{
#line 951 "inform7/Chapter 26/Equations.w"
Problems__Issue__equation_problem(_p_(PM_EquationMispunctuated), eqn, "",
"this seems to be wrongly punctuated, and doesn't make sense as a "
"mathematical formula.");
return NULL;
}
#line 929 "inform7/Chapter 26/Equations.w"
;
enode_count++;
} else if (Equations__multiplication_is_implied(previous_token, token)) {
if (Equations__enode_sr_token(eqn, Equations__enode_new_op(IMPLICIT_TIMES_OPERATION)) == FALSE)
{
#line 951 "inform7/Chapter 26/Equations.w"
Problems__Issue__equation_problem(_p_(PM_EquationMispunctuated), eqn, "",
"this seems to be wrongly punctuated, and doesn't make sense as a "
"mathematical formula.");
return NULL;
}
#line 933 "inform7/Chapter 26/Equations.w"
;
enode_count++;
}
if (Equations__enode_sr_token(eqn, token) == FALSE)
{
#line 951 "inform7/Chapter 26/Equations.w"
Problems__Issue__equation_problem(_p_(PM_EquationMispunctuated), eqn, "",
"this seems to be wrongly punctuated, and doesn't make sense as a "
"mathematical formula.");
return NULL;
}
#line 938 "inform7/Chapter 26/Equations.w"
;
enode_count++;
if (enode_count >= MAX_ENODES_IN_EXPRESSION - 2) {
Problems__Issue__equation_problem(_p_(PM_EquationTooComplex), eqn, "",
"this is too long and complex an equation.");
return NULL;
}
}
#line 778 "inform7/Chapter 26/Equations.w"
;
previous_token = token;
if (p[i] == 0) p = NULL;
}
if (Equations__enode_sr_token(eqn, Equations__enode_new(END_EQN)) == FALSE)
{
#line 951 "inform7/Chapter 26/Equations.w"
Problems__Issue__equation_problem(_p_(PM_EquationMispunctuated), eqn, "",
"this seems to be wrongly punctuated, and doesn't make sense as a "
"mathematical formula.");
return NULL;
}
#line 784 "inform7/Chapter 26/Equations.w"
;
equation_node *result = Equations__enode_sr_result();
if (bl != 0) {
Problems__Issue__equation_problem(_p_(BelievedImpossible), eqn, "",
"this seems to use brackets in a mismatched way, since there "
"are different numbers of left and right brackets '(' and ')'.");
return NULL;
}
return result;
}
#line 959 "inform7/Chapter 26/Equations.w"
int Equations__multiplication_is_implied(equation_node *previous_token, equation_node *token) {
int lt, rt;
if ((token == NULL) || (previous_token == NULL)) return FALSE;
lt = previous_token->eqn_type; rt = token->eqn_type;
if (((lt == SYMBOL_EQN) || (lt == CONSTANT_EQN) || (lt == CLOSE_BRACKET_EQN)) &&
((rt == SYMBOL_EQN) || (rt == CONSTANT_EQN) || (rt == OPEN_BRACKET_EQN)))
return TRUE;
return FALSE;
}
#line 972 "inform7/Chapter 26/Equations.w"
int Equations__application_is_implied(equation_node *previous_token, equation_node *token) {
int lt, rt;
if ((token == NULL) || (previous_token == NULL)) return FALSE;
lt = previous_token->eqn_type; rt = token->eqn_type;
if ((lt == SYMBOL_EQN) && (previous_token->leaf_symbol->function_notated)) return TRUE;
return FALSE;
}
#line 999 "inform7/Chapter 26/Equations.w"
int SR_sp = 0;
equation_node *SR_stack[MAX_ENODES_IN_EXPRESSION+2];
int emitter_sp = 0;
equation_node *emitter_stack[MAX_ENODES_IN_EXPRESSION+2];
void Equations__log_sr_stacks(void) {
int i;
LOG("SR: ");
for (i=0; i<SR_sp; i++) { LOG(" %d: ", i); Equations__log_equation_node(SR_stack[i]); }
LOG("EMITTER: ");
for (i=0; i<emitter_sp; i++) { LOG(" %d: ", i); Equations__log_equation_node(emitter_stack[i]); }
}
#line 1020 "inform7/Chapter 26/Equations.w"
void Equations__enode_sr_start(void) {
SR_stack[0] = Equations__enode_new(END_EQN);
SR_sp = 1;
emitter_sp = 0;
}
#line 1030 "inform7/Chapter 26/Equations.w"
equation_node *Equations__enode_sr_result(void) {
return emitter_stack[0];
}
#line 1054 "inform7/Chapter 26/Equations.w"
int Equations__enode_sr_token(equation *eqn, equation_node *tok) {
int safety_cutout = 3*MAX_ENODES_IN_EXPRESSION;
while (TRUE) {
if (SR_sp <= 0) internal_error("SR stack empty");
if ((SR_stack[SR_sp-1]->eqn_type == END_EQN) && (tok->eqn_type == END_EQN)) break;
if ((Equations__enode_lt(SR_stack[SR_sp-1], tok)) || (Equations__enode_eq(SR_stack[SR_sp-1], tok)))
{
#line 1079 "inform7/Chapter 26/Equations.w"
SR_stack[SR_sp++] = tok;
return TRUE;
}
#line 1063 "inform7/Chapter 26/Equations.w"
else if (Equations__enode_gt(SR_stack[SR_sp-1], tok))
{
#line 1094 "inform7/Chapter 26/Equations.w"
do { if (SR_sp <= 1) return FALSE;
if (Equations__enode_emit(SR_stack[--SR_sp]) == FALSE) return FALSE;
} while ((SR_sp >= 1) && (Equations__enode_lt(SR_stack[SR_sp-1], SR_stack[SR_sp]) == FALSE));
}
#line 1065 "inform7/Chapter 26/Equations.w"
else return FALSE;
if (safety_cutout-- < 0) internal_error("SR parser deadlocked");
}
if ((emitter_sp != 1) || (SR_sp != 1)) return FALSE;
return TRUE;
}
#line 1106 "inform7/Chapter 26/Equations.w"
int Equations__enode_emit(equation_node *tok) {
switch (tok->eqn_type) {
case SYMBOL_EQN: case CONSTANT_EQN:
emitter_stack[emitter_sp++] = tok;
break;
case OPERATION_EQN:
if (tok->eqn_operation == IMPLICIT_TIMES_OPERATION)
tok->eqn_operation = TIMES_OPERATION;
if (tok->eqn_operation == IMPLICIT_APPLICATION_OPERATION)
tok->enode_arity = 2;
else if (Kinds__Dimensions__arithmetic_op_is_unary(tok->eqn_operation))
tok->enode_arity = 1;
else
tok->enode_arity = 2;
int i;
for (i = tok->enode_arity - 1; i >= 0; i--) {
emitter_sp--;
if (emitter_sp < 0) return FALSE;
tok->enode_operands[i] = emitter_stack[emitter_sp];
}
emitter_stack[emitter_sp++] = tok;
break;
}
return TRUE;
}
#line 1146 "inform7/Chapter 26/Equations.w"
int Equations__enode_lt(equation_node *tok1, equation_node *tok2) {
int f_left = Equations__f_function(tok1), g_right = Equations__g_function(tok2);
if (f_left < g_right) return TRUE; return FALSE;
}
int Equations__enode_eq(equation_node *tok1, equation_node *tok2) {
int f_left = Equations__f_function(tok1), g_right = Equations__g_function(tok2);
if (f_left == g_right) return TRUE; return FALSE;
}
int Equations__enode_gt(equation_node *tok1, equation_node *tok2) {
int f_left = Equations__f_function(tok1), g_right = Equations__g_function(tok2);
if (f_left > g_right) return TRUE; return FALSE;
}
#line 1173 "inform7/Chapter 26/Equations.w"
int Equations__f_function(equation_node *tok) {
switch (tok->eqn_type) {
case SYMBOL_EQN: case CONSTANT_EQN: return 16;
case OPERATION_EQN:
switch (tok->eqn_operation) {
case EQUALS_OPERATION: return 2;
case PLUS_OPERATION: case MINUS_OPERATION: return 4;
case TIMES_OPERATION: case DIVIDE_OPERATION: return 6;
case IMPLICIT_TIMES_OPERATION: return 8;
case POWER_OPERATION: return 9;
case IMPLICIT_APPLICATION_OPERATION: return 5;
case UNARY_MINUS_OPERATION: return 1;
}
internal_error("unknown operator precedence");
case OPEN_BRACKET_EQN: return 0;
case CLOSE_BRACKET_EQN: return 16;
case END_EQN: return 0;
}
internal_error("unknown f-value"); return 0;
}
#line 1197 "inform7/Chapter 26/Equations.w"
int Equations__g_function(equation_node *tok) {
switch (tok->eqn_type) {
case SYMBOL_EQN: case CONSTANT_EQN: return 15;
case OPERATION_EQN:
if (tok) switch (tok->eqn_operation) {
case EQUALS_OPERATION: return 1;
case PLUS_OPERATION: case MINUS_OPERATION: return 3;
case TIMES_OPERATION: case DIVIDE_OPERATION: return 5;
case IMPLICIT_TIMES_OPERATION: return 7;
case POWER_OPERATION: return 10;
case IMPLICIT_APPLICATION_OPERATION: return 14;
case UNARY_MINUS_OPERATION: return 12;
}
internal_error("unknown operator precedence");
case OPEN_BRACKET_EQN: return 15;
case CLOSE_BRACKET_EQN: return 0;
case END_EQN: return 0;
}
internal_error("unknown g-value"); return 0;
}
#line 1224 "inform7/Chapter 26/Equations.w"
int Equations__eqn_typecheck(equation *eqn) {
switch (Equations__enode_count_equals(eqn->parsed_equation)) {
case 0:
Problems__Issue__equation_problem(_p_(PM_EquationDoesntEquate), eqn, "",
"this equation doesn't seem to contain an equals sign, and "
"without '=' there is no equating anything with anything.");
return FALSE;
case 1:
if (Equations__enode_is_equals(eqn->parsed_equation) == FALSE) {
Problems__Issue__equation_problem(_p_(PM_EquationEquatesBadly), eqn, "",
"the equals sign '=' here seems to be buried inside the "
"formula, not at the surface. For instance, 'F = ma' is "
"fine, but 'F(m=a)' would not make sense - the '=' would "
"be inside brackets.");
return FALSE;
}
break;
default:
Problems__Issue__equation_problem(_p_(PM_EquationEquatesMultiply), eqn, "",
"this equation seems to contain more than one equals "
"sign '='.");
return FALSE;
}
return Equations__enode_typecheck(eqn, eqn->parsed_equation);
}
#line 1254 "inform7/Chapter 26/Equations.w"
int Equations__enode_count_equals(equation_node *tok) {
int c = 0, i;
if (tok) {
if (Equations__enode_is_equals(tok)) c++;
for (i=0; i<tok->enode_arity; i++)
c += Equations__enode_count_equals(tok->enode_operands[i]);
}
return c;
}
int Equations__enode_is_equals(equation_node *tok) {
if (tok == NULL) return FALSE;
if ((tok->eqn_type == OPERATION_EQN) && (tok->eqn_operation == EQUALS_OPERATION))
return TRUE;
return FALSE;
}
#line 1277 "inform7/Chapter 26/Equations.w"
int float_terminal_nodes = FALSE;
int Equations__enode_typecheck(equation *eqn, equation_node *tok) {
int result = TRUE;
if (tok == NULL) return result;
LOG_INDENT;
int i;
for (i=0; i<tok->enode_arity; i++)
if (Equations__enode_typecheck(eqn, tok->enode_operands[i]) == FALSE)
result = FALSE;
if (result) {
switch (tok->eqn_type) {
case SYMBOL_EQN:
tok->gK_before =
Kinds__FloatingPoint__new_gk(tok->leaf_symbol->var_kind);
break;
case CONSTANT_EQN:
tok->gK_before =
Kinds__FloatingPoint__new_gk(
ParseTree__get_kind_of_value(tok->leaf_constant));
if ((tok->enode_promotion) && (VirtualMachines__supports(K_real_number)))
tok->gK_before =
Kinds__FloatingPoint__to_real(tok->gK_before);
break;
case OPERATION_EQN:
if (tok->eqn_operation == EQUALS_OPERATION)
{
#line 1326 "inform7/Chapter 26/Equations.w"
kind *L = Kinds__FloatingPoint__underlying(tok->enode_operands[0]->gK_after);
kind *R = Kinds__FloatingPoint__underlying(tok->enode_operands[1]->gK_after);
L = Kinds__FloatingPoint__integer_equivalent(L);
R = Kinds__FloatingPoint__integer_equivalent(R);
if (Kinds__Compare__eq(L, R) == FALSE) {
result = FALSE;
LOG("Tried to equate $u and $u\n", L, R);
Problems__Issue__equation_problem(_p_(PM_EquationIncomparable), eqn, "",
"this equation tries to set two values equal which have "
"different kinds from each other.");
}
int lf = Kinds__FloatingPoint__is_real(tok->enode_operands[0]->gK_after);
int rf = Kinds__FloatingPoint__is_real(tok->enode_operands[1]->gK_after);
if ((lf == TRUE) && (rf == FALSE)) Equations__promote_subequation(eqn, tok->enode_operands[1], TRUE);
if ((lf == FALSE) && (rf == TRUE)) Equations__demote_subequation(eqn, tok->enode_operands[1]);
tok->gK_before = tok->enode_operands[0]->gK_after;
}
#line 1303 "inform7/Chapter 26/Equations.w"
else if (tok->eqn_operation == POWER_OPERATION)
{
#line 1349 "inform7/Chapter 26/Equations.w"
equation_node *base = tok->enode_operands[0];
equation_node *power = tok->enode_operands[1];
if (Kinds__Dimensions__dimensionless(Kinds__FloatingPoint__underlying(base->gK_after))) {
tok->gK_before = base->gK_after;
tok->gK_after = base->gK_after;
} else
{
#line 1395 "inform7/Chapter 26/Equations.w"
kind *F =
Kinds__FloatingPoint__integer_equivalent(
Kinds__FloatingPoint__underlying(
base->gK_after));
int real = FALSE;
if (Kinds__FloatingPoint__is_real(base->gK_after)) real = TRUE;
int n = -1, m = 1;
if (power->rational_m != 0) {
n = power->rational_n; m = power->rational_m;
if ((m > 1) && (real == FALSE)) {
result = FALSE;
Problems__Issue__equation_problem(_p_(PM_EquationCantPower2-G), eqn, "",
"except for the special cases of squaring and cubing, the '^' "
"raise-to-power symbol can only be used to power a value using "
"real rather than integer arithmetic.");
}
} else if ((Kinds__Compare__eq(Kinds__FloatingPoint__underlying(power->gK_after), K_number) == FALSE) ||
(power->eqn_type != CONSTANT_EQN)) {
result = FALSE;
Problems__Issue__equation_problem(_p_(PM_EquationDimensionPower), eqn, "",
"the '^' raise-to-power symbol can only be used to raise a value "
"with dimensions to a specific number. So 'mv^2' is fine, but not "
"'mv^n' or 'mv^(1+n)'. (This is because I would need to work out what "
"kind of value 'v^n' would be, and the answer would depend on 'n', "
"but I wouldn't know what 'n' is.)");
} else {
n = Rvalues__to_int(power->leaf_constant);
}
if (n >= 1) {
kind *K = Kinds__Dimensions__to_rational_power(F, n, m);
if (K == NULL) {
Problems__Issue__equation_problem(_p_(BelievedImpossible), eqn, "",
"this would involve taking a fractional power of an amount whose "
"dimensions are not of that power form - for example, the square "
"root of the area 100 sq m makes sense (it's 10m), but the square "
"root of 4m doesn't make sense, because what's a square root of "
"a meter?");
return FALSE;
}
if (real)
tok->gK_before =
Kinds__FloatingPoint__to_real(
Kinds__FloatingPoint__new_gk(K));
else
tok->gK_before =
Kinds__FloatingPoint__new_gk(K);
}
}
#line 1355 "inform7/Chapter 26/Equations.w"
;
int lf = Kinds__FloatingPoint__is_real(tok->enode_operands[0]->gK_after);
int rf = Kinds__FloatingPoint__is_real(tok->enode_operands[1]->gK_after);
if ((lf == TRUE) && (rf == FALSE)) Equations__promote_subequation(eqn, tok->enode_operands[1], FALSE);
if ((lf == FALSE) && (rf == TRUE)) Equations__promote_subequation(eqn, tok->enode_operands[0], FALSE);
if ((Kinds__FloatingPoint__is_real(tok->gK_after) == FALSE) && ((lf) || (rf))) {
tok->gK_before = Kinds__FloatingPoint__to_real(tok->gK_before);
}
}
#line 1305 "inform7/Chapter 26/Equations.w"
else if (tok->eqn_operation == IMPLICIT_APPLICATION_OPERATION)
{
#line 1367 "inform7/Chapter 26/Equations.w"
equation_node *fn = tok->enode_operands[0];
if ((fn->eqn_type == SYMBOL_EQN) && (fn->leaf_symbol->function_notated)) {
phrase *ph = fn->leaf_symbol->function_notated;
kind *RK;
if (Phrases__TypeData__arithmetic_operation(ph) == REALROOT_OPERATION) {
kind *OPK = Kinds__FloatingPoint__underlying(tok->enode_operands[1]->gK_after);
RK = Kinds__Dimensions__arithmetic_on_kinds(OPK, NULL, REALROOT_OPERATION);
if (RK == NULL) {
Problems__Issue__equation_problem(_p_(PM_EquationCantRoot-G), eqn, "",
"the square root function 'root' can only be used on quantities "
"whose dimensions are themselves a square - for example, the "
"root of the area 100 sq m makes sense (it's 10m), but the root "
"of 4m doesn't make sense, because what's a square root of a meter?");
return FALSE;
}
} else {
RK = Phrases__TypeData__get_return_kind(&(ph->type_data));
}
tok->gK_before = Kinds__FloatingPoint__to_real(Kinds__FloatingPoint__new_gk(RK));
}
int rf = Kinds__FloatingPoint__is_real(tok->enode_operands[1]->gK_after);
if (rf == FALSE) Equations__promote_subequation(eqn, tok->enode_operands[1], FALSE);
}
#line 1307 "inform7/Chapter 26/Equations.w"
else
{
#line 1448 "inform7/Chapter 26/Equations.w"
kind *K = NULL;
kind *O1 =
Kinds__FloatingPoint__integer_equivalent(
Kinds__FloatingPoint__underlying(
tok->enode_operands[0]->gK_after));
int real = FALSE;
if (Kinds__FloatingPoint__is_real(tok->enode_operands[0]->gK_after))
real = TRUE;
if (Kinds__Dimensions__arithmetic_op_is_unary(tok->eqn_operation))
K = Kinds__Dimensions__arithmetic_on_kinds(O1, NULL, tok->eqn_operation);
else {
kind *O2 =
Kinds__FloatingPoint__integer_equivalent(
Kinds__FloatingPoint__underlying(
tok->enode_operands[1]->gK_after));
if (Kinds__FloatingPoint__is_real(tok->enode_operands[1]->gK_after))
real = TRUE;
K = Kinds__Dimensions__arithmetic_on_kinds(O1, O2, tok->eqn_operation);
int lf = Kinds__FloatingPoint__is_real(tok->enode_operands[0]->gK_after);
int rf = Kinds__FloatingPoint__is_real(tok->enode_operands[1]->gK_after);
if ((lf == TRUE) && (rf == FALSE)) Equations__promote_subequation(eqn, tok->enode_operands[1], FALSE);
if ((lf == FALSE) && (rf == TRUE)) Equations__promote_subequation(eqn, tok->enode_operands[0], FALSE);
}
if (K == NULL) {
result = FALSE;
tok->gK_before = Kinds__FloatingPoint__new_gk(K_value);
LOG("Failed at operation:\n"); Equations__log_equation_node(tok);
if (Kinds__Dimensions__arithmetic_op_is_unary(tok->eqn_operation))
{
#line 1490 "inform7/Chapter 26/Equations.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(4,
Kinds__FloatingPoint__underlying(tok->enode_operands[0]->gK_after));
switch(tok->eqn_operation) {
case UNARY_MINUS_OPERATION:
Problems__quote_text(6, "negating");
break;
case ROOT_OPERATION:
Problems__quote_text(6, "taking the square root of");
break;
case REALROOT_OPERATION:
Problems__quote_text(6, "taking the (real-valued) square root of");
break;
case CUBEROOT_OPERATION:
Problems__quote_text(6, "taking the cube root of");
break;
}
Problems__Issue__handmade_problem(_p_(BelievedImpossible));
Problems__issue_problem_segment(
"You wrote %1, but that equation seems to involve %6 %4, which is not "
"good arithmetic.");
Problems__issue_problem_end();
}
#line 1476 "inform7/Chapter 26/Equations.w"
else
{
#line 1516 "inform7/Chapter 26/Equations.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(4, Kinds__FloatingPoint__underlying(tok->enode_operands[0]->gK_after));
Problems__quote_kind(5, Kinds__FloatingPoint__underlying(tok->enode_operands[1]->gK_after));
switch(tok->eqn_operation) {
case PLUS_OPERATION:
Problems__quote_text(6, "adding"); Problems__quote_text(7, "to");
break;
case MINUS_OPERATION:
Problems__quote_text(6, "subtracting"); Problems__quote_text(7, "from");
break;
case TIMES_OPERATION:
Problems__quote_text(6, "multiplying"); Problems__quote_text(7, "by");
break;
case DIVIDE_OPERATION:
case REMAINDER_OPERATION:
Problems__quote_text(6, "dividing"); Problems__quote_text(7, "by");
break;
case POWER_OPERATION:
Problems__quote_text(6, "raising"); Problems__quote_text(7, "to the power of");
break;
default:
Problems__quote_text(6, "combining"); Problems__quote_text(7, "with");
break;
}
Problems__Issue__handmade_problem(_p_(PM_EquationBadArithmetic));
Problems__issue_problem_segment(
"You wrote %1, but that equation seems to involve "
"%6 %4 %7 %5, which is not good arithmetic.");
Problems__issue_problem_end();
}
#line 1478 "inform7/Chapter 26/Equations.w"
;
} else if (real)
tok->gK_before =
Kinds__FloatingPoint__to_real(
Kinds__FloatingPoint__new_gk(K));
else
tok->gK_before =
Kinds__FloatingPoint__new_gk(K);
}
#line 1309 "inform7/Chapter 26/Equations.w"
;
break;
default: internal_error("forbidden enode found in parsed equation");
}
}
tok->gK_after = tok->gK_before;
if ((float_terminal_nodes) && (tok->enode_arity == FALSE))
Equations__promote_subequation(eqn, tok, FALSE);
LOG_OUTDENT;
return result;
}
#line 1550 "inform7/Chapter 26/Equations.w"
void Equations__promote_subequation(equation *eqn, equation_node *tok, int deeply) {
if (tok == NULL) return;
if (deeply) {
float_terminal_nodes = TRUE;
Equations__enode_typecheck(eqn, tok);
float_terminal_nodes = FALSE;
}
tok->gK_after = Kinds__FloatingPoint__to_real(tok->gK_after);
}
void Equations__demote_subequation(equation *eqn, equation_node *tok) {
if (tok == NULL) return;
tok->gK_after = Kinds__FloatingPoint__to_integer(tok->gK_after);
}
#line 1571 "inform7/Chapter 26/Equations.w"
void Equations__compile(OUTPUT_STREAM) {
equation *eqn;
LOOP_OVER(eqn, equation) {
OUT = Routines__begin(OUT, eqn->eqn_I6_identifier);
WRITE("return 0;\n");
OUT = Routines__end(OUT);
}
}
#line 1583 "inform7/Chapter 26/Equations.w"
char *Equations__identifier(equation *eqn) {
return eqn->eqn_I6_identifier;
}
#line 1594 "inform7/Chapter 26/Equations.w"
void Equations__set_usage_notes(equation *eqn, wording W) {
eqn->usage_text = W;
}
#line 1603 "inform7/Chapter 26/Equations.w"
void Equations__compile_solution(OUTPUT_STREAM, wording W, equation *eqn) {
if (Wordings__nonempty(eqn->usage_text))
Equations__eqn_declare_variables_inner(eqn, eqn->usage_text, TRUE);
Equations__compile_solution_inner(OUT, W, eqn);
Equations__eqn_remove_temp_variables(eqn);
eqn->usage_text = EMPTY_WORDING;
}
#line 1616 "inform7/Chapter 26/Equations.w"
void Equations__compile_solution_inner(OUTPUT_STREAM, wording W, equation *eqn) {
equation_symbol *to_solve = NULL;
{
#line 1630 "inform7/Chapter 26/Equations.w"
if (Wordings__length(W) == 1)
for (equation_symbol *ev = eqn->symbol_list; ev; ev = ev->next)
if (Wordings__match_cs(W, ev->name))
to_solve = ev;
if (to_solve == NULL) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_wording(3, eqn->equation_text);
Problems__Issue__handmade_problem(_p_(PM_EquationBadTarget));
Problems__issue_problem_segment(
"In %1, you asked to let %2 be given by the equation '%3', "
"but '%2' isn't a symbol in that equation.");
Problems__issue_problem_end();
return;
}
if (to_solve->var_const) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_wording(3, eqn->equation_text);
Problems__quote_spec(4, to_solve->var_const);
Problems__Issue__handmade_problem(_p_(PM_EquationConstantTarget));
Problems__issue_problem_segment(
"In %1, you asked to let %2 be given by the equation '%3', "
"but '%2' isn't something which can vary freely in that equation - "
"it's been set equal to %4.");
Problems__issue_problem_end();
return;
}
}
#line 1619 "inform7/Chapter 26/Equations.w"
;
{
#line 1670 "inform7/Chapter 26/Equations.w"
if (Equations__eqn_rearrange(eqn, to_solve) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_wording(3, eqn->equation_text);
Problems__Issue__handmade_problem(_p_(PM_EquationInsoluble));
Problems__issue_problem_segment(
"In %1, you asked to let %2 be given by the equation '%3', "
"but I am unable to rearrange the equation in any simple way "
"so that it sets '%2' equal to something else. Maybe you could "
"write a more explicit equation? (You're certainly better at "
"maths than I am; I can only make easy deductions.)");
Problems__issue_problem_end();
return;
}
if (Equations__eqn_typecheck(eqn) == FALSE) return;
}
#line 1620 "inform7/Chapter 26/Equations.w"
;
{
#line 1696 "inform7/Chapter 26/Equations.w"
equation_symbol *ev;
for (ev = eqn->symbol_list; ev; ev = ev->next)
if (ev->var_const == NULL) {
ev->local_map = LocalVariables__parse(Frames__current_stack_frame(), ev->name);
ev->promote_local_to_real = FALSE;
if (ev->local_map == NULL)
{
#line 1714 "inform7/Chapter 26/Equations.w"
if (ev == to_solve) internal_error("can't find 'let' variable to assign");
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_wording(3, eqn->equation_text);
Problems__quote_wording(4, ev->name);
Problems__Issue__handmade_problem(_p_(PM_EquationSymbolMissing));
Problems__issue_problem_segment(
"In %1, you asked to let %2 be given by the equation '%3', "
"but I can't see what to use for '%4'. The usual idea is "
"to set the other variables in the equation using 'let': "
"so adding 'let %4 be ...' before trying to find '%2' "
"should work.");
Problems__issue_problem_end();
return;
}
#line 1702 "inform7/Chapter 26/Equations.w"
else
{
#line 1739 "inform7/Chapter 26/Equations.w"
kind *K = LocalVariables__kind(ev->local_map);
if (Kinds__Compare__eq(K, K_value)) {
K = ev->var_kind;
LocalVariables__set_kind(ev->local_map, K);
}
if ((Kinds__Compare__eq(K, K_number)) &&
(Kinds__Compare__eq(ev->var_kind, K_real_number))) {
K = K_real_number;
ev->promote_local_to_real = TRUE;
}
if (Kinds__Compare__eq(K, ev->var_kind) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_wording(3, eqn->equation_text);
Problems__quote_wording(4, ev->name);
Problems__quote_kind(5, K);
Problems__quote_kind(6, ev->var_kind);
Problems__Issue__handmade_problem(_p_(PM_EquationSymbolWrongKOV));
Problems__issue_problem_segment(
"In %1, you asked to let %2 be given by the equation '%3', "
"but in that equation '%4' is supposedly %6 - whereas right "
"here, it seems to be %5. Perhaps two different quantities have "
"ended up with the same symbol in the source text?");
Problems__issue_problem_end();
return;
}
}
#line 1704 "inform7/Chapter 26/Equations.w"
;
}
}
#line 1621 "inform7/Chapter 26/Equations.w"
;
WRITE("! Solving %s for '$w'\n", eqn->eqn_I6_identifier, to_solve->name);
Equations__enode_compile(OUT, eqn, eqn->parsed_equation);
}
#line 1769 "inform7/Chapter 26/Equations.w"
void Equations__enode_compile(OUTPUT_STREAM, equation *eqn, equation_node *tok) {
int a = 0;
if (Kinds__FloatingPoint__is_real(tok->gK_before)) a = 1;
int b = 0;
if (Kinds__FloatingPoint__is_real(tok->gK_after)) b = 1;
int f = b - a;
if (f == 1) Kinds__FloatingPoint__begin_flotation(OUT, Kinds__FloatingPoint__underlying(tok->gK_before));
else if (f == -1) Kinds__FloatingPoint__begin_deflotation(OUT, Kinds__FloatingPoint__underlying(tok->gK_before));
switch (tok->eqn_type) {
case SYMBOL_EQN:
if (tok->leaf_symbol->var_const)
Specifications__Compiler__compile(OUT, tok->leaf_symbol->var_const);
else if (tok->leaf_symbol->local_map) {
if (tok->leaf_symbol->promote_local_to_real)
WRITE("NUMBER_TY_to_REAL_NUMBER_TY(");
WRITE("%s",
LocalVariables__lvalue(tok->leaf_symbol->local_map));
if (tok->leaf_symbol->promote_local_to_real)
WRITE(")");
}
else if (tok->leaf_symbol->function_notated) {
char identifier[32];
Routines__ToPhrases__make_identifier(identifier,
tok->leaf_symbol->function_notated,
Phrases__TypeData__kind(
&(tok->leaf_symbol->function_notated->type_data)));
WRITE("%s", identifier);
} else internal_error("uncompilable equation node");
break;
case CONSTANT_EQN:
Specifications__Compiler__compile(OUT, tok->leaf_constant);
break;
case OPERATION_EQN: WRITE("(");
{
#line 1811 "inform7/Chapter 26/Equations.w"
equation_node *X = tok->enode_operands[0];
kind *KX = Kinds__FloatingPoint__underlying(X->gK_after);
equation_node *Y = tok->enode_operands[1];
kind *KY = (Y)?(Kinds__FloatingPoint__underlying(Y->gK_after)):NULL;
if (Kinds__FloatingPoint__is_real(X->gK_after)) {
KX = K_real_number; KY = K_real_number;
}
Kinds__Dimensions__perform_arithmetic(OUT, tok->eqn_operation, eqn, NULL, X, KX, NULL, Y, KY);
}
#line 1801 "inform7/Chapter 26/Equations.w"
; WRITE(")"); break;
default: internal_error("forbidden enode found in parsed equation");
}
if (f == 1) Kinds__FloatingPoint__end_flotation(OUT, Kinds__FloatingPoint__underlying(tok->gK_before));
else if (f == -1) Kinds__FloatingPoint__end_deflotation(OUT, Kinds__FloatingPoint__underlying(tok->gK_before));
}
#line 1824 "inform7/Chapter 26/Equations.w"
void Equations__enode_compilation_error(equation *eqn, equation_node *tok) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, eqn->equation_text);
Problems__Issue__handmade_problem(_p_(PM_HardIntegerRoot));
Problems__issue_problem_segment(
"In %1, you asked me to solve the equation '%2', but that would have "
"involved taking a tricky root of a whole number. Using real numbers "
"that would be easy, but with whole numbers I'm unable to get there.");
Problems__issue_problem_end();
}
#line 1852 "inform7/Chapter 26/Equations.w"
int Equations__eqn_rearrange(equation *eqn, equation_symbol *to_solve) {
while (TRUE) {
{
#line 1875 "inform7/Chapter 26/Equations.w"
int lc = Equations__enode_count_var(eqn->parsed_equation->enode_operands[0], to_solve);
int rc = Equations__enode_count_var(eqn->parsed_equation->enode_operands[1], to_solve);
if (lc + rc != 1) return FALSE;
if (lc == 0) {
equation_node *swap = eqn->parsed_equation->enode_operands[0];
eqn->parsed_equation->enode_operands[0] = eqn->parsed_equation->enode_operands[1];
eqn->parsed_equation->enode_operands[1] = swap;
}
}
#line 1854 "inform7/Chapter 26/Equations.w"
;
equation_node *old_LHS = eqn->parsed_equation->enode_operands[0];
equation_node *old_RHS = eqn->parsed_equation->enode_operands[1];
if (old_LHS->eqn_type != OPERATION_EQN) break;
if (old_LHS->enode_arity == 2)
{
#line 1939 "inform7/Chapter 26/Equations.w"
/* rearrange to move this operator */
int op = old_LHS->eqn_operation;
if (op == POWER_OPERATION)
{
#line 1997 "inform7/Chapter 26/Equations.w"
int p = Rvalues__to_int(old_LHS->enode_operands[1]->leaf_constant);
if (p == 2) {
eqn->parsed_equation->enode_operands[0] = old_LHS->enode_operands[0];
eqn->parsed_equation->enode_operands[1] = old_LHS;
old_LHS->eqn_operation = ROOT_OPERATION;
old_LHS->enode_arity = 1;
old_LHS->enode_operands[0] = old_RHS;
} else if (p == 3) {
eqn->parsed_equation->enode_operands[0] = old_LHS->enode_operands[0];
eqn->parsed_equation->enode_operands[1] = old_LHS;
old_LHS->eqn_operation = CUBEROOT_OPERATION;
old_LHS->enode_arity = 1;
old_LHS->enode_operands[0] = old_RHS;
} else {
eqn->parsed_equation->enode_operands[0] = old_LHS->enode_operands[0];
eqn->parsed_equation->enode_operands[1] = old_LHS;
old_LHS->eqn_operation = POWER_OPERATION;
old_LHS->enode_arity = 2;
old_LHS->enode_operands[0] = old_RHS;
equation_node *the_power = old_LHS->enode_operands[1];
old_LHS->enode_operands[1] = Equations__enode_new_op(DIVIDE_OPERATION);
old_LHS->enode_operands[1]->enode_arity = 2;
old_LHS->enode_operands[1]->enode_operands[0] = Equations__enode_new_constant(
Rvalues__from_int(1, EMPTY_WORDING));
old_LHS->enode_operands[1]->enode_operands[0]->gK_before =
Kinds__FloatingPoint__new_gk(K_number);
old_LHS->enode_operands[1]->enode_operands[0]->enode_promotion = TRUE;
old_LHS->enode_operands[1]->enode_operands[1] = the_power;
old_LHS->enode_operands[1]->enode_operands[1]->gK_before =
Kinds__FloatingPoint__new_gk(K_number);
old_LHS->enode_operands[1]->enode_operands[1]->enode_promotion = TRUE;
old_LHS->enode_operands[1]->gK_before =
Kinds__FloatingPoint__new_gk(K_real_number);
old_LHS->enode_operands[1]->gK_after =
Kinds__FloatingPoint__new_gk(K_real_number);
old_LHS->enode_operands[1]->rational_n = 1;
old_LHS->enode_operands[1]->rational_m = p;
Kinds__Behaviour__notify_of_use(K_real_number);
}
}
#line 1942 "inform7/Chapter 26/Equations.w"
else if (op == IMPLICIT_APPLICATION_OPERATION)
{
#line 2056 "inform7/Chapter 26/Equations.w"
equation_node *fnode = old_LHS->enode_operands[0];
if ((fnode->leaf_symbol == NULL) ||
(fnode->leaf_symbol->function_notated == NULL)) {
Equations__log_equation_node(fnode);
internal_error("not a function being applied");
}
phrase *f = fnode->leaf_symbol->function_notated;
phrase *finv = Phrases__Usage__get_equation_inverse(&(f->usage_data));
if (finv == NULL) return FALSE; /* no known inverse for this function */
equation_symbol *ev, *ev_inverse = NULL;
for (ev = standard_equation_symbols; ev; ev = ev->next)
if (ev->function_notated == finv)
ev_inverse = ev;
if (ev_inverse == NULL) return FALSE; /* inverse can't be used in equations */
fnode->leaf_symbol = ev_inverse;
eqn->parsed_equation->enode_operands[0] = old_LHS->enode_operands[1];
eqn->parsed_equation->enode_operands[1] = old_LHS;
old_LHS->enode_operands[1] = old_RHS;
}
#line 1944 "inform7/Chapter 26/Equations.w"
else {
int promote = 0, new_op = PLUS_OPERATION;
if (Equations__enode_count_var(old_LHS->enode_operands[1], to_solve) > 0) promote = 1;
switch (op) {
case PLUS_OPERATION: new_op = MINUS_OPERATION; break;
case MINUS_OPERATION: new_op = PLUS_OPERATION; promote = 0; break;
case TIMES_OPERATION: new_op = DIVIDE_OPERATION; break;
case DIVIDE_OPERATION: new_op = TIMES_OPERATION; promote = 0; break;
default: LOG("%d\n", op); internal_error("strange operator in rearrangement");
}
equation_node *E = old_LHS->enode_operands[1 - promote];
/* the new LHS is the promoted operand: */
eqn->parsed_equation->enode_operands[0] = old_LHS->enode_operands[promote];
/* the new RHS is the operator which used to be the LHS... */
eqn->parsed_equation->enode_operands[1] = old_LHS;
/* ...the former RHS being the operand replacing the promoted one... */
old_LHS->enode_operands[0] = old_RHS;
old_LHS->enode_operands[1] = E;
/* ...except that the operator reverses in "sense" */
old_LHS->eqn_operation = new_op;
}
}
#line 1862 "inform7/Chapter 26/Equations.w"
else
{
#line 2087 "inform7/Chapter 26/Equations.w"
int op = old_LHS->eqn_operation;
switch (op) {
case UNARY_MINUS_OPERATION:
eqn->parsed_equation->enode_operands[0] = old_LHS->enode_operands[0];
eqn->parsed_equation->enode_operands[1] = old_LHS;
old_LHS->enode_operands[0] = old_RHS;
break;
case ROOT_OPERATION:
case REALROOT_OPERATION:
eqn->parsed_equation->enode_operands[0] = old_LHS->enode_operands[0];
eqn->parsed_equation->enode_operands[1] = old_LHS;
old_LHS->eqn_operation = TIMES_OPERATION;
old_LHS->enode_arity = 2;
old_LHS->enode_operands[0] = old_RHS;
old_LHS->enode_operands[1] = old_RHS;
break;
case CUBEROOT_OPERATION:
eqn->parsed_equation->enode_operands[0] = old_LHS->enode_operands[0];
eqn->parsed_equation->enode_operands[1] = old_LHS;
old_LHS->eqn_operation = TIMES_OPERATION;
old_LHS->enode_arity = 2;
old_LHS->enode_operands[0] = old_RHS;
old_LHS->enode_operands[1] = Equations__enode_new_op(TIMES_OPERATION);
old_LHS->enode_operands[1]->enode_operands[0] = old_RHS;
old_LHS->enode_operands[1]->enode_operands[1] = old_RHS;
break;
default: internal_error("unanticipated operator in rearrangement");
}
}
#line 1864 "inform7/Chapter 26/Equations.w"
;
}
return TRUE;
}
#line 2121 "inform7/Chapter 26/Equations.w"
int Equations__enode_count_var(equation_node *tok, equation_symbol *to_solve) {
int c = 0, i;
if (tok == NULL) return c;
if ((tok->eqn_type == SYMBOL_EQN) && (tok->leaf_symbol == to_solve))
return 1;
for (i=0; i<tok->enode_arity; i++)
c += Equations__enode_count_var(tok->enode_operands[i], to_solve);
return c;
}
#line 2136 "inform7/Chapter 26/Equations.w"
void Equations__internal_test(wording E) {
wording WH = EMPTY_WORDING;
if (Preform__parse_nt_against_word_range(equation_where_NTM, E, NULL, NULL)) {
E = GET_RW(equation_where_NTM, 1);
WH = GET_RW(equation_where_NTM, 2);
}
equation *eqn = Equations__new(E, TRUE);
Equations__set_wherewithal(eqn, WH);
Equations__examine(eqn);
PL__Parsing__TestScripts__begin_internal_reporting();
Equations__log_equation_parsed(eqn);
equation_symbol *ev;
for (ev = eqn->symbol_list; ev; ev = ev->next) {
if (Equations__eqn_rearrange(eqn, ev) == FALSE)
LOG("Too hard to rearrange to solve for $w\n", ev->name);
else {
LOG("Rearranged to solve for $w:\n", ev->name);
Equations__log_equation_parsed(eqn);
}
}
PL__Parsing__TestScripts__end_internal_reporting();
}
#line 2163 "inform7/Chapter 26/Equations.w"
void Equations__log(equation *eqn) {
LOG("{$w}", eqn->equation_text);
}
void Equations__log_equation_parsed(equation *eqn) {
if (eqn == NULL) LOG("<null>\n");
else Equations__log_equation_node(eqn->parsed_equation);
}
void Equations__index(void) {
int ec = 0; equation *eqn;
LOOP_OVER(eqn, equation) { ec++; }
if (ec == 0) return;
INDEX("<p><b>List of Named or Numbered Equations</b> (<i>About equations</i>");
Index__DocReferences__link("EQUATIONS"); INDEX(")<p>\n");
int N = 0;
LOOP_OVER(eqn, equation) {
int mw = Wordings__last_wn(eqn->equation_no_text);
if (Wordings__last_wn(eqn->equation_name_text) > mw)
mw = Wordings__last_wn(eqn->equation_name_text);
if (mw >= 0) {
Wordings__index_raw(Wordings__up_to(ParseTree__get_text(eqn->equation_created_at), mw));
Index__link(Wordings__first_wn(ParseTree__get_text(eqn->equation_created_at)));
INDEX(" (");
Wordings__index_raw(eqn->equation_text);
INDEX(")<br>\n");
N++;
}
}
if (N == 0) INDEX("<p><i>None</i>.</p>");
}
#line 110 "inform7/Chapter 27/Rules.w"
rule *Rules__new(wording W, int named) {
W = Articles__remove_the(W);
rule *R = Rules__by_name(W);
if (R) return R;
R = CREATE(rule);
R->kind_of_rule = NULL;
R->defn_as_phrase = NULL;
R->defn_as_I6_routine[0] = 0;
R->name = W;
R->italicised_text = EMPTY_WORDING;
R->listed_stv_owners = NULL;
R->automatic_booking = NULL;
R->first_applicability_condition = NULL;
R->defn_compiled = FALSE;
R->explicitly_named = named;
int l;
for (l=0; l<26; l++) {
R->lettered_responses[l] = NULL;
R->lettered_responses_used[l] = NULL;
R->lettered_responses_value[l] = EMPTY_WORDING;
}
if (Wordings__nonempty(W)) {
if (Rules__vet_name(W))
{
#line 141 "inform7/Chapter 27/Rules.w"
unsigned int mc = RULE_MC;
if (Preform__parse_nt_against_word_range(rule_name_formal_NTM, W, NULL, NULL)) mc = MISCELLANEOUS_MC;
Semantics__Nouns__ExcerptMeanings__register_noun(mc, W, Rvalues__from_rule(R));
}
#line 132 "inform7/Chapter 27/Rules.w"
;
}
return R;
}
#line 148 "inform7/Chapter 27/Rules.w"
rule *Rules__by_name(wording W) {
if (Wordings__empty(W)) return NULL;
W = Articles__remove_the(W);
if (Preform__parse_nt_against_word_range(rule_name_formal_NTM, W, NULL, NULL)) {
parse_node *p = SParser__parse_excerpt(MISCELLANEOUS_MC, W);
if (Rvalues__is_CONSTANT_construction(p, CON_rule))
return Rvalues__to_rule(p);
} else {
parse_node *p = SParser__parse_excerpt(RULE_MC, W);
if (Rvalues__is_CONSTANT_construction(p, CON_rule))
return Rvalues__to_rule(p);
}
return NULL;
}
#line 166 "inform7/Chapter 27/Rules.w"
int PM_RuleWithComma_issued_at = -1;
int Rules__vet_name(wording W) {
if (Preform__parse_nt_against_word_range(unsuitable_name_NTM, W, NULL, NULL)) {
if (PM_RuleWithComma_issued_at != Wordings__first_wn(W)) {
PM_RuleWithComma_issued_at = Wordings__first_wn(W);
Problems__Issue__sentence_problem(_p_(PM_RuleWithComma),
"a rule name is not allowed to contain punctuation, or "
"to consist only of an article like 'a' or 'an', or to "
"contain double-quoted text",
"because this leads to too much ambiguity later on.");
}
return FALSE;
}
return TRUE;
}
#line 187 "inform7/Chapter 27/Rules.w"
kind *Rules__to_kind(rule *R) {
kind *K = R->kind_of_rule;
if (K == NULL) K = Kinds__binary_construction(CON_rule, K_action_name, K_nil);
return K;
}
#line 198 "inform7/Chapter 27/Rules.w"
void Rules__set_I7_definition(rule *R, phrase *ph) {
R->defn_as_phrase = ph;
}
void Rules__set_I6_definition(rule *R, char *identifier) {
strcpy(R->defn_as_I6_routine, identifier);
}
char *Rules__get_I6_definition(rule *R) {
return R->defn_as_I6_routine;
}
phrase *Rules__get_I7_definition(rule *R) {
if (R == NULL) return NULL;
return R->defn_as_phrase;
}
#line 218 "inform7/Chapter 27/Rules.w"
void Rules__impose_constraint(rule *S, rule *R, wording W, int sense) {
applicability_condition *nac = CREATE(applicability_condition);
{
#line 227 "inform7/Chapter 27/Rules.w"
nac->text_of_condition = W;
nac->sense_of_applicability = sense;
nac->next_applicability_condition = NULL;
nac->where_imposed = current_sentence;
nac->substituted_rule = S;
}
#line 220 "inform7/Chapter 27/Rules.w"
;
{
#line 236 "inform7/Chapter 27/Rules.w"
applicability_condition *ac = R->first_applicability_condition;
if (ac == NULL) R->first_applicability_condition = nac;
else {
while ((ac) && (ac->next_applicability_condition))
ac = ac->next_applicability_condition;
ac->next_applicability_condition = nac;
}
}
#line 221 "inform7/Chapter 27/Rules.w"
;
}
#line 248 "inform7/Chapter 27/Rules.w"
void Rules__compile_constraint(OUTPUT_STREAM, applicability_condition *acl) {
for (; acl; acl = acl->next_applicability_condition) {
current_sentence = acl->where_imposed;
if (acl->sense_of_applicability) WRITE("if (~~("); else WRITE("if (");
{
#line 261 "inform7/Chapter 27/Rules.w"
if (Wordings__nonempty(acl->text_of_condition) == FALSE) {
WRITE("true");
} else {
if (Preform__parse_nt_against_word_range(s_condition_NTM, acl->text_of_condition, NULL, NULL)) {
parse_node *spec = most_recent_result_p;
Dash__check_condition(spec);
Specifications__Compiler__compile(OUT, spec);
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, acl->text_of_condition);
Problems__Issue__handmade_problem(_p_(PM_BadRuleConstraint));
Problems__issue_problem_segment(
"In %1, you placed a constraint '%2' on a rule, but this isn't "
"a condition I can understand.");
Problems__issue_problem_end();
}
}
}
#line 252 "inform7/Chapter 27/Rules.w"
;
if (acl->sense_of_applicability) WRITE(")) "); else WRITE(") ");
{
#line 283 "inform7/Chapter 27/Rules.w"
if (acl->substituted_rule) {
WRITE("return ");
Rules__compile(OUT, acl->substituted_rule);
WRITE("();\n");
} else {
WRITE("rfalse;\n");
}
}
#line 254 "inform7/Chapter 27/Rules.w"
;
}
}
#line 294 "inform7/Chapter 27/Rules.w"
void Rules__log(rule *R) {
if (R == NULL) { LOG("<null-rule>"); return; }
if (R->defn_as_phrase) LOG("[$R]", R->defn_as_phrase);
else if (R->defn_as_I6_routine[0]) LOG("[%s]", R->defn_as_I6_routine);
else LOG("[-]");
}
#line 309 "inform7/Chapter 27/Rules.w"
int Rules__compare_specificity(rule *R1, rule *R2, int dflag) {
phrase *ph1 = R1->defn_as_phrase, *ph2 = R2->defn_as_phrase;
ph_runtime_context_data *phrcd1 = NULL, *phrcd2 = NULL;
if (ph1) phrcd1 = &(ph1->runtime_context_data);
if (ph2) phrcd2 = &(ph2->runtime_context_data);
int rv = Phrases__Context__compare_specificity(phrcd1, phrcd2);
if (dflag) {
if (rv != 0) LOG("Decided by Law %s that ", c_s_stage_law);
else LOG("Decided that ");
switch(rv) {
case -1: LOG("(2) is more specific than (1)\n"); break;
case 0: LOG("they are equally specific\n"); break;
case 1: LOG("(1) is more specific than (2)\n"); break;
}
}
return rv;
}
#line 333 "inform7/Chapter 27/Rules.w"
int Rules__eq(rule *R1, rule *R2) {
if (R2->defn_as_phrase != R1->defn_as_phrase) return FALSE;
if (strcmp(R1->defn_as_I6_routine, R2->defn_as_I6_routine) != 0) return FALSE;
return TRUE;
}
#line 353 "inform7/Chapter 27/Rules.w"
void Rules__set_kind_from(rule *R, rulebook *RB) {
kind *K = Rulebooks__contains_kind(RB);
if (R->kind_of_rule) {
if (Kinds__Compare__compatible(R->kind_of_rule, K) != ALWAYS_MATCH) {
kind *B1 = NULL, *B2 = NULL, *P1 = NULL, *P2 = NULL;
Kinds__binary_construction_material(R->kind_of_rule, &B1, &P1);
Kinds__binary_construction_material(K, &B2, &P2);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, R->name);
Problems__quote_kind(3, B1);
Problems__quote_kind(4, P1);
Problems__quote_kind(5, B2);
Problems__quote_kind(6, P2);
Problems__quote_wording_as_source(7, R->kind_of_rule_set_from->primary_name);
Problems__quote_wording_as_source(8, RB->primary_name);
Problems__Issue__handmade_problem(_p_(PM_RuleInIncompatibleRulebooks));
Problems__issue_problem_segment(
"You've asked to put the rule '%2' into the rulebook %8, "
"which is based on %5 and produces %6; but it was originally "
"written to go into a rulebook of a different kind, %7, "
"which is based on %3 and produces %4. Because those kinds "
"are different, '%2' can't go into %8.");
Problems__issue_problem_end();
}
}
R->kind_of_rule = K;
R->kind_of_rule_set_from = RB;
}
#line 385 "inform7/Chapter 27/Rules.w"
void Rules__acquire_stvol(rule *R, stacked_variable_owner_list *stvol) {
R->listed_stv_owners =
StackedVariables__append_owner_list(R->listed_stv_owners, stvol);
}
void Rules__acquire_action_variables(rule *R) {
Rules__acquire_stvol(R, all_nonempty_stacked_action_vars);
if (all_action_processing_vars == NULL) internal_error("APROC not ready");
Rules__acquire_stvol(R, all_action_processing_vars);
}
#line 414 "inform7/Chapter 27/Rules.w"
void Rules__request_automatic_placement(rule *R) {
if (R->automatic_booking == NULL)
R->automatic_booking = Rules__Bookings__new(R);
Rules__Bookings__request_automatic_placement(R->automatic_booking);
}
#line 426 "inform7/Chapter 27/Rules.w"
void Rules__check_placement_safety(void) {
rule *R;
LOOP_OVER(R, rule) {
kind *KR = R->kind_of_rule;
applicability_condition *ac;
for (ac = R->first_applicability_condition; ac; ac = ac->next_applicability_condition) {
if (ac->substituted_rule) {
kind *KS = ac->substituted_rule->kind_of_rule;
kind *B1 = NULL, *B2 = NULL, *P1 = NULL, *P2 = NULL;
Kinds__binary_construction_material(KR, &B1, &P1);
Kinds__binary_construction_material(KS, &B2, &P2);
if (Kinds__Compare__eq(B1, NULL)) B1 = K_nil;
if (Kinds__Compare__eq(B2, NULL)) B2 = K_nil;
if (Kinds__Compare__eq(P1, NULL)) P1 = K_nil;
if (Kinds__Compare__eq(P2, NULL)) P2 = K_nil;
if (Kinds__Compare__eq(B2, K_nil)) B2 = B1;
kind *K1 = Kinds__binary_construction(CON_rule, B1, P1);
kind *K2 = Kinds__binary_construction(CON_rule, B2, P2);
if (Kinds__Compare__compatible(K2, K1) != ALWAYS_MATCH) {
Problems__quote_source(1, ac->where_imposed);
Problems__quote_wording(2, ac->substituted_rule->name);
Problems__quote_wording(3, R->name);
Problems__quote_kind(4, KR);
Problems__quote_kind(5, KS);
Problems__Issue__handmade_problem(_p_(PM_RulesCantInterchange));
Problems__issue_problem_segment(
"In the sentence %1 you've asked to use the rule '%2' in "
"place of '%3', but one is based on %4 whereas the other "
"is %5, and those aren't interchangeable.");
Problems__issue_problem_end();
break;
}
}
}
}
}
#line 469 "inform7/Chapter 27/Rules.w"
void Rules__compile(OUTPUT_STREAM, rule *R) {
if (R->defn_as_phrase) WRITE("%s", Phrases__identifier(R->defn_as_phrase));
else if (R->defn_as_I6_routine[0]) {
if (R->first_applicability_condition) {
WRITE("I6_Rule_Shell_%d", R->allocation_id);
} else {
WRITE("%s", R->defn_as_I6_routine);
}
} else internal_error("tried to compile nameless rule");
}
#line 483 "inform7/Chapter 27/Rules.w"
void Rules__compile_rule_printing_switch(OUTPUT_STREAM) {
INDENT; INDENT;
rule *R;
LOOP_OVER(R, rule) {
if ((Wordings__nonempty(R->name) == FALSE) &&
((R->defn_as_phrase == NULL) ||
(R->defn_as_phrase->declaration_node == NULL) ||
(R->defn_as_phrase->declaration_node->down == NULL)))
continue;
WRITE("if (R == "); Rules__compile(OUT, R); WRITE(") { print \"");
{
#line 502 "inform7/Chapter 27/Rules.w"
if (Wordings__nonempty(R->name)) {
CompiledText__from_text(OUT, R->name);
} else if (R->defn_as_phrase->declaration_node) {
CompiledText__from_text(OUT,
Articles__remove_the(
ParseTree__get_text(R->defn_as_phrase->declaration_node)));
} else Rules__compile(OUT, R);
}
#line 493 "inform7/Chapter 27/Rules.w"
;
WRITE("\"; rtrue; } ! rule %d\n", R->allocation_id);
}
OUTDENT; OUTDENT;
}
#line 513 "inform7/Chapter 27/Rules.w"
void Rules__compile_comment(OUTPUT_STREAM, rule *R, int index, int from) {
if (R->defn_as_phrase) {
WRITE("! Rule %d/%d ", index, from);
Phrases__Usage__write_I6_comment_describing(&(R->defn_as_phrase->usage_data), OUT);
} else {
WRITE("! Rule %d/%d: %s\n", index, from, R->defn_as_I6_routine);
}
}
#line 527 "inform7/Chapter 27/Rules.w"
void Rules__compile_definition(OUTPUT_STREAM, rule *R, int *i, int max_i) {
if (R->defn_compiled == FALSE) {
R->defn_compiled = TRUE;
rule_being_compiled = R;
if (R->defn_as_phrase)
Phrases__compile(OUT, R->defn_as_phrase, i, max_i,
R->listed_stv_owners, NULL, R->first_applicability_condition);
if ((R->defn_as_I6_routine[0]) && (R->first_applicability_condition))
{
#line 550 "inform7/Chapter 27/Rules.w"
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "I6_Rule_Shell_%d", R->allocation_id);
OUT = Routines__begin(OUT, i6_routine_identifier);
Rules__compile_constraint(OUT, R->first_applicability_condition);
WRITE("return %s();\n", R->defn_as_I6_routine);
OUT = Routines__end(OUT);
}
#line 535 "inform7/Chapter 27/Rules.w"
;
rule_being_compiled = NULL;
}
}
#line 564 "inform7/Chapter 27/Rules.w"
void Rules__set_italicised_index_text(rule *R, wording W) {
R->italicised_text = W;
}
#line 572 "inform7/Chapter 27/Rules.w"
int use_numbered_rules = FALSE;
void Rules__set_numbered_rules(void) {
use_numbered_rules = TRUE;
}
#line 581 "inform7/Chapter 27/Rules.w"
int Rules__index(rule *R, rulebook *owner, scene *during_scene) {
int no_responses_indexed = 0;
if (Wordings__nonempty(R->italicised_text))
{
#line 599 "inform7/Chapter 27/Rules.w"
INDEX("<i>");
Wordings__index_raw(R->italicised_text);
if (during_scene) {
INDEX(" during ");
wording SW = PL__Scenes__get_name(during_scene);
Wordings__index_raw(SW);
}
INDEX("</i>&nbsp;&nbsp;");
}
#line 583 "inform7/Chapter 27/Rules.w"
;
if (Wordings__nonempty(R->name))
{
#line 613 "inform7/Chapter 27/Rules.w"
INDEX("<font color=\"#800000\">");
Wordings__index_raw(R->name);
INDEX("</font>");
INDEX("&nbsp;&nbsp;");
char S[2*MAX_PASTEABLE_RULE_NAME_LENGTH + 50];
Wordings__to_string_raw_truncated(S, MAX_PASTEABLE_RULE_NAME_LENGTH, R->name);
HTML__Javascript__paste(ifl, S);
INDEX("&nbsp;<i>name</i> ");
sprintf(S, "The ");
Wordings__to_string_truncated(S+Platform__strlen(S),
MAX_PASTEABLE_RULE_NAME_LENGTH, R->name);
sprintf(S+Platform__strlen(S), " is not listed in the ");
Wordings__to_string_truncated(S+Platform__strlen(S),
MAX_PASTEABLE_RULE_NAME_LENGTH, owner->primary_name);
sprintf(S+Platform__strlen(S), " rulebook.\n");
HTML__Javascript__paste(ifl, S);
INDEX("&nbsp;<i>unlist</i>");
int l, c;
for (l=0, c=0; l<26; l++)
if (R->lettered_responses[l]) {
c++;
}
if (c > 0) {
INDEX("&nbsp;&nbsp;");
Index__extra_link_with(1000000+R->allocation_id, "responses");
INDEX("%d", c);
}
}
#line 584 "inform7/Chapter 27/Rules.w"
;
if ((Wordings__nonempty(R->italicised_text) == FALSE) &&
(Wordings__nonempty(R->name) == FALSE) && (R->defn_as_phrase))
{
#line 662 "inform7/Chapter 27/Rules.w"
parse_node *pn = R->defn_as_phrase->declaration_node->down;
if ((pn) && (Wordings__nonempty(ParseTree__get_text(pn)))) {
INDEX("(");
Wordings__index_raw(ParseTree__get_text(pn));
if (pn->next) INDEX("; ...");
INDEX(")");
}
}
#line 587 "inform7/Chapter 27/Rules.w"
;
{
#line 673 "inform7/Chapter 27/Rules.w"
if (R->defn_as_phrase) {
parse_node *pn = R->defn_as_phrase->declaration_node;
if ((pn) && (Wordings__nonempty(ParseTree__get_text(pn))))
Index__link(Wordings__first_wn(ParseTree__get_text(pn)));
}
}
#line 588 "inform7/Chapter 27/Rules.w"
;
if (use_numbered_rules)
{
#line 682 "inform7/Chapter 27/Rules.w"
INDEX(" <small>");
if (R->defn_as_phrase) INDEX("%d", R->defn_as_phrase->allocation_id);
else INDEX("primitive");
INDEX("</small>");
}
#line 589 "inform7/Chapter 27/Rules.w"
;
{
#line 690 "inform7/Chapter 27/Rules.w"
applicability_condition *acl;
for (acl = R->first_applicability_condition; acl; acl = acl->next_applicability_condition) {
INDEX("<br>");
Index__link(Wordings__first_wn(ParseTree__get_text(acl->where_imposed)));
INDEX("&nbsp;");
Wordings__index_raw(ParseTree__get_text(acl->where_imposed));
}
}
#line 590 "inform7/Chapter 27/Rules.w"
;
INDEX("</p>\n");
{
#line 648 "inform7/Chapter 27/Rules.w"
int l, c;
for (l=0, c=0; l<26; l++)
if (R->lettered_responses[l]) {
if (c == 0) Index__extra_div_open_nested(1000000+R->allocation_id, 2);
else INDEX("<br>");
Strings__index_response(R, l, R->lettered_responses[l]);
c++;
}
if (c > 0) Index__extra_div_close_nested();
no_responses_indexed = c;
}
#line 592 "inform7/Chapter 27/Rules.w"
;
return no_responses_indexed;
}
#line 705 "inform7/Chapter 27/Rules.w"
void Rules__set_always_test_actor(rule *R) {
if (R->defn_as_phrase) {
ph_runtime_context_data *phrcd = &(R->defn_as_phrase->runtime_context_data);
Phrases__Context__set_always_test_actor(phrcd);
}
}
void Rules__set_never_test_actor(rule *R) {
if (R->defn_as_phrase) {
ph_runtime_context_data *phrcd = &(R->defn_as_phrase->runtime_context_data);
Phrases__Context__set_never_test_actor(phrcd);
}
}
void Rules__set_marked_for_anyone(rule *R, int to) {
if (R->defn_as_phrase) {
ph_runtime_context_data *phrcd = &(R->defn_as_phrase->runtime_context_data);
Phrases__Context__set_marked_for_anyone(phrcd, to);
}
}
void Rules__suppress_action_testing(rule *R) {
if (R->defn_as_phrase) {
ph_runtime_context_data *phrcd = &(R->defn_as_phrase->runtime_context_data);
Phrases__Context__suppress_action_testing(phrcd);
}
}
void Rules__copy_actor_test_flags(rule *R_to, rule *R_from) {
if ((R_from == NULL) || (R_to == NULL)) internal_error("improper catf");
ph_runtime_context_data *phrcd_from = NULL;
if (R_from->defn_as_phrase) phrcd_from = &(R_from->defn_as_phrase->runtime_context_data);
ph_runtime_context_data *phrcd_to = NULL;
if (R_to->defn_as_phrase) phrcd_to = &(R_to->defn_as_phrase->runtime_context_data);
if (phrcd_to) {
if ((phrcd_from == NULL) ||
((Phrases__Context__get_marked_for_anyone(phrcd_from)) &&
(Phrases__Context__get_marked_for_anyone(phrcd_to) == FALSE))) {
Phrases__Context__clear_always_test_actor(phrcd_to);
Phrases__Context__set_never_test_actor(phrcd_to);
}
}
}
int Rules__rule_is_named(rule *R) {
if (R == NULL) return FALSE;
return R->explicitly_named;
}
response_message *Rules__rule_defines_response(rule *R, int code) {
if (R == NULL) return NULL;
if (code < 0) return NULL;
return R->lettered_responses[code];
}
void Rules__check_response_usages(void) {
rule *R;
LOOP_OVER(R, rule) {
char offers[100];
offers[0] = 0;
int c = 0;
for (int l=0; l<26; l++)
if (R->lettered_responses[l]) {
c++;
if (c > 1) strcat(offers, ", ");
sprintf(offers+Platform__strlen(offers), "%c", (char) ('A'+l));
}
for (int l=0; l<26; l++) {
if ((R->lettered_responses_used[l]) &&
(R->lettered_responses[l] == NULL)) {
char p[2]; p[0] = (char) ('A'+l); p[1] = 0;
Problems__quote_source(1, R->lettered_responses_used[l]);
Problems__quote_wording(2, R->name);
Problems__quote_text(3, p);
if (c == 0) Problems__quote_text(4, "no lettered responses at all");
else Problems__quote_text(4, offers);
Problems__Issue__handmade_problem(_p_(PM_NoSuchResponse));
Problems__issue_problem_segment(
"You wrote %1, but the '%2' doesn't have a response "
"lettered '%3'. (It has %4.)");
Problems__issue_problem_end();
}
}
}
}
void Rules__now_rule_defines_response(rule *R, int code, response_message *resp) {
if (R == NULL) internal_error("null rule defines response");
R->lettered_responses[code] = resp;
}
void Rules__now_rule_needs_response(rule *R, int code, wording W) {
if (R == NULL) internal_error("null rule uses response");
R->lettered_responses_used[code] = current_sentence;
if (Wordings__nonempty(W)) R->lettered_responses_value[code] = W;
}
wording Rules__get_response_value(rule *R, int code) {
if (R == NULL) internal_error("null rule uses response");
return R->lettered_responses_value[code];
}
parse_node *Rules__get_response_sentence(rule *R, int code) {
if (R == NULL) internal_error("null rule uses response");
return R->lettered_responses_used[code];
}
ph_stack_frame *Rules__stack_frame(rule *R) {
if ((R == NULL) || (R->defn_as_phrase == NULL)) return NULL;
return &(R->defn_as_phrase->stack_frame);
}
#line 51 "inform7/Chapter 27/Rule Bookings.w"
booking *Rules__Bookings__new(rule *R) {
booking *br = CREATE(booking);
br->next_rule = NULL;
br->rule_being_booked = R;
br->placement = MIDDLE_PLACEMENT;
br->automatic_placement = FALSE;
br->next_rule_specificity = 0;
br->next_rule_specificity_law = NULL;
br->next_rule_specificity_lawname = NULL;
return br;
}
#line 68 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__log(booking *br) {
if (br == NULL) { LOG("BR:<null-booked-rule>"); return; }
LOG("BR%d", br->allocation_id);
switch (br->placement) {
case MIDDLE_PLACEMENT: LOG("m"); break;
case FIRST_PLACEMENT: LOG("f"); break;
case LAST_PLACEMENT: LOG("l"); break;
default: LOG("?"); break;
}
Rules__log(br->rule_being_booked);
}
#line 83 "inform7/Chapter 27/Rule Bookings.w"
rule *Rules__Bookings__get_rule(booking *br) {
if (br == NULL) return NULL;
return br->rule_being_booked;
}
#line 103 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__request_automatic_placement(booking *br) {
br->automatic_placement = TRUE;
}
#line 113 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__make_automatic_placements(void) {
booking *br;
LOOP_OVER(br, booking)
if (br->automatic_placement) {
phrase *ph = Rules__get_I7_definition(br->rule_being_booked);
if (ph) {
current_sentence = ph->declaration_node;
Rules__Bookings__place(&(ph->usage_data), br);
Rules__set_kind_from(br->rule_being_booked,
Phrases__Usage__get_rulebook(&(ph->usage_data)));
}
}
}
#line 133 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__place(ph_usage_data *phud, booking *br) {
if (Phrases__Usage__get_effect(phud) == RULE_IN_RULEBOOK_EFF) {
rulebook *original_owner = Phrases__Usage__get_rulebook(phud);
if (Rulebooks__requires_specific_action(original_owner)) {
int waiver = FALSE;
action_name_list *anl;
action_name *an;
wording PW = Phrases__Usage__get_prewhile_text(phud);
if (Wordings__nonempty(PW)) {
LOOP_THROUGH_WORDING(i, PW)
if (PL__Actions__Patterns__Named__by_name(Wordings__from(PW, i)))
goto NotSingleAction;
anl = PL__Actions__Lists__extract_actions_only(PW);
an = PL__Actions__Lists__get_single_action(anl);
Rules__set_marked_for_anyone(Rules__Bookings__get_rule(br),
PL__Actions__Lists__get_explicit_anyone_flag(anl));
} else {
anl = NULL;
an = NULL;
waiver = TRUE;
if (original_owner == built_in_rulebooks[CHECK_RB]) waiver = FALSE;
if (original_owner == built_in_rulebooks[CARRY_OUT_RB]) waiver = FALSE;
if (original_owner == built_in_rulebooks[REPORT_RB]) waiver = FALSE;
}
LOGIF(RULE_ATTACHMENTS, "BR is: $b\n AN is: $l\n", br, an);
if ((an == NULL) && (waiver == FALSE)) {
int x;
an = PL__Actions__longest_null(PW, IS_TENSE, &x);
}
if ((an == NULL) && (waiver == FALSE)) {
NotSingleAction:
Phrases__Usage__log(phud);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, PW);
Problems__Issue__handmade_problem(_p_(PM_MultipleCCR));
Problems__issue_problem_segment(
"You wrote %1, but the situation this refers to ('%2') is "
"not a single action. Rules in the form of 'check', 'carry "
"out' and 'report' are tied to specific actions, and must "
"give a single explicit action name - even if they then go "
"on to very complicated conditions about any nouns also "
"involved. So 'Check taking something: ...' is fine, "
"but not 'Check taking or dropping something: ...' or "
"'Check doing something: ...' - the former names two "
"actions, the latter none.");
Problems__issue_problem_end();
} else {
if (original_owner == built_in_rulebooks[CHECK_RB]) {
Phrases__Usage__set_rulebook(phud,
PL__Actions__get_fragmented_rulebook(an, built_in_rulebooks[CHECK_RB]));
} else if (original_owner == built_in_rulebooks[CARRY_OUT_RB]) {
Phrases__Usage__set_rulebook(phud,
PL__Actions__get_fragmented_rulebook(an, built_in_rulebooks[CARRY_OUT_RB]));
} else if (original_owner == built_in_rulebooks[REPORT_RB]) {
Phrases__Usage__set_rulebook(phud,
PL__Actions__get_fragmented_rulebook(an, built_in_rulebooks[REPORT_RB]));
} else {
Phrases__Usage__set_rulebook(phud,
PL__Actions__switch_fragmented_rulebook(an, original_owner));
}
if (original_owner != Phrases__Usage__get_rulebook(phud))
LOGIF(RULE_ATTACHMENTS, "Rerouting $b to $K\n", br,
Phrases__Usage__get_rulebook(phud));
}
}
Rulebooks__attach_rule(Phrases__Usage__get_rulebook(phud), br,
Phrases__Usage__get_rulebook_placement(phud), 0, NULL);
}
}
#line 211 "inform7/Chapter 27/Rule Bookings.w"
int Rules__Bookings__compare_specificity_of_br(booking *br1, booking *br2, int log) {
if ((br1 == NULL) || (br2 == NULL)) internal_error("compared null specificity");
if (log) LOG("Comparing specificity of rules:\n(1) $b\n(2) $b\n", br1, br2);
return Rules__compare_specificity(
br1->rule_being_booked, br2->rule_being_booked, log);
}
#line 246 "inform7/Chapter 27/Rule Bookings.w"
booking *Rules__Bookings__list_new(void) {
return Rules__Bookings__new(NULL);
}
#line 304 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_add(booking *list_head, booking *new_rule,
int placing, int side, rule *ref_rule) {
{
#line 317 "inform7/Chapter 27/Rule Bookings.w"
if ((side != IN_SIDE) && (ref_rule == NULL))
internal_error("tried to add before or after or instead of non-rule");
if ((side == IN_SIDE) && (ref_rule != NULL))
internal_error("tried to add in middle but with ref rule");
if ((side != IN_SIDE) && (placing != MIDDLE_PLACEMENT))
internal_error("tried to add before or after but with non-middle placement");
if (list_head == NULL)
internal_error("tried to add rule to null list");
switch(placing) {
case MIDDLE_PLACEMENT: break;
case FIRST_PLACEMENT: LOGIF(RULE_ATTACHMENTS, "Placed first\n"); break;
case LAST_PLACEMENT: LOGIF(RULE_ATTACHMENTS, "Placed last\n"); break;
default:
LOG("Invalid placing %d\n", placing);
internal_error("invalid placing of rule");
}
}
#line 306 "inform7/Chapter 27/Rule Bookings.w"
;
{
#line 337 "inform7/Chapter 27/Rule Bookings.w"
booking *pos, *prev;
for (prev=list_head, pos=list_head->next_rule; pos; prev=pos, pos=pos->next_rule)
if (Rules__eq(Rules__Bookings__get_rule(pos),
Rules__Bookings__get_rule(new_rule))) {
if ((side == IN_SIDE) && (placing == MIDDLE_PLACEMENT))
return; /* rule is already in rulebook: do nothing */
prev->next_rule = pos->next_rule;
pos->next_rule = NULL;
LOGIF(RULE_ATTACHMENTS, "Removing previous entry from rulebook\n");
break; /* rule can only appear once, so no need to keep checking */
}
}
#line 307 "inform7/Chapter 27/Rule Bookings.w"
;
{
#line 352 "inform7/Chapter 27/Rule Bookings.w"
if (side == INSTEAD_SIDE) {
booking *pos, *prev;
for (prev=list_head, pos=list_head->next_rule; pos; prev=pos, pos=pos->next_rule)
if (Rules__eq(Rules__Bookings__get_rule(pos), ref_rule)) {
new_rule->placement = pos->placement; /* replace with same placement */
new_rule->next_rule = pos->next_rule;
prev->next_rule = new_rule;
}
return;
}
}
#line 308 "inform7/Chapter 27/Rule Bookings.w"
;
{
#line 366 "inform7/Chapter 27/Rule Bookings.w"
if (placing == FIRST_PLACEMENT) { /* first in valid interval (must be whole list) */
booking *subseq = list_head->next_rule;
list_head->next_rule = new_rule;
new_rule->next_rule = subseq; /* pushes any existing first rule forward */
new_rule->placement = placing;
return;
}
}
#line 309 "inform7/Chapter 27/Rule Bookings.w"
;
{
#line 377 "inform7/Chapter 27/Rule Bookings.w"
if (placing == LAST_PLACEMENT) { /* last in valid interval (must be whole list) */
booking *prev = list_head;
while (prev->next_rule != NULL) prev = prev->next_rule;
prev->next_rule = new_rule; /* pushes any existing last rule backward */
new_rule->next_rule = NULL;
new_rule->placement = placing;
return;
}
}
#line 310 "inform7/Chapter 27/Rule Bookings.w"
;
{
#line 389 "inform7/Chapter 27/Rule Bookings.w"
booking *start_rule = list_head; /* valid interval begins after this rule */
booking *end_rule = NULL; /* valid interval ends before this rule, or runs to end if |NULL| */
{
#line 403 "inform7/Chapter 27/Rule Bookings.w"
booking *pos;
switch(side) {
case BEFORE_SIDE:
for (pos=list_head->next_rule; pos; pos=pos->next_rule)
if (Rules__eq(Rules__Bookings__get_rule(pos), ref_rule))
end_rule = pos; /* insert before: so valid interval ends here */
if (end_rule == NULL) internal_error("can't find end rule");
break;
case AFTER_SIDE:
for (pos=list_head->next_rule; pos; pos=pos->next_rule)
if (Rules__eq(Rules__Bookings__get_rule(pos), ref_rule))
start_rule = pos; /* insert after: so valid interval begins here */
if (start_rule == list_head) internal_error("can't find start rule");
break;
}
}
#line 391 "inform7/Chapter 27/Rule Bookings.w"
;
{
#line 422 "inform7/Chapter 27/Rule Bookings.w"
int i = 0, t = 2;
if (end_rule == NULL) t = 1;
booking *pos;
for (pos = list_head; pos; pos = pos->next_rule) {
if ((pos == start_rule) && (i == 0)) i = 1;
if ((pos == end_rule) && (i == 1)) i = 2;
}
if (i != t) internal_error("valid rule interval isn't");
}
#line 392 "inform7/Chapter 27/Rule Bookings.w"
;
booking *insert_after = start_rule; /* insertion point is after this */
{
#line 434 "inform7/Chapter 27/Rule Bookings.w"
int log = FALSE; if (Log__aspect_switched_on(SPECIFICITIES_DA)) log = TRUE;
/* move forward to final valid first rule (if any exist) */
while ((insert_after->next_rule != end_rule)
&& (insert_after->next_rule->placement == FIRST_PLACEMENT))
insert_after = insert_after->next_rule;
/* move forward past other middle rules if they are not less specific */
while ((insert_after->next_rule != end_rule) /* stop before $p$ leaves valid range */
&& (insert_after->next_rule->placement != LAST_PLACEMENT) /* or reaches a last rule */
&& (Rules__Bookings__compare_specificity_of_br(insert_after->next_rule, new_rule,
log) >= 0)) /* or a rule less specific than the new one */
insert_after = insert_after->next_rule;
}
#line 394 "inform7/Chapter 27/Rule Bookings.w"
;
booking *subseq = insert_after->next_rule;
insert_after->next_rule = new_rule;
new_rule->next_rule = subseq;
{
#line 457 "inform7/Chapter 27/Rule Bookings.w"
new_rule->placement = MIDDLE_PLACEMENT;
if ((insert_after != list_head) &&
(insert_after->placement == LAST_PLACEMENT))
new_rule->placement =
LAST_PLACEMENT; /* happens if valid interval is after a last rule */
if ((subseq) &&
(subseq->placement == FIRST_PLACEMENT))
new_rule->placement =
FIRST_PLACEMENT; /* happens if valid interval is before a first rule */
}
#line 398 "inform7/Chapter 27/Rule Bookings.w"
;
}
#line 311 "inform7/Chapter 27/Rule Bookings.w"
;
}
#line 471 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_remove(booking *list_head, rule *ref_rule) {
booking *br, *pr;
for (br = list_head->next_rule, pr = list_head; br; pr = br, br = br->next_rule) {
if (Rules__eq(Rules__Bookings__get_rule(br), ref_rule)) {
pr->next_rule = br->next_rule;
return;
}
}
}
#line 484 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_log(booking *list_head) {
if (list_head == NULL) { LOG("<null-booked-rule-list>\n"); return; }
int t = Rules__Bookings__no_rules_in_list(list_head);
if (t == 0) { LOG("<empty-booked-rule-list>\n"); return; }
booking *br; int s;
for (br = list_head->next_rule, s = 1; br; br = br->next_rule, s++)
LOG(" %d/%d. $b\n", ++s, t, br);
}
#line 498 "inform7/Chapter 27/Rule Bookings.w"
int Rules__Bookings__no_rules_in_list(booking *list_head) {
if (list_head == NULL) return 0;
int n = 0;
booking *br;
for (br = list_head->next_rule; br; br = br->next_rule) n++;
return n;
}
int Rules__Bookings__list_is_empty(booking *list_head, scene *S) {
if (list_head == NULL) return TRUE;
booking *br;
for (br = list_head->next_rule; br; br = br->next_rule) {
if (S == NULL) return FALSE;
phrase *ph = Rules__get_I7_definition(br->rule_being_booked);
if ((ph) &&
(Phrases__Context__get_scene(&(ph->runtime_context_data)) == S))
return FALSE;
}
return TRUE;
}
int Rules__Bookings__list_is_empty_of_i7_rules(booking *list_head) {
if (list_head == NULL) return TRUE;
booking *br;
for (br = list_head->next_rule; br; br = br->next_rule)
if (Rules__get_I7_definition(br->rule_being_booked))
return FALSE;
return TRUE;
}
int Rules__Bookings__list_contains(booking *list_head, rule *to_find) {
if (list_head == NULL) return FALSE;
booking *br;
for (br = list_head->next_rule; br; br = br->next_rule)
if (Rules__eq(Rules__Bookings__get_rule(br), to_find))
return TRUE;
return FALSE;
}
int Rules__Bookings__list_contains_ph(booking *list_head, phrase *ph_to_find) {
if (list_head == NULL) return FALSE;
booking *br;
for (br = list_head->next_rule; br; br = br->next_rule)
if (Rules__get_I7_definition(br->rule_being_booked) == ph_to_find)
return TRUE;
return FALSE;
}
#line 553 "inform7/Chapter 27/Rule Bookings.w"
int Rules__Bookings__list_index(booking *list_head, scene *context,
action_name *action_context, char *billing, rulebook *owner, int *resp_count) {
booking *br, *prev;
int count = 0;
for (br = list_head->next_rule, prev = NULL; br; prev = br, br = br->next_rule) {
rule *R = br->rule_being_booked;
phrase *ph = Rules__get_I7_definition(R);
if (ph) {
ph_runtime_context_data *phrcd = &(ph->runtime_context_data);
scene *during_scene = Phrases__Context__get_scene(phrcd);
if ((context) && (during_scene != context)) continue;
if ((action_context) &&
(Phrases__Context__within_action_context(phrcd, action_context) == FALSE))
continue;
}
count++;
Rules__Bookings__br_start_index_line(prev, billing);
*resp_count += Rules__index(R, owner, context);
}
return count;
}
#line 580 "inform7/Chapter 27/Rule Bookings.w"
int show_index_links = TRUE;
void Rules__Bookings__list_suppress_indexed_links(void) {
show_index_links = FALSE;
}
void Rules__Bookings__list_resume_indexed_links(void) {
show_index_links = TRUE;
}
void Rules__Bookings__br_start_index_line(booking *prev, char *billing) {
HTML__open_para(ifl, 2, "hanging");
if ((billing[0]) && (show_index_links)) Rules__Bookings__br_show_linkage_icon(prev);
INDEX("%s", billing);
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;");
if ((billing[0] == 0) && (show_index_links)) Rules__Bookings__br_show_linkage_icon(prev);
}
#line 601 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__br_show_linkage_icon(booking *prev) {
char *icon_name = NULL; /* redundant assignment to appease |gcc -O2| */
if ((prev == NULL) || (prev->next_rule_specificity_law == NULL)) {
HTML__html_icon_with_tooltip(ifl, "rulenone.png", "start of rulebook", NULL);
return;
}
switch (prev->next_rule_specificity) {
case -1: icon_name = "ruleless.png"; break;
case 0: icon_name = "ruleequal.png"; break;
case 1: icon_name = "rulemore.png"; break;
default: internal_error("unknown rule specificity");
}
HTML__html_icon_with_tooltip(ifl, icon_name, prev->next_rule_specificity_law,
prev->next_rule_specificity_lawname);
}
#line 623 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_judge_ordering(booking *list_head) {
booking *br;
if (list_head == NULL) return;
for (br = list_head->next_rule; br; br = br->next_rule) {
if (br->next_rule) {
if (br->placement != br->next_rule->placement)
{
#line 642 "inform7/Chapter 27/Rule Bookings.w"
br->next_rule_specificity = 1;
switch(br->placement) {
case FIRST_PLACEMENT:
switch(br->next_rule->placement) {
case MIDDLE_PLACEMENT:
br->next_rule_specificity_law =
"the rule above was listed as 'first' so precedes this "
"one, which wasn't";
break;
case LAST_PLACEMENT:
br->next_rule_specificity_law =
"the rule above was listed as 'first' so precedes this "
"one, which was listed as 'last'";
break;
default:
Rules__Bookings__list_log(list_head);
internal_error("booking list invariant broken");
break;
}
break;
case MIDDLE_PLACEMENT:
switch(br->next_rule->placement) {
case LAST_PLACEMENT:
br->next_rule_specificity_law =
"the rule below was listed as 'last' so comes after the "
"rule above, which wasn't";
break;
default:
Rules__Bookings__list_log(list_head);
internal_error("booking list invariant broken");
break;
}
break;
default:
Rules__Bookings__list_log(list_head);
internal_error("booking list invariant broken");
break;
}
}
#line 629 "inform7/Chapter 27/Rule Bookings.w"
else
{
#line 684 "inform7/Chapter 27/Rule Bookings.w"
int r;
switch(br->placement) {
case FIRST_PLACEMENT:
br->next_rule_specificity = 0;
br->next_rule_specificity_law =
"these rules were both listed as 'first', so they appear in "
"reverse order of listing";
break;
case MIDDLE_PLACEMENT:
r = Rules__Bookings__compare_specificity_of_br(br, br->next_rule, FALSE);
br->next_rule_specificity = r;
if (r == 0) br->next_rule_specificity_law =
"these rules are equally ranked, so their order is determined by "
"which was defined first (or by explicit 'listed in' sentences)";
else {
br->next_rule_specificity_law =
"the arrow points from a more specific rule to a more general one, "
"as decided by Law";
br->next_rule_specificity_lawname = c_s_stage_law;
}
break;
case LAST_PLACEMENT:
br->next_rule_specificity = 0;
br->next_rule_specificity_law =
"these rules were both listed as 'last', so they appear in order "
"of listing";
break;
}
}
#line 631 "inform7/Chapter 27/Rule Bookings.w"
;
} else {
br->next_rule_specificity = 0;
br->next_rule_specificity_law = NULL;
}
}
}
#line 719 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_compile_rule_phrases(booking *list_head,
OUTPUT_STREAM, int *i, int max_i) {
if (list_head == NULL) return;
int t = Rules__Bookings__no_rules_in_list(list_head);
booking *br; int s;
for (br = list_head->next_rule, s = 1; br; br = br->next_rule, s++) {
Rules__compile_comment(OUT, br->rule_being_booked, s, t);
if (br->next_rule) {
if (br->placement != br->next_rule->placement) {
WRITE("! --- now the ");
switch(br->next_rule->placement) {
case FIRST_PLACEMENT: WRITE("first-placed rules"); break;
case MIDDLE_PLACEMENT: WRITE("mid-placed rules"); break;
case LAST_PLACEMENT: WRITE("last-placed rules"); break;
}
WRITE(" ---\n");
} else {
char *law = br->next_rule_specificity_lawname;
switch(br->next_rule_specificity) {
case -1: WRITE("! <<< %s <<<\n", law); break;
case 0: WRITE("! === equally specific with ===\n"); break;
case 1: WRITE("! >>> %s >>>\n", law); break;
}
}
}
}
CompiledText__divider_comment(OUT);
for (br = list_head->next_rule; br; br = br->next_rule)
Rules__compile_definition(OUT, br->rule_being_booked, i, max_i);
}
#line 756 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__start_list_compilation(OUTPUT_STREAM) {
if (Rulebooks__procedurals_exist()) {
WRITE("Constant PROCEDURAL_RULES_EXIST = true;\n");
WRITE("Array EMPTY_RULEBOOK -> $ff $ff $ff $ff;\n");
} else {
OUT = Routines__begin(OUT, "EMPTY_RULEBOOK");
LocalVariables__add_named_call("forbid_breaks");
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
}
}
#line 776 "inform7/Chapter 27/Rule Bookings.w"
void Rules__Bookings__list_compile(booking *list_head, OUTPUT_STREAM,
char *identifier, int action_based, int parameter_based) {
if (list_head == NULL) return;
int countup = Rules__Bookings__no_rules_in_list(list_head);
if (countup == 0) {
WRITE("Constant %s = EMPTY_RULEBOOK;\n", identifier);
return;
}
int format = ARRAY_RBF;
if (countup > RULE_OPTIMISATION_THRESHOLD) format = GROUPED_ARRAY_RBF;
if (Rulebooks__procedurals_exist() == FALSE)
format = ROUTINE_RBF;
{
#line 799 "inform7/Chapter 27/Rule Bookings.w"
int grouping = FALSE, group_cap = 0;
switch (format) {
case GROUPED_ARRAY_RBF: grouping = TRUE; group_cap = 31; break;
case ROUTINE_RBF: grouping = TRUE; group_cap = 2000000000; break;
}
if (action_based == FALSE) grouping = FALSE;
{
#line 835 "inform7/Chapter 27/Rule Bookings.w"
switch (format) {
case ARRAY_RBF: WRITE("Array %s -->", identifier); break;
case GROUPED_ARRAY_RBF: WRITE("Array %s --> (-2)", identifier); break;
case ROUTINE_RBF:
OUT = Routines__begin(OUT, identifier);
LocalVariables__add_named_call("forbid_breaks");
LocalVariables__add_internal_local_c("rv", "return value");
if (countup > 1)
LocalVariables__add_internal_local_c("original_deadflag", "saved state");
if (parameter_based)
LocalVariables__add_internal_local_c("p", "rulebook parameter");
if (countup > 1) WRITE("original_deadflag = deadflag;\n");
if (parameter_based) WRITE("p = parameter_value;\n");
break;
}
}
#line 806 "inform7/Chapter 27/Rule Bookings.w"
;
int group_size = 0, group_started = FALSE, entry_count = 0, action_group_open = FALSE;
booking *br;
for (br = list_head->next_rule; br; br = br->next_rule) {
parse_node *spec = Rvalues__from_rule(br->rule_being_booked);
if (grouping) {
if (group_size == 0) {
if (group_started)
{
#line 898 "inform7/Chapter 27/Rule Bookings.w"
if (action_group_open) {
switch (format) {
case ROUTINE_RBF: OUTDENT; WRITE("} else {\n"); INDENT;
{
#line 924 "inform7/Chapter 27/Rule Bookings.w"
if (entry_count > 0) WRITE("if (say__p) RulebookParBreak(forbid_breaks);\n");
}
#line 901 "inform7/Chapter 27/Rule Bookings.w"
;
OUTDENT; WRITE("}\n"); break;
}
action_group_open = FALSE;
}
}
#line 813 "inform7/Chapter 27/Rule Bookings.w"
;
action_name *an = Rules__Bookings__br_required_action(br);
booking *brg = br;
while ((brg) && (an == Rules__Bookings__br_required_action(brg))) {
group_size++;
brg = brg->next_rule;
}
if (group_size > group_cap) group_size = group_cap;
group_started = TRUE;
{
#line 855 "inform7/Chapter 27/Rule Bookings.w"
switch (format) {
case GROUPED_ARRAY_RBF:
if (an) WRITE(" ##%s", PL__Actions__identifier(an));
else WRITE(" (-2)");
if (group_size > 1) WRITE(" %d", group_size);
action_group_open = TRUE;
break;
case ROUTINE_RBF:
if (an) {
WRITE("if (action == ##%s) {\n", PL__Actions__identifier(an));
INDENT;
action_group_open = TRUE;
}
break;
}
}
#line 822 "inform7/Chapter 27/Rule Bookings.w"
;
}
group_size--;
}
{
#line 874 "inform7/Chapter 27/Rule Bookings.w"
switch (format) {
case ARRAY_RBF:
case GROUPED_ARRAY_RBF:
WRITE(" "); Specifications__Compiler__compile(OUT, spec);
break;
case ROUTINE_RBF:
if (entry_count > 0) WRITE("if (original_deadflag ~= deadflag) return 0;\n");
{
#line 924 "inform7/Chapter 27/Rule Bookings.w"
if (entry_count > 0) WRITE("if (say__p) RulebookParBreak(forbid_breaks);\n");
}
#line 881 "inform7/Chapter 27/Rule Bookings.w"
;
if (parameter_based) WRITE("parameter_value = p;\n");
WRITE("rv = "); Specifications__Compiler__compile(OUT, spec);
WRITE("();\n");
WRITE("if (rv) {\n"); INDENT;
WRITE("if (rv == 2) return reason_the_action_failed;\n");
WRITE("return ");
Specifications__Compiler__compile(OUT, spec);
WRITE(";\n");
OUTDENT; WRITE("}\n");
WRITE("latest_rule_result-->0 = 0;\n");
break;
}
}
#line 826 "inform7/Chapter 27/Rule Bookings.w"
;
entry_count++;
}
if (group_started)
{
#line 898 "inform7/Chapter 27/Rule Bookings.w"
if (action_group_open) {
switch (format) {
case ROUTINE_RBF: OUTDENT; WRITE("} else {\n"); INDENT;
{
#line 924 "inform7/Chapter 27/Rule Bookings.w"
if (entry_count > 0) WRITE("if (say__p) RulebookParBreak(forbid_breaks);\n");
}
#line 901 "inform7/Chapter 27/Rule Bookings.w"
;
OUTDENT; WRITE("}\n"); break;
}
action_group_open = FALSE;
}
}
#line 829 "inform7/Chapter 27/Rule Bookings.w"
;
{
#line 910 "inform7/Chapter 27/Rule Bookings.w"
switch (format) {
case ARRAY_RBF:
case GROUPED_ARRAY_RBF:
WRITE(" NULL; ! %d rule(s)\n", countup);
break;
case ROUTINE_RBF:
WRITE("return 0; ! %d rule(s)\n", countup);
OUT = Routines__end(OUT);
break;
}
}
#line 830 "inform7/Chapter 27/Rule Bookings.w"
;
}
#line 791 "inform7/Chapter 27/Rule Bookings.w"
;
}
#line 930 "inform7/Chapter 27/Rule Bookings.w"
action_name *Rules__Bookings__br_required_action(booking *br) {
phrase *ph = Rules__get_I7_definition(br->rule_being_booked);
if (ph) return Phrases__Context__required_action(&(ph->runtime_context_data));
return NULL;
}
#line 160 "inform7/Chapter 27/Rulebooks.w"
int new_rulebook_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 171 "inform7/Chapter 27/Rulebooks.w"
Problems__Issue__sentence_problem(_p_(PM_RulebookWithAt),
"this would create a rulebook whose name begins with 'at'",
"which is forbidden since it would lead to ambiguities in "
"the way people write rules. A rule beginning with 'At' "
"is one which happens at a given time, whereas a rule "
"belonging to a rulebook starts with the name of that "
"rulebook, so a rulebook named 'at ...' would make such "
"a rule inscrutable.");
}
#line 163 "inform7/Chapter 27/Rulebooks.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 183 "inform7/Chapter 27/Rulebooks.w"
Problems__Issue__sentence_problem(_p_(PM_RulebookWithTo),
"this would create a rulebook whose name begins with 'to'",
"which is forbidden since it would lead to ambiguities in "
"the way people write rules. A rule beginning with 'To' "
"is one which defines a phrase, whereas a rule "
"belonging to a rulebook starts with the name of that "
"rulebook, so a rulebook named 'to ...' would make such "
"a rule inscrutable.");
}
#line 164 "inform7/Chapter 27/Rulebooks.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 195 "inform7/Chapter 27/Rulebooks.w"
Problems__Issue__sentence_problem(_p_(PM_RulebookWithDefinition),
"this would create a rulebook whose name begins with 'definition'",
"which is forbidden since it would lead to ambiguities in "
"the way people write rules. A rule beginning with 'Definition' "
"is one which defines an adjective, whereas a rule "
"belonging to a rulebook starts with the name of that "
"rulebook, so a rulebook named 'to ...' would make such "
"a rule inscrutable.");
}
#line 165 "inform7/Chapter 27/Rulebooks.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 167 "inform7/Chapter 27/Rulebooks.w"
#line 209 "inform7/Chapter 27/Rulebooks.w"
int rulebook_name_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 212 "inform7/Chapter 27/Rulebooks.w"
#line 222 "inform7/Chapter 27/Rulebooks.w"
rulebook *Rulebooks__new(kind *create_as, wording W) {
rulebook *rb = CREATE(rulebook);
Preform__parse_nt_against_word_range(new_rulebook_name_NTM, W, NULL, NULL);
W = GET_RW(new_rulebook_name_NTM, 1);
rb->primary_name = W;
rb->alternative_name = EMPTY_WORDING;
Identifiers__compose(rb->rb_I6_identifier, 'B', rb->allocation_id, rb->primary_name);
rb->rule_list = Rules__Bookings__list_new();
rb->automatically_generated = FALSE;
rb->used_by_future_action_activity = FALSE;
rb->runs_during_activities = FALSE;
kind *parameter_kind = NULL;
kind *producing_kind = NULL;
Kinds__binary_construction_material(create_as, &parameter_kind, &producing_kind);
Rulebooks__Outcomes__initialise_focus(&(rb->my_focus), parameter_kind);
rb->fragmentation_stem_length = 0;
int def = NO_OUTCOME;
if (rb->allocation_id == INSTEAD_RB) def = FAILURE_OUTCOME;
if (rb->allocation_id == AFTER_RB) def = SUCCESS_OUTCOME;
if (rb->allocation_id == UNSUCCESSFUL_ATTEMPT_BY_RB) def = SUCCESS_OUTCOME;
Rulebooks__Outcomes__initialise_outcomes(&(rb->my_outcomes), producing_kind, def);
rb->placement_list = NULL;
rb->owned_by_rb = StackedVariables__new_owner(rb->allocation_id);
rb->accessible_from_rb = StackedVariables__add_owner_to_list(NULL, rb->owned_by_rb);
if (rb->allocation_id < MAX_BUILT_IN_RULEBOOKS)
built_in_rulebooks[rb->allocation_id] = rb;
if (rb == built_in_rulebooks[ACTION_PROCESSING_RB])
all_action_processing_vars = StackedVariables__add_owner_to_list(NULL, rb->owned_by_rb);
Semantics__Nouns__ExcerptMeanings__register_noun(RULEBOOK_MC, rb->primary_name,
Rvalues__from_rulebook(rb));
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(RULEBOOK_MC,
Preform__Nonparsing__merge(rulebook_name_construction_NTM, 0,
WordAssemblages__from_wording(rb->primary_name)),
Rvalues__from_rulebook(rb));
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(RULEBOOK_MC,
Preform__Nonparsing__merge(rulebook_name_construction_NTM, 1,
WordAssemblages__from_wording(rb->primary_name)),
Rvalues__from_rulebook(rb));
return rb;
}
outcomes *Rulebooks__get_outcomes(rulebook *rb) {
return &(rb->my_outcomes);
}
kind *Rulebooks__contains_kind(rulebook *rb) {
return Kinds__binary_construction(CON_rule,
Rulebooks__get_parameter_kind(rb),
Rulebooks__Outcomes__get_outcome_kind(&(rb->my_outcomes)));
}
kind *Rulebooks__to_kind(rulebook *rb) {
return Kinds__binary_construction(CON_rulebook,
Rulebooks__get_parameter_kind(rb),
Rulebooks__Outcomes__get_outcome_kind(&(rb->my_outcomes)));
}
rulebook *Rulebooks__new_automatic(wording W, kind *basis,
int oc, int ata, int ubfaa, int rda) {
rulebook *rb = Rulebooks__new(
Kinds__binary_construction(CON_rulebook, basis, K_nil),
W);
Rulebooks__Outcomes__set_default_outcome(&(rb->my_outcomes), oc);
Rulebooks__Outcomes__set_focus_ata(&(rb->my_focus), ata);
rb->automatically_generated = TRUE;
rb->used_by_future_action_activity = ubfaa;
rb->runs_during_activities = rda;
return rb;
}
void Rulebooks__set_alt_name(rulebook *rb, wording AW) {
rb->alternative_name = AW;
Semantics__Nouns__ExcerptMeanings__register_noun(RULEBOOK_MC, AW,
Rvalues__from_rulebook(rb));
}
void Rulebooks__fragment_by_actions(rulebook *rb, int wn) {
rb->fragmentation_stem_length = wn;
}
int Rulebooks__requires_specific_action(rulebook *rb) {
if (rb == built_in_rulebooks[CHECK_RB]) return TRUE;
if (rb == built_in_rulebooks[CARRY_OUT_RB]) return TRUE;
if (rb == built_in_rulebooks[REPORT_RB]) return TRUE;
if (rb->fragmentation_stem_length > 0) return TRUE;
return FALSE;
}
#line 327 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__affected_by_placement(rulebook *rb, parse_node *where) {
placement_affecting *npl = CREATE(placement_affecting);
npl->placement_sentence = where;
npl->next = rb->placement_list;
rb->placement_list = npl;
}
int Rulebooks__rb_no_placements(rulebook *rb) {
int t = 0;
placement_affecting *npl = rb->placement_list;
while (npl) { t++; npl = npl->next; }
return t;
}
void Rulebooks__rb_index_placements(rulebook *rb) {
placement_affecting *npl = rb->placement_list;
while (npl) {
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<small><i>NB:</i> ");
Wordings__index(ParseTree__get_text(npl->placement_sentence));
Index__link(Wordings__first_wn(ParseTree__get_text(npl->placement_sentence)));
INDEX("</small><br>\n");
npl = npl->next;
}
}
#line 356 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__focus(rulebook *rb) {
return Rulebooks__Outcomes__get_focus(&(rb->my_focus));
}
kind *Rulebooks__get_parameter_kind(rulebook *rb) {
return Rulebooks__Outcomes__get_focus_parameter_kind(&(rb->my_focus));
}
int Rulebooks__used_by_future_actions(rulebook *rb) {
return rb->used_by_future_action_activity;
}
int Rulebooks__is_empty(rulebook *rb, scene *context) {
if (rb == NULL) return TRUE;
return Rules__Bookings__list_is_empty(rb->rule_list, context);
}
int Rulebooks__no_rules(rulebook *rb) {
if (rb == NULL) return 0;
return Rules__Bookings__no_rules_in_list(rb->rule_list);
}
int Rulebooks__rule_in_rulebook(rule *R, rulebook *rb) {
if (rb == NULL) return FALSE;
return Rules__Bookings__list_contains(rb->rule_list, R);
}
booking *Rulebooks__first_booking(rulebook *rb) {
if (rb == NULL) return NULL;
return rb->rule_list;
}
int Rulebooks__runs_during_activities(rulebook *rb) {
return rb->runs_during_activities;
}
#line 396 "inform7/Chapter 27/Rulebooks.w"
int rulebook_variable_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 403 "inform7/Chapter 27/Rulebooks.w"
*X = NOT_APPLICABLE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_RulebookVariableAnd));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for a rulebook - a value associated "
"with a rulebook and which has a name. The request seems to "
"say that the name in question is '%2', but I'd prefer to "
"avoid 'and', 'or', 'with', or 'having' in such names, please.");
Problems__issue_problem_end();
}
#line 397 "inform7/Chapter 27/Rulebooks.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 399 "inform7/Chapter 27/Rulebooks.w"
#line 418 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__add_variable(rulebook *rb, parse_node *cnode) {
if (ParseTree__get_type(cnode) != PROPERTYCALLED_NT) {
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_RulebookVarUncalled));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for an rulebook - a value associated "
"with a action and which has a name. But since you only give "
"a kind, not a name, I'm stuck. ('The every turn rulebook has a "
"number called importance' is right, 'The every turn rulebook has a "
"number' is too vague.)");
Problems__issue_problem_end();
return;
}
if (Preform__parse_nt_against_word_range(rulebook_variable_name_NTM, ParseTree__get_text(cnode->down->next), NULL, NULL)) {
if (most_recent_result == NOT_APPLICABLE) return;
}
parse_node *spec = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, ParseTree__get_text(cnode->down), NULL, NULL)) spec = most_recent_result_p;
if ((Specifications__is_description(spec)) &&
(Descriptions__is_qualified(spec))) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down));
Problems__Issue__handmade_problem(_p_(PM_RulebookVariableTooSpecific));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for a rulebook - a value associated "
"with a rulebook and which has a name. The request seems to "
"say that the value in question is '%2', but this is too "
"specific a description. (Instead, a kind of value "
"(such as 'number') or a kind of object (such as 'room' "
"or 'thing') should be given. To get a property whose "
"contents can be any kind of object, use 'object'.)");
Problems__issue_problem_end();
return;
}
if (ParseTree__is(spec, CONSTANT_VNT)) {
LOG("Offending SP: $T", spec);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down));
Problems__Issue__handmade_problem(_p_(PM_RulebookVariableBadKind));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is not the name of a kind of "
"value which I know (such as 'number' or 'text').");
Problems__issue_problem_end();
return;
}
kind *K = Specifications__to_kind(spec);
if (K == NULL) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down));
Problems__Issue__handmade_problem(_p_(PM_RulebookVariableKindless));
Problems__issue_problem_segment(
"You wrote %1, but I was expecting to see a kind of value there, "
"and '%2' isn't something I recognise as a kind.");
Problems__issue_problem_end();
return;
}
if (Kinds__Compare__eq(K, K_value)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down));
Problems__Issue__handmade_problem(_p_(PM_RulebookVariableVague));
Problems__issue_problem_segment(
"You wrote %1, but saying that a variable is a 'value' "
"does not give me a clear enough idea what it will hold. "
"You need to say what kind of value: for instance, 'A door "
"has a number called street address.' is allowed because "
"'number' is specific about the kind of value.");
Problems__issue_problem_end();
return;
}
StackedVariables__add_empty(rb->owned_by_rb, ParseTree__get_text(cnode->down->next), K);
}
void Rulebooks__make_stvs_accessible(rulebook *rb, stacked_variable_owner *stvo) {
rb->accessible_from_rb = StackedVariables__add_owner_to_list(rb->accessible_from_rb, stvo);
}
void Rulebooks__rulebook_var_creators_array(OUTPUT_STREAM) {
rulebook *rb;
WRITE("#IFNDEF MEMORY_ECONOMY;\n");
WRITE("Array rulebook_var_creators -->");
LOOP_OVER(rb, rulebook) {
if (StackedVariables__owner_empty(rb->owned_by_rb)) WRITE(" 0");
else WRITE(" RBSTVC_%d", rb->allocation_id);
}
WRITE(" 0;\n");
WRITE("#endif;\n");
LOOP_OVER(rb, rulebook) {
if (StackedVariables__owner_empty(rb->owned_by_rb) == FALSE)
StackedVariables__compile_frame_creator(OUT, rb->owned_by_rb,
" RBSTVC_%d", rb->allocation_id);
}
}
void Rulebooks__rulebook_var_creators_lookup(OUTPUT_STREAM) {
rulebook *rb;
WRITE("#ifdef MEMORY_ECONOMY;\n");
WRITE("switch (rb) {\n");
LOOP_OVER(rb, rulebook)
if (StackedVariables__owner_empty(rb->owned_by_rb) == FALSE)
WRITE("%d: cr = RBSTVC_%d;\n", rb->allocation_id, rb->allocation_id);
WRITE("}\n");
WRITE("#IFNOT;\n");
WRITE("cr = rulebook_var_creators-->rb;\n");
WRITE("#endif;\n");
}
#line 535 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__log_name_only(rulebook *rb) {
LOG("Rulebook %d ($w)", rb->allocation_id, rb->primary_name);
}
void Rulebooks__log(rulebook *rb) {
Rulebooks__log_name_only(rb);
LOG(": ");
Rules__Bookings__list_log(rb->rule_list);
}
int Rulebooks__index(rulebook *rb, char *billing, scene *context,
action_name *action_context, int *resp_count) {
int suppress_outcome = FALSE, t;
if (rb == NULL) return 0;
if (billing == NULL) internal_error("No billing for rb index");
if (billing[0] != 0) {
if ((action_context) || (Rules__Bookings__list_is_empty(rb->rule_list, context)))
suppress_outcome = TRUE;
}
t = Rules__Bookings__list_index(rb->rule_list, context, action_context,
billing, rb, resp_count);
Rulebooks__Outcomes__index_outcomes(&(rb->my_outcomes), suppress_outcome);
Rulebooks__rb_index_placements(rb);
return t;
}
void Rulebooks__index_action_rules(action_name *an, rulebook *rb,
int code, char *desc, int *resp_count) {
int t = 0;
Rules__Bookings__list_suppress_indexed_links();
if (code >= 0) t += Rulebooks__index(built_in_rulebooks[code], desc,
NULL, an, resp_count);
if (rb) t += Rulebooks__index(rb, desc, NULL, NULL, resp_count);
Rules__Bookings__list_resume_indexed_links();
if (t > 0) INDEX("<br>");
}
#line 583 "inform7/Chapter 27/Rulebooks.w"
int rulebook_stem_NTMR(wording W, int *X, void **XP) {
#line 584 "inform7/Chapter 27/Rulebooks.w"
rulebook_match rm = Rulebooks__rb_match_from_description(W);
if (rm.matched_rulebook == NULL) return FALSE;
parsed_rm = rm;
return Wordings__first_wn(W) + rm.advance_words - 1;
}
#line 611 "inform7/Chapter 27/Rulebooks.w"
int rulebook_stem_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = INDEF_ART; place_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = DEF_ART; place_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = NO_ART; place_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 615 "inform7/Chapter 27/Rulebooks.w"
int rulebook_stem_inner_unarticled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = MIDDLE_PLACEMENT; len_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = MIDDLE_PLACEMENT; len_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = FIRST_PLACEMENT; len_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = FIRST_PLACEMENT; len_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = LAST_PLACEMENT; len_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = LAST_PLACEMENT; len_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = MIDDLE_PLACEMENT; len_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 624 "inform7/Chapter 27/Rulebooks.w"
int rulebook_stem_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 2; rulebook_m_NTMV = built_in_rulebooks[WHEN_SCENE_BEGINS_RB] /* scenes\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2; rulebook_m_NTMV = built_in_rulebooks[WHEN_SCENE_ENDS_RB] /* scenes\_plugin */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; rulebook_m_NTMV = NULL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 629 "inform7/Chapter 27/Rulebooks.w"
#line 633 "inform7/Chapter 27/Rulebooks.w"
rulebook_match Rulebooks__rb_match_from_description(wording W) {
int initial_w1 = Wordings__first_wn(W), modifier_words;
int art = NO_ART, pl = MIDDLE_PLACEMENT;
rulebook *rb;
rulebook_match rm;
Preform__parse_nt_against_word_range(rulebook_stem_inner_NTM, W, NULL, NULL);
W = GET_RW(rulebook_stem_name_NTM, 1);
art = most_recent_result; pl = place_NTMV;
modifier_words = Wordings__first_wn(W) - initial_w1;
rm.match_length = 0;
rm.advance_words = 0;
rm.match_from = initial_w1;
rm.tail_words = 0;
rm.matched_rulebook = NULL;
rm.article_used = art;
rm.placement_requested = pl;
LOOP_OVER(rb, rulebook) {
if (rb == rulebook_m_NTMV) {
if (rm.match_length < len_NTMV) {
rm.match_length = len_NTMV;
rm.matched_rulebook = rb;
}
} else {
if (Wordings__starts_with(W, rb->primary_name)) {
if (rm.match_length < Wordings__length(rb->primary_name)) {
rm.match_length = Wordings__length(rb->primary_name);
rm.matched_rulebook = rb;
}
} else if (Wordings__starts_with(W, rb->alternative_name)) {
if (rm.match_length < Wordings__length(rb->alternative_name)) {
rm.match_length = Wordings__length(rb->alternative_name);
rm.matched_rulebook = rb;
}
}
}
}
if (rm.match_length == 0) return rm;
rm.advance_words = rm.match_length;
if (rm.matched_rulebook == rulebook_m_NTMV) {
rm.tail_words = 1;
rm.match_length = 1;
}
if (rm.matched_rulebook->fragmentation_stem_length) {
int w1a = Wordings__first_wn(W) + rm.match_length - 1;
if (w1a != Wordings__last_wn(W))
rm.match_length = rm.matched_rulebook->fragmentation_stem_length;
}
rm.match_length += modifier_words;
rm.advance_words += modifier_words;
return rm;
}
#line 715 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__attach_rule(rulebook *rb, booking *the_new_rule,
int placing, int side, rule *ref_rule) {
LOGIF(RULE_ATTACHMENTS, "Attaching booked rule $b at sentence:\n $T",
the_new_rule, current_sentence);
LOGIF(RULE_ATTACHMENTS, "Rulebook before attachment: $K", rb);
if (Rules__Bookings__get_rule(the_new_rule) == ref_rule) {
if (side != INSTEAD_SIDE)
Problems__Issue__sentence_problem(_p_(PM_BeforeOrAfterSelf),
"a rule can't be before or after itself",
"so this makes no sense to me.");
return;
}
if ((rb == built_in_rulebooks[BEFORE_RB]) ||
(rb == built_in_rulebooks[AFTER_RB]) ||
(rb == built_in_rulebooks[INSTEAD_RB])) {
phrase *ph = Rules__get_I7_definition(Rules__Bookings__get_rule(the_new_rule));
if (ph) {
action_name *an = Phrases__Context__required_action(&(ph->runtime_context_data));
if ((an) && (PL__Actions__is_out_of_world(an)))
Problems__Issue__sentence_problem(_p_(PM_OOWinIWRulebook),
"this rulebook has no effect on actions which happen out of world",
"so I'm not going to let you file this rule in it. ('Check', "
"'Carry out' and 'Report' work fine for out of world actions: "
"but 'Before', 'Instead' and 'After' have no effect on them.)");
}
}
if (rb == built_in_rulebooks[SETTING_ACTION_VARIABLES_RB]) {
Rules__set_never_test_actor(Rules__Bookings__get_rule(the_new_rule));
} else {
Rulebooks__Outcomes__modify_rule_to_suit_focus(&(rb->my_focus),
Rules__Bookings__get_rule(the_new_rule));
}
if (side == INSTEAD_SIDE) {
LOGIF(RULE_ATTACHMENTS,
"Copying actor test flags from rule being replaced\n");
Rules__copy_actor_test_flags(Rules__Bookings__get_rule(the_new_rule), ref_rule);
LOGIF(RULE_ATTACHMENTS,
"Copying former rulebook's variable permissions to displaced rule\n");
Rules__acquire_stvol(ref_rule, rb->accessible_from_rb);
if (Rulebooks__focus(rb) == ACTION_FOCUS)
Rules__acquire_action_variables(ref_rule);
}
Rules__acquire_stvol(Rules__Bookings__get_rule(the_new_rule), rb->accessible_from_rb);
if (Rulebooks__focus(rb) == ACTION_FOCUS)
Rules__acquire_action_variables(Rules__Bookings__get_rule(the_new_rule));
if (rb->fragmentation_stem_length > 0)
Rules__suppress_action_testing(Rules__Bookings__get_rule(the_new_rule));
Phrases__Context__ensure_avl(Rules__Bookings__get_rule(the_new_rule));
Rules__Bookings__list_add(rb->rule_list, the_new_rule, placing, side, ref_rule);
LOGIF(RULE_ATTACHMENTS, "Rulebook after attachment: $K", rb);
}
void Rulebooks__detach_rule(rulebook *rb, rule *the_new_rule) {
Rules__Bookings__list_remove(rb->rule_list, the_new_rule);
}
#line 785 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__compile_rule_phrases(rulebook *rb, OUTPUT_STREAM, int *i, int max_i) {
Rules__Bookings__list_judge_ordering(rb->rule_list);
if (Rules__Bookings__list_is_empty_of_i7_rules(rb->rule_list)) return;
WRITE("\n");
CompiledText__divider_comment(OUT);
WRITE("! Rules in rulebook: ");
Wordings__to_stream_raw_within_i6_literal(OUT, rb->primary_name);
WRITE(" (%s)\n", rb->rb_I6_identifier);
CompiledText__divider_comment(OUT);
Rules__Bookings__list_compile_rule_phrases(rb->rule_list, OUT, i, max_i);
CompiledText__divider_comment(OUT);
}
void Rulebooks__rulebooks_array_array(OUTPUT_STREAM) {
rulebook *rb;
WRITE("Array rulebooks_array -->");
LOOP_OVER(rb, rulebook)
WRITE(" %s", rb->rb_I6_identifier);
WRITE(" 0;\n");
}
int Rulebooks__procedurals_exist(void) {
return FALSE;
}
void Rulebooks__compile_rulebooks(OUTPUT_STREAM) {
Rules__Bookings__start_list_compilation(OUT);
rulebook *rb;
LOOP_OVER(rb, rulebook) {
int act = FALSE;
if (Rulebooks__focus(rb) == ACTION_FOCUS) act = TRUE;
if (rb->automatically_generated) act = FALSE;
int par = FALSE;
if (Rulebooks__focus(rb) == PARAMETER_FOCUS) par = TRUE;
LOGIF(RULEBOOK_COMPILATION, "Compiling rulebook: $w = %s\n",
rb->primary_name, rb->rb_I6_identifier);
Rules__Bookings__list_compile(rb->rule_list, OUT, rb->rb_I6_identifier, act, par);
}
Rules__check_placement_safety();
}
void Rulebooks__RulebookNames_array(OUTPUT_STREAM) {
rulebook *rb;
WRITE("Array RulebookNames -->\n"); INDENT;
LOOP_OVER(rb, rulebook) {
WRITE("\"");
Wordings__to_stream_raw_within_i6_literal(OUT, rb->primary_name);
WRITE(" rulebook\" ! %d\n", rb->allocation_id);
}
OUTDENT; WRITE(";\n\n");
}
#line 848 "inform7/Chapter 27/Rulebooks.w"
int rulebook_property_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 856 "inform7/Chapter 27/Rulebooks.w"
*X = NOT_APPLICABLE;
Problems__Issue__sentence_problem(_p_(PM_NonOutcomeProperty),
"the only properties of a rulebook are its outcomes",
"for the time being at least.");
}
#line 851 "inform7/Chapter 27/Rulebooks.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 852 "inform7/Chapter 27/Rulebooks.w"
#line 864 "inform7/Chapter 27/Rulebooks.w"
outcomes *outcomes_being_parsed = NULL;
void Rulebooks__parse_properties(rulebook *rb, wording W) {
outcomes_being_parsed = &(rb->my_outcomes);
Preform__parse_nt_against_word_range(rulebook_property_NTM, W, NULL, NULL);
}
kind *Rulebooks__kind_from_context(void) {
phrase *ph = phrase_being_compiled;
rulebook *rb;
if (ph == NULL) return NULL;
LOOP_OVER(rb, rulebook)
if (Rules__Bookings__list_contains_ph(rb->rule_list, ph))
return Rulebooks__Outcomes__get_outcome_kind(&(rb->my_outcomes));
return NULL;
}
#line 886 "inform7/Chapter 27/Rulebooks.w"
void Rulebooks__index_page(int n) {
if (n == 1) {
{
#line 970 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>Rules governing actions</b><p>");
INDEX("<p>These rules are the ones which tell Inform how actions work, "
"and which affect how they happen in particular cases.</p>");
Rulebooks__index_rules_box("Persuasion", EMPTY_WORDING, "rules_per",
built_in_rulebooks[PERSUASION_RB], NULL, NULL, 1, TRUE);
Rulebooks__index_rules_box("Unsuccessful attempt by", EMPTY_WORDING, "rules_fail",
built_in_rulebooks[UNSUCCESSFUL_ATTEMPT_BY_RB], NULL, NULL, 1, TRUE);
Rulebooks__index_rules_box("Before", EMPTY_WORDING, "rules_before",
built_in_rulebooks[BEFORE_RB], NULL, NULL, 1, TRUE);
Rulebooks__index_rules_box("Instead", EMPTY_WORDING, "rules_instead",
built_in_rulebooks[INSTEAD_RB], NULL, NULL, 1, TRUE);
Rulebooks__index_rules_box("Check", EMPTY_WORDING, NULL, NULL, NULL,
"Check rules are tied to specific actions, and there are too many "
"to index here. For instance, the check taking rules can only ever "
"affect the taking action, so they are indexed on the detailed index "
"page for taking.", 1, TRUE);
Rulebooks__index_rules_box("Carry out", EMPTY_WORDING, NULL, NULL, NULL,
"Carry out rules are tied to specific actions, and there are too many "
"to index here.", 1, TRUE);
Rulebooks__index_rules_box("After", EMPTY_WORDING, "rules_after",
built_in_rulebooks[AFTER_RB], NULL, NULL, 1, TRUE);
Rulebooks__index_rules_box("Report", EMPTY_WORDING, NULL, NULL, NULL,
"Report rules are tied to specific actions, and there are too many "
"to index here.", 1, TRUE);
}
#line 888 "inform7/Chapter 27/Rulebooks.w"
;
{
#line 932 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>Rules added to the sequence of play</b></p>");
INDEX("<p>These rulebooks are the best places to put rules timed to happen "
"at the start, at the end, or once each turn. (Each is run through at "
"a carefully chosen moment in the relevant top-level rulebook.) It is "
"also possible to have rules take effect at specific times of day "
"or when certain events happen. Those are listed in the Scenes index, "
"alongside rules taking place when scenes begin or end.</p>");
Rulebooks__index_rules_box("When play begins", EMPTY_WORDING, "rules_wpb",
built_in_rulebooks[WHEN_PLAY_BEGINS_RB], NULL, NULL, 1, TRUE);
Rulebooks__index_rules_box("Every turn", EMPTY_WORDING, "rules_et",
built_in_rulebooks[EVERY_TURN_RB], NULL, NULL, 1, TRUE);
Rulebooks__index_rules_box("When play ends", EMPTY_WORDING, "rules_wpe",
built_in_rulebooks[WHEN_PLAY_ENDS_RB], NULL, NULL, 1, TRUE);
}
#line 889 "inform7/Chapter 27/Rulebooks.w"
;
{
#line 949 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>How commands are understood</b></p>");
INDEX("<p>'Understanding' here means turning a typed command, like GET FISH, "
"into one or more actions, like taking the red herring. This is all handled "
"by a single large rule (the parse command rule), but that rule makes use "
"of the following activities and rulebooks in its work.</p>");
Rulebooks__index_rules_box("Does the player mean", EMPTY_WORDING, "rules_dtpm",
built_in_rulebooks[DOES_THE_PLAYER_MEAN_RB], NULL, NULL, 1, TRUE);
Activities__index_by_number(READING_A_COMMAND_ACT, 1);
Activities__index_by_number(DECIDING_SCOPE_ACT, 1);
Activities__index_by_number(DECIDING_CONCEALED_POSSESS_ACT, 1);
Activities__index_by_number(DECIDING_WHETHER_ALL_INC_ACT, 1);
Activities__index_by_number(CLARIFYING_PARSERS_CHOICE_ACT, 1);
Activities__index_by_number(ASKING_WHICH_DO_YOU_MEAN_ACT, 1);
Activities__index_by_number(PRINTING_A_PARSER_ERROR_ACT, 1);
Activities__index_by_number(SUPPLYING_A_MISSING_NOUN_ACT, 1);
Activities__index_by_number(SUPPLYING_A_MISSING_SECOND_ACT, 1);
Activities__index_by_number(IMPLICITLY_TAKING_ACT, 1);
}
#line 890 "inform7/Chapter 27/Rulebooks.w"
;
{
#line 1043 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>How things are described</b></p>");
INDEX("<p>These activities control what is printed when naming rooms or "
"things, and their descriptions.</p>");
Activities__index_by_number(PRINTING_THE_NAME_ACT, 1);
Activities__index_by_number(PRINTING_THE_PLURAL_NAME_ACT, 1);
Activities__index_by_number(PRINTING_A_NUMBER_OF_ACT, 1);
Activities__index_by_number(PRINTING_ROOM_DESC_DETAILS_ACT, 1);
Activities__index_by_number(PRINTING_INVENTORY_DETAILS_ACT, 1);
Activities__index_by_number(LISTING_CONTENTS_ACT, 1);
Activities__index_by_number(GROUPING_TOGETHER_ACT, 1);
Activities__index_by_number(WRITING_A_PARAGRAPH_ABOUT_ACT, 1);
Activities__index_by_number(LISTING_NONDESCRIPT_ITEMS_ACT, 1);
Activities__index_by_number(PRINTING_LOCALE_DESCRIPTION_ACT, 1);
Activities__index_by_number(CHOOSING_NOTABLE_LOCALE_OBJ_ACT, 1);
Activities__index_by_number(PRINTING_LOCALE_PARAGRAPH_ACT, 1);
}
#line 891 "inform7/Chapter 27/Rulebooks.w"
;
{
#line 1019 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>How accessibility is judged</b></p>");
INDEX("<p>These rulebooks are used when deciding who can reach what, and "
"who can see what.</p>");
Rulebooks__index_rules_box("Reaching inside", EMPTY_WORDING, "rules_ri",
built_in_rulebooks[REACHING_INSIDE_RB], NULL, NULL, 1, TRUE);
Rulebooks__index_rules_box("Reaching outside", EMPTY_WORDING, "rules_ri",
built_in_rulebooks[REACHING_OUTSIDE_RB], NULL, NULL, 1, TRUE);
Rulebooks__index_rules_box("Visibility", EMPTY_WORDING, "visibility",
built_in_rulebooks[VISIBILITY_RB], NULL, NULL, 1, TRUE);
}
#line 892 "inform7/Chapter 27/Rulebooks.w"
;
{
#line 1032 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>Light and darkness</b></p>");
INDEX("<p>These activities control how we describe darkness.</p>");
Activities__index_by_number(PRINTING_NAME_OF_DARK_ROOM_ACT, 1);
Activities__index_by_number(PRINTING_DESC_OF_DARK_ROOM_ACT, 1);
Activities__index_by_number(PRINTING_NEWS_OF_DARKNESS_ACT, 1);
Activities__index_by_number(PRINTING_NEWS_OF_LIGHT_ACT, 1);
Activities__index_by_number(REFUSAL_TO_ACT_IN_DARK_ACT, 1);
}
#line 893 "inform7/Chapter 27/Rulebooks.w"
;
{
#line 911 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>The top level</b></p>");
INDEX("<p>An Inform story file spends its whole time working through "
"these three master rulebooks. They can be altered, just as all "
"rulebooks can, but it's generally better to leave them alone.</p>");
Rulebooks__index_rules_box("Startup rules", EMPTY_WORDING, NULL,
built_in_rulebooks[STARTUP_RB], NULL, NULL, 1, TRUE);
Activities__index_by_number(STARTING_VIRTUAL_MACHINE_ACT, 2);
Activities__index_by_number(PRINTING_BANNER_TEXT_ACT, 2);
Rulebooks__index_rules_box("Turn sequence rules", EMPTY_WORDING, NULL,
built_in_rulebooks[TURN_SEQUENCE_RB], NULL, NULL, 1, TRUE);
Activities__index_by_number(CONSTRUCTING_STATUS_LINE_ACT, 2);
Rulebooks__index_rules_box("Shutdown rules", EMPTY_WORDING, NULL,
built_in_rulebooks[SHUTDOWN_RB], NULL, NULL, 1, TRUE);
Activities__index_by_number(AMUSING_A_VICTORIOUS_PLAYER_ACT, 2);
Activities__index_by_number(PRINTING_PLAYERS_OBITUARY_ACT, 2);
Activities__index_by_number(DEALING_WITH_FINAL_QUESTION_ACT, 2);
}
#line 894 "inform7/Chapter 27/Rulebooks.w"
;
{
#line 998 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>How actions are processed</b></p>");
INDEX("<p>These form the technical machinery for dealing with actions, and are "
"called on at least once every turn. They seldom need to be changed.</p>");
Rulebooks__index_rules_box("Action-processing rules", EMPTY_WORDING, NULL,
built_in_rulebooks[ACTION_PROCESSING_RB], NULL, NULL, 1, TRUE);
Rulebooks__index_rules_box("Specific action-processing rules", EMPTY_WORDING, NULL,
built_in_rulebooks[SPECIFIC_ACTION_PROCESSING_RB], NULL, NULL, 2, TRUE);
Rulebooks__index_rules_box("Player's action awareness rules", EMPTY_WORDING, NULL,
built_in_rulebooks[PLAYERS_ACTION_AWARENESS_RB], NULL, NULL, 3, TRUE);
}
#line 895 "inform7/Chapter 27/Rulebooks.w"
;
{
#line 1011 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>How responses are printed</b></p>");
INDEX("<p>The Standard Rules, and some extensions, reply to the player's "
"commands with messages which are able to be modified.</p>");
Activities__index_by_number(PRINTING_RESPONSE_ACT, 1);
}
#line 896 "inform7/Chapter 27/Rulebooks.w"
;
} else {
if (Rulebooks__noteworthy_rulebooks(NULL) > 0)
{
#line 1062 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>From the source text</b></p>");
extension_file *ef = NULL; /* that is, not in an extension at all */
{
#line 1077 "inform7/Chapter 27/Rulebooks.w"
activity *av;
rulebook *rb;
LOOP_OVER(rb, rulebook) {
source_file *sf = Lexer__file_of_origin(Wordings__first_wn(rb->primary_name));
if (rb->automatically_generated) continue;
if (((ef == NULL) && (sf == NULL)) ||
(SourceFiles__get_extension_corresponding(sf) == ef))
Rulebooks__index_rules_box(NULL, rb->primary_name, NULL, rb, NULL, NULL, 1, TRUE);
}
LOOP_OVER(av, activity) {
source_file *sf = Lexer__file_of_origin(Wordings__first_wn(av->name));
if (((ef == NULL) && (sf == NULL)) ||
(SourceFiles__get_extension_corresponding(sf) == ef))
Activities__index(av, 1);
}
}
#line 1064 "inform7/Chapter 27/Rulebooks.w"
;
}
#line 899 "inform7/Chapter 27/Rulebooks.w"
;
extension_file *ef;
LOOP_OVER(ef, extension_file)
if (ef != standard_rules_extension)
if (Rulebooks__noteworthy_rulebooks(ef) > 0)
{
#line 1069 "inform7/Chapter 27/Rulebooks.w"
INDEX("<p><b>From the extension ");
Extensions__IDs__write_to_HTML_file(ifl, Extensions__Files__get_eid(ef), FALSE);
INDEX("</b></p>");
{
#line 1077 "inform7/Chapter 27/Rulebooks.w"
activity *av;
rulebook *rb;
LOOP_OVER(rb, rulebook) {
source_file *sf = Lexer__file_of_origin(Wordings__first_wn(rb->primary_name));
if (rb->automatically_generated) continue;
if (((ef == NULL) && (sf == NULL)) ||
(SourceFiles__get_extension_corresponding(sf) == ef))
Rulebooks__index_rules_box(NULL, rb->primary_name, NULL, rb, NULL, NULL, 1, TRUE);
}
LOOP_OVER(av, activity) {
source_file *sf = Lexer__file_of_origin(Wordings__first_wn(av->name));
if (((ef == NULL) && (sf == NULL)) ||
(SourceFiles__get_extension_corresponding(sf) == ef))
Activities__index(av, 1);
}
}
#line 1072 "inform7/Chapter 27/Rulebooks.w"
;
}
#line 904 "inform7/Chapter 27/Rulebooks.w"
;
}
}
#line 1096 "inform7/Chapter 27/Rulebooks.w"
int Rulebooks__noteworthy_rulebooks(extension_file *ef) {
int nb = 0;
activity *av;
rulebook *rb;
LOOP_OVER(rb, rulebook) {
source_file *sf = Lexer__file_of_origin(Wordings__first_wn(rb->primary_name));
if (rb->automatically_generated) continue;
if (((ef == NULL) && (sf == NULL)) ||
(SourceFiles__get_extension_corresponding(sf) == ef)) nb++;
}
LOOP_OVER(av, activity) {
source_file *sf = Lexer__file_of_origin(Wordings__first_wn(av->name));
if (((ef == NULL) && (sf == NULL)) ||
(SourceFiles__get_extension_corresponding(sf) == ef)) nb++;
}
return nb;
}
void Rulebooks__index_scene(void) {
INDEX("<p><b>The scene-changing machinery</b><p>");
Rulebooks__index_rules_box("Scene changing", EMPTY_WORDING, NULL, built_in_rulebooks[SCENE_CHANGING_RB], NULL, NULL, 1, FALSE);
}
int unique_xtra_no = 0;
void Rulebooks__index_rules_box(char *name, wording W, char *doc_link,
rulebook *rb, activity *av, char *text, int indent, int hide_behind_plus) {
int xtra_no = 0;
if (rb) xtra_no = rb->allocation_id;
else if (av) xtra_no = NUMBER_CREATED(rulebook) + av->allocation_id;
else xtra_no = NUMBER_CREATED(rulebook) + NUMBER_CREATED(activity) + unique_xtra_no++;
char *col = "e0e0e0";
if (av) col = "e8e0c0";
int n = 0;
if (rb) n = Rulebooks__no_rules(rb);
if (av) n = Activities__no_rules(av);
char textual_name[600];
if (name) strcpy(textual_name, name);
else if (Wordings__first_wn(W) >= 0)
Wordings__to_string_raw_truncated(textual_name, 500, W);
else strcpy(textual_name, "nameless");
textual_name[0] = Platform__tolower(textual_name[0]);
if (hide_behind_plus) {
HTML__open_para(ifl, indent+1, "tight");
Index__extra_link(xtra_no);
if (n == 0) INDEX("<font color=\"#808080\">");
INDEX("%s", textual_name);
{
#line 1211 "inform7/Chapter 27/Rulebooks.w"
if (doc_link) Index__DocReferences__link(doc_link);
INDEX(" ... ");
if (av) INDEX(" activity"); else {
if ((rb) && (Rulebooks__get_parameter_kind(rb)) &&
(Kinds__Compare__eq(Rulebooks__get_parameter_kind(rb), K_action_name) == FALSE)) {
INDEX(" ");
Kinds__Textual__write_articled(ifl, Rulebooks__get_parameter_kind(rb));
INDEX(" based");
}
INDEX(" rulebook");
}
int wn = -1;
if (rb) wn = Wordings__first_wn(rb->primary_name);
else if (av) wn = Wordings__first_wn(av->name);
if (wn >= 0) Index__link(wn);
}
#line 1146 "inform7/Chapter 27/Rulebooks.w"
;
INDEX(" (%d rule%s)", n, (n==1)?"":"s");
if (n == 0) INDEX("</font>");
INDEX("</p>");
Index__extra_div_open(xtra_no, indent+1, col);
} else {
HTML__open_para(ifl, indent, "");
HTML__open_coloured_box(ifl, col, ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
}
HTML__begin_html_table(ifl, NULL, TRUE, 0, 4, 0, 0, 0);
HTML__first_html_column(ifl, 0);
HTML__open_para(ifl, 1, "tight");
INDEX("<b>%s</b>", textual_name);
{
#line 1211 "inform7/Chapter 27/Rulebooks.w"
if (doc_link) Index__DocReferences__link(doc_link);
INDEX(" ... ");
if (av) INDEX(" activity"); else {
if ((rb) && (Rulebooks__get_parameter_kind(rb)) &&
(Kinds__Compare__eq(Rulebooks__get_parameter_kind(rb), K_action_name) == FALSE)) {
INDEX(" ");
Kinds__Textual__write_articled(ifl, Rulebooks__get_parameter_kind(rb));
INDEX(" based");
}
INDEX(" rulebook");
}
int wn = -1;
if (rb) wn = Wordings__first_wn(rb->primary_name);
else if (av) wn = Wordings__first_wn(av->name);
if (wn >= 0) Index__link(wn);
}
#line 1163 "inform7/Chapter 27/Rulebooks.w"
;
INDEX("</p>");
HTML__next_html_column_right_justified(ifl, 0);
HTML__open_para(ifl, 1, "tight");
if (av) {
char skeleton[600];
sprintf(skeleton, "Before %s:", textual_name);
HTML__Javascript__paste(ifl, skeleton);
INDEX("&nbsp;<i>b</i> ");
sprintf(skeleton, "Rule for %s:", textual_name);
HTML__Javascript__paste(ifl, skeleton);
INDEX("&nbsp;<i>f</i> ");
sprintf(skeleton, "After %s:", textual_name);
HTML__Javascript__paste(ifl, skeleton);
INDEX("&nbsp;<i>a</i>");
} else {
HTML__Javascript__paste(ifl, textual_name);
INDEX("&nbsp;<i>name</i>");
}
INDEX("</p>");
HTML__end_html_row(ifl);
HTML__end_html_table(ifl);
if ((rb) && (Rulebooks__is_empty(rb, NULL))) text = "There are no rules in this rulebook.";
if (text) {
HTML__open_para(ifl, 2, "tight");
INDEX("%s</p>", text);
} else {
if (rb) {
int ignore_me = 0;
Rulebooks__index(rb, "", NULL, NULL, &ignore_me);
}
if (av) Activities__index_details(av);
}
if (hide_behind_plus) {
Index__extra_div_close(col);
} else {
HTML__close_coloured_box(ifl, col, ROUND_BOX_TOP+ROUND_BOX_BOTTOM);
INDEX("</p>");
}
}
#line 90 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__initialise_outcomes(outcomes *outs, kind *K, int def) {
outs->value_outcome_kind = K;
outs->default_outcome_declared = FALSE;
outs->default_rule_outcome = def;
outs->default_named_outcome = NULL;
}
void Rulebooks__Outcomes__set_default_outcome(outcomes *outs, int def) {
outs->default_rule_outcome = def;
}
kind *Rulebooks__Outcomes__get_outcome_kind(outcomes *outs) {
return outs->value_outcome_kind;
}
#line 110 "inform7/Chapter 27/Focus and Outcome.w"
int rulebook_default_outcome_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 122 "inform7/Chapter 27/Focus and Outcome.w"
if (outcomes_being_parsed->default_outcome_declared) {
Problems__Issue__sentence_problem(_p_(PM_DefaultOutcomeTwice),
"the default outcome for this rulebook has already been declared",
"and this is something which can only be done once.");
} else {
outcomes_being_parsed->default_outcome_declared = TRUE;
outcomes_being_parsed->default_rule_outcome = R[1];
}
}
#line 111 "inform7/Chapter 27/Focus and Outcome.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 134 "inform7/Chapter 27/Focus and Outcome.w"
Problems__Issue__sentence_problem(_p_(PM_BadDefaultOutcome),
"the default outcome given for the rulebook isn't what I expected",
"which would be one of 'default success', 'default failure' or "
"'default no outcome'.");
}
#line 112 "inform7/Chapter 27/Focus and Outcome.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 113 "inform7/Chapter 27/Focus and Outcome.w"
int rule_outcome_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = SUCCESS_OUTCOME;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FAILURE_OUTCOME;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = NO_OUTCOME;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 118 "inform7/Chapter 27/Focus and Outcome.w"
#line 142 "inform7/Chapter 27/Focus and Outcome.w"
int default_rbno_flag = FALSE;
#line 153 "inform7/Chapter 27/Focus and Outcome.w"
int rulebook_outcome_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 157 "inform7/Chapter 27/Focus and Outcome.w"
int rulebook_outcome_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 161 "inform7/Chapter 27/Focus and Outcome.w"
int rulebook_outcome_setting_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; if (!preform_lookahead_mode)
{
#line 183 "inform7/Chapter 27/Focus and Outcome.w"
wording OW = GET_RW(form_of_named_rule_outcome_NTM, 1);
int def = FALSE;
if (default_rbno_flag) {
if (outcomes_being_parsed->default_named_outcome) {
Problems__Issue__sentence_problem(_p_(PM_DefaultNamedOutcomeTwice),
"at most one of the named outcomes from a rulebook "
"can be the default",
"and here we seem to have two.");
return TRUE;
}
def = TRUE;
if (outcomes_being_parsed->default_outcome_declared) {
Problems__Issue__sentence_problem(_p_(PM_DefaultOutcomeAlready),
"the default outcome for this rulebook has already "
"been declared",
"and this is something which can only be done once.");
return TRUE;
}
outcomes_being_parsed->default_outcome_declared = TRUE;
}
int koo = R[1];
if (koo != UNRECOGNISED_OUTCOME) {
named_rulebook_outcome *rbno = Rulebooks__Outcomes__rbno_by_name(OW);
rulebook_outcome *ro, *last = NULL;
int dup = FALSE;
for (ro = outcomes_being_parsed->named_outcomes; ro; ro = ro->next) {
if (ro->outcome_name == rbno) dup = TRUE;
last = ro;
}
if (dup) {
Problems__Issue__sentence_problem(_p_(PM_DuplicateOutcome),
"this duplicates a previous assignment of the same outcome",
"and to the same rulebook.");
} else {
rulebook_outcome *nro = CREATE(rulebook_outcome);
nro->next = NULL;
nro->outcome_name = rbno;
nro->kind_of_outcome = koo;
if (def) outcomes_being_parsed->default_named_outcome = nro;
if (last) last->next = nro; else outcomes_being_parsed->named_outcomes = nro;
}
}
}
#line 163 "inform7/Chapter 27/Focus and Outcome.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 164 "inform7/Chapter 27/Focus and Outcome.w"
int form_of_named_rule_outcome_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; default_rbno_flag = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; default_rbno_flag = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1]; default_rbno_flag = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 175 "inform7/Chapter 27/Focus and Outcome.w"
*X = UNRECOGNISED_OUTCOME;
Problems__Issue__sentence_problem(_p_(PM_BadOutcomeClarification),
"the bracketed clarification isn't what I expected",
"which would be one of '(success)', '(failure)' or '(no outcome)'.");
}
#line 169 "inform7/Chapter 27/Focus and Outcome.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = SUCCESS_OUTCOME; default_rbno_flag = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 171 "inform7/Chapter 27/Focus and Outcome.w"
#line 230 "inform7/Chapter 27/Focus and Outcome.w"
int named_rulebook_outcome_NTMR(wording W, int *X, void **XP) {
#line 231 "inform7/Chapter 27/Focus and Outcome.w"
parse_node *p = SParser__parse_excerpt(MISCELLANEOUS_MC, W);
if (Rvalues__is_CONSTANT_of_kind(p, K_rulebook_outcome)) {
*XP = Rvalues__to_named_rulebook_outcome(p);
return TRUE;
}
return FALSE;
}
#line 242 "inform7/Chapter 27/Focus and Outcome.w"
named_rulebook_outcome *Rulebooks__Outcomes__rbno_by_name(wording W) {
parse_node *p = SParser__parse_excerpt(MISCELLANEOUS_MC, W);
if (Rvalues__is_CONSTANT_of_kind(p, K_rulebook_outcome)) {
return Rvalues__to_named_rulebook_outcome(p);
}
named_rulebook_outcome *rbno = CREATE(named_rulebook_outcome);
Semantics__Nouns__ExcerptMeanings__register_noun(
MISCELLANEOUS_MC, W,
Rvalues__from_named_rulebook_outcome(rbno));
rbno->name = W;
return rbno;
}
void Rulebooks__Outcomes__compile_default_outcome(outcomes *outs, OUTPUT_STREAM) {
rulebook_outcome *rbo = outs->default_named_outcome;
if (rbo) {
switch(rbo->kind_of_outcome) {
case SUCCESS_OUTCOME:
WRITE("RulebookSucceeds(%d, RBNO_%d); rtrue;\n",
Kinds__RunTime__weak_id(K_rulebook_outcome),
rbo->outcome_name->allocation_id);
break;
case FAILURE_OUTCOME:
WRITE("RulebookFails(%d, RBNO_%d); rtrue;\n",
Kinds__RunTime__weak_id(K_rulebook_outcome),
rbo->outcome_name->allocation_id);
break;
}
} else {
if (outs->default_rule_outcome == FAILURE_OUTCOME) {
WRITE("RulebookFails(); rtrue;\n");
}
if (outs->default_rule_outcome == SUCCESS_OUTCOME) {
WRITE("RulebookSucceeds(); rtrue;\n");
}
}
}
rulebook_outcome *Rulebooks__Outcomes__rbo_from_context(named_rulebook_outcome *rbno) {
phrase *ph = phrase_being_compiled;
rulebook *rb;
if (ph == NULL) return NULL;
LOOP_OVER(rb, rulebook) {
outcomes *outs = Rulebooks__get_outcomes(rb);
rulebook_outcome *ro;
for (ro = outs->named_outcomes; ro; ro = ro->next) {
if (ro->outcome_name == rbno) {
if (Rules__Bookings__list_contains_ph(Rulebooks__first_booking(rb), ph))
return ro;
}
}
}
return NULL;
}
rulebook *Rulebooks__Outcomes__allow_outcome(named_rulebook_outcome *rbno) {
if (Phrases__Context__outcome_restrictions_waived()) return NULL;
phrase *ph = phrase_being_compiled;
if (ph == NULL) return NULL;
rulebook *rb;
LOOP_OVER(rb, rulebook) {
outcomes *outs = Rulebooks__get_outcomes(rb);
if (Rules__Bookings__list_contains_ph(Rulebooks__first_booking(rb), ph)) {
int okay = FALSE;
rulebook_outcome *ro;
for (ro = outs->named_outcomes; ro; ro = ro->next)
if (ro->outcome_name == rbno)
okay = TRUE;
if (okay == FALSE) return rb;
}
}
return NULL;
}
void Rulebooks__Outcomes__compile_outcome(OUTPUT_STREAM, named_rulebook_outcome *rbno) {
rulebook_outcome *rbo = Rulebooks__Outcomes__rbo_from_context(rbno);
if (rbo == NULL) {
rulebook *rb;
LOOP_OVER(rb, rulebook) {
outcomes *outs = Rulebooks__get_outcomes(rb);
rulebook_outcome *ro;
for (ro = outs->named_outcomes; ro; ro = ro->next)
if (ro->outcome_name == rbno) {
rbo = ro;
break;
}
}
if (rbo == NULL)
internal_error("rbno with no rb context");
}
switch(rbo->kind_of_outcome) {
case SUCCESS_OUTCOME:
WRITE("RulebookSucceeds(%d, RBNO_%d); rtrue;\n",
Kinds__RunTime__weak_id(K_rulebook_outcome),
rbno->allocation_id);
break;
case FAILURE_OUTCOME:
WRITE("RulebookFails(%d, RBNO_%d); rtrue;\n",
Kinds__RunTime__weak_id(K_rulebook_outcome),
rbno->allocation_id);
break;
case NO_OUTCOME:
WRITE("rfalse;\n");
break;
default:
internal_error("bad RBO outcome kind");
}
}
void Rulebooks__Outcomes__index_outcomes(outcomes *outs, int suppress_outcome) {
if (suppress_outcome == FALSE) {
rulebook_outcome *ro;
for (ro = outs->named_outcomes; ro; ro = ro->next) {
named_rulebook_outcome *rbno = ro->outcome_name;
HTML__open_para(ifl, 2, "hanging");
INDEX("<i>outcome</i>&nbsp;&nbsp;");
if (outs->default_named_outcome == ro) INDEX("<b>");
Wordings__index_raw(rbno->name);
if (outs->default_named_outcome == ro) INDEX("</b> (default)");
INDEX(" - <i>");
switch(ro->kind_of_outcome) {
case SUCCESS_OUTCOME: INDEX("a success"); break;
case FAILURE_OUTCOME: INDEX("a failure"); break;
case NO_OUTCOME: INDEX("no outcome"); break;
}
INDEX("</i>");
INDEX("</p>\n");
}
}
if ((outs->default_named_outcome == NULL) &&
(outs->default_rule_outcome != NO_OUTCOME) &&
(suppress_outcome == FALSE)) {
HTML__open_para(ifl, 2, "hanging");
INDEX("<i>default outcome is</i> ");
switch(outs->default_rule_outcome) {
case SUCCESS_OUTCOME: INDEX("success"); break;
case FAILURE_OUTCOME: INDEX("failure"); break;
}
INDEX("</p>");
}
}
void Rulebooks__Outcomes__RulebookOutcomePrintingRule_routine(OUTPUT_STREAM) {
named_rulebook_outcome *rbno;
LOOP_OVER(rbno, named_rulebook_outcome) {
WRITE("Constant RBNO_%d = \"", rbno->allocation_id);
Wordings__to_stream_raw(OUT, rbno->name);
WRITE("\";\n");
}
OUT = Routines__begin(OUT, "RulebookOutcomePrintingRule");
LocalVariables__add_named_call("rbno");
WRITE("if (rbno == 0) print \"(no outcome)\";\n");
WRITE("else print (string) rbno; rfalse;\n");
OUT = Routines__end(OUT);
}
char default_value_of_rulebook_outcome_kind[16];
char *Rulebooks__Outcomes__get_default_value(void) {
named_rulebook_outcome *rbno;
LOOP_OVER(rbno, named_rulebook_outcome) {
sprintf(default_value_of_rulebook_outcome_kind, "RBNO_%d", rbno->allocation_id);
return default_value_of_rulebook_outcome_kind;
}
return NULL;
}
#line 413 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__initialise_focus(focus *foc, kind *parameter_kind) {
foc->rules_always_test_actor = FALSE;
int parametrisation = PARAMETER_FOCUS;
if (Kinds__Compare__eq(parameter_kind, K_action_name)) parametrisation = ACTION_FOCUS;
else if (Kinds__Behaviour__definite(parameter_kind) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_RulebookIndefinite),
"this is a rulebook for values of a kind which isn't definite",
"and doesn't tell me enough about what sort of value the rulebook "
"should work on. For example, 'The mystery rules are a number based "
"rulebook' is fine because 'number' is definite, but 'The mystery "
"rules are a value based rulebook' is too vague.");
parameter_kind = K_object;
}
foc->kind_of_parameter = parameter_kind;
foc->rulebook_focus = parametrisation;
}
#line 435 "inform7/Chapter 27/Focus and Outcome.w"
void Rulebooks__Outcomes__modify_rule_to_suit_focus(focus *foc, rule *R) {
if (foc->rules_always_test_actor) {
LOGIF(RULE_ATTACHMENTS,
"Setting always test actor for destination rulebook\n");
Rules__set_always_test_actor(R);
}
if (foc->rulebook_focus == PARAMETER_FOCUS){
LOGIF(RULE_ATTACHMENTS,
"Setting never test actor for destination rulebook\n");
Rules__set_never_test_actor(R);
}
}
int Rulebooks__Outcomes__get_focus(focus *foc) {
return foc->rulebook_focus;
}
kind *Rulebooks__Outcomes__get_focus_parameter_kind(focus *foc) {
return foc->kind_of_parameter;
}
void Rulebooks__Outcomes__set_focus_ata(focus *foc, int ata) {
foc->rules_always_test_actor = ata;
}
#line 17 "inform7/Chapter 27/Rule Placement Sentences.w"
void Rules__Placement__declare_I6_written_rule(wording W, parse_node *p2) {
char *I6_name = Lexer__word_text(Wordings__first_wn(ParseTree__get_text(p2)));
rule *R = Rules__new(W, TRUE);
Rules__set_I6_definition(R, I6_name);
}
#line 28 "inform7/Chapter 27/Rule Placement Sentences.w"
int rulebook_name_NTMR(wording W, int *X, void **XP) {
#line 29 "inform7/Chapter 27/Rule Placement Sentences.w"
W = Articles__remove_the(W);
parse_node *p = SParser__parse_excerpt(RULEBOOK_MC, W);
if (Rvalues__is_CONSTANT_construction(p, CON_rulebook)) {
*XP = Rvalues__to_rulebook(p);
return TRUE;
}
return FALSE;
}
int rule_name_NTMR(wording W, int *X, void **XP) {
#line 39 "inform7/Chapter 27/Rule Placement Sentences.w"
W = Articles__remove_the(W);
rule *R = Rules__by_name(W);
if (R) {
*XP = R;
return TRUE;
}
return FALSE;
}
#line 61 "inform7/Chapter 27/Rule Placement Sentences.w"
int substitutes_for_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 72 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 63 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 64 "inform7/Chapter 27/Rule Placement Sentences.w"
int substitutes_for_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 72 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 67 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 68 "inform7/Chapter 27/Rule Placement Sentences.w"
#line 83 "inform7/Chapter 27/Rule Placement Sentences.w"
void Rules__Placement__request_substitute(parse_node *p1, parse_node *p2, parse_node *p3,
int sense) {
Preform__parse_nt_against_word_range(substitutes_for_sentence_subject_NTM, ParseTree__get_text(p1), NULL, NULL);
if (most_recent_result == FALSE) return;
rule *new_rule = most_recent_result_p;
Preform__parse_nt_against_word_range(substitutes_for_sentence_object_NTM, ParseTree__get_text(p2), NULL, NULL);
if (most_recent_result == FALSE) return;
rule *old_rule = most_recent_result_p;
wording CW = EMPTY_WORDING;
if (p3) CW = ParseTree__get_text(p3);
Rules__impose_constraint(new_rule, old_rule, CW, (sense)?FALSE:TRUE);
}
#line 106 "inform7/Chapter 27/Rule Placement Sentences.w"
int does_nothing_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 72 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 108 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 109 "inform7/Chapter 27/Rule Placement Sentences.w"
#line 113 "inform7/Chapter 27/Rule Placement Sentences.w"
void Rules__Placement__constrain_effect(parse_node *p1, parse_node *p2, int sense) {
if (ParseTree__get_type(p1) == AND_NT) {
Rules__Placement__constrain_effect(p1->down, p2, sense);
Rules__Placement__constrain_effect(p1->down->next, p2, sense);
return;
}
Preform__parse_nt_against_word_range(does_nothing_sentence_subject_NTM, ParseTree__get_text(p1), NULL, NULL);
if (most_recent_result == FALSE) return;
rule *existing_rule = most_recent_result_p;
if (p2)
Rules__impose_constraint(NULL, existing_rule, ParseTree__get_text(p2), sense);
else
Rules__impose_constraint(NULL, existing_rule, EMPTY_WORDING, FALSE);
}
#line 131 "inform7/Chapter 27/Rule Placement Sentences.w"
rule *relative_to_which = NULL;
#line 141 "inform7/Chapter 27/Rule Placement Sentences.w"
int listed_in_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE;
{
#line 72 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 143 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 144 "inform7/Chapter 27/Rule Placement Sentences.w"
#line 148 "inform7/Chapter 27/Rule Placement Sentences.w"
int listed_in_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = ANY_RULE_PLACEMENT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = MIDDLE_PLACEMENT + 1000*IN_SIDE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = FIRST_PLACEMENT + 1000*IN_SIDE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = LAST_PLACEMENT + 1000*IN_SIDE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = MIDDLE_PLACEMENT + 1000*INSTEAD_SIDE; relative_to_which = RP[1]; *XP = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5:
{
#line 207 "inform7/Chapter 27/Rule Placement Sentences.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRulebookPlacement));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rulebook was required.");
Problems__issue_problem_end();
}
#line 154 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 72 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 155 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = MIDDLE_PLACEMENT + 1000*BEFORE_SIDE; relative_to_which = RP[1]; *XP = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8:
{
#line 207 "inform7/Chapter 27/Rule Placement Sentences.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRulebookPlacement));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rulebook was required.");
Problems__issue_problem_end();
}
#line 157 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9:
{
#line 72 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 158 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10: *X = MIDDLE_PLACEMENT + 1000*AFTER_SIDE; relative_to_which = RP[1]; *XP = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11:
{
#line 207 "inform7/Chapter 27/Rule Placement Sentences.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRulebookPlacement));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rulebook was required.");
Problems__issue_problem_end();
}
#line 160 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12:
{
#line 72 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = FALSE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRuleExists));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rule was required.");
Problems__issue_problem_end();
}
#line 161 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13:
{
#line 177 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = BAD_RULE_PLACEMENT;
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_UnspecifiedRulebookPlacement));
Problems__issue_problem_segment(
"In %1, you didn't specify in which rulebook the rule was to "
"be listed, only which existing rule it should go before or "
"after.");
Problems__issue_problem_end();
}
#line 162 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14:
{
#line 177 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = BAD_RULE_PLACEMENT;
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_UnspecifiedRulebookPlacement));
Problems__issue_problem_segment(
"In %1, you didn't specify in which rulebook the rule was to "
"be listed, only which existing rule it should go before or "
"after.");
Problems__issue_problem_end();
}
#line 163 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15:
{
#line 177 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = BAD_RULE_PLACEMENT;
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_UnspecifiedRulebookPlacement));
Problems__issue_problem_segment(
"In %1, you didn't specify in which rulebook the rule was to "
"be listed, only which existing rule it should go before or "
"after.");
Problems__issue_problem_end();
}
#line 164 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 16:
{
#line 189 "inform7/Chapter 27/Rule Placement Sentences.w"
*X = BAD_RULE_PLACEMENT;
{
#line 195 "inform7/Chapter 27/Rule Placement Sentences.w"
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_ImproperRulePlacement));
Problems__issue_problem_segment(
"In %1, you used the special verb 'to be listed' - which specifies "
"how rules are listed in rulebooks - in a way I didn't recognise. "
"The usual form is: 'The summer breeze rule is listed in the "
"meadow noises rulebook'.");
Problems__issue_problem_end();
}
#line 190 "inform7/Chapter 27/Rule Placement Sentences.w"
;
}
#line 165 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 166 "inform7/Chapter 27/Rule Placement Sentences.w"
int destination_rulebook_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 207 "inform7/Chapter 27/Rule Placement Sentences.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchRulebookPlacement));
Problems__issue_problem_segment(
"In %1, you gave '%2' where a rulebook was required.");
Problems__issue_problem_end();
}
#line 169 "inform7/Chapter 27/Rule Placement Sentences.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 170 "inform7/Chapter 27/Rule Placement Sentences.w"
#line 217 "inform7/Chapter 27/Rule Placement Sentences.w"
void Rules__Placement__manual_placement(int verb, parse_node *subj) {
switch(verb) {
case IN_RULEBOOK_VB:
Rules__Placement__place_in_rulebook(subj, subj->next, TRUE);
break;
case NOT_IN_RULEBOOK_VB:
Rules__Placement__place_in_rulebook(subj, subj->next, FALSE);
break;
case NO_EFFECT_IF_VB:
Rules__Placement__constrain_effect(subj, subj->next, FALSE);
break;
case NO_EFFECT_UNLESS_VB:
Rules__Placement__constrain_effect(subj, subj->next, TRUE);
break;
case NO_EFFECT_AT_ALL_VB:
Rules__Placement__constrain_effect(subj, NULL, NOT_APPLICABLE);
break;
case SUBSTITUTES_VB:
Rules__Placement__request_substitute(subj, subj->next, NULL, NOT_APPLICABLE);
break;
case SUBSTITUTES_IF_VB:
Rules__Placement__request_substitute(subj, subj->next, subj->next->next, TRUE);
break;
case SUBSTITUTES_UNLESS_VB:
Rules__Placement__request_substitute(subj, subj->next, subj->next->next, FALSE);
break;
}
}
#line 249 "inform7/Chapter 27/Rule Placement Sentences.w"
void Rules__Placement__place_in_rulebook(parse_node *p1, parse_node *p2, int sense) {
if (ParseTree__get_type(p1) == AND_NT) {
Rules__Placement__place_in_rulebook(p1->down, p2, sense);
Rules__Placement__place_in_rulebook(p1->down->next, p2, sense);
return;
}
int side, new_rule_placement;
LOGIF(RULE_ATTACHMENTS, "Placement sentence (%d):\np1=$T\np2=$T\n", sense, p1, p2);
relative_to_which = NULL;
int pc = problem_count;
Preform__parse_nt_against_word_range(listed_in_sentence_object_NTM, ParseTree__get_text(p2), NULL, NULL);
if (problem_count > pc) return;
rulebook *the_rulebook = most_recent_result_p;
int pair = most_recent_result;
if (pair == BAD_RULE_PLACEMENT) return;
if (pair == ANY_RULE_PLACEMENT) {
if (sense == TRUE) {
{
#line 195 "inform7/Chapter 27/Rule Placement Sentences.w"
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_ImproperRulePlacement));
Problems__issue_problem_segment(
"In %1, you used the special verb 'to be listed' - which specifies "
"how rules are listed in rulebooks - in a way I didn't recognise. "
"The usual form is: 'The summer breeze rule is listed in the "
"meadow noises rulebook'.");
Problems__issue_problem_end();
}
#line 268 "inform7/Chapter 27/Rule Placement Sentences.w"
;
return;
}
new_rule_placement = MIDDLE_PLACEMENT; side = IN_SIDE;
} else {
new_rule_placement = pair%1000; side = pair/1000;
}
if ((sense == FALSE) &&
((new_rule_placement != MIDDLE_PLACEMENT) || (side != IN_SIDE))) {
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_BadRulePlacementNegation));
Problems__issue_problem_segment(
"In %1, you used the special verb 'to be listed' - which specifies "
"how rules are listed in rulebooks - in a way too complicated to "
"be accompanied by 'not', so that the result was too vague. "
"The usual form is: 'The summer breeze rule is not listed in the "
"meadow noises rulebook'.");
Problems__issue_problem_end();
return;
}
Preform__parse_nt_against_word_range(listed_in_sentence_subject_NTM, ParseTree__get_text(p1), NULL, NULL);
if (most_recent_result == FALSE) return;
rule *existing_rule = most_recent_result_p;
if (pair == ANY_RULE_PLACEMENT) {
rulebook *rb;
LOOP_OVER(rb, rulebook) Rulebooks__detach_rule(rb, existing_rule);
return;
}
if (sense == FALSE) {
Rulebooks__affected_by_placement(the_rulebook, current_sentence);
Rulebooks__detach_rule(the_rulebook, existing_rule);
return;
}
booking *new_rule_booking = Rules__Bookings__new(existing_rule);
Rules__set_kind_from(existing_rule, the_rulebook);
if (relative_to_which) {
LOGIF(RULE_ATTACHMENTS, "Relative to which = $w\n", relative_to_which->name);
Rulebooks__affected_by_placement(the_rulebook, current_sentence);
if (Rulebooks__rule_in_rulebook(relative_to_which, the_rulebook) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, the_rulebook->primary_name);
Problems__quote_wording(3, relative_to_which->name);
Problems__Issue__handmade_problem(_p_(PM_PlaceWithMissingRule));
Problems__issue_problem_segment(
"In %1, you talk about the position of the rule '%3' "
"in the rulebook '%2', but in fact that rule isn't in this "
"rulebook, so the placing instruction makes no sense.");
Problems__issue_problem_end();
return;
}
}
Rulebooks__attach_rule(the_rulebook, new_rule_booking, new_rule_placement,
side, relative_to_which);
}
#line 55 "inform7/Chapter 27/Stacked Variables.w"
void StackedVariables__compile_lvalue_to_text(stacked_variable *stv, char *to) {
if ((stv->owner_id == ACTION_PROCESSING_RB) && (stv->offset_in_owning_frame == 0))
strcpy(to, "actor");
else
sprintf(to, "(MStack-->MstVO(%d,%d))", stv->owner_id, stv->offset_in_owning_frame);
}
void StackedVariables__compile_rvalue_to_text(stacked_variable *stv, char *to) {
if ((stv->owner_id == ACTION_PROCESSING_RB) && (stv->offset_in_owning_frame == 0))
strcpy(to, "actor");
else
sprintf(to, "(MStack-->MstVON(%d,%d))", stv->owner_id, stv->offset_in_owning_frame);
}
int StackedVariables__get_owner_id(stacked_variable *stv) {
return stv->owner_id;
}
int StackedVariables__get_offset(stacked_variable *stv) {
return stv->offset_in_owning_frame;
}
kind *StackedVariables__get_kind(stacked_variable *stv) {
nonlocal_variable *nlv = StackedVariables__get_variable(stv);
return NonlocalVariables__kind(nlv);
}
nonlocal_variable *StackedVariables__get_variable(stacked_variable *stv) {
if (stv == NULL) return NULL;
return stv->underlying_var;
}
void StackedVariables__set_matching_text(stacked_variable *stv, wording W) {
stv->match_wording_text = W;
}
wording StackedVariables__get_matching_text(stacked_variable *stv) {
return stv->match_wording_text;
}
stacked_variable *StackedVariables__parse_match_clause(stacked_variable_owner *stvo,
wording W) {
for (stacked_variable_list *stvl = stvo->list_of_stvs; stvl; stvl = stvl->next)
if (Wordings__starts_with(W, stvl->the_stv->match_wording_text))
return stvl->the_stv;
return NULL;
}
stacked_variable_owner *StackedVariables__new_owner(int id) {
stacked_variable_owner *stvo = CREATE(stacked_variable_owner);
stvo->recognition_id = id;
stvo->no_stvs = 0;
stvo->list_of_stvs = NULL;
return stvo;
}
int StackedVariables__owner_empty(stacked_variable_owner *stvo) {
if (stvo->no_stvs == 0) return TRUE;
return FALSE;
}
stacked_variable *StackedVariables__add_empty(stacked_variable_owner *stvo,
wording W, kind *K) {
stacked_variable *stv = CREATE(stacked_variable);
nonlocal_variable *q;
W = Articles__remove_the(W);
stv->name = W;
stv->owner_id = stvo->recognition_id;
stv->offset_in_owning_frame = stvo->no_stvs++;
stv->assigned_at = current_sentence;
stv->match_wording_text = EMPTY_WORDING;
stvo->list_of_stvs = StackedVariables__add_to_list(stvo->list_of_stvs, stv);
if (stvo->no_stvs > max_frame_size_needed)
max_frame_size_needed = stvo->no_stvs;
q = NonlocalVariables__new_stacked(W, K, stv);
stv->underlying_var = q;
char lv[32], rv[32];
StackedVariables__compile_rvalue_to_text(stv, rv);
StackedVariables__compile_lvalue_to_text(stv, lv);
NonlocalVariables__set_I6_identifier(q, rv, lv);
return stv;
}
stacked_variable_owner_list *StackedVariables__add_owner_to_list(stacked_variable_owner_list *stvol,
stacked_variable_owner *stvo) {
stacked_variable_owner_list *ostvol = stvol;
while (stvol) {
if (stvol->stvo == stvo) return ostvol;
stacked_variable_owner_list *nxt = stvol->next;
if (nxt == NULL) break;
stvol = nxt;
}
stacked_variable_owner_list *nstvol = CREATE(stacked_variable_owner_list);
nstvol->next = NULL;
nstvol->stvo = stvo;
if (stvol == NULL) return nstvol;
stvol->next = nstvol;
return ostvol;
}
stacked_variable_owner_list *StackedVariables__append_owner_list(stacked_variable_owner_list *stvol,
stacked_variable_owner_list *extras) {
LOGIF(RULEBOOK_COMPILATION,
"Appending list %08x to list %08x\n", (int) extras, (int) stvol);
stacked_variable_owner_list *new_head = stvol;
for (; extras; extras = extras->next)
new_head = StackedVariables__add_owner_to_list(new_head, extras->stvo);
return new_head;
}
int StackedVariables__list_length(stacked_variable_list *stvl) {
int l = 0;
while (stvl) {
l++;
stvl = stvl->next;
}
return l;
}
void StackedVariables__index_owner(stacked_variable_owner *stvo) {
stacked_variable_list *stvl;
for (stvl=stvo->list_of_stvs; stvl; stvl = stvl->next)
if ((stvl->the_stv) && (stvl->the_stv->underlying_var)) {
HTML__open_para(ifl, 2, "tight");
NonlocalVariables__index_single(stvl->the_stv->underlying_var);
INDEX("</p>");
}
}
stacked_variable *StackedVariables__parse_from_owner_list(stacked_variable_owner_list *stvol, wording W) {
if (Wordings__empty(W)) return NULL;
W = Articles__remove_the(W);
while (stvol) {
stacked_variable *stv = NULL;
if (stvol->stvo) stv = StackedVariables__parse_from_list(stvol->stvo->list_of_stvs, W);
if (stv) return stv;
stvol = stvol->next;
}
return NULL;
}
stacked_variable *StackedVariables__parse_from_list(stacked_variable_list *stvl, wording W) {
while (stvl) {
if (Wordings__match(stvl->the_stv->name, W))
return stvl->the_stv;
stvl = stvl->next;
}
return NULL;
}
stacked_variable_list *StackedVariables__add_to_list(stacked_variable_list *stvl,
stacked_variable *stv) {
stacked_variable_list *nstvl = CREATE(stacked_variable_list), *ostvl = stvl;
nstvl->the_stv = stv;
nstvl->next = NULL;
if (stvl == NULL) return nstvl;
while (stvl->next) stvl = stvl->next;
stvl->next = nstvl;
return ostvl;
}
int StackedVariables__compile_frame_creator(OUTPUT_STREAM, stacked_variable_owner *stvo,
char *name_prototype, int name_id) {
int i;
stacked_variable_list *stvl;
if (stvo == NULL) return 0;
OUT = Routines__begin_numbered(OUT, name_prototype, name_id);
LocalVariables__add_named_call("pos");
LocalVariables__add_named_call("state");
WRITE("if (state == 1) {\n"); INDENT;
for (i=0, stvl = stvo->list_of_stvs; stvl; i++, stvl = stvl->next) {
nonlocal_variable *q = StackedVariables__get_variable(stvl->the_stv);
kind *K = NonlocalVariables__kind(q);
WRITE("MStack-->pos = ");
if (Kinds__Behaviour__uses_pointer_values(K))
Kinds__RunTime__compile_heap_allocation(OUT, K, 1, -1);
else
NonlocalVariables__compile_initial_value(OUT, q);
WRITE("; pos++;\n");
}
OUTDENT;
WRITE("} else {\n");
INDENT;
for (i=0, stvl = stvo->list_of_stvs; stvl; i++, stvl = stvl->next) {
nonlocal_variable *q = StackedVariables__get_variable(stvl->the_stv);
kind *K = NonlocalVariables__kind(q);
if (Kinds__Behaviour__uses_pointer_values(K)) WRITE("BlkValueFree(MStack-->pos);\n");
WRITE("pos++;\n");
}
OUTDENT; WRITE("}\n");
WRITE("return %d;\n", i);
OUT = Routines__end(OUT);
return i;
}
#line 98 "inform7/Chapter 27/Activities.w"
sentence_handler NEW_ACTIVITY_SH_handler =
{ SENTENCE_NT, NEW_ACTIVITY_VB, 1, Activities__create };
void Activities__create(parse_node *pn) {
Activities__new(Kinds__unary_construction(CON_activity, K_nil),
ParseTree__get_text(pn->down->next));
}
#line 116 "inform7/Chapter 27/Activities.w"
int activity_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; ds_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; ds_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1]; ds_NTMV = -1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 120 "inform7/Chapter 27/Activities.w"
int activity_noted_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; future_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 141 "inform7/Chapter 27/Activities.w"
*X = FALSE;
Problems__Issue__sentence_problem(_p_(PM_ActivityNoteUnknown),
"one of the notes about this activity makes no sense",
"and should be either 'documented at SYMBOL' or 'future action'.");
}
#line 123 "inform7/Chapter 27/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; future_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 125 "inform7/Chapter 27/Activities.w"
int activity_new_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; any_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; any_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; any_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 130 "inform7/Chapter 27/Activities.w"
#line 135 "inform7/Chapter 27/Activities.w"
int activity_name_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 137 "inform7/Chapter 27/Activities.w"
#line 149 "inform7/Chapter 27/Activities.w"
activity *Activities__new(kind *creation_kind, wording W) {
activity *av = CREATE(activity);
int future_action_flag = FALSE;
parse_node *spec;
creation_kind = Kinds__unary_construction_material(creation_kind);
if ((Kinds__Behaviour__definite(creation_kind) == FALSE) &&
(Kinds__Compare__eq(creation_kind, K_nil) == FALSE)) {
LOG("I'm reading the kind as: $u\n", creation_kind);
Problems__Issue__sentence_problem(_p_(PM_ActivityIndefinite),
"this is an activity on a kind which isn't definite",
"and doesn't tell me enough about what sort of value the activity "
"should work on. For example, 'Divining is an activity on numbers' "
"is fine because 'numbers' is definite, but 'Divining is an "
"activity on values' is not allowed.");
creation_kind = K_object;
}
Preform__parse_nt_against_word_range(activity_sentence_subject_NTM, W, NULL, NULL);
W = GET_RW(activity_new_name_NTM, 1);
av->av_documentation_symbol = Wordings__one_word(ds_NTMV);
future_action_flag = future_NTMV;
if (any_NTMV) {
if (Kinds__Compare__eq(creation_kind, K_nil)) creation_kind = K_object;
} else {
if (Kinds__Compare__eq(creation_kind, K_nil) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_ActivityMisnamed),
"the name of this activity implies that it acts on nothing",
"which doesn't fit with what you say about it. For example, "
"'Painting is an activity on brushes' isn't allowed because "
"the activity's name doesn't end with 'something': it should "
"be 'Painting something is an activity on brushes'.");
}
}
av->name = W;
LOGIF(ACTION_CREATIONS, "Created activity: $w\n", av->name);
Identifiers__compose(av->av_I6_identifier, 'V', av->allocation_id, av->name);
av->activity_on_what_kind = creation_kind;
if (Preform__parse_nt_against_word_range(s_value_NTM, av->name, NULL, NULL)) spec = most_recent_result_p;
else spec = Specifications__new_UNKNOWN(av->name);
if (!(ParseTree__is(spec, UNKNOWN_VNT)) && (!(ParseTree__is(spec, PROPERTY_VALUE_VNT)))) {
LOG("$w means $P\n", av->name, spec);
Problems__Issue__sentence_problem(_p_(PM_BadActivityName),
"this already has a meaning",
"and so cannot be the name of a newly created activity.");
} else {
Semantics__Nouns__ExcerptMeanings__register_noun(ACTIVITY_MC, W,
Rvalues__from_activity(av));
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(ACTIVITY_MC,
Preform__Nonparsing__merge(activity_name_construction_NTM, 0,
WordAssemblages__from_wording(av->name)),
Rvalues__from_activity(av));
}
feed_t id = Feeds__begin();
Feeds__feed_text_expanding_strings("before");
Feeds__feed_wording(av->name);
wording SW = Feeds__end(id);
av->before_rules =
Rulebooks__new_automatic(SW, av->activity_on_what_kind,
NO_OUTCOME, FALSE, future_action_flag, TRUE);
id = Feeds__begin();
Feeds__feed_text_expanding_strings("for");
Feeds__feed_wording(av->name);
SW = Feeds__end(id);
av->for_rules =
Rulebooks__new_automatic(SW, av->activity_on_what_kind,
SUCCESS_OUTCOME, FALSE, future_action_flag, TRUE);
id = Feeds__begin();
Feeds__feed_text_expanding_strings("after");
Feeds__feed_wording(av->name);
SW = Feeds__end(id);
av->after_rules =
Rulebooks__new_automatic(SW, av->activity_on_what_kind,
NO_OUTCOME, FALSE, future_action_flag, TRUE);
av->owned_by_av = StackedVariables__new_owner(10000+av->allocation_id);
Rulebooks__make_stvs_accessible(av->before_rules, av->owned_by_av);
Rulebooks__make_stvs_accessible(av->for_rules, av->owned_by_av);
Rulebooks__make_stvs_accessible(av->after_rules, av->owned_by_av);
av->activity_indexed = FALSE;
av->cross_references = NULL;
return av;
}
kind *Activities__to_kind(activity *av) {
return Kinds__unary_construction(CON_activity,
av->activity_on_what_kind);
}
#line 248 "inform7/Chapter 27/Activities.w"
int activity_variable_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 255 "inform7/Chapter 27/Activities.w"
*X = NOT_APPLICABLE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_ActivityVarAnd));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for an activity - a value associated "
"with a activity and which has a name. The request seems to "
"say that the name in question is '%2', but I'd prefer to "
"avoid 'and', 'or', 'with', or 'having' in such names, please.");
Problems__issue_problem_end();
}
#line 249 "inform7/Chapter 27/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 251 "inform7/Chapter 27/Activities.w"
#line 270 "inform7/Chapter 27/Activities.w"
void Activities__add_variable(activity *av, parse_node *cnode) {
parse_node *spec;
if ((ParseTree__get_type(cnode) != PROPERTYCALLED_NT) &&
(ParseTree__get_type(cnode) != PROPER_NOUN_NT)) {
LOG("Tree: $T\n", cnode);
internal_error("ac_add_variable on a node of unknown type");
}
if (ParseTree__get_type(cnode) == PROPER_NOUN_NT) {
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_ActivityVariableNameless));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for an activity - a value associated "
"with a activity and which has a name. Here, though, there "
"seems to be no name for the variable as such, only an indication "
"of its kind. Try something like 'The printing the banner text "
"activity has a number called the accumulated vanity'.");
Problems__issue_problem_end();
return;
}
spec = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, ParseTree__get_text(cnode->down), NULL, NULL)) spec = most_recent_result_p;
if (Preform__parse_nt_against_word_range(activity_variable_name_NTM, ParseTree__get_text(cnode->down->next), NULL, NULL)) {
if (most_recent_result == NOT_APPLICABLE) return;
}
if (Specifications__is_description(spec)) {
if ((Specifications__to_kind(spec)) &&
(Descriptions__number_of_adjectives_applied_to(spec) == 0)) {
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down));
Problems__Issue__handmade_problem(_p_(PM_ActivityVarOverspecific));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for an activity - a value associated "
"with a activity and which has a name. The request seems to "
"say that the value in question is '%2', but this is too "
"specific a description. (Instead, a kind of value "
"(such as 'number') or a kind of object (such as 'room' "
"or 'thing') should be given. To get a property whose "
"contents can be any kind of object, use 'object'.)");
Problems__issue_problem_end();
return;
}
}
if (!(Specifications__is_kind_like(spec))) {
LOG("Offending SP: $T", spec);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down));
Problems__Issue__handmade_problem(_p_(PM_ActivityVarUnknownKOV));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is not the name of a kind of "
"value which I know (such as 'number' or 'text').");
Problems__issue_problem_end();
return;
}
if (Kinds__Compare__eq(Specifications__to_kind(spec), K_value)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down));
Problems__Issue__handmade_problem(_p_(PM_ActivityVarValue));
Problems__issue_problem_segment(
"You wrote %1, but saying that a variable is a 'value' "
"does not give me a clear enough idea what it will hold. "
"You need to say what kind of value: for instance, 'A door "
"has a number called street address.' is allowed because "
"'number' is specific about the kind of value.");
Problems__issue_problem_end();
return;
}
StackedVariables__add_empty(av->owned_by_av, ParseTree__get_text(cnode->down->next),
Specifications__to_kind(spec));
}
void Activities__activity_var_creators_array(OUTPUT_STREAM) {
activity *av;
WRITE("Array activity_var_creators -->");
LOOP_OVER(av, activity) {
if (StackedVariables__owner_empty(av->owned_by_av)) WRITE(" 0");
else WRITE(" AVSTVC_%d", av->allocation_id);
}
WRITE(" 0;\n");
LOOP_OVER(av, activity) {
if (StackedVariables__owner_empty(av->owned_by_av) == FALSE)
StackedVariables__compile_frame_creator(OUT, av->owned_by_av,
" AVSTVC_%d", av->allocation_id);
}
}
#line 366 "inform7/Chapter 27/Activities.w"
void Activities__index_by_number(int id, int indent) {
activity *av;
LOOP_OVER(av, activity)
if (av->allocation_id == id) Activities__index(av, indent);
}
void Activities__index(activity *av, int indent) {
int empty = TRUE;
char *doc_link = NULL, *text = NULL;
if (av->activity_indexed) return;
av->activity_indexed = TRUE;
if (Rulebooks__is_empty(av->before_rules, NULL) == FALSE) empty = FALSE;
if (Rulebooks__is_empty(av->for_rules, NULL) == FALSE) empty = FALSE;
if (Rulebooks__is_empty(av->after_rules, NULL) == FALSE) empty = FALSE;
if (av->cross_references) empty = FALSE;
if (Wordings__nonempty(av->av_documentation_symbol))
doc_link = Lexer__word_raw_text(Wordings__first_wn(av->av_documentation_symbol));
if (empty) text = "There are no rules before, for or after this activity.";
Rulebooks__index_rules_box(NULL, av->name, doc_link,
NULL, av, text, indent, TRUE);
}
int Activities__no_rules(activity *av) {
int t = 0;
t += Rulebooks__no_rules(av->before_rules);
t += Rulebooks__no_rules(av->for_rules);
t += Rulebooks__no_rules(av->after_rules);
return t;
}
void Activities__index_details(activity *av) {
int ignore_me = 0;
Rulebooks__index(av->before_rules, "before", NULL, NULL, &ignore_me);
Rulebooks__index(av->for_rules, "for", NULL, NULL, &ignore_me);
Rulebooks__index(av->after_rules, "after", NULL, NULL, &ignore_me);
Activities__index_cross_references(av);
}
char *Activities__identifier(activity *av) {
return av->av_I6_identifier;
}
int Activities__count_list(activity_list *avl) {
int n = 0;
while (avl) {
n += 10;
if (avl->only_when) n += Conditions__count(avl->only_when);
avl = avl->next;
}
return n;
}
#line 434 "inform7/Chapter 27/Activities.w"
int run_time_context_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
{
#line 471 "inform7/Chapter 27/Activities.w"
activity_list *al = *XP;
for (; al; al=al->next) {
al->ACL_parity = (al->ACL_parity)?FALSE:TRUE;
}
}
#line 435 "inform7/Chapter 27/Activities.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 437 "inform7/Chapter 27/Activities.w"
int activity_list_unnegated_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 479 "inform7/Chapter 27/Activities.w"
activity_list *al1 = RP[1], *al2 = RP[2];
al1->next = al2;
*XP = al1;
}
#line 440 "inform7/Chapter 27/Activities.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 442 "inform7/Chapter 27/Activities.w"
int activity_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 446 "inform7/Chapter 27/Activities.w"
int activity_list_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 486 "inform7/Chapter 27/Activities.w"
activity_list *al;
{
#line 523 "inform7/Chapter 27/Activities.w"
al = CREATE(activity_list);
al->acting_on = NULL;
al->only_when = NULL;
al->next = NULL;
al->ACL_parity = TRUE;
al->activity = NULL;
*XP = al;
}
#line 487 "inform7/Chapter 27/Activities.w"
;
al->activity = RP[1];
}
#line 448 "inform7/Chapter 27/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 493 "inform7/Chapter 27/Activities.w"
activity *an = RP[1];
if (an->activity_on_what_kind == NULL) return FALSE;
if ((R[2]) &&
(PL__Actions__Patterns__validate_parameter(RP[2], an->activity_on_what_kind) == FALSE))
return FALSE;
activity_list *al;
{
#line 523 "inform7/Chapter 27/Activities.w"
al = CREATE(activity_list);
al->acting_on = NULL;
al->only_when = NULL;
al->next = NULL;
al->ACL_parity = TRUE;
al->activity = NULL;
*XP = al;
}
#line 499 "inform7/Chapter 27/Activities.w"
;
al->activity = an;
al->acting_on = RP[2];
}
#line 449 "inform7/Chapter 27/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 493 "inform7/Chapter 27/Activities.w"
activity *an = RP[1];
if (an->activity_on_what_kind == NULL) return FALSE;
if ((R[2]) &&
(PL__Actions__Patterns__validate_parameter(RP[2], an->activity_on_what_kind) == FALSE))
return FALSE;
activity_list *al;
{
#line 523 "inform7/Chapter 27/Activities.w"
al = CREATE(activity_list);
al->acting_on = NULL;
al->only_when = NULL;
al->next = NULL;
al->ACL_parity = TRUE;
al->activity = NULL;
*XP = al;
}
#line 499 "inform7/Chapter 27/Activities.w"
;
al->activity = an;
al->acting_on = RP[2];
}
#line 450 "inform7/Chapter 27/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 506 "inform7/Chapter 27/Activities.w"
parse_node *cond = Specifications__new_UNKNOWN(EMPTY_WORDING);
activity_list *al;
{
#line 523 "inform7/Chapter 27/Activities.w"
al = CREATE(activity_list);
al->acting_on = NULL;
al->only_when = NULL;
al->next = NULL;
al->ACL_parity = TRUE;
al->activity = NULL;
*XP = al;
}
#line 508 "inform7/Chapter 27/Activities.w"
;
al->only_when = cond;
}
#line 451 "inform7/Chapter 27/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 514 "inform7/Chapter 27/Activities.w"
parse_node *cond = RP[2];
if (PL__Actions__Patterns__validate_when(cond) == FALSE) return FALSE;
activity_list *al;
{
#line 523 "inform7/Chapter 27/Activities.w"
al = CREATE(activity_list);
al->acting_on = NULL;
al->only_when = NULL;
al->next = NULL;
al->ACL_parity = TRUE;
al->activity = NULL;
*XP = al;
}
#line 517 "inform7/Chapter 27/Activities.w"
;
al->only_when = cond;
}
#line 452 "inform7/Chapter 27/Activities.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 453 "inform7/Chapter 27/Activities.w"
#line 463 "inform7/Chapter 27/Activities.w"
int activity_operand_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE; *XP = Specifications__new_UNKNOWN(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE; *XP = Specifications__new_UNKNOWN(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 467 "inform7/Chapter 27/Activities.w"
#line 534 "inform7/Chapter 27/Activities.w"
int activity_name_NTMR(wording W, int *X, void **XP) {
#line 535 "inform7/Chapter 27/Activities.w"
parse_node *p = SParser__parse_excerpt(ACTIVITY_MC, W);
if (Rvalues__is_CONSTANT_construction(p, CON_activity)) {
*XP = Rvalues__to_activity(p);
return TRUE;
}
return FALSE;
}
#line 546 "inform7/Chapter 27/Activities.w"
int parsing_al_conditions = TRUE;
activity_list *Activities__parse_list(wording W) {
return Activities__parse_list_inner(W, TRUE);
}
#line 555 "inform7/Chapter 27/Activities.w"
int if_parsing_al_conditions_NTMR(wording W, int *X, void **XP) {
#line 556 "inform7/Chapter 27/Activities.w"
if (parsing_al_conditions) return TRUE;
return FALSE;
}
#line 563 "inform7/Chapter 27/Activities.w"
activity_list *Activities__parse_list_inner(wording W, int state) {
int save_pac = parsing_al_conditions;
parsing_al_conditions = state;
int rv = Preform__parse_nt_against_word_range(run_time_context_NTM, W, NULL, NULL);
parsing_al_conditions = save_pac;
if (rv) return most_recent_result_p;
return NULL;
}
void Activities__compile_activity_list(OUTPUT_STREAM, activity_list *al) {
if (al->ACL_parity == FALSE) WRITE("(~~(");
else WRITE("((");
while (al != NULL) {
if (al->activity != NULL) {
if (al->acting_on == NULL)
WRITE("(TestActivity(%s))", al->activity->av_I6_identifier);
else if (Specifications__is_description(al->acting_on)) {
WRITE("(TestActivity(%s, Prop_%d))",
al->activity->av_I6_identifier,
Calculus__Deferrals__compile_deferred_description_test(al->acting_on));
} else {
WRITE("(TestActivity(%s, 0, ", al->activity->av_I6_identifier);
Specifications__Compiler__compile(OUT, al->acting_on);
WRITE("))");
}
}
else {
WRITE("(");
Specifications__Compiler__compile(OUT, al->only_when);
WRITE(")");
}
al = al->next;
if (al != NULL) WRITE(" || ");
}
WRITE("))");
}
void Activities__compile_activity_constants(OUTPUT_STREAM) {
activity *av;
LOOP_OVER(av, activity) {
WRITE("Constant %s = %d;\n", av->av_I6_identifier, av->allocation_id);
}
}
void Activities__Activity_before_rulebooks_array(OUTPUT_STREAM) {
activity *av; int i = 0;
WRITE("Array Activity_before_rulebooks --> ");
LOOP_OVER(av, activity) {
WRITE("%d ", av->before_rules->allocation_id); i++;
}
if (i==0) WRITE("NULL ");
WRITE("NULL;\n");
}
void Activities__Activity_for_rulebooks_array(OUTPUT_STREAM) {
activity *av; int i = 0;
WRITE("Array Activity_for_rulebooks --> ");
LOOP_OVER(av, activity) {
WRITE("%d ", av->for_rules->allocation_id); i++;
}
if (i==0) WRITE("NULL ");
WRITE("NULL;\n");
}
void Activities__Activity_after_rulebooks_array(OUTPUT_STREAM) {
activity *av; int i = 0;
WRITE("Array Activity_after_rulebooks --> ");
LOOP_OVER(av, activity) {
WRITE("%d ", av->after_rules->allocation_id); i++;
}
if (i==0) WRITE("NULL ");
WRITE("NULL;\n");
}
void Activities__Activity_atb_rulebooks_array(OUTPUT_STREAM) {
activity *av; int i = 0;
WRITE("Array Activity_atb_rulebooks -> ");
LOOP_OVER(av, activity) {
WRITE("%d ", Rulebooks__used_by_future_actions(av->before_rules));
i++;
}
if (i==0) WRITE("$ff ");
WRITE("$ff;\n");
}
void Activities__annotate_list_for_cross_references(activity_list *avl, phrase *ph) {
for (; avl; avl = avl->next)
if (avl->activity) {
activity *av = avl->activity;
activity_crossref *acr = CREATE(activity_crossref);
acr->next = av->cross_references;
av->cross_references = acr;
acr->rule_dependent = ph;
}
}
void Activities__index_cross_references(activity *av) {
activity_crossref *acr;
for (acr = av->cross_references; acr; acr = acr->next) {
phrase *ph = acr->rule_dependent;
if ((ph->declaration_node) && (Wordings__nonempty(ParseTree__get_text(ph->declaration_node)))) {
HTML__open_para(ifl, 2, "tight");
INDEX("NB: ");
Wordings__index(ParseTree__get_text(ph->declaration_node));
Index__link(Wordings__first_wn(ParseTree__get_text(ph->declaration_node)));
INDEX("</p>");
}
}
}
#line 49 "inform7/Chapter 28/Construction Sequence.w"
int phrase_time_now = DAWN_PHT;
void Phrases__Manager__advance_phrase_time_to(int advance_to) {
if (advance_to < phrase_time_now) {
LOG("Advance from %d to %d\n", phrase_time_now, advance_to);
internal_error(
"The necessary phrase construction events are out of sequence");
}
phrase_time_now = advance_to;
}
#line 75 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__traverse_for_names(void) {
Phrases__Manager__advance_phrase_time_to(EARLY_MORNING_PHT);
ParseTree__traverse(Phrases__Manager__visit_for_names);
}
void Phrases__Manager__visit_for_names(parse_node *p) {
if (ParseTree__get_type(p) == ROUTINE_NT)
Phrases__Usage__predeclare_name_in(p);
}
#line 99 "inform7/Chapter 28/Construction Sequence.w"
sentence_handler COMMAND_SH_handler = { INVOCATION_LIST_NT, -1, 0, NULL };
sentence_handler ROUTINE_SH_handler = { ROUTINE_NT, -1, 0, NULL };
#line 146 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__traverse(void) {
Phrases__Manager__advance_phrase_time_to(LATE_MORNING_PHT);
int progress_target = 0, progress_made = 0;
ParseTree__traverse_int(Phrases__Manager__visit_to_count, &progress_target);
ParseTree__traverse_int_int(Phrases__Manager__visit_to_create, &progress_target, &progress_made);
}
void Phrases__Manager__visit_to_count(parse_node *p, int *progress_target) {
(*progress_target)++;
}
void Phrases__Manager__visit_to_create(parse_node *p, int *progress_target, int *progress_made) {
(*progress_made)++;
if ((*progress_made) % 10 == 0)
ProgressBar__update_progress_bar(3,
((float) (*progress_made))/((float) (*progress_target)));
if (ParseTree__get_type(p) == ROUTINE_NT) {
Phrases__create_from_preamble(p);
}
}
#line 180 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__register_meanings(void) {
Phrases__Manager__advance_phrase_time_to(PRE_NOON_PHT);
Routines__ToPhrases__register_all();
}
#line 213 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__parse_rule_parameters(void) {
Phrases__Manager__advance_phrase_time_to(EARLY_AFTERNOON_PHT);
phrase *ph;
LOOP_OVER(ph, phrase) {
current_sentence = ph->declaration_node;
Frames__make_current(&(ph->stack_frame));
ph->runtime_context_data =
Phrases__Usage__to_runtime_context_data(&(ph->usage_data));
Frames__remove_current();
}
}
#line 231 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__add_rules_to_rulebooks(void) {
Phrases__Manager__advance_phrase_time_to(EARLY_AFTERNOON_PHT);
Rules__Bookings__make_automatic_placements();
}
#line 246 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__parse_rule_placements(void) {
Phrases__Manager__advance_phrase_time_to(EARLY_AFTERNOON_PHT);
ParseTree__traverse(Phrases__Manager__visit_to_parse_placements);
}
void Phrases__Manager__visit_to_parse_placements(parse_node *p) {
if ((ParseTree__get_type(p) == SENTENCE_NT) &&
(p->down) &&
(ParseTree__get_type(p->down) == AVERB_NT)) {
prevailing_mood =
ParseTree__int_annotation(p->down, verbal_certainty_ANNOT);
int verb = ParseTree__int_annotation(p->down, verb_id_ANNOT);
switch(verb) {
case IN_RULEBOOK_VB:
case NOT_IN_RULEBOOK_VB:
case NO_EFFECT_IF_VB:
case NO_EFFECT_UNLESS_VB:
case NO_EFFECT_AT_ALL_VB:
case SUBSTITUTES_VB:
case SUBSTITUTES_IF_VB:
case SUBSTITUTES_UNLESS_VB:
Rules__Placement__manual_placement(verb, p->down->next);
ParseTree__annotate_int(p, sentence_unparsed_ANNOT, TRUE);
break;
}
}
}
#line 282 "inform7/Chapter 28/Construction Sequence.w"
int total_phrases_to_compile = 0;
int total_phrases_compiled = 0;
void Phrases__Manager__compile_first_block(OUTPUT_STREAM) {
Phrases__Manager__advance_phrase_time_to(MID_AFTERNOON_PHT);
{
#line 299 "inform7/Chapter 28/Construction Sequence.w"
total_phrases_compiled = 0;
phrase *ph;
LOOP_OVER(ph, phrase)
if (ph->at_least_one_compiled_form_needed)
total_phrases_to_compile++;
}
#line 287 "inform7/Chapter 28/Construction Sequence.w"
;
{
#line 308 "inform7/Chapter 28/Construction Sequence.w"
WRITE("! Definitions of rules in rulebooks\n\n");
rulebook *rb;
LOOP_OVER(rb, rulebook)
Rulebooks__compile_rule_phrases(rb, OUT,
&total_phrases_compiled, total_phrases_to_compile);
}
#line 288 "inform7/Chapter 28/Construction Sequence.w"
;
{
#line 317 "inform7/Chapter 28/Construction Sequence.w"
rule *R;
WRITE("! Definitions of displaced and unbooked rules\n\n");
LOOP_OVER(R, rule)
Rules__compile_definition(OUT, R,
&total_phrases_compiled, total_phrases_to_compile);
}
#line 289 "inform7/Chapter 28/Construction Sequence.w"
;
{
#line 328 "inform7/Chapter 28/Construction Sequence.w"
WRITE("! Definitions of adjectives\n\n");
phrase *ph;
LOOP_OVER(ph, phrase)
if (Phrases__Usage__get_effect(&(ph->usage_data)) ==
DEFINITIONAL_PHRASE_EFF)
Phrases__compile(OUT, ph,
&total_phrases_compiled, total_phrases_to_compile, NULL, NULL, NULL);
Adjectives__Meanings__compile_support_code(OUT);
}
#line 290 "inform7/Chapter 28/Construction Sequence.w"
;
{
#line 350 "inform7/Chapter 28/Construction Sequence.w"
phrase *ph;
LOOP_OVER(ph, phrase) {
kind *K = Phrases__TypeData__kind(&(ph->type_data));
if (Kinds__Behaviour__definite(K)) {
if (ph->at_least_one_compiled_form_needed)
Routines__ToPhrases__make_request(ph, K, NULL, EMPTY_WORDING);
}
}
}
#line 291 "inform7/Chapter 28/Construction Sequence.w"
;
{
#line 362 "inform7/Chapter 28/Construction Sequence.w"
phrase *ph;
LOOP_OVER(ph, phrase) {
kind *KR = Phrases__TypeData__get_return_kind(&(ph->type_data));
if ((Kinds__Behaviour__semidefinite(KR) == FALSE) &&
(Phrases__TypeData__arithmetic_operation(ph) == -1)) {
current_sentence = Phrases__declaration_node(ph);
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_ReturnKindVague));
Problems__issue_problem_segment(
"The declaration %1 tries to set up a phrase which decides a "
"value which is too vaguely described. For example, 'To decide "
"which number is the target: ...' is fine, because 'number' "
"is clear about what kind of value should emerge; but 'To "
"decide which value is the target: ...' is not clear enough.");
Problems__issue_problem_end();
}
for (int k=1; k<=26; k++)
if ((Kinds__Behaviour__involves_var(KR, k)) &&
(Phrases__TypeData__tokens_contain_variable(&(ph->type_data), k) == FALSE)) {
current_sentence = Phrases__declaration_node(ph);
char var_text[2];
var_text[0] = (char) ('A'+k-1); var_text[1] = 0;
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, var_text);
Problems__Issue__handmade_problem(_p_(PM_ReturnKindUndetermined));
Problems__issue_problem_segment(
"The declaration %1 tries to set up a phrase which decides a "
"value which is too vaguely described, because it involves "
"a kind variable (%2) which it can't determine through "
"usage.");
Problems__issue_problem_end();
}
}
}
#line 292 "inform7/Chapter 28/Construction Sequence.w"
;
{
#line 399 "inform7/Chapter 28/Construction Sequence.w"
phrase *ph;
LOOP_OVER(ph, phrase)
if ((Phrases__TypeData__invoked_inline(ph)) &&
(Phrases__Usage__has_name_as_constant(&(ph->usage_data)))) {
current_sentence = Phrases__declaration_node(ph);
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_NamedInline));
Problems__issue_problem_segment(
"The declaration %1 tries to give a name to a phrase which is "
"defined using inline Inform 6 code in (- markers -). Such "
"phrases can't be named and used as constants because they "
"have no independent existence, being instead made fresh "
"each time they are used.");
Problems__issue_problem_end();
}
}
#line 293 "inform7/Chapter 28/Construction Sequence.w"
;
}
#line 425 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__TimedEventsTable_array(OUTPUT_STREAM) {
Phrases__Manager__advance_phrase_time_to(LATE_AFTERNOON_PHT);
Phrases__Timed__TimedEventsTable_array(OUT);
}
void Phrases__Manager__TimedEventTimesTable_array(OUTPUT_STREAM) {
Phrases__Manager__advance_phrase_time_to(LATE_AFTERNOON_PHT);
Phrases__Timed__TimedEventTimesTable_array(OUT);
}
#line 438 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__rulebooks_array_array(OUTPUT_STREAM) {
Phrases__Manager__advance_phrase_time_to(LATE_AFTERNOON_PHT);
Rulebooks__rulebooks_array_array(OUT);
}
void Phrases__Manager__compile_rulebooks(OUTPUT_STREAM) {
Phrases__Manager__advance_phrase_time_to(LATE_AFTERNOON_PHT);
Rulebooks__compile_rulebooks(OUT);
}
void Phrases__Manager__RulebookNames_array(OUTPUT_STREAM) {
Phrases__Manager__advance_phrase_time_to(LATE_AFTERNOON_PHT);
Rulebooks__RulebookNames_array(OUT);
}
#line 459 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__compile_rule_printing_switch(OUTPUT_STREAM) {
Phrases__Manager__advance_phrase_time_to(LATE_AFTERNOON_PHT);
Rules__compile_rule_printing_switch(OUT);
}
#line 498 "inform7/Chapter 28/Construction Sequence.w"
void Phrases__Manager__compile_as_needed(OUTPUT_STREAM) {
Phrases__Manager__advance_phrase_time_to(EVENING_PHT);
int repeat = TRUE;
while (repeat) {
repeat = FALSE;
if (Routines__ToPhrases__compilation_coroutine(OUT,
&total_phrases_compiled, total_phrases_to_compile) > 0)
repeat = TRUE;
if (ListTogether__compilation_coroutine(OUT) > 0)
repeat = TRUE;
if (PL__Actions__ScopeLoops__compilation_coroutine(OUT) > 0)
repeat = TRUE;
if (Strings__TextSubstitutions__compilation_coroutine(OUT, FALSE) > 0)
repeat = TRUE;
if (Calculus__Propositions__Deferred__compilation_coroutine(OUT) > 0)
repeat = TRUE;
}
}
#line 85 "inform7/Chapter 28/Phrases.w"
void Phrases__create_from_preamble(parse_node *p) {
if ((p == NULL) || (ParseTree__get_type(p) != ROUTINE_NT))
internal_error("a phrase preamble should be at a ROUTINE_NT node");
int inline_wn = -1; /* the word number of an inline I6 definition if any */
int mor = DONT_KNOW_MOR; /* and its manner of return */
wording OW = EMPTY_WORDING; /* the text of the phrase options, if any */
wording documentation_W = EMPTY_WORDING; /* the documentation reference, if any */
{
#line 122 "inform7/Chapter 28/Phrases.w"
if ((p->down) && (p->down->down) && (p->down->down->next == NULL))
Phrases__parse_possible_inline_defn(
ParseTree__get_text(p->down->down), &inline_wn, &mor);
if (inline_wn >= 0) {
char *inline_defn = Lexer__word_text(inline_wn);
if (Platform__strlen(inline_defn) >= MAX_INLINE_DEFN_LENGTH)
{
#line 261 "inform7/Chapter 28/Phrases.w"
LOG("Inline definition: <%s>\n", inline_defn);
Problems__Issue__sentence_problem(_p_(PM_InlineTooLong),
"the inline definition of this 'to...' phrase is too long",
"using a quantity of Inform 6 code which exceeds the fairly small limit "
"allowed. You will need either to write the phrase definition in Inform 7, "
"or to call an I6 routine which you define elsewhere with an 'Include ...'.");
inline_defn[MAX_INLINE_DEFN_LENGTH-1] = 0;
}
#line 128 "inform7/Chapter 28/Phrases.w"
;
}
}
#line 93 "inform7/Chapter 28/Phrases.w"
;
ph_options_data phod;
ph_type_data phtd;
ph_usage_data phud;
ph_stack_frame phsf;
ph_runtime_context_data phrcd;
{
#line 134 "inform7/Chapter 28/Phrases.w"
phud = Phrases__Usage__new(ParseTree__get_text(p), FALSE);
}
#line 101 "inform7/Chapter 28/Phrases.w"
;
int effect = Phrases__Usage__get_effect(&phud);
if ((inline_wn >= 0) && (effect != TO_PHRASE_EFF))
{
#line 272 "inform7/Chapter 28/Phrases.w"
Problems__Issue__sentence_problem(_p_(PM_InlineRule),
"only 'to...' phrases can be given inline Inform 6 definitions",
"and in particular rules and adjective definitions can't.");
}
#line 104 "inform7/Chapter 28/Phrases.w"
;
if ((effect != DEFINITIONAL_PHRASE_EFF) && (p->down == NULL))
{
#line 254 "inform7/Chapter 28/Phrases.w"
Problems__Issue__sentence_problem(_p_(PM_Undefined),
"there doesn't seem to be any definition here",
"so I can't see what this rule or phrase would do.");
}
#line 107 "inform7/Chapter 28/Phrases.w"
;
{
#line 139 "inform7/Chapter 28/Phrases.w"
wording XW = Phrases__Usage__get_preamble_text(&phud);
phtd = Phrases__TypeData__new();
if (inline_wn >= 0) Phrases__TypeData__make_inline(&phtd);
switch (effect) {
case TO_PHRASE_EFF:
documentation_W = Index__DocReferences__position_of_symbol(&XW);
Phrases__TypeData__Textual__parse(&phtd, XW, &OW);
break;
case DEFINITIONAL_PHRASE_EFF:
Phrases__TypeData__set_mor(&phtd, DECIDES_CONDITION_MOR, NULL);
break;
default:
Phrases__TypeData__set_mor(&phtd, DECIDES_NOTHING_AND_RETURNS_MOR, NULL);
break;
}
}
#line 109 "inform7/Chapter 28/Phrases.w"
;
{
#line 158 "inform7/Chapter 28/Phrases.w"
phod = Phrases__Options__parse_declared_options(OW);
}
#line 110 "inform7/Chapter 28/Phrases.w"
;
{
#line 170 "inform7/Chapter 28/Phrases.w"
phsf = Frames__new();
Phrases__TypeData__into_stack_frame(&phsf, &phtd,
Phrases__TypeData__kind(&phtd), TRUE);
if (Phrases__Options__allows_options(&phod))
LocalVariables__options_parameter_is_needed(&phsf);
}
#line 111 "inform7/Chapter 28/Phrases.w"
;
{
#line 179 "inform7/Chapter 28/Phrases.w"
phrcd = Phrases__Context__new();
}
#line 112 "inform7/Chapter 28/Phrases.w"
;
phrase *new_ph;
{
#line 223 "inform7/Chapter 28/Phrases.w"
wording XW = Phrases__Usage__get_preamble_text(&phud);
LOGIF(PHRASE_CREATIONS, "Creating phrase: <$w>\n$U", XW, &phud);
new_ph = CREATE(phrase);
new_ph->declaration_node = p;
new_ph->options_data = phod;
new_ph->runtime_context_data = phrcd;
new_ph->stack_frame = phsf;
new_ph->type_data = phtd;
new_ph->usage_data = phud;
new_ph->inline_wn = inline_wn;
new_ph->inline_mor = mor;
if (inline_wn >= 0) {
new_ph->at_least_one_compiled_form_needed = FALSE;
new_ph->ph_I6_identifier[0] = 0;
} else {
new_ph->at_least_one_compiled_form_needed = TRUE;
sprintf(new_ph->ph_I6_identifier, "R_%d", new_ph->allocation_id);
}
new_ph->compile_with_run_time_debugging = FALSE;
new_ph->next_in_logical_order = NULL;
new_ph->sequence_count = -1;
new_ph->ph_documentation_symbol = documentation_W;
}
#line 115 "inform7/Chapter 28/Phrases.w"
;
{
#line 184 "inform7/Chapter 28/Phrases.w"
switch (effect) {
case TO_PHRASE_EFF:
Routines__ToPhrases__new(new_ph);
break;
case DEFINITIONAL_PHRASE_EFF:
{
#line 215 "inform7/Chapter 28/Phrases.w"
wording CW = EMPTY_WORDING;
kind *K = NULL;
Phrases__Phrasal__define_adjective_by_phrase(p, new_ph, &CW, &K);
LocalVariables__add_pronoun(&(new_ph->stack_frame), CW, K);
}
#line 189 "inform7/Chapter 28/Phrases.w"
;
break;
case RULE_IN_RULEBOOK_EFF:
Rules__request_automatic_placement(
Phrases__Usage__to_rule(&(new_ph->usage_data), new_ph));
new_ph->compile_with_run_time_debugging = TRUE;
break;
case RULE_NOT_IN_RULEBOOK_EFF:
Phrases__Usage__to_rule(&(new_ph->usage_data), new_ph);
new_ph->compile_with_run_time_debugging = TRUE;
break;
}
}
#line 116 "inform7/Chapter 28/Phrases.w"
;
}
#line 285 "inform7/Chapter 28/Phrases.w"
int inline_phrase_definition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = DECIDES_NOTHING_MOR; inlinecode_NTMV = Wordings__first_wn(inline_phrase_definition_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = DECIDES_CONDITION_MOR; inlinecode_NTMV = Wordings__first_wn(inline_phrase_definition_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = DECIDES_VALUE_MOR; inlinecode_NTMV = Wordings__first_wn(inline_phrase_definition_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = DONT_KNOW_MOR; inlinecode_NTMV = Wordings__first_wn(inline_phrase_definition_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = DONT_KNOW_MOR; inlinecode_NTMV = Wordings__first_wn(inline_phrase_definition_NTM->range_result[1]);
{
#line 295 "inform7/Chapter 28/Phrases.w"
*X = DONT_KNOW_MOR;
Problems__Issue__sentence_problem(_p_(PM_TailAfterInline),
"some unexpected text appears after the tail of an inline definition",
"placed within '(-' and '-)' markers to indicate that it is written in "
"Inform 6. Here, there seems to be something extra after the '-)'.");
}
#line 290 "inform7/Chapter 28/Phrases.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 291 "inform7/Chapter 28/Phrases.w"
#line 304 "inform7/Chapter 28/Phrases.w"
void Phrases__parse_possible_inline_defn(wording W, int *wn, int *mor) {
LOGIF(MATCHING, "form of inline: $w\n", W);
*wn = -1;
if (Preform__parse_nt_against_word_range(inline_phrase_definition_NTM, W, NULL, NULL)) { *wn = inlinecode_NTMV; *mor = most_recent_result; }
}
#line 314 "inform7/Chapter 28/Phrases.w"
void Phrases__log(phrase *ph) {
if (ph == NULL) { LOG("RULE:NULL"); return; }
LOG("%s", ph->ph_I6_identifier);
Phrases__Usage__log_rule_name(&(ph->usage_data));
}
void Phrases__log_briefly(phrase *ph) {
Phrases__TypeData__Textual__log_briefly(&(ph->type_data));
}
#line 327 "inform7/Chapter 28/Phrases.w"
void Phrases__write_HTML_representation(OUTPUT_STREAM, phrase *ph, int format) {
Phrases__TypeData__Textual__write_HTML_representation(OUT, &(ph->type_data), format, NULL);
}
#line 334 "inform7/Chapter 28/Phrases.w"
int Phrases__compiled_inline(phrase *ph) {
if (ph->inline_wn < 0) return FALSE;
return TRUE;
}
char *Phrases__get_inline_definition(phrase *ph) {
if (ph->inline_wn < 0)
internal_error("tried to access inline definition of non-inline phrase");
return Lexer__word_text(ph->inline_wn);
}
char *Phrases__identifier(phrase *ph) {
return ph->ph_I6_identifier;
}
parse_node *Phrases__declaration_node(phrase *ph) {
return ph->declaration_node;
}
#line 360 "inform7/Chapter 28/Phrases.w"
void Phrases__compile(OUTPUT_STREAM, phrase *ph, int *i, int max_i,
stacked_variable_owner_list *legible, to_phrase_request *req, applicability_condition *acl) {
int effect = Phrases__Usage__get_effect(&(ph->usage_data));
if (effect == TO_PHRASE_EFF) {
Routines__Compile__routine(OUT, ph, legible, req, acl);
{
#line 378 "inform7/Chapter 28/Phrases.w"
if (ph->at_least_one_compiled_form_needed) {
ph->at_least_one_compiled_form_needed = FALSE;
(*i)++;
ProgressBar__update_progress_bar(4, ((float) (*i))/((float) max_i));
}
}
#line 366 "inform7/Chapter 28/Phrases.w"
;
} else {
if (ph->at_least_one_compiled_form_needed) {
Routines__Compile__routine(OUT, ph, legible, NULL, acl);
{
#line 378 "inform7/Chapter 28/Phrases.w"
if (ph->at_least_one_compiled_form_needed) {
ph->at_least_one_compiled_form_needed = FALSE;
(*i)++;
ProgressBar__update_progress_bar(4, ((float) (*i))/((float) max_i));
}
}
#line 370 "inform7/Chapter 28/Phrases.w"
;
}
}
}
#line 53 "inform7/Chapter 28/Phrase Usage.w"
void Phrases__Usage__predeclare_name_in(parse_node *p) {
ph_usage_data phud = Phrases__Usage__new(ParseTree__get_text(p), TRUE);
if (Wordings__nonempty(phud.explicit_name))
Rules__new(phud.explicit_name, TRUE);
}
#line 74 "inform7/Chapter 28/Phrase Usage.w"
rule *Phrases__Usage__to_rule(ph_usage_data *phud, phrase *ph) {
wording W = EMPTY_WORDING;
int explicitly = FALSE;
{
#line 93 "inform7/Chapter 28/Phrase Usage.w"
if (Wordings__nonempty(phud->event_name)) {
W = Articles__remove_the(phud->event_name);
} else if (Wordings__nonempty(phud->explicit_name)) {
W = Articles__remove_the(phud->explicit_name);
explicitly = TRUE;
}
}
#line 77 "inform7/Chapter 28/Phrase Usage.w"
;
rule *R = NULL;
if (Wordings__nonempty(W)) R = Rules__by_name(W);
if (R)
{
#line 103 "inform7/Chapter 28/Phrase Usage.w"
phrase *ph_found = Rules__get_I7_definition(R);
if ((ph_found) && (ph_found != ph)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_DuplicateRuleName));
Problems__issue_problem_segment(
"You wrote %1, but this would give a name ('%2') to a "
"new rule which already belongs to an existing one.");
Problems__issue_problem_end();
}
}
#line 81 "inform7/Chapter 28/Phrase Usage.w"
else R = Rules__new(W, explicitly);
Rules__set_I7_definition(R, ph);
{
#line 117 "inform7/Chapter 28/Phrase Usage.w"
wording IX = phud->rule_parameter;
if (Wordings__nonempty(phud->whenwhile)) {
if (Wordings__first_wn(phud->whenwhile) == Wordings__last_wn(phud->rule_parameter) + 1) {
IX = Wordings__new(Wordings__first_wn(phud->rule_parameter), Wordings__last_wn(phud->whenwhile));
} else {
IX = phud->whenwhile;
}
}
Rules__set_italicised_index_text(R, IX);
}
#line 85 "inform7/Chapter 28/Phrase Usage.w"
;
return R;
}
#line 136 "inform7/Chapter 28/Phrase Usage.w"
int rule_preamble_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = DEFINITIONAL_PHRASE_EFF;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = RULE_NOT_IN_RULEBOOK_EFF; event_time_NTMV = NOT_AN_EVENT; written_NTMV = FALSE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 158 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__sentence_problem(_p_(PM_NamelessRule),
"there are many rules in Inform",
"so you need to give a name: 'this is the abolish dancing rule', say, "
"not just 'this is the rule'.");
}
#line 139 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 166 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__sentence_problem(_p_(PM_UnarticledRule),
"a rule must be given a definite name",
"which begins with 'the', just to emphasise that it is the only one "
"with this name: 'this is the promote dancing rule', say, not just "
"'this is promote dancing rule'.");
}
#line 140 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 175 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__sentence_problem(_p_(PM_PluralisedRule),
"a rule must be given a definite name ending in 'rule' not 'rules'",
"since the plural is only used for rulebooks, which can of course "
"contain many rules at once.");
}
#line 141 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = RULE_NOT_IN_RULEBOOK_EFF; event_time_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 183 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__sentence_problem(_p_(PM_BareTo),
"'to' what? No name is given",
"which means that this would not define a new phrase.");
}
#line 143 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7:
{
#line 190 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__sentence_problem(_p_(PM_DontCallPhrasesWithCalled),
"phrases aren't named using 'called'",
"and instead use 'this is...'. For example, 'To salute (called saluting)' "
"isn't allowed, but 'To salute (this is saluting)' is.");
}
#line 144 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = TO_PHRASE_EFF; named_NTMV = TRUE; written_NTMV = TRUE; inverted_NTMV = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *X = TO_PHRASE_EFF; named_NTMV = TRUE; written_NTMV = TRUE; inverted_NTMV = FALSE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10: *X = TO_PHRASE_EFF; named_NTMV = TRUE; written_NTMV = FALSE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11: *X = TO_PHRASE_EFF; named_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12: *X = RULE_IN_RULEBOOK_EFF; named_NTMV = TRUE; written_NTMV = FALSE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13:
{
#line 158 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__sentence_problem(_p_(PM_NamelessRule),
"there are many rules in Inform",
"so you need to give a name: 'this is the abolish dancing rule', say, "
"not just 'this is the rule'.");
}
#line 150 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14:
{
#line 166 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__sentence_problem(_p_(PM_UnarticledRule),
"a rule must be given a definite name",
"which begins with 'the', just to emphasise that it is the only one "
"with this name: 'this is the promote dancing rule', say, not just "
"'this is promote dancing rule'.");
}
#line 151 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15:
{
#line 175 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__sentence_problem(_p_(PM_PluralisedRule),
"a rule must be given a definite name ending in 'rule' not 'rules'",
"since the plural is only used for rulebooks, which can of course "
"contain many rules at once.");
}
#line 152 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 16: *X = RULE_IN_RULEBOOK_EFF; named_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 154 "inform7/Chapter 28/Phrase Usage.w"
#line 200 "inform7/Chapter 28/Phrase Usage.w"
int now_phrase_preamble_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 202 "inform7/Chapter 28/Phrase Usage.w"
#line 210 "inform7/Chapter 28/Phrase Usage.w"
int rule_preamble_fine_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; parse_node_scenes_NTMV = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; parse_node_scenes_NTMV = NULL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 213 "inform7/Chapter 28/Phrase Usage.w"
int rule_preamble_finer_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = NOT_APPLICABLE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 218 "inform7/Chapter 28/Phrase Usage.w"
int rulebook_stem_embellished_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; bud1_NTMV = Wordings__first_wn(rulebook_stem_embellished_NTM->range_result[1]); bud2_NTMV = Wordings__last_wn(rulebook_stem_embellished_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; bud1_NTMV = Wordings__first_wn(rulebook_stem_embellished_NTM->range_result[1]); bud2_NTMV = Wordings__last_wn(rulebook_stem_embellished_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; bud1_NTMV = Wordings__first_wn(rulebook_stem_embellished_NTM->range_result[1]); bud2_NTMV = Wordings__last_wn(rulebook_stem_embellished_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; bud1_NTMV = Wordings__first_wn(rulebook_stem_embellished_NTM->range_result[1]); bud2_NTMV = Wordings__last_wn(rulebook_stem_embellished_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 0; bud1_NTMV = Wordings__first_wn(rulebook_stem_embellished_NTM->range_result[1]); bud2_NTMV = Wordings__last_wn(rulebook_stem_embellished_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 225 "inform7/Chapter 28/Phrase Usage.w"
int rulebook_bud_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 230 "inform7/Chapter 28/Phrase Usage.w"
#line 244 "inform7/Chapter 28/Phrase Usage.w"
int no_now_phrases = 0;
ph_usage_data Phrases__Usage__new(wording W, int coarse_mode) {
ph_usage_data phud;
{
#line 273 "inform7/Chapter 28/Phrase Usage.w"
phud.full_preamble = W;
phud.constant_phrase_holder = NULL;
phud.phrase_effect = AS_YET_UNKNOWN_EFF;
phud.explicit_name = EMPTY_WORDING;
phud.explicit_name_used_in_maths = FALSE;
phud.rule_preamble = EMPTY_WORDING;
phud.rule_parameter = EMPTY_WORDING;
phud.whenwhile = EMPTY_WORDING;
phud.during_scene_spec = NULL;
phud.event_name = EMPTY_WORDING;
phud.timing_of_event = NOT_A_TIMED_EVENT;
phud.uses_as_event = NULL;
phud.owning_rulebook = NULL;
phud.owning_rulebook_placement = MIDDLE_PLACEMENT;
phud.explicit_name_for_inverse = EMPTY_WORDING;
}
#line 248 "inform7/Chapter 28/Phrase Usage.w"
;
if (Preform__parse_nt_against_word_range(rule_preamble_NTM, W, NULL, NULL)) {
phud.phrase_effect = most_recent_result;
switch (most_recent_result) {
case TO_PHRASE_EFF:
{
#line 292 "inform7/Chapter 28/Phrase Usage.w"
phud.rule_preamble = W;
if (named_NTMV)
{
#line 311 "inform7/Chapter 28/Phrase Usage.w"
wording RW = GET_RW(rule_preamble_NTM, 1);
wording NW = GET_RW(rule_preamble_NTM, 2);
if (coarse_mode) {
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, NW, NULL, NULL)) {
Problems__Issue__sentence_problem(_p_(PM_PhraseNameDuplicated),
"that name for this new phrase is not allowed",
"because it already has a meaning.");
}
phud.constant_phrase_holder = Phrases__Constants__parse(NW);
if (phud.constant_phrase_holder == NULL)
phud.constant_phrase_holder =
Phrases__Constants__create(NW, RW);
} else {
constant_phrase *cphr = Phrases__Constants__parse(NW);
if (Kinds__Behaviour__definite(cphr->cphr_kind) == FALSE) {
phrase *ph = Phrases__Constants__as_phrase(cphr);
if (ph) current_sentence = Phrases__declaration_node(ph);
Problems__quote_source(1, Sentences__NPs__new_raw(cphr->name));
Problems__quote_wording(2, cphr->name);
Problems__Issue__handmade_problem(_p_(PM_NamedGeneric));
Problems__issue_problem_segment(
"I can't allow %1, because the phrase it gives a name to "
"is generic, that is, it has a kind which is too vague. "
"That means there isn't any single phrase which '%2' "
"could refer to - there would have to be different versions "
"for every setting where it might be needed, and we can't "
"predict in advance which one '%2' might need to be.");
Problems__issue_problem_end();
LOG("CPHR failed at %d, $u\n", cphr->allocation_id, cphr->cphr_kind);
}
if (written_NTMV) {
phud.explicit_name_used_in_maths = TRUE;
if (inverted_NTMV) {
wording IW = GET_RW(rule_preamble_NTM, 3);
phud.explicit_name_for_inverse = Wordings__first_word(IW);
}
}
phud.constant_phrase_holder = cphr;
}
phud.rule_preamble = RW;
}
#line 294 "inform7/Chapter 28/Phrase Usage.w"
;
if (Preform__parse_nt_against_word_range(now_phrase_preamble_NTM, W, NULL, NULL)) {
if ((coarse_mode) && (no_now_phrases++ == 1)) {
Problems__Issue__sentence_problem(_p_(PM_RedefinedNow),
"creating new variants on 'now' is not allowed",
"because 'now' plays a special role in the language. "
"It has a wide-ranging ability to make a condition "
"become immediately true. (To give it wider abilities, "
"the idea is to create new relations.)");
}
}
}
#line 254 "inform7/Chapter 28/Phrase Usage.w"
;
break;
case DEFINITIONAL_PHRASE_EFF:
break;
case RULE_IN_RULEBOOK_EFF:
{
#line 356 "inform7/Chapter 28/Phrase Usage.w"
if (named_NTMV) {
W = GET_RW(rule_preamble_NTM, 1);
phud.explicit_name = GET_RW(rule_preamble_NTM, 2);
}
if (coarse_mode == FALSE)
{
#line 383 "inform7/Chapter 28/Phrase Usage.w"
Preform__parse_nt_against_word_range(rule_preamble_fine_NTM, W, NULL, NULL);
W = GET_RW(rule_preamble_finer_NTM, 1);
if (most_recent_result == NOT_APPLICABLE) {
Preform__parse_nt_against_word_range(unrecognised_rule_stem_diagnosis_NTM, W, NULL, NULL);
} else {
if (most_recent_result) phud.whenwhile = GET_RW(rule_preamble_finer_NTM, 2);
phud.during_scene_spec = parse_node_scenes_NTMV;
phud.owning_rulebook = parsed_rm.matched_rulebook;
if (phud.owning_rulebook == NULL) internal_error("rulebook stem misparsed");
phud.owning_rulebook_placement = parsed_rm.placement_requested;
{
#line 502 "inform7/Chapter 28/Phrase Usage.w"
if ((parsed_rm.article_used == DEF_ART) &&
(parsed_rm.placement_requested == MIDDLE_PLACEMENT))
Problems__Issue__sentence_problem(_p_(PM_RuleWithDefiniteArticle),
"a rulebook can contain any number of rules",
"so (e.g.) 'the before rule: ...' is disallowed; you should "
"write 'a before rule: ...' instead.");
}
#line 393 "inform7/Chapter 28/Phrase Usage.w"
;
{
#line 402 "inform7/Chapter 28/Phrase Usage.w"
int b1 = bud1_NTMV, b2 = bud2_NTMV;
if ((b1 == -1) || (b1 > b2)) {
b1 = parsed_rm.match_from + parsed_rm.advance_words;
b2 = parsed_rm.match_from + parsed_rm.advance_words - 1;
}
b2 -= parsed_rm.tail_words;
wording BW = Wordings__new(b1, b2);
wording CW = EMPTY_WORDING;
if (parsed_rm.advance_words != parsed_rm.match_length) {
if (!((Preform__parse_nt_against_word_range(rulebook_bud_NTM, BW, NULL, NULL)) && (most_recent_result == FALSE))) {
BW = Wordings__from(BW, parsed_rm.match_from + parsed_rm.match_length);
if (Preform__parse_nt_against_word_range(rulebook_bud_NTM, BW, NULL, NULL)) {
if (most_recent_result) CW = GET_RW(rulebook_bud_NTM, 1);
} else {
CW = BW;
}
}
} else {
if (Preform__parse_nt_against_word_range(rulebook_bud_NTM, BW, NULL, NULL)) {
if (most_recent_result) CW = GET_RW(rulebook_bud_NTM, 1);
} else {
CW = BW;
}
}
if (Preform__parse_nt_against_word_range(rulebook_bud_NTM, BW, NULL, NULL)) {
if (most_recent_result) CW = GET_RW(rulebook_bud_NTM, 1);
} else if (parsed_rm.advance_words != parsed_rm.match_length) {
BW = Wordings__from(BW, parsed_rm.match_from + parsed_rm.match_length);
if (Preform__parse_nt_against_word_range(rulebook_bud_NTM, BW, NULL, NULL)) {
if (most_recent_result) CW = GET_RW(rulebook_bud_NTM, 1);
} else {
CW = BW;
}
} else {
CW = BW;
}
if (Wordings__nonempty(CW)) phud.rule_parameter = CW;
if ((phud.owning_rulebook) &&
(Rulebooks__runs_during_activities(phud.owning_rulebook) == FALSE) &&
(Rulebooks__focus(phud.owning_rulebook) == ACTION_FOCUS) &&
(Wordings__nonempty(phud.rule_parameter)) &&
(Wordings__nonempty(phud.whenwhile))) {
phud.rule_parameter =
Wordings__new(Wordings__first_wn(phud.rule_parameter),
Wordings__last_wn(phud.whenwhile));
phud.whenwhile = EMPTY_WORDING;
}
}
#line 394 "inform7/Chapter 28/Phrase Usage.w"
;
}
phud.rule_preamble = W;
}
#line 360 "inform7/Chapter 28/Phrase Usage.w"
;
}
#line 259 "inform7/Chapter 28/Phrase Usage.w"
;
break;
case RULE_NOT_IN_RULEBOOK_EFF:
{
#line 365 "inform7/Chapter 28/Phrase Usage.w"
if (event_time_NTMV == NOT_AN_EVENT) {
phud.explicit_name = GET_RW(rule_preamble_NTM, 1);
if (Rules__vet_name(phud.explicit_name) == FALSE)
phud.explicit_name = EMPTY_WORDING;
} else {
phud.timing_of_event = event_time_NTMV;
if (event_time_NTMV == NO_FIXED_TIME)
phud.event_name = GET_RW(event_rule_preamble_NTM, 1);
}
}
#line 262 "inform7/Chapter 28/Phrase Usage.w"
;
break;
}
}
return phud;
}
#line 457 "inform7/Chapter 28/Phrase Usage.w"
int unrecognised_rule_stem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 464 "inform7/Chapter 28/Phrase Usage.w"
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_BadRulePreambleWhen));
Problems__issue_problem_segment(
"The punctuation makes me think %1 should be a definition "
"of a phrase or a rule, but it doesn't begin as it should, "
"with either 'To' (e.g. 'To flood the riverplain:'), 'Definition:', "
"a name for a rule (e.g. 'This is the devilishly cunning rule:'), "
"'At' plus a time (e.g. 'At 11:12 PM:' or 'At the time when "
"the clock chimes:') or the name of a rulebook. %P"
"As your rule begins with 'When', it may be worth noting that in "
"December 2006 the syntax used by Inform for timed events changed: "
"the old syntax 'When the sky falls in:' to create a named "
"event, the sky falls in, became 'At the time when the sky "
"falls in:'. This was changed to avoid confusion with rules "
"relating to when scenes begin or end. %P"
"Or perhaps you meant to say that something would only happen "
"when some condition held. Inform often allows this, but the "
"'when...' part tends to be at the end, not up front - for "
"instance, 'Understand \"blue\" as the deep crevasse when the "
"location is the South Pole.'");
Problems__issue_problem_end();
}
#line 458 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 489 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__sentence_problem(_p_(PM_BadRulePreamble),
"the punctuation here ':' makes me think this should be a definition "
"of a phrase and it doesn't begin as it should",
"with either 'To' (e.g. 'To flood the riverplain:'), 'Definition:', "
"a name for a rule (e.g. 'This is the devilishly cunning rule:'), "
"'At' plus a time (e.g. 'At 11:12 PM:' or 'At the time when "
"the clock chimes') or the name of a rulebook, possibly followed "
"by some description of the action or value to apply to (e.g. "
"'Instead of taking something:' or 'Every turn:').");
}
#line 459 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 460 "inform7/Chapter 28/Phrase Usage.w"
#line 513 "inform7/Chapter 28/Phrase Usage.w"
wording Phrases__Usage__get_preamble_text(ph_usage_data *phud) {
if (phud->phrase_effect == TO_PHRASE_EFF) return phud->rule_preamble;
return phud->full_preamble;
}
#line 525 "inform7/Chapter 28/Phrase Usage.w"
wording Phrases__Usage__get_prewhile_text(ph_usage_data *phud) {
if (Wordings__nonempty(phud->rule_parameter)) {
wording E = phud->rule_parameter;
if (Preform__parse_nt_against_word_range(when_while_clause_NTM, E, NULL, NULL)) E = GET_RW(when_while_clause_NTM, 1);
return E;
}
return EMPTY_WORDING;
}
#line 537 "inform7/Chapter 28/Phrase Usage.w"
int when_while_clause_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 539 "inform7/Chapter 28/Phrase Usage.w"
#line 544 "inform7/Chapter 28/Phrase Usage.w"
int Phrases__Usage__get_effect(ph_usage_data *phud) {
return phud->phrase_effect;
}
int Phrases__Usage__get_rulebook_placement(ph_usage_data *phud) {
return phud->owning_rulebook_placement;
}
rulebook *Phrases__Usage__get_rulebook(ph_usage_data *phud) {
return phud->owning_rulebook;
}
void Phrases__Usage__set_rulebook(ph_usage_data *phud, rulebook *rb) {
phud->owning_rulebook = rb;
}
int Phrases__Usage__get_timing_of_event(ph_usage_data *phud) {
return phud->timing_of_event;
}
int Phrases__Usage__has_name_as_constant(ph_usage_data *phud) {
if ((phud->constant_phrase_holder) &&
(phud->explicit_name_used_in_maths == FALSE) &&
(Wordings__nonempty(phud->constant_phrase_holder->name))) return TRUE;
return FALSE;
}
wording Phrases__Usage__get_equation_form(ph_usage_data *phud) {
if (phud->explicit_name_used_in_maths)
return Wordings__first_word(phud->constant_phrase_holder->name);
return EMPTY_WORDING;
}
phrase *Phrases__Usage__get_equation_inverse(ph_usage_data *phud) {
if (Wordings__nonempty(phud->explicit_name_for_inverse)) {
phrase *ph;
LOOP_OVER(ph, phrase) {
wording W = Phrases__Usage__get_equation_form(&(ph->usage_data));
if (Wordings__nonempty(W))
if (Wordings__match(W, phud->explicit_name_for_inverse))
return ph;
}
}
return NULL;
}
#line 596 "inform7/Chapter 28/Phrase Usage.w"
void Phrases__Usage__log(ph_usage_data *phud) {
char *ram = "<UNKNOWN_VNT>";
switch(phud->phrase_effect) {
case AS_YET_UNKNOWN_EFF: ram = "AS_YET_UNKNOWN_EFF"; break;
case DEFINITIONAL_PHRASE_EFF: ram = "DEFINITIONAL_PHRASE_EFF"; break;
case RULE_NOT_IN_RULEBOOK_EFF: ram = "RULE_NOT_IN_RULEBOOK_EFF"; break;
case TO_PHRASE_EFF: ram = "TO_PHRASE_EFF"; break;
case RULE_IN_RULEBOOK_EFF: ram = "RULE_IN_RULEBOOK_EFF"; break;
}
LOG("PHUD: <$w>: rule attachment mode %s\n", phud->full_preamble, ram);
if (phud->constant_phrase_holder)
LOG(" Constant name: <$w>\n", phud->constant_phrase_holder->name);
if (Wordings__nonempty(phud->explicit_name))
LOG(" Explicit name: <$w>\n", phud->explicit_name);
if (phud->explicit_name_used_in_maths)
LOG(" Used functionally in equations\n");
if (Wordings__nonempty(phud->rule_preamble))
LOG(" Rule preamble: <$w>\n", phud->rule_preamble);
if (Wordings__nonempty(phud->rule_parameter))
LOG(" Rule parameter: <$w>\n", phud->rule_parameter);
if (Wordings__nonempty(phud->whenwhile))
LOG(" When/while text: <$w>\n", phud->whenwhile);
if (Wordings__nonempty(phud->event_name))
LOG(" Event name: <$w>\n", phud->event_name);
if (phud->timing_of_event != NOT_A_TIMED_EVENT)
LOG(" Timed event: at %d\n", phud->timing_of_event);
if (phud->during_scene_spec)
LOG(" During scene: <$P>\n", phud->during_scene_spec);
if (phud->owning_rulebook) {
char *place = "<UNKNOWN_VNT>";
LOG(" Owned by rulebook: ");
Rulebooks__log_name_only(phud->owning_rulebook);
switch(phud->owning_rulebook_placement) {
case MIDDLE_PLACEMENT: place = "MIDDLE_PLACEMENT"; break;
case FIRST_PLACEMENT: place = "FIRST_PLACEMENT"; break;
case LAST_PLACEMENT: place = "LAST_PLACEMENT"; break;
}
LOG("\n Placement: %s\n", place);
}
}
void Phrases__Usage__log_rule_name(ph_usage_data *phud) {
if (Wordings__empty(phud->explicit_name)) {
if (Wordings__nonempty(phud->full_preamble))
LOG("\"$w\"", phud->full_preamble);
else LOG("(nameless)");
} else LOG("($w)", phud->explicit_name);
}
#line 648 "inform7/Chapter 28/Phrase Usage.w"
void Phrases__Usage__write_I6_comment_describing(ph_usage_data *phud, OUTPUT_STREAM) {
WRITE("! ");
Wordings__to_stream_raw_within_i6_literal(OUT, phud->full_preamble);
WRITE(":\n");
}
#line 657 "inform7/Chapter 28/Phrase Usage.w"
void Phrases__Usage__index_preamble(ph_usage_data *phud) {
Wordings__index_raw(phud->full_preamble);
}
#line 671 "inform7/Chapter 28/Phrase Usage.w"
int NAP_problem_explained = FALSE; /* pertains to Named Action Patterns */
int issuing_ANL_problem = FALSE; /* pertains to Action Name Lists */
#line 677 "inform7/Chapter 28/Phrase Usage.w"
ph_runtime_context_data Phrases__Usage__to_runtime_context_data(ph_usage_data *phud) {
ph_runtime_context_data phrcd = Phrases__Context__new();
if (phud->phrase_effect == RULE_NOT_IN_RULEBOOK_EFF)
phrcd.permit_all_outcomes = TRUE;
if (phud->phrase_effect == RULE_IN_RULEBOOK_EFF)
{
#line 692 "inform7/Chapter 28/Phrase Usage.w"
phrcd.compile_for_rulebook = &(phud->owning_rulebook);
if (Wordings__nonempty(phud->rule_parameter))
{
#line 709 "inform7/Chapter 28/Phrase Usage.w"
if (Rulebooks__focus(phud->owning_rulebook) == ACTION_FOCUS) {
permit_trying_omission = TRUE;
Frames__set_stvol(
Frames__current_stack_frame(), all_action_processing_vars);
if (Preform__parse_nt_against_word_range(action_pattern_NTM, phud->rule_parameter, NULL, NULL)) phrcd.ap = *((action_pattern *) most_recent_result_p);
Frames__remove_nonphrase_stack_frame();
permit_trying_omission = FALSE;
if (PL__Actions__Patterns__is_valid(&(phrcd.ap)) == FALSE)
{
#line 745 "inform7/Chapter 28/Phrase Usage.w"
Phrases__Usage__log(phud);
LOG("Bad action pattern: $w = $A\nPAP failure reason: %d\n",
phud->rule_parameter, &(phrcd.ap), pap_failure_reason);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, phud->rule_parameter);
if (Preform__parse_nt_against_word_range(action_problem_diagnosis_NTM, phud->rule_parameter, NULL, NULL) == FALSE)
switch(pap_failure_reason) {
case MIXEDNOUNS_PAPF:
{
#line 762 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__handmade_problem(_p_(PM_APWithDisjunction));
Problems__issue_problem_segment(
"You wrote %1, which seems to introduce a rule, but the "
"circumstances ('%2') seem to be too general for me to "
"understand in a single rule. I can understand a choice of "
"of actions, in a list such as 'taking or dropping the ball', "
"but there can only be one set of noun(s) supplied. So 'taking "
"the ball or taking the bat' is disallowed. You can get around "
"this by using named actions ('Taking the ball is being "
"mischievous. Taking the bat is being mischievous. Instead of "
"being mischievous...'), or it may be less bother just to "
"write more than one rule.");
Problems__issue_problem_end();
}
#line 752 "inform7/Chapter 28/Phrase Usage.w"
; break;
case NOPARTICIPLE_PAPF:
{
#line 779 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__handmade_problem(_p_(PM_APWithNoParticiple));
Problems__issue_problem_segment(
"You wrote %1, which seems to introduce a rule taking effect "
"only '%2'. But this does not look like an action, since "
"there is no sign of a participle ending '-ing' (as in "
"'taking the brick', say) - which makes me think I have "
"badly misunderstood what you intended.");
Problems__issue_problem_end();
}
#line 753 "inform7/Chapter 28/Phrase Usage.w"
; break;
case IMMISCIBLE_PAPF:
{
#line 791 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__handmade_problem(_p_(PM_APWithImmiscible));
Problems__issue_problem_segment(
"You wrote %1, which seems to introduce a rule taking effect "
"only '%2'. But this is a combination of actions which cannot "
"be mixed. The only alternatives where 'or' is allowed are "
"cases where a choice of actions is given but applying to "
"the same objects in each case. (So 'taking or dropping the "
"CD' is allowed, but 'dropping the CD or inserting the CD "
"into the jewel box' is not, because the alternatives there "
"would make different use of objects from each other.)");
Problems__issue_problem_end();
}
#line 754 "inform7/Chapter 28/Phrase Usage.w"
; break;
case WHEN_PAPF:
{
#line 806 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__handmade_problem(_p_(PM_APWithBadWhen));
wording Q = phud->rule_parameter;
int diagnosis = 0;
if (Preform__parse_nt_against_word_range(action_when_diagnosis_NTM, Q, NULL, NULL)) {
Q = Wordings__new(cw1_NTMV, cw2_NTMV);
diagnosis = most_recent_result;
}
Problems__quote_wording(2, Q);
Problems__quote_text(3, "so I am unable to accept this rule.");
if (diagnosis == 2) {
Problems__quote_text(3,
"perhaps because 'nothing' tends not to be allowed in Inform conditions? "
"(Whereas 'no thing' is usually allowed.)");
}
if (diagnosis == 3) {
Problems__quote_text(3,
"perhaps because 'nowhere' tends not to be allowed in Inform conditions? "
"(Whereas 'no room' is usually allowed.)");
}
Problems__issue_problem_segment(
"You wrote %1, which seems to introduce a rule taking effect "
"only '%2'. But this condition did not make sense, %3");
if (diagnosis == 1)
Problems__issue_problem_segment(
"%PIt might be worth mentioning that a 'when' condition tacked on to "
"an action like this is not allowed to mention or use 'called' values.");
if (diagnosis == 4)
Problems__issue_problem_segment(
"%PThe problem might be that 'and' has been followed by 'when' or "
"'while'. For example, to make a rule with two conditions, this is "
"okay: 'Instead of jumping when Peter is happy and Peter is in the "
"location'; but the same thing with '...and when Peter is...' is not allowed.");
Problems__issue_problem_end();
}
#line 755 "inform7/Chapter 28/Phrase Usage.w"
; break;
default:
{
#line 843 "inform7/Chapter 28/Phrase Usage.w"
Problems__quote_wording(2, phud->rule_parameter);
if (pap_failure_reason == WHENOKAY_PAPF)
Problems__quote_text(3,
"The part after 'when' (or 'while') was fine, but the earlier words");
else Problems__quote_text(3, "But that");
Problems__Issue__handmade_problem(_p_(PM_APUnknown));
Problems__issue_problem_segment(
"You wrote %1, which seems to introduce a rule taking effect only if the "
"action is '%2'. %3 did not make sense as a description of an action.");
{
#line 862 "inform7/Chapter 28/Phrase Usage.w"
action_name *an;
LOOP_OVER(an, action_name)
if ((Wordings__length(phud->rule_parameter) < Wordings__length(an->present_name)) &&
(Wordings__match(phud->rule_parameter,
Wordings__truncate(an->present_name, Wordings__length(phud->rule_parameter))))) {
Problems__quote_wording(3, an->present_name);
Problems__issue_problem_segment(
" I notice that there's an action called '%3', though: perhaps "
"this is what you meant?");
break;
}
}
#line 852 "inform7/Chapter 28/Phrase Usage.w"
;
{
#line 877 "inform7/Chapter 28/Phrase Usage.w"
if (pap_failure_reason == WHENOKAY_PAPF) {
time_period duration = TimePeriods__parse(phud->rule_preamble);
LOG("Checking $w\n", phud->rule_preamble);
if (TimePeriods__is_valid(&duration)) {
Problems__quote_wording(3,
Wordings__from(phud->rule_preamble, TimePeriods__is_valid(&duration) + 1));
Problems__issue_problem_segment(
" (I wonder if this might be because '%3', which looks like a "
"condition on the timing, is the wrong side of the 'when...' "
"clause?)");
}
}
}
#line 853 "inform7/Chapter 28/Phrase Usage.w"
;
{
#line 900 "inform7/Chapter 28/Phrase Usage.w"
issuing_ANL_problem = FALSE; NAP_problem_explained = FALSE;
Preform__parse_nt_against_word_range(anl_diagnosis_NTM, phud->rule_parameter, NULL, NULL);
int N = most_recent_result;
if (N > 1) {
int avoids = FALSE;
if ((Preform__parse_nt_against_word_range(action_list_NTM, phud->rule_parameter, NULL, NULL)) && (most_recent_result == FALSE)) avoids = TRUE;
if (avoids)
Problems__issue_problem_segment(
" This looks like a list of actions to avoid: ");
else
Problems__issue_problem_segment(
" Looking at this as a list of alternative actions: ");
issuing_ANL_problem = TRUE; NAP_problem_explained = FALSE;
Preform__parse_nt_against_word_range(anl_diagnosis_NTM, phud->rule_parameter, NULL, NULL);
Problems__issue_problem_segment(" so");
}
}
#line 854 "inform7/Chapter 28/Phrase Usage.w"
;
Problems__issue_problem_segment(
" I am unable to place this rule into any rulebook.");
Problems__issue_problem_end();
}
#line 756 "inform7/Chapter 28/Phrase Usage.w"
; break;
}
}
#line 718 "inform7/Chapter 28/Phrase Usage.w"
;
} else {
kind *pk = Rulebooks__get_parameter_kind(phud->owning_rulebook);
phrcd.ap = PL__Actions__Patterns__parse_parametric(phud->rule_parameter, pk);
if (PL__Actions__Patterns__is_valid(&(phrcd.ap)) == FALSE) {
if (Wordings__nonempty(phud->whenwhile)) {
wording F = Wordings__up_to(phud->rule_parameter, Wordings__last_wn(phud->whenwhile));
phrcd.ap = PL__Actions__Patterns__parse_parametric(F, pk);
if (PL__Actions__Patterns__is_valid(&(phrcd.ap)) == TRUE) {
phud->rule_parameter = F;
phud->whenwhile = EMPTY_WORDING;
}
}
}
if (PL__Actions__Patterns__is_valid(&(phrcd.ap)) == FALSE)
{
#line 921 "inform7/Chapter 28/Phrase Usage.w"
Phrases__Usage__log(phud);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, phud->rule_parameter);
Problems__quote_kind(3, pk);
Preform__parse_nt_against_word_range(parametric_problem_diagnosis_NTM, phud->rule_preamble, NULL, NULL);
}
#line 733 "inform7/Chapter 28/Phrase Usage.w"
;
}
}
#line 694 "inform7/Chapter 28/Phrase Usage.w"
;
if (Wordings__nonempty(phud->whenwhile)) {
phrcd.activity_context =
Wordings__new(
Wordings__first_wn(phud->whenwhile) + 1,
Wordings__last_wn(phud->whenwhile));
phrcd.activity_where = current_sentence;
}
if (phud->during_scene_spec) phrcd.during_scene = phud->during_scene_spec;
}
#line 684 "inform7/Chapter 28/Phrase Usage.w"
;
return phrcd;
}
#line 934 "inform7/Chapter 28/Phrase Usage.w"
int parametric_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 941 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__sentence_problem(_p_(PM_WhenThePlay),
"there's no scene called 'the play'",
"so I think you need to remove 'the' - Inform has two "
"special rulebooks, 'When play begins' and 'When play ends', "
"and I think you probably mean to refer to one of those.");
}
#line 935 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 950 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__handmade_problem(_p_(PM_BadParameter));
Problems__issue_problem_segment(
"You wrote %1, but the description of the thing(s) to which the rule "
"applies ('%2') did not make sense. This is %3 based rulebook, so "
"that should have described %3.");
Problems__issue_problem_end();
}
#line 936 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 937 "inform7/Chapter 28/Phrase Usage.w"
#line 961 "inform7/Chapter 28/Phrase Usage.w"
int action_problem_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 969 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__handmade_problem(_p_(PM_NonActionInPresenceOf));
Problems__issue_problem_segment(
"You wrote %1, but 'in the presence of...' is a clause which can "
"only be used to talk about an action: so, for instance, 'waiting "
"in the presence of...' is needed. "
"This problem arises especially with 'every turn' rules, where "
"'every turn in the presence of...' looks plausible but doesn't "
"work. This could be fixed by writing 'Every turn doing something "
"in the presence of...', but a neater solution talks about the "
"current situation instead: 'Every turn when the player can "
"see...'.");
Problems__issue_problem_end();
}
#line 962 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 985 "inform7/Chapter 28/Phrase Usage.w"
Problems__Issue__handmade_problem(_p_(PM_NonActionIn));
Problems__issue_problem_segment(
"You wrote %1, but 'in...' used in this way should really belong "
"to an action: for instance, 'Before waiting in the Library'. "
"Rules like 'Every turn in the Library' don't work, because "
"'every turn' is not an action; what's wanted is 'Every turn "
"when in the Library'.");
Problems__issue_problem_end();
}
#line 963 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 964 "inform7/Chapter 28/Phrase Usage.w"
#line 1000 "inform7/Chapter 28/Phrase Usage.w"
int action_when_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1; cw1_NTMV = Wordings__first_wn(action_when_diagnosis_NTM->range_result[3]); cw2_NTMV = Wordings__last_wn(action_when_diagnosis_NTM->range_result[3]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2; cw1_NTMV = Wordings__first_wn(action_when_diagnosis_NTM->range_result[2]); cw2_NTMV = Wordings__last_wn(action_when_diagnosis_NTM->range_result[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 3; cw1_NTMV = Wordings__first_wn(action_when_diagnosis_NTM->range_result[2]); cw2_NTMV = Wordings__last_wn(action_when_diagnosis_NTM->range_result[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 4; cw1_NTMV = Wordings__first_wn(action_when_diagnosis_NTM->range_result[2]); cw2_NTMV = Wordings__last_wn(action_when_diagnosis_NTM->range_result[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 5; cw1_NTMV = Wordings__first_wn(action_when_diagnosis_NTM->range_result[2]); cw2_NTMV = Wordings__last_wn(action_when_diagnosis_NTM->range_result[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1006 "inform7/Chapter 28/Phrase Usage.w"
#line 1010 "inform7/Chapter 28/Phrase Usage.w"
int anl_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1013 "inform7/Chapter 28/Phrase Usage.w"
int anl_inner_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]+R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1017 "inform7/Chapter 28/Phrase Usage.w"
int anl_tail_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1021 "inform7/Chapter 28/Phrase Usage.w"
int anl_entry_diagnosis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 1028 "inform7/Chapter 28/Phrase Usage.w"
*X = 1;
if ((issuing_ANL_problem) && (!preform_lookahead_mode)) {
Problems__quote_wording(4, W);
if (Preform__parse_nt_against_word_range(action_pattern_NTM, W, NULL, NULL) == FALSE) {
Problems__issue_problem_segment("'%4' did not make sense; ");
return TRUE;
}
action_pattern *ap = most_recent_result_p;
int form = most_recent_result;
if (PL__Actions__Patterns__is_request(ap)) {
Problems__issue_problem_segment(
"'%4' would make sense as an action on its own, but 'or' can't "
"be used in combination with 'asking... to try...' actions; ");
return TRUE;
}
if (PL__Actions__Patterns__refers_to_past(ap)) {
Problems__issue_problem_segment(
"'%4' would make sense as an action on its own, but 'or' can't "
"be used in combination with actions with time periods attached; ");
return TRUE;
}
if (Preform__parse_nt_against_word_range(named_action_pattern_NTM, W, NULL, NULL)) {
if (NAP_problem_explained == FALSE)
Problems__issue_problem_segment(
"'%4' only made sense as a named kind of action, which can "
"be used on its own but not in an action list; ");
else
Problems__issue_problem_segment(
"'%4' is another named kind of action; ");
NAP_problem_explained = TRUE;
} else {
if (form == ACTOR_EXPLICITLY_PLAYER) {
Problems__issue_problem_segment(
"'%4' would have been okay except for using the word 'trying', "
"which isn't allowed in a list like this; ");
} else
Problems__issue_problem_segment("'%4' was okay; ");
}
}
}
#line 1023 "inform7/Chapter 28/Phrase Usage.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 1024 "inform7/Chapter 28/Phrase Usage.w"
#line 46 "inform7/Chapter 28/Phrase Runtime Context Data.w"
ph_runtime_context_data Phrases__Context__new(void) {
ph_runtime_context_data phrcd;
phrcd.activity_context = EMPTY_WORDING;
phrcd.activity_where = NULL;
phrcd.avl = NULL;
phrcd.during_scene = NULL;
phrcd.ap = PL__Actions__Patterns__new();
phrcd.always_test_actor = FALSE;
phrcd.never_test_actor = FALSE;
phrcd.marked_for_anyone = FALSE;
phrcd.permit_all_outcomes = FALSE;
phrcd.compile_for_rulebook = NULL;
return phrcd;
}
#line 65 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__set_always_test_actor(ph_runtime_context_data *phrcd) {
phrcd->always_test_actor = TRUE;
}
void Phrases__Context__clear_always_test_actor(ph_runtime_context_data *phrcd) {
phrcd->always_test_actor = FALSE;
}
void Phrases__Context__set_never_test_actor(ph_runtime_context_data *phrcd) {
phrcd->never_test_actor = TRUE;
}
void Phrases__Context__set_marked_for_anyone(ph_runtime_context_data *phrcd, int to) {
phrcd->marked_for_anyone = to;
}
int Phrases__Context__get_marked_for_anyone(ph_runtime_context_data *phrcd) {
return phrcd->marked_for_anyone;
}
#line 88 "inform7/Chapter 28/Phrase Runtime Context Data.w"
int Phrases__Context__within_action_context(ph_runtime_context_data *phrcd,
action_name *an) {
if (phrcd == NULL) return FALSE;
return PL__Actions__Patterns__within_action_context(&(phrcd->ap), an);
}
action_name *Phrases__Context__required_action(ph_runtime_context_data *phrcd) {
if (PL__Actions__Patterns__is_valid(&(phrcd->ap)))
return PL__Actions__Patterns__required_action(&(phrcd->ap));
return NULL;
}
void Phrases__Context__suppress_action_testing(ph_runtime_context_data *phrcd) {
PL__Actions__Patterns__suppress_action_testing(&(phrcd->ap));
}
#line 110 "inform7/Chapter 28/Phrase Runtime Context Data.w"
scene *Phrases__Context__get_scene(ph_runtime_context_data *phrcd) {
if (phrcd == NULL) return NULL;
if (ParseTree__is_rvalue(phrcd->during_scene)) {
instance *q = Rvalues__to_instance(phrcd->during_scene);
if (q) return PL__Scenes__from_named_constant(q);
}
return NULL;
}
#line 123 "inform7/Chapter 28/Phrase Runtime Context Data.w"
int Phrases__Context__outcome_restrictions_waived(void) {
if ((phrase_being_compiled) &&
(phrase_being_compiled->runtime_context_data.permit_all_outcomes))
return TRUE;
return FALSE;
}
#line 141 "inform7/Chapter 28/Phrase Runtime Context Data.w"
int Phrases__Context__compare_specificity(ph_runtime_context_data *rcd1,
ph_runtime_context_data *rcd2) {
action_pattern *ap1, *ap2;
parse_node *sc1, *sc2;
wording AL1W, AL2W;
{
#line 158 "inform7/Chapter 28/Phrase Runtime Context Data.w"
if (rcd1) {
ap1 = &(rcd1->ap); sc1 = rcd1->during_scene;
AL1W = rcd1->activity_context;
} else {
ap1 = NULL; sc1 = NULL;
AL1W = EMPTY_WORDING;
}
if (rcd2) {
ap2 = &(rcd2->ap); sc2 = rcd2->during_scene;
AL2W = rcd2->activity_context;
} else {
ap2 = NULL; sc2 = NULL;
AL2W = EMPTY_WORDING;
}
}
#line 146 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
{
#line 176 "inform7/Chapter 28/Phrase Runtime Context Data.w"
c_s_stage_law = "I - Number of aspects constrained";
int rct1 = PL__Actions__Patterns__count_aspects(ap1);
int rct2 = PL__Actions__Patterns__count_aspects(ap2);
if (Wordings__nonempty(AL1W)) rct1++; if (Wordings__nonempty(AL2W)) rct2++;
if (sc1) rct1++; if (sc2) rct2++;
if (rct1 > rct2) return 1;
if (rct1 < rct2) return -1;
}
#line 147 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
{
#line 189 "inform7/Chapter 28/Phrase Runtime Context Data.w"
if ((sc1) && (sc2)) {
int rv = Specifications__compare_specificity(sc1, sc2, NULL);
if (rv != 0) return rv;
}
}
#line 148 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
{
#line 197 "inform7/Chapter 28/Phrase Runtime Context Data.w"
c_s_stage_law = "III - When/while requirement";
if ((Wordings__nonempty(AL1W)) && (Wordings__empty(AL2W))) return 1;
if ((Wordings__empty(AL1W)) && (Wordings__nonempty(AL2W))) return -1;
if (Wordings__nonempty(AL1W)) {
int n1 = Activities__count_list(rcd1->avl);
int n2 = Activities__count_list(rcd2->avl);
if (n1 > n2) return 1;
if (n2 > n1) return -1;
}
}
#line 149 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
{
#line 210 "inform7/Chapter 28/Phrase Runtime Context Data.w"
c_s_stage_law = "IV - Action requirement";
int rv = PL__Actions__Patterns__compare_specificity(ap1, ap2);
if (rv != 0) return rv;
}
#line 150 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
{
#line 217 "inform7/Chapter 28/Phrase Runtime Context Data.w"
c_s_stage_law = "V - Scene requirement";
if ((sc1 != NULL) && (sc2 == NULL)) return 1;
if ((sc1 == NULL) && (sc2 != NULL)) return -1;
}
#line 151 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
return 0;
}
#line 232 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__ensure_avl(rule *R) {
phrase *ph = R->defn_as_phrase;
if (ph) {
ph_runtime_context_data *rcd = &(ph->runtime_context_data);
if (Wordings__nonempty(rcd->activity_context)) {
parse_node *save_cs = current_sentence;
current_sentence = rcd->activity_where;
ph_stack_frame *phsf = &(ph->stack_frame);
Frames__make_current(phsf);
Frames__set_stvol(phsf, R->listed_stv_owners);
rcd->avl = Activities__parse_list(rcd->activity_context);
current_sentence = save_cs;
}
}
}
#line 271 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__compile_test_head(OUTPUT_STREAM, phrase *ph,
applicability_condition *acl) {
char *identifier = Phrases__identifier(ph);
ph_runtime_context_data *phrcd = &(ph->runtime_context_data);
Rules__compile_constraint(OUT, acl);
int tests = 0;
if (phrcd->during_scene)
{
#line 315 "inform7/Chapter 28/Phrase Runtime Context Data.w"
PL__Scenes__test_during_clause(OUT, phrcd->during_scene);
tests++;
}
#line 280 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
if (PL__Actions__Patterns__is_valid(&(phrcd->ap)))
{
#line 327 "inform7/Chapter 28/Phrase Runtime Context Data.w"
WRITE("if (");
if (phrcd->never_test_actor)
PL__Actions__Patterns__compile_pattern_match(OUT, phrcd->ap, TRUE);
else
PL__Actions__Patterns__compile_pattern_match(OUT, phrcd->ap, FALSE);
WRITE(") { ! Runs only when pattern matches\n");
tests++;
if (PL__Actions__Patterns__object_based(&(phrcd->ap)))
WRITE("self = noun;\n");
}
#line 281 "inform7/Chapter 28/Phrase Runtime Context Data.w"
else if (phrcd->always_test_actor == TRUE)
{
#line 346 "inform7/Chapter 28/Phrase Runtime Context Data.w"
WRITE("if (actor == player) {\n");
tests++;
}
#line 282 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
if (Wordings__nonempty(phrcd->activity_context))
{
#line 358 "inform7/Chapter 28/Phrase Runtime Context Data.w"
activity_list *avl = phrcd->avl;
if (avl == NULL)
Problems__Issue__sentence_problem(_p_(PM_BadWhenWhile),
"I don't understand the 'when/while' clause",
"which should name activities or conditions.");
else {
WRITE("if ");
Activities__compile_activity_list(OUT, avl);
WRITE(" { ! Runs only while condition holds\n");
Activities__annotate_list_for_cross_references(avl, ph);
tests++;
}
}
#line 283 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
if ((tests > 0) || (ph->compile_with_run_time_debugging)) {
WRITE("if (debug_rules) DB_Rule(%s, %d);\n", identifier, ph->allocation_id);
}
}
#line 294 "inform7/Chapter 28/Phrase Runtime Context Data.w"
void Phrases__Context__compile_test_tail(OUTPUT_STREAM, phrase *ph,
applicability_condition *acl) {
char *identifier = Phrases__identifier(ph);
ph_runtime_context_data *phrcd = &(ph->runtime_context_data);
if (phrcd->compile_for_rulebook) {
rulebook *rb = *(phrcd->compile_for_rulebook);
if (rb)
Rulebooks__Outcomes__compile_default_outcome(
Rulebooks__get_outcomes(rb), OUT);
}
if (Wordings__nonempty(phrcd->activity_context))
{
#line 374 "inform7/Chapter 28/Phrase Runtime Context Data.w"
WRITE("} else if (debug_rules > 1) DB_Rule(%s, %d, 'context');\n",
identifier, ph->allocation_id);
}
#line 306 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
if (PL__Actions__Patterns__is_valid(&(phrcd->ap)))
{
#line 340 "inform7/Chapter 28/Phrase Runtime Context Data.w"
WRITE("} else if (debug_rules > 1) DB_Rule(%s, %d, 'action');\n",
identifier, ph->allocation_id);
}
#line 307 "inform7/Chapter 28/Phrase Runtime Context Data.w"
else if (phrcd->always_test_actor == TRUE)
{
#line 352 "inform7/Chapter 28/Phrase Runtime Context Data.w"
WRITE("} else if (debug_rules > 1) DB_Rule(%s, %d, 'actor');\n",
identifier, ph->allocation_id);
}
#line 308 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
if (phrcd->during_scene)
{
#line 321 "inform7/Chapter 28/Phrase Runtime Context Data.w"
WRITE("} else if (debug_rules > 1) DB_Rule(%s, %d, 'scene');\n",
identifier, ph->allocation_id);
}
#line 309 "inform7/Chapter 28/Phrase Runtime Context Data.w"
;
}
#line 196 "inform7/Chapter 28/Phrase Type Data.w"
ph_type_data Phrases__TypeData__new(void) {
ph_type_data phtd;
phtd.registration_text = EMPTY_WORDING;
phtd.manner_of_return = DECIDES_NOTHING_MOR;
phtd.return_kind = NULL;
phtd.no_words = 0;
phtd.no_tokens = 0;
phtd.as_say = Phrases__TypeData__new_say_details();
phtd.as_inline = Phrases__TypeData__new_inline_details();
phtd.now_deprecated = FALSE;
return phtd;
}
#line 216 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__set_mor(ph_type_data *phtd, int mor, kind *K) {
phtd->manner_of_return = mor;
phtd->return_kind = K;
}
int Phrases__TypeData__get_mor(ph_type_data *phtd) {
return phtd->manner_of_return;
}
kind *Phrases__TypeData__get_return_kind(ph_type_data *phtd) {
if (phtd->manner_of_return == DECIDES_CONDITION_MOR) return K_truth_state;
return phtd->return_kind;
}
#line 233 "inform7/Chapter 28/Phrase Type Data.w"
char *Phrases__TypeData__describe_manner_of_return(int mor, ph_type_data *phtd, kind **K) {
switch (mor) {
case DECIDES_NOTHING_MOR: return "no value resulting";
case DECIDES_VALUE_MOR:
if ((phtd) && (phtd->return_kind) && (K)) *K = phtd->return_kind;
return "a phrase to decide a value";
case DECIDES_CONDITION_MOR: return "a phrase to make a decision";
case DECIDES_NOTHING_AND_RETURNS_MOR:
return "a phrase providing an outcome to a rulebook";
}
return "some phrase"; /* should never actually be needed */
}
#line 285 "inform7/Chapter 28/Phrase Type Data.w"
kind *Phrases__TypeData__kind(ph_type_data *phtd) {
kind *argument_kinds[MAX_TOKENS_PER_PHRASE];
int i, j = 0;
for (i=0; i<phtd->no_tokens; i++)
argument_kinds[j++] = phtd->token_sequence[i].token_kind;
kind *R = Phrases__TypeData__get_return_kind(phtd);
return Kinds__function_kind(j, argument_kinds, R);
}
#line 297 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__contains_variables(ph_type_data *phtd) {
return
Kinds__contains(
Phrases__TypeData__kind(phtd),
CON_KIND_VARIABLE);
}
#line 307 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__tokens_contain_variable(ph_type_data *phtd, int v) {
for (int i=0; i<phtd->no_tokens; i++)
if (Kinds__Behaviour__involves_var(phtd->token_sequence[i].token_kind, v))
return TRUE;
return FALSE;
}
#line 317 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__get_no_tokens(ph_type_data *phtd) {
return phtd->no_tokens;
}
#line 324 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__index_of_token_creating_a_variable(ph_type_data *phtd) {
int i;
for (i=0; i<phtd->no_tokens; i++)
if (phtd->token_sequence[i].construct == NEW_LOCAL_PT_CONSTRUCT)
return i;
return -1;
}
#line 338 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__preamble_requires_property_value(ph_type_data *phtd) {
int i;
for (i=0; i<phtd->no_tokens; i++) {
if (Lvalues__get_storage_form(phtd->token_sequence[i].to_match)
== PROPERTY_VALUE_VNT)
return FALSE;
}
return TRUE;
}
#line 356 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__deprecated(ph_type_data *phtd) {
return phtd->now_deprecated;
}
void Phrases__TypeData__deprecate_phrase(ph_type_data *phtd) {
phtd->now_deprecated = TRUE;
}
#line 395 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__into_stack_frame(ph_stack_frame *phsf,
ph_type_data *phtd, kind *kind_in_this_compilation, int first) {
if (Kinds__get_construct(kind_in_this_compilation) != CON_phrase)
internal_error("no function kind");
kind *args = NULL, *ret = NULL;
Kinds__binary_construction_material(kind_in_this_compilation, &args, &ret);
int i;
for (i=0; i<phtd->no_tokens; i++) {
kind *K;
if (Kinds__get_construct(args) != CON_TUPLE_ENTRY) internal_error("bad tupling");
Kinds__binary_construction_material(args, &K, &args);
if (first) {
LocalVariables__add_call_parameter(phsf, phtd->token_sequence[i].token_name, K);
} else {
local_variable *lvar = LocalVariables__get_ith_parameter(i);
if (lvar) LocalVariables__set_kind(lvar, K);
}
}
if (Kinds__Compare__eq(ret, K_nil)) Frames__set_kind_returned(phsf, NULL);
else Frames__set_kind_returned(phsf, ret);
}
#line 425 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__comparison(ph_type_data *phtd1, ph_type_data *phtd2) {
if (phtd1 == phtd2) return EQUAL_PH;
{
#line 441 "inform7/Chapter 28/Phrase Type Data.w"
int i = Phrases__TypeData__inline_type_data_comparison(phtd1, phtd2);
if (i != EQUAL_PH) return i;
}
#line 429 "inform7/Chapter 28/Phrase Type Data.w"
;
{
#line 447 "inform7/Chapter 28/Phrase Type Data.w"
int fw1 = phtd1->no_words - phtd1->no_tokens;
int fw2 = phtd2->no_words - phtd2->no_tokens;
if (fw1 > fw2) return BEFORE_PH;
if (fw1 < fw2) return AFTER_PH;
}
#line 430 "inform7/Chapter 28/Phrase Type Data.w"
;
{
#line 455 "inform7/Chapter 28/Phrase Type Data.w"
if (phtd1->no_tokens > phtd2->no_tokens) return BEFORE_PH;
if (phtd1->no_tokens < phtd2->no_tokens) return AFTER_PH;
}
#line 431 "inform7/Chapter 28/Phrase Type Data.w"
;
{
#line 468 "inform7/Chapter 28/Phrase Type Data.w"
int i;
for (i=0; i<phtd1->no_words; i++) {
if (phtd1->word_sequence[i] < MAX_TOKENS_PER_PHRASE) {
if (phtd2->word_sequence[i] >= MAX_TOKENS_PER_PHRASE)
return AFTER_PH;
} else {
if (phtd2->word_sequence[i] < MAX_TOKENS_PER_PHRASE) return BEFORE_PH;
int x = strcmp(
Lexer__word_raw_text(phtd1->word_sequence[i]),
Lexer__word_raw_text(phtd2->word_sequence[i]));
if (x > 0) return AFTER_PH;
if (x < 0) return BEFORE_PH;
}
}
}
#line 432 "inform7/Chapter 28/Phrase Type Data.w"
;
{
#line 496 "inform7/Chapter 28/Phrase Type Data.w"
int i, possibly_subschema = TRUE, possibly_superschema = TRUE;
for (i=0; i<phtd1->no_tokens; i++) {
parse_node *spec1 = phtd1->token_sequence[i].to_match;
parse_node *spec2 = phtd2->token_sequence[i].to_match;
{
#line 534 "inform7/Chapter 28/Phrase Type Data.w"
if ((phtd1->token_sequence[i].construct == NEW_LOCAL_PT_CONSTRUCT) &&
(phtd2->token_sequence[i].construct != NEW_LOCAL_PT_CONSTRUCT)) {
possibly_superschema = FALSE;
} else if ((phtd1->token_sequence[i].construct != NEW_LOCAL_PT_CONSTRUCT) &&
(phtd2->token_sequence[i].construct == NEW_LOCAL_PT_CONSTRUCT)) {
possibly_subschema = FALSE;
} else {
int wont_mix = FALSE;
int r = Specifications__compare_specificity(spec1, spec2, &wont_mix);
if (wont_mix) { possibly_subschema = FALSE; possibly_superschema = FALSE; }
else if (r < 0) possibly_subschema = FALSE;
else if (r > 0) possibly_superschema = FALSE;
}
}
#line 500 "inform7/Chapter 28/Phrase Type Data.w"
;
}
if ((possibly_subschema) || (possibly_superschema))
{
#line 517 "inform7/Chapter 28/Phrase Type Data.w"
if ((phtd1->manner_of_return != phtd2->manner_of_return) ||
((Kinds__Compare__eq(phtd1->return_kind, phtd2->return_kind) == FALSE) &&
(Kinds__Behaviour__definite(phtd1->return_kind))))
return CONFLICTED_PH;
}
#line 503 "inform7/Chapter 28/Phrase Type Data.w"
;
if (possibly_subschema) return SUBSCHEMA_PH;
if (possibly_superschema) return SUPERSCHEMA_PH;
}
#line 433 "inform7/Chapter 28/Phrase Type Data.w"
;
return INCOMPARABLE_PH;
}
#line 555 "inform7/Chapter 28/Phrase Type Data.w"
say_details Phrases__TypeData__new_say_details(void) {
say_details sd;
sd.say_phrase = NOT_A_SAY_PHRASE;
sd.say_phrase_running_on = FALSE;
sd.say_control_structure = NO_SAY_CS;
sd.say_phrase_stream_position = SSP_NONE;
sd.say_phrase_stream_token_at = -1;
sd.say_phrase_stream_closing_token_at = -1;
return sd;
}
int first_say_made = FALSE;
void Phrases__TypeData__make_sd(say_details *sd, int ro, int cs, int pos, int at, int cat) {
sd->say_phrase = A_MISCELLANEOUS_SAY_PHRASE;
if (first_say_made == FALSE) {
sd->say_phrase = THE_PRIMORDIAL_SAY_PHRASE;
first_say_made = TRUE;
}
sd->say_phrase_running_on = ro;
if (cs >= 0) sd->say_control_structure = cs;
if (pos >= 0) sd->say_phrase_stream_position = pos;
if (at >= 0) sd->say_phrase_stream_token_at = at;
if (cat >= 0) sd->say_phrase_stream_closing_token_at = cat;
}
void Phrases__TypeData__log_say_details(say_details sd) {
switch (sd.say_phrase) {
case NOT_A_SAY_PHRASE: break;
case A_MISCELLANEOUS_SAY_PHRASE: LOG(" A_MISCELLANEOUS_SAY_PHRASE\n"); break;
case THE_PRIMORDIAL_SAY_PHRASE: LOG(" THE_PRIMORDIAL_SAY_PHRASE\n"); break;
default: LOG(" <invalid say phrase status>\n"); break;
}
if (sd.say_phrase_running_on)
LOG(" running on from previous say invocation without implied newline\n");
switch (sd.say_control_structure) {
case NO_SAY_CS: break;
case IF_SAY_CS: LOG(" IF_SAY_CS\n"); break;
case END_IF_SAY_CS: LOG(" END_IF_SAY_CS\n"); break;
case OTHERWISE_SAY_CS: LOG(" OTHERWISE_SAY_CS\n"); break;
case OTHERWISE_IF_SAY_CS: LOG(" OTHERWISE_IF_SAY_CS\n"); break;
default: LOG(" <invalid say phrase status>\n"); break;
}
}
int Phrases__TypeData__is_a_say_phrase(phrase *ph) {
if ((ph) && (ph->type_data.as_say.say_phrase)) return TRUE;
return FALSE;
}
int Phrases__TypeData__is_a_say_X_phrase(ph_type_data *phtd) {
if (phtd->as_say.say_phrase == NOT_A_SAY_PHRASE) return FALSE;
if ((phtd->no_words == 2) && (phtd->word_sequence[1] < MAX_TOKENS_PER_PHRASE))
return TRUE;
return FALSE;
}
int Phrases__TypeData__is_a_spare_say_X_phrase(ph_type_data *phtd) {
if (phtd->as_say.say_phrase == NOT_A_SAY_PHRASE) return FALSE;
if ((phtd->no_words == 2) && (phtd->word_sequence[1] < MAX_TOKENS_PER_PHRASE)) {
kind *K = phtd->token_sequence[0].token_kind;
if ((K) && (Kinds__Behaviour__definite(K) == FALSE)) return FALSE;
return TRUE;
}
return FALSE;
}
int Phrases__TypeData__is_the_primordial_say(ph_type_data *phtd) {
if (phtd->as_say.say_phrase == THE_PRIMORDIAL_SAY_PHRASE) return TRUE;
return FALSE;
}
void Phrases__TypeData__get_say_data(say_details *sd,
int *say_cs, int *ssp_tok, int *ssp_ctok, int *ssp_pos) {
*say_cs = sd->say_control_structure;
*ssp_tok = sd->say_phrase_stream_token_at;
*ssp_ctok = sd->say_phrase_stream_closing_token_at;
*ssp_pos = sd->say_phrase_stream_position;
}
int Phrases__TypeData__preface_for_say_HTML(OUTPUT_STREAM, say_details sd, int paste_format) {
if (sd.say_phrase) {
if (sd.say_phrase != THE_PRIMORDIAL_SAY_PHRASE) {
switch (paste_format) {
case PASTE_PHRASE_FORMAT: WRITE("["); break;
case INDEX_PHRASE_FORMAT: WRITE("say \"["); break;
}
} else {
switch (paste_format) {
case PASTE_PHRASE_FORMAT: WRITE("say \"\""); return NOT_APPLICABLE;
case INDEX_PHRASE_FORMAT: WRITE("say \""); break;
}
}
return TRUE;
}
return FALSE;
}
void Phrases__TypeData__epilogue_for_say_HTML(OUTPUT_STREAM, say_details sd, int paste_format) {
if (sd.say_phrase) {
if (sd.say_phrase != THE_PRIMORDIAL_SAY_PHRASE) {
if (paste_format == PASTE_PHRASE_FORMAT) WRITE("]");
else if (paste_format == INDEX_PHRASE_FORMAT) WRITE("]\"");
} else {
if (paste_format == INDEX_PHRASE_FORMAT) WRITE("\"");
}
}
}
int Phrases__TypeData__ssp_matches(ph_type_data *phtd, int ssp_tok, int list_pos,
wording *W) {
int this_tok = phtd->as_say.say_phrase_stream_token_at;
int this_pos = phtd->as_say.say_phrase_stream_position;
if (this_tok == -1) return FALSE;
if (this_pos != list_pos) return FALSE;
if (compare_words(ssp_tok, this_tok) == FALSE) return FALSE;
*W = Wordings__trim_first_word(phtd->registration_text); /* to remove the word "say" */
return TRUE;
}
#line 686 "inform7/Chapter 28/Phrase Type Data.w"
inline_details Phrases__TypeData__new_inline_details(void) {
inline_details id;
id.invoked_inline_not_as_call = FALSE;
id.let_phrase = NOT_A_LET_PHRASE;
id.block_follows = NO_BLOCK_FOLLOWS;
id.only_in_loop = NULL;
id.assignment_phrase = FALSE;
id.arithmetical_operation = -1;
return id;
}
#line 703 "inform7/Chapter 28/Phrase Type Data.w"
int no_lets_made = 0;
void Phrases__TypeData__make_id(inline_details *id, int op, int assgn, int let, int blk, int only_in) {
id->arithmetical_operation = op;
id->assignment_phrase = assgn;
if ((let == ASSIGNMENT_LET_PHRASE) && (no_lets_made++ >= 3)) let = NOT_A_LET_PHRASE;
id->let_phrase = let;
id->block_follows = blk;
if (only_in == -1) id->only_in_loop = "loop";
else if (only_in > 0) id->only_in_loop = Lexer__word_text(only_in);
}
#line 718 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__log_inline_details(inline_details id) {
if (id.block_follows) LOG(" block follows\n");
if (id.let_phrase != NOT_A_LET_PHRASE) LOG(" let phrase (%d)\n", id.let_phrase);
if (id.only_in_loop) LOG(" may only be used in a %s body\n", id.only_in_loop);
switch (id.invoked_inline_not_as_call) {
case TRUE: LOG(" invoked inline\n"); break;
case FALSE: LOG(" invoked by I6 function call\n"); break;
}
}
#line 731 "inform7/Chapter 28/Phrase Type Data.w"
void Phrases__TypeData__make_inline(ph_type_data *phtd) {
phtd->as_inline.invoked_inline_not_as_call = TRUE;
}
int Phrases__TypeData__invoked_inline(phrase *ph) {
return ph->type_data.as_inline.invoked_inline_not_as_call;
}
#line 742 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__is_a_let_assignment(phrase *ph) {
if (ph->type_data.as_inline.let_phrase == ASSIGNMENT_LET_PHRASE) return TRUE;
return FALSE;
}
int Phrases__TypeData__is_a_let_equation(phrase *ph) {
if (ph->type_data.as_inline.let_phrase == EQUATION_LET_PHRASE) return TRUE;
return FALSE;
}
int Phrases__TypeData__arithmetic_operation(phrase *ph) {
return ph->type_data.as_inline.arithmetical_operation;
}
int Phrases__TypeData__is_arithmetic_phrase(phrase *ph) {
if ((Phrases__TypeData__arithmetic_operation(ph) >= 0) &&
(Phrases__TypeData__arithmetic_operation(ph) < NO_OPERATIONS)) return TRUE;
return FALSE;
}
int Phrases__TypeData__is_assignment_phrase(phrase *ph) {
return ph->type_data.as_inline.assignment_phrase;
}
char *Phrases__TypeData__only_in(phrase *ph) {
if (ph) return ph->type_data.as_inline.only_in_loop;
return NULL;
}
int Phrases__TypeData__block_follows(phrase *ph) {
return ph->type_data.as_inline.block_follows;
}
#line 784 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__return_decided_dimensionally(ph_type_data *phtd) {
if ((phtd->manner_of_return == DECIDES_VALUE_MOR) &&
(phtd->as_inline.arithmetical_operation >= 0)) return TRUE;
return FALSE;
}
#line 798 "inform7/Chapter 28/Phrase Type Data.w"
int Phrases__TypeData__inline_type_data_comparison(ph_type_data *phtd1, ph_type_data *phtd2) {
if ((phtd1->as_inline.only_in_loop) && (phtd2->as_inline.only_in_loop == FALSE))
return BEFORE_PH;
if ((phtd2->as_inline.only_in_loop) && (phtd1->as_inline.only_in_loop == FALSE))
return AFTER_PH;
return EQUAL_PH;
}
#line 12 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__log(ph_type_data *phtd) {
LOG(" PHTD: register as <$w>\n %s\n", phtd->registration_text,
Phrases__TypeData__describe_manner_of_return(phtd->manner_of_return, phtd, NULL));
if (phtd->manner_of_return == DECIDES_VALUE_MOR)
LOG(" decides value of kind $u\n", phtd->return_kind);
{
#line 26 "inform7/Chapter 28/Describing Phrase Type Data.w"
LOG(" ");
int i;
for (i=0; i<phtd->no_words; i++)
if (phtd->word_sequence[i] < MAX_TOKENS_PER_PHRASE)
LOG("#%d ", phtd->word_sequence[i]);
else
LOG("%s ", Lexer__word_text(phtd->word_sequence[i]));
LOG("(%d words)\n", phtd->no_words);
}
#line 17 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
{
#line 38 "inform7/Chapter 28/Describing Phrase Type Data.w"
int i;
for (i=0; i<phtd->no_tokens; i++)
LOG(" #%d: \"$w\" = $P\n", i,
phtd->token_sequence[i].token_name, phtd->token_sequence[i].to_match);
}
#line 18 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
Phrases__TypeData__log_inline_details(phtd->as_inline);
Phrases__TypeData__log_say_details(phtd->as_say);
}
#line 46 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__log_briefly(ph_type_data *phtd) {
if (phtd == NULL) { LOG("NULL-PHTD"); return; }
LOG("\"$w\"", phtd->registration_text);
switch(phtd->manner_of_return) {
case DECIDES_CONDITION_MOR: LOG("(=condition)"); break;
case DECIDES_VALUE_MOR: LOG("(=$u)", phtd->return_kind); break;
}
}
#line 69 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__write_HTML_representation(OUTPUT_STREAM,
ph_type_data *phtd, int paste_format, parse_node *inv) {
int seq_from = 0, seq_to = phtd->no_words;
int writing_a_say = Phrases__TypeData__preface_for_say_HTML(OUT, phtd->as_say, paste_format);
if (writing_a_say == NOT_APPLICABLE) return;
if (writing_a_say) seq_from = 1; /* skip the first word, which is necessarily "say" in this case */
if (phtd->as_inline.block_follows) seq_to--; /* skip the last word, which is a block marker */
if ((paste_format == PASTE_PHRASE_FORMAT) && (writing_a_say == FALSE)) {
if (phtd->word_sequence[0] < MAX_TOKENS_PER_PHRASE) seq_from++;
if ((phtd->word_sequence[seq_to-1] < MAX_TOKENS_PER_PHRASE) &&
(phtd->as_inline.block_follows == NO_BLOCK_FOLLOWS)) seq_to--;
}
{
#line 97 "inform7/Chapter 28/Describing Phrase Type Data.w"
int j;
for (j=seq_from; j<seq_to; j++) {
if (j > seq_from) WRITE(" ");
int ix = phtd->word_sequence[j];
if (ix < MAX_TOKENS_PER_PHRASE)
{
#line 125 "inform7/Chapter 28/Describing Phrase Type Data.w"
switch (paste_format) {
case INDEX_PHRASE_FORMAT:
if (writing_a_say == FALSE) WRITE("(");
if (inv) {
parse_node *found = Invocations__get_token_as_parsed(inv, ix);
if (ParseTree__is(found, UNKNOWN_VNT)) WRITE("<font color=\"#800000\">");
else WRITE("<font color=\"#008000\">");
Wordings__to_stream(OUT, ParseTree__get_text(found));
WRITE("</font>");
WRITE(" - ");
Dash__note_inv_token_text(found,
(phtd->token_sequence[ix].construct == NEW_LOCAL_PT_CONSTRUCT)?TRUE:FALSE);
}
{
#line 149 "inform7/Chapter 28/Describing Phrase Type Data.w"
switch (phtd->token_sequence[ix].construct) {
case STANDARD_PT_CONSTRUCT: {
parse_node *spec = phtd->token_sequence[ix].to_match;
if (Specifications__is_kind_like(spec)) {
WRITE("<font color=\"#4040ff\">");
Kinds__Textual__write(OUT, Specifications__to_kind(spec));
WRITE("</font>");
} else if ((ParseTree__is(spec, CONSTANT_VNT)) ||
(Specifications__is_description(spec))) {
WRITE("<font color=\"#4040ff\">");
Wordings__to_stream(OUT, ParseTree__get_text(spec));
WRITE("</font>");
} else {
WRITE("<i>");
WRITE("<font color=\"#ff4040\">");
Specifications__write_out_in_English(OUT, spec);
WRITE("</font>");
WRITE("</i>");
}
break;
}
case NEW_LOCAL_PT_CONSTRUCT:
WRITE("<font color=\"#E00060\">");
WRITE("a new name");
WRITE("</font>"); break;
case EXISTING_LOCAL_PT_CONSTRUCT:
WRITE("<font color=\"#E00060\">");
WRITE("a temporary named value");
if ((phtd->token_sequence[ix].token_kind) &&
(Kinds__Compare__eq(phtd->token_sequence[ix].token_kind, K_value) == FALSE)) {
WRITE(" holding ");
Kinds__Textual__write_articled(OUT, phtd->token_sequence[ix].token_kind);
}
WRITE("</font>"); break;
case CONDITION_PT_CONSTRUCT:
WRITE("<font color=\"#E00060\">");
WRITE("a condition");
WRITE("</font>"); break;
case STORAGE_PT_CONSTRUCT:
WRITE("<font color=\"#E00060\">");
WRITE("a stored value");
WRITE("</font>"); break;
case TABLE_REFERENCE_PT_CONSTRUCT:
WRITE("<font color=\"#E00060\">");
WRITE("a table entry");
WRITE("</font>"); break;
case KIND_NAME_PT_CONSTRUCT:
WRITE("<font color=\"#E00060\">");
WRITE("name of kind");
WRITE("</font>"); break;
case VOID_PT_CONSTRUCT:
WRITE("<font color=\"#E00060\">");
WRITE("a phrase");
WRITE("</font>"); break;
}
}
#line 138 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
if (writing_a_say == FALSE) WRITE(")");
break;
case PASTE_PHRASE_FORMAT:
WRITE("...");
break;
}
}
#line 102 "inform7/Chapter 28/Describing Phrase Type Data.w"
else
{
#line 110 "inform7/Chapter 28/Describing Phrase Type Data.w"
char *p = Lexer__word_raw_text(phtd->word_sequence[j]);
int i, tinted = FALSE;
for (i=0; p[i]; i++) {
if ((p[i] == '/') && (tinted == FALSE)) {
tinted = TRUE;
if (paste_format == PASTE_PHRASE_FORMAT) break;
WRITE("<font color=\"#808080\">");
}
WRITE("%c", p[i]);
}
if ((paste_format != PASTE_PHRASE_FORMAT) && (tinted)) WRITE("</font>");
}
#line 104 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
}
}
#line 85 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
if (phtd->as_inline.block_follows) {
if (paste_format) WRITE(":\n");
else WRITE(":<br>&nbsp;&nbsp;&nbsp;<i><font color=\"#ff4040\">phrases</font></i>");
}
Phrases__TypeData__epilogue_for_say_HTML(OUT, phtd->as_say, paste_format);
}
#line 209 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__inv_write_HTML_representation(OUTPUT_STREAM, parse_node *inv) {
phrase *ph = ParseTree__get_phrase_invoked(inv);
if (ph) {
ph_type_data *phtd = &(ph->type_data);
if (Wordings__nonempty(ph->ph_documentation_symbol))
Index__DocReferences__link_to(OUT,
Lexer__word_raw_text(Wordings__first_wn(ph->ph_documentation_symbol)), -1);
else
Index__link_to(OUT, Wordings__first_wn(ParseTree__get_text(ph->declaration_node)), FALSE);
WRITE(" ");
Phrases__TypeData__Textual__write_HTML_representation(OUT, phtd, INDEX_PHRASE_FORMAT, inv);
WRITE(" ");
switch (Dash__reading_passed(inv)) {
case TRUE: WRITE("<img border=0 src=inform:/doc_images/tick.png>"); break;
case FALSE: WRITE("<img border=0 src=inform:/doc_images/cross.png>"); break;
default: WRITE("<img border=0 src=inform:/doc_images/greytick.png>"); break;
}
}
}
#line 233 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__write_index_representation(ph_type_data *phtd, phrase *ph) {
if (phtd->manner_of_return == DECIDES_CONDITION_MOR)
INDEX("<i>if</i> ");
Phrases__write_HTML_representation(ifl, ph, INDEX_PHRASE_FORMAT);
if (phtd->return_kind == NULL) {
if (phtd->manner_of_return == DECIDES_CONDITION_MOR) INDEX("<i>:</i>");
} else {
INDEX(" ... <i>");
if (Kinds__Behaviour__definite(phtd->return_kind) == FALSE) INDEX("value");
else Kinds__Textual__write(ifl, phtd->return_kind);
INDEX("</i>");
wording W = Phrases__Usage__get_equation_form(&(ph->usage_data));
if (Wordings__nonempty(W)) {
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<i>y</i>&nbsp;=&nbsp;<b>");
Wordings__index_raw(W);
INDEX("</b>(<i>x</i>)");
}
}
}
#line 258 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__write_reveal_box(ph_type_data *phtd, phrase *ph) {
{
#line 273 "inform7/Chapter 28/Describing Phrase Type Data.w"
TEMPORARY_STREAM;
Phrases__write_HTML_representation(TEMP, ph, PASTE_PHRASE_FORMAT);
HTML__Javascript__paste(ifl, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
INDEX("&nbsp;");
}
#line 259 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
Phrases__TypeData__Textual__write_index_representation(phtd, ph);
Phrases__Options__index(&(ph->options_data));
{
#line 283 "inform7/Chapter 28/Describing Phrase Type Data.w"
if (Wordings__nonempty(ph->ph_documentation_symbol)) {
INDEX("</p>");
Index__DocReferences__doc_fragment(
Lexer__word_raw_text(Wordings__first_wn(ph->ph_documentation_symbol)));
INDEX("<p><b>See</b> ");
Index__DocReferences__fully_link(
Lexer__word_raw_text(Wordings__first_wn(ph->ph_documentation_symbol)));
}
}
#line 262 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
{
#line 295 "inform7/Chapter 28/Describing Phrase Type Data.w"
wording W = Phrases__Usage__get_equation_form(&(ph->usage_data));
if (Wordings__nonempty(W)) {
INDEX("</p><p><b>In equations:</b> write as ");
HTML__Javascript__paste_W(ifl, W);
INDEX("&nbsp;");
Wordings__index_raw(W);
INDEX("()");
}
}
#line 263 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
{
#line 307 "inform7/Chapter 28/Describing Phrase Type Data.w"
if (ph->usage_data.constant_phrase_holder) {
wording W = ph->usage_data.constant_phrase_holder->name;
INDEX("</p><p><b>Name:</b> ");
HTML__Javascript__paste_W(ifl, W);
INDEX("&nbsp;");
Wordings__index_raw(W);
}
}
#line 264 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
{
#line 319 "inform7/Chapter 28/Describing Phrase Type Data.w"
if (Phrases__TypeData__is_a_say_phrase(ph) == FALSE) {
INDEX("</p><p><b>Kind:</b> ");
Kinds__Textual__write(ifl, Phrases__TypeData__kind(phtd));
}
}
#line 265 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
INDEX("</p>\n");
{
#line 327 "inform7/Chapter 28/Describing Phrase Type Data.w"
if (Phrases__TypeData__deprecated(&(ph->type_data))) {
INDEX("</p><p><b>Warning:</b> ");
INDEX("This phrase is now deprecated! It will probably be withdrawn in "
"future builds of Inform, and even the present build will reject it "
"if the 'Use no deprecated features' option is set. If you're using "
"it now, try following the documentation link above for advice on "
"what to write instead.");
}
}
#line 267 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
}
#line 342 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__phtd_write_I6_comment_describing(ph_type_data *phtd, OUTPUT_STREAM) {
int j;
WRITE("! ");
for (j=0; j<phtd->no_words; j++) {
if (phtd->word_sequence[j] < MAX_TOKENS_PER_PHRASE)
WRITE("#%d ", phtd->word_sequence[j]);
else
WRITE("%s ", Lexer__word_text(phtd->word_sequence[j]));
}
WRITE(":\n");
}
#line 369 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__parse(ph_type_data *phtd, wording XW, wording *OW) {
int say_flag = FALSE; /* is this going to be a "say" phrase? */
if (Wordings__nonempty(XW)) XW = Phrases__TypeData__Textual__phtd_parse_return_data(phtd, XW); /* trim return data from the front */
if (Wordings__nonempty(XW)) Index__DocReferences__position_of_symbol(&XW); /* trim documentation ref from the back */
if (Wordings__nonempty(XW)) XW = Phrases__TypeData__Textual__phtd_parse_doodads(phtd, XW, &say_flag); /* and other doodads from the back */
int cw = -1; /* word number of first comma */
{
#line 394 "inform7/Chapter 28/Describing Phrase Type Data.w"
int bl = 0;
LOOP_THROUGH_WORDING(i, XW) {
if ((Lexer__word(i) == OPENBRACE_V) || (Lexer__word(i) == OPENBRACKET_V)) bl++;
if ((Lexer__word(i) == CLOSEBRACE_V) || (Lexer__word(i) == CLOSEBRACKET_V)) bl--;
if ((Lexer__word(i) == COMMA_V) && (bl == 0) &&
(i>Wordings__first_wn(XW)) && (i<Wordings__last_wn(XW))) { cw = i; break; }
}
}
#line 377 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
if (cw >= 0) {
int comma_presages_options = TRUE;
{
#line 405 "inform7/Chapter 28/Describing Phrase Type Data.w"
if ((Preform__parse_nt_against_word_range(control_structure_phrase_NTM, XW, NULL, NULL)) &&
(Sentences__RuleSubtrees__comma_possible(most_recent_result_p)))
comma_presages_options = FALSE;
}
#line 380 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
if (comma_presages_options) {
if (say_flag)
{
#line 414 "inform7/Chapter 28/Describing Phrase Type Data.w"
Problems__Issue__sentence_problem(_p_(PM_SayWithPhraseOptions),
"phrase options are not allowed for 'say' phrases",
"because the commas would lead to ambiguous sentences, and because the "
"content of a substitution is intended to be something conceptually simple "
"and not needing clarification.");
}
#line 382 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
*OW = Wordings__from(XW, cw + 1);
XW = Wordings__up_to(XW, cw - 1); /* trim the preamble range to to the text before the comma */
}
}
phtd->registration_text = XW;
Phrases__TypeData__Textual__phtd_parse_word_sequence(phtd, XW);
}
#line 457 "inform7/Chapter 28/Describing Phrase Type Data.w"
int phrase_preamble_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; deprecated_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = SAY_ANN; say_ann_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 461 "inform7/Chapter 28/Describing Phrase Type Data.w"
int to_preamble_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; operation_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; assignment_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = LET_ANN; eqn_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = LET_ANN; eqn_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = BLOCK_ANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = CONDITIONAL_ANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = LOOP_ANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = IN_LOOP_ANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = IN_ANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *X = NO_ANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 473 "inform7/Chapter 28/Describing Phrase Type Data.w"
#line 481 "inform7/Chapter 28/Describing Phrase Type Data.w"
int phrase_vetting_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = rel1_NTMV = Wordings__first_wn(phrase_vetting_NTM->range_result[2]); rel2_NTMV = Wordings__last_wn(phrase_vetting_NTM->range_result[2]); preposition_usage_pu_NTMV = RP[1];
{
#line 487 "inform7/Chapter 28/Describing Phrase Type Data.w"
preposition_usage *pu = preposition_usage_pu_NTMV;
*XP = K_number;
Problems__quote_source(1, current_sentence);
if (Prepositions__get_where_pu_created(pu) == NULL)
Problems__quote_text(4, "This is a relation defined inside Inform.");
else
Problems__quote_source(4, Prepositions__get_where_pu_created(pu));
Problems__quote_wording(2, W);
Problems__quote_wording(3, Wordings__new(rel1_NTMV, rel2_NTMV));
Problems__Issue__handmade_problem(_p_(PM_MasksRelation));
Problems__issue_problem_segment(
"I don't want you to define a phrase with the wording you've used in "
"in %1 because it could be misunderstood. There is already a definition "
"of what it means for something to be '%3' something else, so this "
"phrase definition would look too much like testing whether "
"'X is %3 Y'. (%4.)");
Problems__issue_problem_end();
}
#line 482 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 483 "inform7/Chapter 28/Describing Phrase Type Data.w"
#line 509 "inform7/Chapter 28/Describing Phrase Type Data.w"
int say_preamble_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; run_on_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = CONTROL_SANN; control_NTMV = OTHERWISE_SAY_CS;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = CONTROL_SANN; control_NTMV = OTHERWISE_IF_SAY_CS;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = CONTROL_SANN; control_NTMV = IF_SAY_CS;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = CONTROL_SANN; control_NTMV = END_IF_SAY_CS;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = BEGIN_SANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = CONTINUE_SANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = ENDM_SANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = END_SANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *X = NO_SANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 520 "inform7/Chapter 28/Describing Phrase Type Data.w"
#line 534 "inform7/Chapter 28/Describing Phrase Type Data.w"
int to_return_data_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = DEC_RANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = DEV_RANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TOC_RANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = TOC_RANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = TOV_RANN; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = TOV_RANN; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = TO_RANN;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 542 "inform7/Chapter 28/Describing Phrase Type Data.w"
int return_kind_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 550 "inform7/Chapter 28/Describing Phrase Type Data.w"
*XP = K_number;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_UnknownValueToDecide));
Problems__issue_problem_segment(
"The phrase you describe in %1 seems to be trying to decide a value, "
"but '%2' is not a kind that I recognise. (I had expected something "
"like 'number' or 'object' - see the Kinds index for what's available.)");
Problems__issue_problem_end();
}
#line 545 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 546 "inform7/Chapter 28/Describing Phrase Type Data.w"
#line 563 "inform7/Chapter 28/Describing Phrase Type Data.w"
int no_truth_state_returns = 0;
wording Phrases__TypeData__Textual__phtd_parse_return_data(ph_type_data *phtd, wording XW) {
phtd->return_kind = NULL;
if (Preform__parse_nt_against_word_range(to_return_data_NTM, XW, NULL, NULL)) {
XW = GET_RW(to_return_data_NTM, 1);
int mor = -1; kind *K = NULL;
switch (most_recent_result) {
case DEC_RANN: break;
case DEV_RANN: break;
case TOC_RANN: mor = DECIDES_CONDITION_MOR; break;
case TOV_RANN: mor = DECIDES_VALUE_MOR; K = most_recent_result_p; break;
case TO_RANN: mor = DECIDES_NOTHING_MOR; break;
}
if (mor >= 0) Phrases__TypeData__set_mor(phtd, mor, K);
} else internal_error("to phrase without to");
if (Kinds__Compare__eq(phtd->return_kind, K_truth_state)) {
if (no_truth_state_returns++ > 0)
Problems__Issue__sentence_problem(_p_(PM_TruthStateToDecide),
"phrases are not allowed to decide a truth state",
"and should be defined with the form 'To decide if ...' rather than "
"'To decide what truth state is ...'.");
}
return XW;
}
#line 593 "inform7/Chapter 28/Describing Phrase Type Data.w"
wording Phrases__TypeData__Textual__phtd_parse_doodads(ph_type_data *phtd, wording W, int *say_flag) {
operation_NTMV = -1; assignment_NTMV = FALSE; deprecated_NTMV = FALSE; run_on_NTMV = FALSE;
Preform__parse_nt_against_word_range(phrase_preamble_NTM, W, NULL, NULL); /* guaranteed to match any non-empty text */
if (most_recent_result == SAY_ANN) W = GET_RW(say_preamble_NTM, 1);
else W = GET_RW(to_preamble_NTM, 1);
if (deprecated_NTMV) Phrases__TypeData__deprecate_phrase(phtd);
int let = FALSE, blk = NO_BLOCK_FOLLOWS, only_in = 0; /* "nothing unusual" defaults */
switch (most_recent_result) {
case BLOCK_ANN: blk = MISCELLANEOUS_BLOCK_FOLLOWS; break;
case CONDITIONAL_ANN: blk = CONDITIONAL_BLOCK_FOLLOWS; break;
case IN_ANN:
{
#line 626 "inform7/Chapter 28/Describing Phrase Type Data.w"
wording OW = GET_RW(to_preamble_NTM, 2);
only_in = Wordings__first_wn(OW);
}
#line 605 "inform7/Chapter 28/Describing Phrase Type Data.w"
; break;
case IN_LOOP_ANN: only_in = -1; break;
case LET_ANN: if (eqn_NTMV) let = EQUATION_LET_PHRASE;
else let = ASSIGNMENT_LET_PHRASE;
break;
case LOOP_ANN: blk = LOOP_BODY_BLOCK_FOLLOWS; break;
case SAY_ANN:
{
#line 632 "inform7/Chapter 28/Describing Phrase Type Data.w"
*say_flag = TRUE;
int cs = -1, pos = -1, at = -1, cat = -1;
wording XW = EMPTY_WORDING;
switch (say_ann_NTMV) {
case CONTROL_SANN: cs = control_NTMV; break;
case BEGIN_SANN: pos = SSP_START; XW = GET_RW(say_preamble_NTM, 2); at = Wordings__first_wn(XW); break;
case CONTINUE_SANN: pos = SSP_MIDDLE; XW = GET_RW(say_preamble_NTM, 2); at = Wordings__first_wn(XW); break;
case ENDM_SANN: pos = SSP_END; XW = GET_RW(say_preamble_NTM, 2); at = Wordings__first_wn(XW);
XW = GET_RW(say_preamble_NTM, 3); cat = Wordings__first_wn(XW);
break;
case END_SANN: pos = SSP_END; XW = GET_RW(say_preamble_NTM, 2); at = Wordings__first_wn(XW); break;
}
Phrases__TypeData__make_sd(&(phtd->as_say), run_on_NTMV, cs, pos, at, cat);
}
#line 611 "inform7/Chapter 28/Describing Phrase Type Data.w"
; break;
}
Phrases__TypeData__make_id(&(phtd->as_inline),
operation_NTMV, assignment_NTMV, let, blk, only_in);
Preform__parse_nt_against_word_range(phrase_vetting_NTM, W, NULL, NULL);
return W;
}
#line 660 "inform7/Chapter 28/Describing Phrase Type Data.w"
int phrase_definition_word_or_token_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 703 "inform7/Chapter 28/Describing Phrase Type Data.w"
*X = NOT_APPLICABLE;
Problems__Issue__sentence_problem(_p_(PM_TokenWithEmptyBrackets),
"nothing is between the opening bracket '(' and its matching close bracket ')'",
"so I can't see what is meant to be the fixed text and what is meant to be "
"changeable. The idea is to put brackets around whatever varies from one "
"usage to another: for instance, 'To contribute (N - a number) dollars: ...'.");
}
#line 661 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE; token_form_NTMV = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 713 "inform7/Chapter 28/Describing Phrase Type Data.w"
*X = NOT_APPLICABLE;
Problems__Issue__sentence_problem(_p_(PM_TokenWithoutCloseBracket),
"the opening bracket '(' has no matching close bracket ')'",
"so I can't see what is meant to be the fixed text and what is meant to be "
"changeable. The idea is to put brackets around whatever varies from one "
"usage to another: for instance, 'To contribute (N - a number) dollars: ...'.");
}
#line 663 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 723 "inform7/Chapter 28/Describing Phrase Type Data.w"
*X = NOT_APPLICABLE;
Problems__Issue__sentence_problem(_p_(PM_TokenWithoutOpenBracket),
"a close bracket ')' appears here with no matching open '('",
"so I can't see what is meant to be the fixed text and what is meant to "
"be changeable. The idea is to put brackets around whatever varies from "
"one usage to another: for instance, 'To contribute (N - a number) "
"dollars: ...'.");
}
#line 664 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 666 "inform7/Chapter 28/Describing Phrase Type Data.w"
#line 673 "inform7/Chapter 28/Describing Phrase Type Data.w"
int phrase_token_declaration_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 734 "inform7/Chapter 28/Describing Phrase Type Data.w"
*X = NOT_APPLICABLE;
Problems__Issue__sentence_problem(_p_(PM_TokenWithNestedBrackets),
"the name of the token inside the brackets '(' and ')' and before the "
"hyphen '-' itself contains another open bracket '('",
"which is not allowed.");
}
#line 674 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE; *XP = Specifications__from_kind(K_value); token_construct_NTMV = NEW_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; *XP = Specifications__from_kind(RP[1]); token_construct_NTMV = NEW_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = TRUE; *XP = Specifications__from_kind(RP[1]); token_construct_NTMV = NEW_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = TRUE; *XP = Specifications__from_kind(K_value); token_construct_NTMV = NEW_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = TRUE; *XP = Specifications__from_kind(RP[1]); token_construct_NTMV = NEW_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = TRUE; *XP = Specifications__from_kind(RP[1]); token_construct_NTMV = NEW_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = TRUE; *XP = Specifications__from_kind(K_value); ParseTree__set_text(*XP, phrase_token_declaration_NTM->range_result[2]); token_construct_NTMV = EXISTING_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = TRUE; *XP = Specifications__from_kind(RP[1]); ParseTree__set_text(*XP, phrase_token_declaration_NTM->range_result[2]); token_construct_NTMV = EXISTING_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *X = TRUE; *XP = Specifications__from_kind(RP[1]); ParseTree__set_text(*XP, phrase_token_declaration_NTM->range_result[2]); token_construct_NTMV = EXISTING_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10: *X = TRUE; *XP = Specifications__from_kind(K_value); ParseTree__set_text(*XP, phrase_token_declaration_NTM->range_result[2]); token_construct_NTMV = EXISTING_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11: *X = TRUE; *XP = Specifications__from_kind(RP[1]); ParseTree__set_text(*XP, phrase_token_declaration_NTM->range_result[2]); token_construct_NTMV = EXISTING_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12: *X = TRUE; *XP = Specifications__from_kind(RP[1]); ParseTree__set_text(*XP, phrase_token_declaration_NTM->range_result[2]); token_construct_NTMV = EXISTING_LOCAL_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13: *X = TRUE; *XP = NULL; token_construct_NTMV = CONDITION_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14: *X = TRUE; *XP = NULL; token_construct_NTMV = CONDITION_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15: *X = TRUE; *XP = NULL; token_construct_NTMV = VOID_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 16: *X = TRUE; *XP = NULL; token_construct_NTMV = VOID_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 17: *X = TRUE; *XP = Specifications__from_kind(K_value); ParseTree__set_text(*XP, phrase_token_declaration_NTM->range_result[2]); token_construct_NTMV = STORAGE_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 18: *X = TRUE; *XP = Specifications__from_kind(K_value); ParseTree__set_text(*XP, phrase_token_declaration_NTM->range_result[2]); token_construct_NTMV = TABLE_REFERENCE_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 19: *X = TRUE; *XP = Specifications__from_kind(K_value); ParseTree__set_text(*XP, phrase_token_declaration_NTM->range_result[2]); token_construct_NTMV = TABLE_REFERENCE_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 20: *X = TRUE; *XP = RP[1]; token_construct_NTMV = STANDARD_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 21: *X = TRUE; *XP = RP[1]; token_construct_NTMV = KIND_NAME_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 22:
{
#line 743 "inform7/Chapter 28/Describing Phrase Type Data.w"
*X = NOT_APPLICABLE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, GET_RW(phrase_token_declaration_NTM, 2));
Problems__Issue__handmade_problem(_p_(PM_BadTypeIndication));
Problems__issue_problem_segment(
"In %1, the text '%2' after the hyphen should tell me what kind of value "
"goes here (like 'a number', or 'a vehicle'), but it's not something I "
"recognise.");
Problems__issue_problem_end();
}
#line 696 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 23: *X = FALSE; *XP = RP[1]; token_construct_NTMV = KIND_NAME_PT_CONSTRUCT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 24:
{
#line 756 "inform7/Chapter 28/Describing Phrase Type Data.w"
LOG("On $w\n", W);
*X = NOT_APPLICABLE;
Problems__Issue__sentence_problem(_p_(PM_TokenMisunderstood),
"the brackets '(' and ')' here neither say that something varies but has "
"a given type, nor specify a called name",
"so I can't make sense of them. For a 'To...' phrase, brackets like this "
"are used with a hyphen dividing the name for a varying value and the "
"kind it has: for instance, 'To contribute (N - a number) dollars: ...'. "
"Rules, on the other hand, use brackets to give names to things or rooms "
"found when matching conditions: for instance, 'Instead of opening a "
"container in the presence of a man (called the box-watcher): ...'");
}
#line 698 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 699 "inform7/Chapter 28/Describing Phrase Type Data.w"
#line 773 "inform7/Chapter 28/Describing Phrase Type Data.w"
void Phrases__TypeData__Textual__phtd_parse_word_sequence(ph_type_data *phtd, wording W) {
phtd->no_tokens = 0;
phtd->no_words = 0;
int i = Wordings__first_wn(W);
while (i <= Wordings__last_wn(W)) {
int word_to_add = 0; /* redundant assignment to keep |gcc| happy */
Preform__parse_nt_against_word_range(phrase_definition_word_or_token_NTM, Wordings__from(W, i), NULL, NULL);
switch (most_recent_result) {
case NOT_APPLICABLE: return; /* a problem message has been issued */
case TRUE:
{
#line 806 "inform7/Chapter 28/Describing Phrase Type Data.w"
if (token_form_NTMV == NOT_APPLICABLE) return; /* a problem message has been issued */
parse_node *spec = most_recent_result_p; /* what is to be matched */
wording TW = EMPTY_WORDING;
if (token_form_NTMV) TW = GET_RW(phrase_token_declaration_NTM, 1); /* the name */
wording A = GET_RW(phrase_definition_word_or_token_NTM, 1);
i = Wordings__first_wn(A);
W = Wordings__up_to(W, Wordings__last_wn(A)); /* move past this token */
{
#line 851 "inform7/Chapter 28/Describing Phrase Type Data.w"
if ((token_construct_NTMV != STANDARD_PT_CONSTRUCT) &&
(token_construct_NTMV != KIND_NAME_PT_CONSTRUCT) &&
(phtd->as_inline.invoked_inline_not_as_call == FALSE)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(spec));
Problems__Issue__handmade_problem(_p_(PM_NoninlineUsesNonvalues));
Problems__issue_problem_segment(
"In %1, the text '%2' after the hyphen should tell me what kind of "
"value goes here (like 'a number', or 'a vehicle'), but this is not "
"a kind: it does describe something I can understand, but not "
"something which can then be used as a value. (It would be allowed "
"in low-level, so-called 'inline' phrase definitions, but not in a "
"standard phrase definition like this one.)");
Problems__issue_problem_end();
return;
}
}
#line 817 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
{
#line 871 "inform7/Chapter 28/Describing Phrase Type Data.w"
if (ParseTree__is(spec, TEST_VALUE_VNT)) {
pcalc_prop *prop = Descriptions__to_proposition(spec);
if (Calculus__Variables__number_free(prop) != 1) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(spec));
Problems__Issue__handmade_problem(_p_(PM_PhraseTokenQuantified));
Problems__issue_problem_segment(
"In %1, the text '%2' after the hyphen should tell me what kind of "
"value goes here (like 'a number', or 'a vehicle'), but it has to "
"be a single value, and not a description of what might be multiple "
"values. So 'N - a number' is fine, but not 'N - three numbers' or "
"'N - every number'.");
Problems__issue_problem_end();
return;
}
}
}
#line 818 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
{
#line 824 "inform7/Chapter 28/Describing Phrase Type Data.w"
phrase_token pht;
pht.to_match = spec;
pht.token_kind = Specifications__to_kind(spec);
pht.construct = token_construct_NTMV;
pht.token_name = TW;
word_to_add = phtd->no_tokens;
if (phtd->no_tokens >= MAX_TOKENS_PER_PHRASE) {
if (phtd->no_tokens == MAX_TOKENS_PER_PHRASE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(spec));
int n = MAX_TOKENS_PER_PHRASE;
Problems__quote_number(3, &n);
Problems__Issue__handmade_problem(_p_(PM_TooManyTokens));
Problems__issue_problem_segment(
"In %1, I ran out of tokens when I got up to '%2'. "
"Phrases are only allowed %3 tokens, that is, they "
"are only allowed %3 bracketed parts in their definitions.");
Problems__issue_problem_end();
}
} else {
phtd->token_sequence[phtd->no_tokens] = pht;
phtd->no_tokens++;
}
}
#line 819 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
}
#line 783 "inform7/Chapter 28/Describing Phrase Type Data.w"
; break;
case FALSE:
{
#line 801 "inform7/Chapter 28/Describing Phrase Type Data.w"
word_to_add = i++;
}
#line 784 "inform7/Chapter 28/Describing Phrase Type Data.w"
; break;
}
if (phtd->no_words >= MAX_WORDS_PER_PHRASE) {
Problems__Issue__sentence_problem(_p_(PM_PhraseTooLong),
"this phrase has too many words",
"and needs to be simplified.");
return;
}
phtd->word_sequence[phtd->no_words++] = word_to_add;
}
{
#line 891 "inform7/Chapter 28/Describing Phrase Type Data.w"
int i, t = 0;
kind *declarations[27];
int usages[27];
for (i=1; i<=26; i++) { usages[i] = 0; declarations[i] = NULL; }
for (i=0; i<phtd->no_tokens; i++)
t += Phrases__TypeData__Textual__find_kind_variable_domains(phtd->token_sequence[i].token_kind,
usages, declarations);
if (t > 0) {
int problem_thrown = FALSE;
for (int v=1; (v<=26) && (problem_thrown == FALSE); v++)
if ((usages[v] > 0) && (declarations[v] == NULL))
{
#line 912 "inform7/Chapter 28/Describing Phrase Type Data.w"
Problems__Issue__sentence_problem(_p_(PM_UndeclaredKindVariable),
"this phrase uses a kind variable which is not declared",
"which is not allowed.");
phtd->token_sequence[i].token_kind =
Kinds__binary_construction(CON_phrase, K_value, K_value);
problem_thrown = TRUE;
}
#line 902 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
if (problem_thrown == FALSE)
for (i=0; i<phtd->no_tokens; i++)
if (phtd->token_sequence[i].token_kind)
{
#line 938 "inform7/Chapter 28/Describing Phrase Type Data.w"
int changed = FALSE;
kind *substituted = Kinds__substitute(
phtd->token_sequence[i].token_kind, declarations, &changed);
if (changed)
phtd->token_sequence[i].to_match =
Specifications__from_kind(substituted);
}
#line 906 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
}
}
#line 795 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
}
#line 950 "inform7/Chapter 28/Describing Phrase Type Data.w"
int Phrases__TypeData__Textual__find_kind_variable_domains(kind *K, int *usages, kind **declarations) {
int t = 0;
if (K) {
int N = Kinds__get_variable_number(K);
if (N > 0) {
t++;
{
#line 982 "inform7/Chapter 28/Describing Phrase Type Data.w"
usages[N]++;
kind *dec = Kinds__get_variable_stipulation(K);
if (dec) {
if (declarations[N]) {
Problems__Issue__sentence_problem(_p_(PM_DoublyDeclaredKindVariable),
"this phrase declares the same kind variable more than once",
"and ought to declare each variable once each.");
}
declarations[N] = dec;
}
}
#line 956 "inform7/Chapter 28/Describing Phrase Type Data.w"
;
}
if (Kinds__is_proper_constructor(K)) {
int a = Kinds__arity_of_constructor(K);
if (a == 1)
t += Phrases__TypeData__Textual__find_kind_variable_domains(
Kinds__unary_construction_material(K), usages, declarations);
else {
kind *X = NULL, *Y = NULL;
Kinds__binary_construction_material(K, &X, &Y);
t += Phrases__TypeData__Textual__find_kind_variable_domains(X, usages, declarations);
t += Phrases__TypeData__Textual__find_kind_variable_domains(Y, usages, declarations);
}
}
}
return t;
}
#line 998 "inform7/Chapter 28/Describing Phrase Type Data.w"
char *Phrases__TypeData__Textual__incipit(phrase *ph) {
if ((ph == NULL) ||
(ph->type_data.no_words == 0) ||
(ph->type_data.word_sequence[0] < MAX_TOKENS_PER_PHRASE)) return "";
return Lexer__word_text(ph->type_data.word_sequence[0]);
}
#line 47 "inform7/Chapter 28/Phrase Options.w"
ph_options_data Phrases__Options__new(wording W) {
ph_options_data phod;
phod.no_options_permitted = 0;
phod.multiple_options_permitted = FALSE;
phod.options_declaration = W;
return phod;
}
int Phrases__Options__allows_options(ph_options_data *phod) {
if (phod->no_options_permitted > 0) return TRUE;
return FALSE;
}
#line 66 "inform7/Chapter 28/Phrase Options.w"
int Phrases__Options__parse(ph_options_data *phod, wording W) {
for (int i = 0; i < phod->no_options_permitted; i++)
if (Wordings__match(W, phod->options_permitted[i]->name))
return (1 << i);
return -1;
}
#line 76 "inform7/Chapter 28/Phrase Options.w"
void Phrases__Options__index(ph_options_data *phod) {
int i;
for (i=0; i<phod->no_options_permitted; i++) {
phrase_option *po = phod->options_permitted[i];
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;");
if (i==0) INDEX("<br><i>optionally</i> ");
else if (i == phod->no_options_permitted-1) {
if (phod->multiple_options_permitted) INDEX("<i>and/or</i> ");
else INDEX("<i>or</i> ");
}
HTML__Javascript__paste_W(ifl, po->name);
INDEX("&nbsp;");
Wordings__index_raw(po->name);
if (i < phod->no_options_permitted-1) INDEX(",<br>");
INDEX("\n");
}
}
#line 97 "inform7/Chapter 28/Phrase Options.w"
ph_options_data *phod_being_parsed = NULL;
phrase *ph_being_parsed = NULL;
ph_options_data Phrases__Options__parse_declared_options(wording W) {
ph_options_data phod = Phrases__Options__new(W);
if (Wordings__nonempty(W)) {
phod_being_parsed = &phod;
Preform__parse_nt_against_word_range(phrase_option_declaration_list_NTM, W, NULL, NULL);
if (most_recent_result) phod.multiple_options_permitted = TRUE;
}
return phod;
}
#line 134 "inform7/Chapter 28/Phrase Options.w"
int phrase_option_declaration_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 138 "inform7/Chapter 28/Phrase Options.w"
int phrase_option_declaration_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 144 "inform7/Chapter 28/Phrase Options.w"
int phrase_option_declaration_setting_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE; if (!preform_lookahead_mode) Phrases__Options__phod_add_phrase_option(phod_being_parsed, W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 147 "inform7/Chapter 28/Phrase Options.w"
#line 151 "inform7/Chapter 28/Phrase Options.w"
int too_many_POs_error = FALSE;
void Phrases__Options__phod_add_phrase_option(ph_options_data *phod, wording W) {
LOGIF(PHRASE_CREATIONS, "Adding phrase option <$w>\n", W);
if (phod->no_options_permitted >= MAX_OPTIONS_PER_PHRASE) {
if (too_many_POs_error == FALSE)
Problems__Issue__sentence_problem(_p_(PM_TooManyPhraseOptions),
"a phrase is only allowed to have 16 different options",
"so either some of these will need to go, or you may want to "
"consider breaking up the phrase into simpler ones whose usage "
"is easier to describe.");
too_many_POs_error = TRUE;
return;
}
too_many_POs_error = FALSE; /* so that the problem can recur on later phrases */
phrase_option *po = CREATE(phrase_option);
po->name = W;
phod->options_permitted[phod->no_options_permitted++] = po;
}
#line 190 "inform7/Chapter 28/Phrase Options.w"
int phod_being_parsed_silently = FALSE; /* context for the grammar below */
int Phrases__Options__parse_invoked_options(parse_node *inv, int silently) {
phrase *ph = ParseTree__get_phrase_invoked(inv);
wording W = Invocations__get_phrase_options(inv);
ph_being_parsed = ph;
phod_being_parsed = &(ph_being_parsed->options_data);
int bitmap = 0;
int pc = problem_count;
{
#line 211 "inform7/Chapter 28/Phrase Options.w"
int s = phod_being_parsed_silently;
phod_being_parsed_silently = silently;
if (Preform__parse_nt_against_word_range(phrase_option_list_NTM, W, NULL, NULL)) bitmap = most_recent_result;
phod_being_parsed_silently = s;
if ((problem_count == pc) &&
(phod_being_parsed->multiple_options_permitted == FALSE))
{
#line 230 "inform7/Chapter 28/Phrase Options.w"
if ((bitmap & (bitmap - 1)) != 0) {
if (silently == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_phrase(3, ph);
Problems__quote_wording(4, phod_being_parsed->options_declaration);
Problems__Issue__handmade_problem(_p_(PM_PhraseOptionsExclusive));
Problems__issue_problem_segment(
"You wrote %1, supplying the options '%2' to the phrase '%3', but "
"the options listed for this phrase ('%4') are mutually exclusive.");
Problems__issue_problem_end();
}
return FALSE;
}
}
#line 218 "inform7/Chapter 28/Phrase Options.w"
;
}
#line 201 "inform7/Chapter 28/Phrase Options.w"
;
Invocations__set_phrase_options_bitmap(inv, bitmap);
if (problem_count > pc) return FALSE;
return TRUE;
}
#line 249 "inform7/Chapter 28/Phrase Options.w"
int phrase_option_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1] | R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 253 "inform7/Chapter 28/Phrase Options.w"
int phrase_option_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 257 "inform7/Chapter 28/Phrase Options.w"
int phrase_option_setting_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 265 "inform7/Chapter 28/Phrase Options.w"
if ((!preform_lookahead_mode) && (!phod_being_parsed_silently)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_phrase(3, ph_being_parsed);
Problems__quote_wording(4, phod_being_parsed->options_declaration);
if (phod_being_parsed->no_options_permitted > 1) {
Problems__Issue__handmade_problem(_p_(PM_NotAPhraseOption));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is not one of the options allowed on "
"the end of the phrase '%3'. (The options allowed are: '%4'.)");
Problems__issue_problem_end();
} else {
Problems__Issue__handmade_problem(_p_(PM_NotTheOnlyPhraseOption));
Problems__issue_problem_segment(
"You wrote %1, but the only option allowed on the end of the "
"phrase '%3' is '%4', so '%2' is not something I know how to "
"deal with.");
Problems__issue_problem_end();
}
}
}
#line 260 "inform7/Chapter 28/Phrase Options.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 261 "inform7/Chapter 28/Phrase Options.w"
#line 289 "inform7/Chapter 28/Phrase Options.w"
int phrase_option_NTMR(wording W, int *X, void **XP) {
#line 290 "inform7/Chapter 28/Phrase Options.w"
int bitmap = Phrases__Options__parse(phod_being_parsed, W);
if (bitmap == -1) return FALSE;
*X = bitmap; return TRUE;
}
#line 33 "inform7/Chapter 28/Phrases as Values.w"
constant_phrase *Phrases__Constants__create(wording NW, wording RW) {
constant_phrase *cphr = CREATE(constant_phrase);
cphr->name = NW;
cphr->phrase_meant = NULL; /* we won't know until later */
cphr->cphr_kind = NULL; /* nor this */
cphr->associated_preamble_text = RW;
Semantics__Nouns__ExcerptMeanings__register_noun(PHRASE_CONSTANT_MC,
NW, Rvalues__from_constant_phrase(cphr));
return cphr;
}
#line 47 "inform7/Chapter 28/Phrases as Values.w"
constant_phrase *Phrases__Constants__parse(wording NW) {
if (Preform__parse_nt_against_word_range(s_value_NTM, NW, NULL, NULL)) {
parse_node *spec = most_recent_result_p;
if (Rvalues__is_CONSTANT_construction(spec, CON_phrase)) {
constant_phrase *cphr = Rvalues__to_constant_phrase(spec);
Phrases__Constants__kind(cphr);
return cphr;
}
}
return NULL;
}
#line 65 "inform7/Chapter 28/Phrases as Values.w"
kind *Phrases__Constants__kind(constant_phrase *cphr) {
if (cphr == NULL) return NULL;
if (traverse < 2) return Kinds__binary_construction(CON_phrase, K_value, K_value);
if (cphr->cphr_kind == NULL) {
wording OW = EMPTY_WORDING;
ph_type_data phtd = Phrases__TypeData__new();
Phrases__TypeData__Textual__parse(&phtd,
cphr->associated_preamble_text, &OW);
cphr->cphr_kind = Phrases__TypeData__kind(&phtd);
}
return cphr->cphr_kind;
}
#line 81 "inform7/Chapter 28/Phrases as Values.w"
phrase *Phrases__Constants__as_phrase(constant_phrase *cphr) {
if (cphr == NULL) internal_error("null cphr");
if (cphr->phrase_meant == NULL) {
phrase *ph;
LOOP_OVER(ph, phrase) {
if (ph->usage_data.constant_phrase_holder == cphr) {
cphr->phrase_meant = ph;
break;
}
}
}
return cphr->phrase_meant;
}
#line 100 "inform7/Chapter 28/Phrases as Values.w"
void Phrases__Constants__compile(OUTPUT_STREAM, constant_phrase *cphr) {
phrase *ph = Phrases__Constants__as_phrase(cphr);
if (ph == NULL) internal_error("cannot reconstruct phrase from cphr");
if (Phrases__compiled_inline(ph) == FALSE)
Routines__ToPhrases__make_request(ph,
Phrases__Constants__kind(cphr), NULL, EMPTY_WORDING);
WRITE("Closure_%d", cphr->allocation_id);
}
#line 112 "inform7/Chapter 28/Phrases as Values.w"
void Phrases__Constants__compile_closures(OUTPUT_STREAM) {
constant_phrase *cphr;
LOOP_OVER(cphr, constant_phrase) {
phrase *ph = Phrases__Constants__as_phrase(cphr);
if (ph == NULL) internal_error("cannot reconstruct phrase from cphr");
Phrases__Constants__kind(cphr);
{
#line 129 "inform7/Chapter 28/Phrases as Values.w"
WRITE("Array Closure_%d -->\n", cphr->allocation_id); INDENT;
Kinds__RunTime__compile_strong_id(OUT, cphr->cphr_kind);
WRITE(" ! "); Kinds__Textual__write(OUT, cphr->cphr_kind); WRITE("\n");
char identifier[32];
Routines__ToPhrases__make_identifier(identifier, ph,
Phrases__Constants__kind(cphr));
WRITE("%s ! routine to call\n", identifier);
WRITE("\""); Wordings__to_stream(OUT, cphr->name);
WRITE("\" ! name\n");
OUTDENT; WRITE(";\n");
}
#line 118 "inform7/Chapter 28/Phrases as Values.w"
;
}
}
#line 160 "inform7/Chapter 28/Phrases as Values.w"
int def_phrase_counter = 0;
void Phrases__Constants__compile_default_closure(OUTPUT_STREAM,
char *closure_identifier, kind *K) {
char routine_identifier[32];
sprintf(routine_identifier, "Def_Phrase_%d", def_phrase_counter++);
{
#line 178 "inform7/Chapter 28/Phrases as Values.w"
WRITE("Array %s -->\n", closure_identifier); INDENT;
Kinds__RunTime__compile_strong_id(OUT, K); WRITE(" ! strong kind ID\n");
WRITE("%s ! routine to call\n", routine_identifier);
WRITE("\"default value of "); Kinds__Textual__write(OUT, K); WRITE("\" ! name\n");
OUTDENT; WRITE(";\n");
}
#line 167 "inform7/Chapter 28/Phrases as Values.w"
;
OUT = Routines__begin(OUT, routine_identifier);
{
#line 191 "inform7/Chapter 28/Phrases as Values.w"
LocalVariables__add_named_call("a");
LocalVariables__add_named_call("b");
LocalVariables__add_named_call("c");
LocalVariables__add_named_call("d");
LocalVariables__add_named_call("e");
LocalVariables__add_named_call("f");
LocalVariables__add_named_call("g");
LocalVariables__add_named_call("h");
kind *result = NULL;
Kinds__binary_construction_material(K, NULL, &result);
if (Kinds__get_construct(result) != CON_NIL) {
WRITE("return ");
if (Kinds__Behaviour__uses_pointer_values(result)) {
WRITE("BlkValueCreate(");
Kinds__RunTime__compile_strong_id(OUT, result);
WRITE(")");
} else {
if (Kinds__Behaviour__compile_default_value(OUT, result, EMPTY_WORDING, NULL) != TRUE)
WRITE("false");
}
WRITE(";\n");
}
}
#line 170 "inform7/Chapter 28/Phrases as Values.w"
;
OUT = Routines__end(OUT);
}
#line 54 "inform7/Chapter 28/To Phrases.w"
int Routines__ToPhrases__compare(phrase *ph1, phrase *ph2) {
int r = Phrases__TypeData__comparison(&(ph1->type_data), &(ph2->type_data));
if ((Log__aspect_switched_on(PHRASE_COMPARISONS_DA)) || (r == CONFLICTED_PH)) {
LOG("Phrase comparison (");
Phrases__write_HTML_representation(dl, ph1, PASTE_PHRASE_FORMAT);
LOG(") ");
switch(r) {
case INCOMPARABLE_PH: LOG("~~"); break;
case SUBSCHEMA_PH: LOG("<="); break;
case SUPERSCHEMA_PH: LOG(">="); break;
case EQUAL_PH: LOG("=="); break;
case BEFORE_PH: LOG("<"); break;
case AFTER_PH: LOG(">"); break;
case CONFLICTED_PH: LOG("!!"); break;
}
LOG(" (");
Phrases__write_HTML_representation(dl, ph2, PASTE_PHRASE_FORMAT);
LOG(")\n");
}
if (r == CONFLICTED_PH) {
Problems__quote_source(1, Phrases__declaration_node(ph1));
Problems__quote_source(2, Phrases__declaration_node(ph2));
Problems__Issue__handmade_problem(_p_(PM_ConflictedReturnKinds));
Problems__issue_problem_segment(
"The two phrase definitions %1 and %2 make the same wording "
"produce two different kinds of value, which is not allowed.");
Problems__issue_problem_end();
}
return r;
}
#line 93 "inform7/Chapter 28/To Phrases.w"
void Routines__ToPhrases__new(phrase *ph) {
phrase *previous_phrase = NULL;
phrase *current_phrase = first_in_logical_order;
sprintf(Phrases__identifier(ph), "PHR_%d", ph->allocation_id);
if (first_in_logical_order == NULL) { first_in_logical_order = ph; return; }
while ((current_phrase != NULL) &&
(Routines__ToPhrases__compare(ph, current_phrase) >= 0)) {
previous_phrase = current_phrase;
current_phrase = current_phrase->next_in_logical_order;
}
if (previous_phrase == NULL) {
ph->next_in_logical_order = first_in_logical_order;
first_in_logical_order = ph;
return;
}
previous_phrase->next_in_logical_order = ph;
ph->next_in_logical_order = current_phrase;
}
#line 123 "inform7/Chapter 28/To Phrases.w"
void Routines__ToPhrases__register_all(void) {
phrase *ph;
int c = 0;
for (ph = first_in_logical_order; ph; ph = ph->next_in_logical_order) {
current_sentence = ph->declaration_node;
Phrases__Parser__register_excerpt(ph);
ph->sequence_count = c++;
}
}
int Routines__ToPhrases__sequence_count(phrase *ph) {
if (ph == NULL) return 0;
if (ph->sequence_count == -1) {
Phrases__log(ph);
internal_error("Sequence count not ready");
}
return ph->sequence_count;
}
#line 160 "inform7/Chapter 28/To Phrases.w"
to_phrase_request *Routines__ToPhrases__make_request(phrase *ph, kind *K,
kind_variable_declaration *kvd, wording W) {
if ((ph == NULL) || (K == NULL)) internal_error("bad request");
to_phrase_request *req;
LOOP_OVER(req, to_phrase_request)
if ((ph == req->requested_phrase) &&
(Kinds__Compare__eq(K, req->requested_exact_kind)))
return req;
if (Kinds__Behaviour__semidefinite(K) == FALSE)
{
#line 191 "inform7/Chapter 28/To Phrases.w"
Problems__quote_source(1, Phrases__declaration_node(ph));
Problems__Issue__handmade_problem(_p_(PM_UndeterminedKind));
if (Wordings__empty(W)) {
Problems__issue_problem_segment(
"The phrase %1 needs to be used in such a way that I know "
"what kinds of values go into it.");
} else {
Problems__quote_wording_as_source(2, W);
Problems__issue_problem_segment(
"The phrase %1 needs to be used in such a way that I know "
"what kinds of values go into it; so I'm not sure how to "
"make sense of it from %2.");
}
Problems__issue_problem_end();
}
#line 171 "inform7/Chapter 28/To Phrases.w"
;
req = CREATE(to_phrase_request);
req->requested_exact_kind = K;
req->requested_phrase = ph;
int i;
for (i=0; i<27; i++) req->kind_variables_interpretation[i] = NULL;
for (; kvd; kvd=kvd->next)
req->kind_variables_interpretation[kvd->kv_number] = kvd->kv_value;
return req;
}
#line 211 "inform7/Chapter 28/To Phrases.w"
void Routines__ToPhrases__make_identifier(char *identifier,
phrase *ph, kind *req_kind) {
if (Phrases__TypeData__invoked_inline(ph)) {
char *p = Phrases__get_inline_definition(ph);
strcpy(identifier, "0");
int i, found = FALSE;
for (i=0; p[i]; i++)
if (isalpha(p[i])) {
int j = 0;
while (((isalpha(p[i])) || (isdigit(p[i])) || (p[i] == '_')) &&
(j < 31))
identifier[j++] = p[i++];
identifier[j] = 0;
found = TRUE;
break;
}
if (found == FALSE) {
current_sentence = Phrases__declaration_node(ph);
Problems__quote_source(1, current_sentence);
Problems__quote_phrase(2, ph);
Problems__Issue__handmade_problem(_p_(PM_PhraseNamedI6Failed));
Problems__issue_problem_segment(
"You wrote %1, defining the phrase '%2' with a piece of Inform 6 "
"code, but also giving it a name as a function to be used in an "
"equation, or in some functional programming context. That's only "
"allowed if the I6 definition consists simply of a call to an "
"I6 function - and this doesn't, so far as I can see.");
Problems__issue_problem_end();
}
} else {
to_phrase_request *req = Routines__ToPhrases__make_request(
ph, req_kind, NULL, EMPTY_WORDING);
Routines__Compile__identifier(identifier, ph, req);
}
}
#line 251 "inform7/Chapter 28/To Phrases.w"
to_phrase_request *latest_request_granted = NULL;
int Routines__ToPhrases__compilation_coroutine(OUTPUT_STREAM, int *i, int max_i) {
int N = 0;
while (TRUE) {
to_phrase_request *req;
if (latest_request_granted == NULL) req = FIRST_OBJECT(to_phrase_request);
else req = NEXT_OBJECT(latest_request_granted, to_phrase_request);
if (req == NULL) break;
latest_request_granted = req;
Phrases__compile(OUT, latest_request_granted->requested_phrase,
i, max_i, NULL, latest_request_granted, NULL);
N++;
}
return N;
}
#line 272 "inform7/Chapter 28/To Phrases.w"
void Routines__ToPhrases__comment_on_request(
to_phrase_request *req, OUTPUT_STREAM) {
WRITE("! ");
if (req == NULL) WRITE("No specific request");
else {
WRITE("Request %d: ", req->allocation_id);
Kinds__Textual__write(OUT, req->requested_exact_kind);
}
WRITE("\n");
}
#line 286 "inform7/Chapter 28/To Phrases.w"
kind *Routines__ToPhrases__kind_of_request(to_phrase_request *req) {
if (req == NULL) internal_error("null request");
return req->requested_exact_kind;
}
kind **Routines__ToPhrases__kind_variables_for_request(to_phrase_request *req) {
if (req == NULL) internal_error("null request");
return req->kind_variables_interpretation;
}
#line 301 "inform7/Chapter 28/To Phrases.w"
int Routines__ToPhrases__allows_options(phrase *ph) {
return Phrases__Options__allows_options(&(ph->options_data));
}
int Routines__ToPhrases__parse_phrase_option_used(phrase *ph, wording W) {
return Phrases__Options__parse(&(ph->options_data), W);
}
#line 37 "inform7/Chapter 28/Timed Phrases.w"
void Phrases__Timed__TimedEventsTable_array(OUTPUT_STREAM) {
phrase *ph;
int i, t, when_count = 0;
WRITE("Array TimedEventsTable table");
LOOP_OVER(ph, phrase) {
t = Phrases__Usage__get_timing_of_event(&(ph->usage_data));
if (t == NOT_A_TIMED_EVENT) continue;
if (t == NO_FIXED_TIME) when_count++;
else WRITE(" %s", Phrases__identifier(ph));
}
for (i=0; i<when_count+1; i++) WRITE(" 0 0");
WRITE(";\n");
}
void Phrases__Timed__TimedEventTimesTable_array(OUTPUT_STREAM) {
phrase *ph;
int i, t, when_count = 0;
WRITE("Array TimedEventTimesTable table");
LOOP_OVER(ph, phrase) {
t = Phrases__Usage__get_timing_of_event(&(ph->usage_data));
if (t == NOT_A_TIMED_EVENT) continue;
if (t == NO_FIXED_TIME) when_count++;
else WRITE(" %d", t);
}
for (i=0; i<when_count+1; i++) WRITE(" 0 0");
WRITE(";\n");
}
#line 68 "inform7/Chapter 28/Timed Phrases.w"
void Phrases__Timed__note_usage(phrase *ph, parse_node *at) {
int t = Phrases__Usage__get_timing_of_event(&(ph->usage_data));
if (t == NO_FIXED_TIME) {
use_as_event *uae = CREATE(use_as_event);
uae->where_triggered = at;
uae->next = NULL;
use_as_event *prev = ph->usage_data.uses_as_event;
if (prev == NULL) ph->usage_data.uses_as_event = uae;
else {
while ((prev) && (prev->next)) prev = prev->next;
prev->next = uae;
}
}
}
#line 87 "inform7/Chapter 28/Timed Phrases.w"
void Phrases__Timed__check_for_unused(void) {
phrase *ph;
LOOP_OVER(ph, phrase)
if (Phrases__Usage__get_timing_of_event(&(ph->usage_data)) == NO_FIXED_TIME) {
if (ph->usage_data.uses_as_event == NULL) {
current_sentence = ph->declaration_node;
Problems__Issue__sentence_problem(_p_(PM_UnusedTimedEvent),
"this sets up a timed event which is never used",
"since you never use any of the phrases which could cause it. "
"(A timed event is just a name, and it needs other instructions "
"elsewhere before it can have any effect.)");
}
}
}
#line 105 "inform7/Chapter 28/Timed Phrases.w"
void Phrases__Timed__index(void) {
int when_count = 0, tt_count = 0;
{
#line 115 "inform7/Chapter 28/Timed Phrases.w"
phrase *ph;
LOOP_OVER(ph, phrase) {
int t = Phrases__Usage__get_timing_of_event(&(ph->usage_data));
if (t == NO_FIXED_TIME) {
if (when_count == 0)
INDEX("<p><i>Events with no specific time</i></p>");
when_count++;
INDEX("<p class=\"tightin2\">");
Phrases__Usage__index_preamble(&(ph->usage_data));
if ((ph->declaration_node) &&
(Wordings__nonempty(ParseTree__get_text(ph->declaration_node))))
Index__link(Wordings__first_wn(ParseTree__get_text(ph->declaration_node)));
INDEX(" (where triggered: ");
use_as_event *uae;
for (uae = ph->usage_data.uses_as_event; uae; uae=uae->next)
Index__link(Wordings__first_wn(ParseTree__get_text(uae->where_triggered)));
INDEX(")</p>");
}
}
}
#line 107 "inform7/Chapter 28/Timed Phrases.w"
;
{
#line 138 "inform7/Chapter 28/Timed Phrases.w"
phrase *ph;
LOOP_OVER(ph, phrase) {
int t = Phrases__Usage__get_timing_of_event(&(ph->usage_data));
if (t >= 0) { /* i.e., an actual time of day in minutes since midnight */
if (tt_count == 0)
INDEX("<p><i>Timetable</i></p>");
tt_count++;
INDEX("<p class=\"in2\">");
Phrases__Usage__index_preamble(&(ph->usage_data));
if ((ph->declaration_node) &&
(Wordings__nonempty(ParseTree__get_text(ph->declaration_node))))
Index__link(Wordings__first_wn(ParseTree__get_text(ph->declaration_node)));
INDEX("</p>");
}
}
}
#line 108 "inform7/Chapter 28/Timed Phrases.w"
;
if ((when_count == 0) && (tt_count == 0)) INDEX("<p><i>None.</i></p>");
}
#line 27 "inform7/Chapter 28/Phrasebook Index.w"
void Phrases__Index__index_page_Phrasebook(void) {
int pass;
for (pass=1; pass<=2; pass++) {
extension_file *last_extension_named = NULL;
int division, N = NUMBER_CREATED(extension_file);
for (division = 0; division <= N; division++) {
heading *last_heading_named = NULL;
int no_subdivision_yet = TRUE;
wording CLW = EMPTY_WORDING;
phrase *ph, *run_begin = NULL;
LOOP_OVER(ph, phrase) {
/* include only if this is a To... phrase */
if (Phrases__Usage__get_effect(&(ph->usage_data)) != TO_PHRASE_EFF)
continue;
/* and only if it is under an indexed heading */
heading *this_heading =
Wordings__heading_of(ParseTree__get_text(Phrases__declaration_node(ph)));
if (Sentences__Headings__indexed(this_heading) == FALSE) continue;
/* and only if that heading lies in the piece of source for this division */
extension_file *this_extension =
Sentences__Headings__get_extension_containing(this_heading);
if (division == N) { /* skip phrase unless it's in the source text */
if (this_extension != NULL) continue;
} else { /* skip phrase unless it's defined in the extension for this division */
if ((this_extension == NULL) || (this_extension->allocation_id != division)) continue;
}
if (last_extension_named != this_extension)
{
#line 70 "inform7/Chapter 28/Phrasebook Index.w"
if (this_extension == NULL) {
INDEX("<p>");
if (pass == 2) INDEX("<hr>");
INDEX("<p class=\"in1\"><b>Defined in the source</b></p>\n");
} else if (this_extension != standard_rules_extension) {
INDEX("<p>");
if (pass == 2) INDEX("<hr>");
INDEX("<p class=\"in1\"><b>From the extension ");
Extensions__Files__write_name_to_file(this_extension, ifl);
INDEX(" by ");
Extensions__Files__write_author_to_file(this_extension, ifl);
INDEX("</b></p>");
}
no_subdivision_yet = TRUE;
}
#line 54 "inform7/Chapter 28/Phrasebook Index.w"
;
if (this_heading != last_heading_named)
{
#line 89 "inform7/Chapter 28/Phrasebook Index.w"
wording HW = Sentences__Headings__get_text(this_heading);
if (Wordings__nonempty(HW)) {
if (pass == 1)
{
#line 110 "inform7/Chapter 28/Phrasebook Index.w"
if (Preform__parse_nt_against_word_range(heading_with_parenthesis_NTM, HW, NULL, NULL)) HW = GET_RW(heading_with_parenthesis_NTM, 1);
}
#line 91 "inform7/Chapter 28/Phrasebook Index.w"
;
if (this_extension == standard_rules_extension)
{
#line 143 "inform7/Chapter 28/Phrasebook Index.w"
Preform__parse_nt_against_word_range(heading_name_hyphenated_NTM, HW, NULL, NULL);
if (most_recent_result == 3) {
wording C = GET_RW(heading_name_hyphenated_NTM, 2);
if ((Wordings__empty(CLW)) || (Wordings__match(C, CLW) == FALSE)) {
CLW = C;
if (pass == 2) INDEX("<p><hr>");
INDEX("<p class=\"in1\"><b>");
Wordings__index_raw(CLW);
INDEX("</b></p>");
no_subdivision_yet = TRUE;
}
HW = GET_RW(heading_name_hyphenated_NTM, 3);
} else {
HW = GET_RW(heading_name_hyphenated_NTM, 1);
}
}
#line 93 "inform7/Chapter 28/Phrasebook Index.w"
;
}
if ((pass == 1) && (no_subdivision_yet == FALSE)) INDEX(", ");
if (pass == 2) {
Index__anchor_numbered(ph->allocation_id);
INDEX("<p class=\"in2\"><b>");
}
if (Wordings__nonempty(HW)) Wordings__index_raw(HW);
else INDEX("Miscellaneous");
if (pass == 1) Index__below_link_numbered(ph->allocation_id);
if (pass == 2) INDEX("</b></p>");
no_subdivision_yet = FALSE;
}
#line 55 "inform7/Chapter 28/Phrasebook Index.w"
;
last_heading_named = this_heading;
last_extension_named = this_extension;
if (pass == 2)
{
#line 165 "inform7/Chapter 28/Phrasebook Index.w"
phrase *ph2 = ph, *run_end = ph;
if (Phrases__Index__ph_same_doc(ph, run_begin) == FALSE) run_begin = ph;
while ((ph2) && (Phrases__Index__ph_same_doc(ph, ph2))) {
run_end = ph2; ph2 = NEXT_OBJECT(ph2, phrase);
}
INDEX("<p class=\"tightin2\">");
if (run_begin == ph) Index__extra_link(run_end->allocation_id);
else Index__noextra_link();
Phrases__TypeData__Textual__write_index_representation(&(ph->type_data), ph);
if (Phrases__TypeData__deprecated(&(ph->type_data)))
Index__deprecation_icon(run_begin->allocation_id);
Index__link(Wordings__first_wn(ParseTree__get_text(ph->declaration_node)));
INDEX("</p>\n");
if (run_end == ph) {
Index__extra_div_open(ph->allocation_id, 3, "e0e0e0");
Phrases__TypeData__Textual__write_reveal_box(&(run_begin->type_data), run_begin);
Index__extra_div_close("e0e0e0");
}
}
#line 59 "inform7/Chapter 28/Phrasebook Index.w"
;
}
}
}
}
#line 130 "inform7/Chapter 28/Phrasebook Index.w"
int heading_with_parenthesis_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 134 "inform7/Chapter 28/Phrasebook Index.w"
int heading_name_hyphenated_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 3;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 139 "inform7/Chapter 28/Phrasebook Index.w"
#line 191 "inform7/Chapter 28/Phrasebook Index.w"
int Phrases__Index__ph_same_doc(phrase *p1, phrase *p2) {
if ((p1 == NULL) || (p2 == NULL) ||
(Wordings__empty(p1->ph_documentation_symbol)) ||
(Wordings__empty(p2->ph_documentation_symbol)))
return FALSE;
if (Wordings__match(p1->ph_documentation_symbol, p2->ph_documentation_symbol))
return TRUE;
return FALSE;
}
#line 205 "inform7/Chapter 28/Phrasebook Index.w"
void Phrases__Index__index_definition_area(wording W, int show_if_unhyphenated) {
Preform__parse_nt_against_word_range(heading_name_hyphenated_NTM, W, NULL, NULL);
if ((most_recent_result == 1) && (show_if_unhyphenated == FALSE)) return;
INDEX("<b>");
switch (most_recent_result) {
case 1: Wordings__index_raw(W); break;
case 2: {
wording C = GET_RW(heading_name_hyphenated_NTM, 2);
Wordings__index_raw(C); break;
}
case 3: {
wording C = GET_RW(heading_name_hyphenated_NTM, 2);
wording D = GET_RW(heading_name_hyphenated_NTM, 3);
Wordings__index_raw(C);
INDEX(" - ");
Wordings__index_raw(D);
break;
}
}
INDEX("</b><br>");
}
#line 52 "inform7/Chapter 29/Adjectival Definitions.w"
int definition_header_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 54 "inform7/Chapter 29/Adjectival Definitions.w"
#line 85 "inform7/Chapter 29/Adjectival Definitions.w"
int adjective_definition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = DEFINED_POSITIVELY;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = DEFINED_NEGATIVELY;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = DEFINED_PHRASALLY;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 89 "inform7/Chapter 29/Adjectival Definitions.w"
int adjective_domain_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; calling_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; calling_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; calling_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 94 "inform7/Chapter 29/Adjectival Definitions.w"
int adjective_wording_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; antonym_NTMV = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; antonym_NTMV = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 98 "inform7/Chapter 29/Adjectival Definitions.w"
#line 107 "inform7/Chapter 29/Adjectival Definitions.w"
void Phrases__Adjectives__traverse(void) {
ParseTree__traverse(Phrases__Adjectives__look_for_headers);
}
void Phrases__Adjectives__look_for_headers(parse_node *p) {
if (ParseTree__get_type(p) == ROUTINE_NT)
if (Preform__parse_nt_against_word_range(definition_header_NTM, ParseTree__get_text(p), NULL, NULL)) {
parse_node *q = (p->down)?(p->down->down):NULL;
if (q == NULL)
{
#line 136 "inform7/Chapter 29/Adjectival Definitions.w"
if ((p->next == NULL) ||
(ParseTree__get_type(p->next) != ROUTINE_NT)) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"don't leave me in suspense",
"write a definition after 'Definition:'!");
return;
}
q = p->next; p->next = q->next; p->down = q->down; q->next = NULL;
}
#line 115 "inform7/Chapter 29/Adjectival Definitions.w"
;
wording DNW = EMPTY_WORDING; /* domain name */
wording CALLW = EMPTY_WORDING; /* calling */
wording AW = EMPTY_WORDING; /* adjective name */
wording NW = EMPTY_WORDING; /* negation name */
wording CONW = EMPTY_WORDING; /* condition text */
int the_format = DEFINED_IN_SOME_WAY_NOT_YET_KNOWN;
{
#line 148 "inform7/Chapter 29/Adjectival Definitions.w"
if (Preform__parse_nt_against_word_range(adjective_definition_NTM, ParseTree__get_text(q), NULL, NULL)) {
the_format = most_recent_result;
DNW = GET_RW(adjective_domain_NTM, 1);
if (calling_NTMV) CALLW = GET_RW(adjective_domain_NTM, 2);
AW = GET_RW(adjective_wording_NTM, 1);
if (antonym_NTMV) NW = GET_RW(adjective_wording_NTM, 2);
if (the_format != DEFINED_PHRASALLY)
CONW = GET_RW(adjective_definition_NTM, 1);
}
}
#line 124 "inform7/Chapter 29/Adjectival Definitions.w"
;
{
#line 161 "inform7/Chapter 29/Adjectival Definitions.w"
if ((the_format == DEFINED_IN_SOME_WAY_NOT_YET_KNOWN) ||
((the_format == DEFINED_PHRASALLY) && (q->down == NULL))) {
LOG("Definition tree (%d):\n$T\n", the_format, q);
Problems__Issue__definition_problem(_p_(PM_DefinitionWithoutCondition),
q, "a definition must take the form 'Definition: a ... is ... if/unless "
"...' or else 'Definition: a ... is ...: ...'",
"but I can't make this fit either shape.");
return;
}
if ((Wordings__mismatched_brackets(AW)) ||
((Wordings__nonempty(NW)) && (Wordings__mismatched_brackets(NW)))) {
LOG("Definition tree:\n$T\n", p);
Problems__Issue__definition_problem(_p_(PM_BracketedAdjective),
q, "this definition seems to involve unexpected brackets in the name of "
"the adjective being defined",
"so I think I must be misreading it.");
return;
}
}
#line 125 "inform7/Chapter 29/Adjectival Definitions.w"
;
{
#line 184 "inform7/Chapter 29/Adjectival Definitions.w"
adjective_meaning *am = Adjectives__Meanings__parse(q, the_format, AW, DNW, CONW, CALLW);
if (am == NULL) internal_error("unclaimed adjective definition");
if (Wordings__nonempty(NW)) {
adjective_meaning *neg = Adjectives__Meanings__negate(am);
Adjectives__Phrases__declare(neg, NW);
}
}
#line 126 "inform7/Chapter 29/Adjectival Definitions.w"
;
if (the_format != DEFINED_PHRASALLY) p->down = NULL;
}
}
#line 195 "inform7/Chapter 29/Adjectival Definitions.w"
definition *Phrases__Adjectives__def_new(parse_node *q) {
definition *def = CREATE(definition);
def->node = q;
def->format = 0;
def->condition_to_match = EMPTY_WORDING;
def->domain_calling = EMPTY_WORDING;
def->definition_node = current_sentence;
return def;
}
#line 11 "inform7/Chapter 29/Adjectives by Raw Phrase.w"
int inform6_routine_adjective_definition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 14 "inform7/Chapter 29/Adjectives by Raw Phrase.w"
#line 18 "inform7/Chapter 29/Adjectives by Raw Phrase.w"
adjective_meaning *Phrases__RawPhrasal__ADJ_parse(parse_node *q,
int sense, wording AW, wording DNW, wording CONW, wording CALLW) {
int setting = FALSE;
wording EW = EMPTY_WORDING, RW = EMPTY_WORDING;
if (Preform__parse_nt_against_word_range(inform6_routine_adjective_definition_NTM, CONW, NULL, NULL)) {
setting = most_recent_result;
RW = GET_RW(inform6_routine_adjective_definition_NTM, 1);
EW = GET_RW(inform6_routine_adjective_definition_NTM, 2);
} else return NULL;
if (sense != 1) return NULL;
if (Wordings__nonempty(CALLW)) return NULL;
int rname_wn = Wordings__first_wn(RW);
Text__dequote_word(rname_wn);
definition *def = Phrases__Adjectives__def_new(q);
adjective_meaning *am =
Adjectives__Meanings__new(I6_ROUTINE_KADJ, STORE_POINTER_definition(def), EW);
def->am_of_def = am;
Adjectives__Phrases__declare(am, AW);
Adjectives__Meanings__set_domain_text(am, DNW);
if (setting) {
i6_schema *sch = Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, TRUE);
Calculus__Schemas__modify(sch, "*=-(%s(*1, -1))", Lexer__word_text(rname_wn));
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_TRUE_TASK, TRUE);
Calculus__Schemas__modify(sch, "*=-(%s(*1, true))", Lexer__word_text(rname_wn));
sch = Adjectives__Meanings__set_i6_schema(am, NOW_ADJECTIVE_FALSE_TASK, TRUE);
Calculus__Schemas__modify(sch, "*=-(%s(*1, false))", Lexer__word_text(rname_wn));
} else {
Adjectives__Meanings__pass_task_to_support_routine(am, TEST_ADJECTIVE_TASK);
i6_schema *sch = Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, TRUE);
Calculus__Schemas__modify(sch, "*=-(%s(*1))", Lexer__word_text(rname_wn));
}
return am;
}
void Phrases__RawPhrasal__ADJ_compiling_soon(adjective_meaning *am, definition *def, int T) {
}
int Phrases__RawPhrasal__ADJ_compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
int Phrases__RawPhrasal__ADJ_assert(definition *def,
inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) {
return FALSE;
}
int Phrases__RawPhrasal__ADJ_index(definition *def) {
return FALSE;
}
#line 10 "inform7/Chapter 29/Adjectives by Raw Condition.w"
int inform6_condition_adjective_definition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 12 "inform7/Chapter 29/Adjectives by Raw Condition.w"
#line 16 "inform7/Chapter 29/Adjectives by Raw Condition.w"
adjective_meaning *Phrases__RawCondition__ADJ_parse(parse_node *q,
int sense, wording AW, wording DNW, wording CONW, wording CALLW) {
if (sense != 1) return NULL;
if (Wordings__nonempty(CALLW)) return NULL;
if (!(Preform__parse_nt_against_word_range(inform6_condition_adjective_definition_NTM, CONW, NULL, NULL))) return NULL;
int text_wn = most_recent_result;
wording IN = GET_RW(inform6_condition_adjective_definition_NTM, 1);
definition *def = Phrases__Adjectives__def_new(q);
adjective_meaning *am =
Adjectives__Meanings__new(I6_CONDITION_KADJ,
STORE_POINTER_definition(def), IN);
def->am_of_def = am;
Adjectives__Phrases__declare(am, AW);
Adjectives__Meanings__pass_task_to_support_routine(am, TEST_ADJECTIVE_TASK);
Adjectives__Meanings__set_domain_text(am, DNW);
i6_schema *sch = Adjectives__Meanings__set_i6_schema(am, TEST_ADJECTIVE_TASK, FALSE);
Text__dequote_word(text_wn);
Calculus__Schemas__modify(sch, "(%s)", Lexer__word_text(text_wn));
return am;
}
void Phrases__RawCondition__ADJ_compiling_soon(adjective_meaning *am, definition *def, int T) {
}
int Phrases__RawCondition__ADJ_compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
int Phrases__RawCondition__ADJ_assert(definition *def,
inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) {
return FALSE;
}
int Phrases__RawCondition__ADJ_index(definition *def) {
return FALSE;
}
#line 11 "inform7/Chapter 29/Adjectives by Phrase.w"
void Phrases__Phrasal__define_adjective_by_phrase(parse_node *p, phrase *ph, wording *CW,
kind **K) {
definition *def;
*CW = EMPTY_WORDING; *K = K_object;
if (ph == NULL) return;
LOOP_OVER(def, definition)
if ((def->definition_node == p) && (Adjectives__Meanings__get_form(def->am_of_def) == PHRASE_KADJ)) {
i6_schema *sch = Adjectives__Meanings__set_i6_schema(def->am_of_def, TEST_ADJECTIVE_TASK, FALSE);
Calculus__Schemas__modify(sch, "(%s(*1))", Phrases__identifier(ph));
*CW = def->domain_calling;
*K = Adjectives__Meanings__get_domain_forcing(def->am_of_def);
if ((*K == NULL) || (Kinds__Compare__le(*K, K_object)))
*K = K_object;
return;
}
}
adjective_meaning *Phrases__Phrasal__ADJ_parse(parse_node *q,
int sense, wording AW, wording DNW, wording CONW, wording CALLW) {
if (sense != 0) return NULL;
definition *def = Phrases__Adjectives__def_new(q);
adjective_meaning *am = Adjectives__Meanings__new(PHRASE_KADJ,
STORE_POINTER_definition(def), ParseTree__get_text(q));
def->domain_calling = CALLW;
def->am_of_def = am;
Adjectives__Phrases__declare(am, AW);
Adjectives__Meanings__pass_task_to_support_routine(am, TEST_ADJECTIVE_TASK);
Adjectives__Meanings__set_domain_text(am, DNW);
return am;
}
void Phrases__Phrasal__ADJ_compiling_soon(adjective_meaning *am, definition *def, int T) {
}
int Phrases__Phrasal__ADJ_compile(definition *def, int T, OUTPUT_STREAM, ph_stack_frame *phsf) {
return FALSE;
}
int Phrases__Phrasal__ADJ_assert(definition *def,
inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) {
return FALSE;
}
int Phrases__Phrasal__ADJ_index(definition *def) {
return FALSE;
}
#line 10 "inform7/Chapter 29/Adjectives by Condition.w"
adjective_meaning *Phrases__Condition__ADJ_parse(parse_node *q,
int sense, wording AW, wording DNW, wording CONW, wording CALLW) {
if (sense == 0) return NULL;
definition *def = Phrases__Adjectives__def_new(q);
adjective_meaning *am =
Adjectives__Meanings__new(CONDITION_KADJ, STORE_POINTER_definition(def),
ParseTree__get_text(q));
def->condition_to_match = CONW;
def->format = sense;
def->domain_calling = CALLW;
def->am_of_def = am;
Adjectives__Phrases__declare(am, AW);
Adjectives__Meanings__pass_task_to_support_routine(am, TEST_ADJECTIVE_TASK);
Adjectives__Meanings__set_domain_text(am, DNW);
return am;
}
void Phrases__Condition__ADJ_compiling_soon(adjective_meaning *am,
definition *def, int T) {
}
int Phrases__Condition__ADJ_compile(definition *def, int T,
OUTPUT_STREAM, ph_stack_frame *phsf) {
switch (T) {
case TEST_ADJECTIVE_TASK:
if (OUT) {
LocalVariables__alias_pronoun(phsf, def->domain_calling);
if (Wordings__nonempty(def->condition_to_match)) {
current_sentence = def->node;
parse_node *spec = NULL;
if (Preform__parse_nt_against_word_range(s_condition_NTM, def->condition_to_match, NULL, NULL))
spec = most_recent_result_p;
if ((spec == NULL) ||
(PL__Actions__Patterns__validate_when(spec) == FALSE)) {
LOG("Error on: $w = $T", def->condition_to_match, spec);
Problems__Issue__definition_problem(_p_(PM_DefinitionBadCondition),
def->node,
"that condition makes no sense to me",
"although the preamble to the definition was properly "
"written. There must be something wrong after 'if'.");
} else {
WRITE("(");
if (def->format == -1) WRITE("~~(");
Specifications__Compiler__compile(OUT, spec);
if (def->format == -1) WRITE(")");
WRITE(")");
}
}
LocalVariables__alias_pronoun(phsf, EMPTY_WORDING);
}
return TRUE;
case NOW_ADJECTIVE_TRUE_TASK:
return FALSE;
case NOW_ADJECTIVE_FALSE_TASK:
return FALSE;
}
return FALSE;
}
int Phrases__Condition__ADJ_assert(definition *def,
inference_subject *infs_to_assert_on, parse_node *val_to_assert_on, int parity) {
return FALSE;
}
int Phrases__Condition__ADJ_index(definition *def) {
return FALSE;
}
#line 104 "inform7/Chapter 30/Local Variables.w"
locals_slate LocalVariables__blank_slate(void) {
locals_slate slate;
slate.local_variable_allocation = NULL;
slate.it_pseudonym = EMPTY_WORDING;
slate.it_variable_exists = FALSE; slate.its_form_allowed = FALSE;
return slate;
}
#line 117 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__deep_copy_locals_slate(locals_slate *slate_to, locals_slate *slate_from) {
*slate_to = *slate_from;
slate_to->local_variable_allocation = NULL;
local_variable *lvar, *tail = NULL;
for (lvar = slate_from->local_variable_allocation; lvar; lvar=lvar->next) {
local_variable *dup = CREATE(local_variable); *dup = *lvar;
dup->next = NULL;
if (tail) tail->next = dup; else slate_to->local_variable_allocation = dup;
tail = dup;
}
}
#line 132 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__add_to_locals_slate(locals_slate *slate, int purpose, wording W,
kind *K, char *override_lvalue, int override_index) {
int ix = 0; /* the new one will be the 0th, 1st, 2nd, ... with the same purpose */
local_variable *lvar = NULL;
if (slate)
{
#line 150 "inform7/Chapter 30/Local Variables.w"
local_variable *find = slate->local_variable_allocation;
if (find == NULL) {
{
#line 172 "inform7/Chapter 30/Local Variables.w"
lvar = CREATE(local_variable);
lvar->next = NULL;
}
#line 152 "inform7/Chapter 30/Local Variables.w"
;
slate->local_variable_allocation = lvar;
} else {
while (find) {
if (find->lv_purpose == purpose) {
if (find->allocated == FALSE) { lvar = find; break; }
ix++;
}
if (find->next == NULL) {
{
#line 172 "inform7/Chapter 30/Local Variables.w"
lvar = CREATE(local_variable);
lvar->next = NULL;
}
#line 161 "inform7/Chapter 30/Local Variables.w"
;
find->next = lvar;
break;
}
find = find->next;
}
}
}
#line 137 "inform7/Chapter 30/Local Variables.w"
else
{
#line 172 "inform7/Chapter 30/Local Variables.w"
lvar = CREATE(local_variable);
lvar->next = NULL;
}
#line 138 "inform7/Chapter 30/Local Variables.w"
;
if (override_index >= 0) ix = override_index;
{
#line 178 "inform7/Chapter 30/Local Variables.w"
lvar->lv_purpose = purpose;
lvar->allocated = TRUE;
if (override_lvalue) strcpy(lvar->lv_lvalue, override_lvalue);
else {
char *prefix = "unknown";
switch (purpose) {
case TOKEN_CALL_PARAMETER_LV: prefix = "t";break;
case OTHER_CALL_PARAMETER_LV: prefix = "ti"; break;
case LET_VALUE_LV: prefix = "tmp"; break;
case INTERNAL_USE_LV: prefix = "misc"; break;
default: internal_error("unknown local variable purpose");
}
sprintf(lvar->lv_lvalue, "%s_%d", prefix, ix);
}
lvar->index_with_this_purpose = ix;
lvar->block_scope = 0; /* by default: universal scope throughout routine */
lvar->free_at_end_of_scope = FALSE;
lvar->kind_as_declared = K;
lvar->protected = TRUE;
lvar->parsed_recently = FALSE;
lvar->comment_on_use = NULL;
if (Wordings__nonempty(W)) {
if (Preform__parse_nt_against_word_range(unsuitable_name_for_locals_NTM, W, NULL, NULL))
{
#line 210 "inform7/Chapter 30/Local Variables.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_CalledThe));
Problems__issue_problem_segment(
"In %1, you seem to be giving a temporary value a pretty "
"odd name - '%2', which I won't allow because it would lead to too "
"many ambiguities.");
Problems__issue_problem_end();
}
#line 201 "inform7/Chapter 30/Local Variables.w"
;
W = Articles__remove_the(W);
}
lvar->varname = W;
lvar->name_hash = Wordings__hash_code(W);
}
#line 140 "inform7/Chapter 30/Local Variables.w"
;
SParser__warn_expression_cache(); /* the range of parsing possibilities has changed */
return lvar;
}
#line 223 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__add_call_parameter(ph_stack_frame *phsf,
wording W, kind *K) {
local_variable *lvar = LocalVariables__add_to_locals_slate(&(phsf->local_value_variables),
TOKEN_CALL_PARAMETER_LV, W, K, NULL, -1);
LOGIF(LOCAL_VARIABLES, "Call parameter $k added\n", lvar);
return lvar;
}
#line 234 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__get_parameter_number(local_variable *lvar) {
if ((lvar == NULL) || (lvar->lv_purpose != TOKEN_CALL_PARAMETER_LV))
internal_error("not a call parameter");
return lvar->index_with_this_purpose;
}
#line 244 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__new(wording W, kind *K) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) internal_error("tried to add let value without stack frame");
local_variable *lvar = LocalVariables__add_to_locals_slate(&(phsf->local_value_variables),
LET_VALUE_LV, W, K, NULL, -1);
LOGIF(LOCAL_VARIABLES, "Let value $k allocated\n", lvar);
return lvar;
}
#line 258 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__add_internal(locals_slate *slate,
char *name, int purpose) {
local_variable *lvar = LocalVariables__find_i6_var(slate, name, purpose);
if (lvar == NULL) lvar = LocalVariables__add_to_locals_slate(slate, purpose, EMPTY_WORDING, NULL, name, -1);
return lvar;
}
local_variable *LocalVariables__add_internal_local(char *name) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf)
return LocalVariables__add_internal(&(phsf->local_value_variables), name,
INTERNAL_USE_LV);
return NULL;
}
local_variable *LocalVariables__add_named_call(char *name) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf)
return LocalVariables__add_internal(&(phsf->local_value_variables), name,
OTHER_CALL_PARAMETER_LV);
return NULL;
}
void LocalVariables__add_internal_local_c(char *name, char *comment) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf) {
local_variable *lvar =
LocalVariables__add_internal(&(phsf->local_value_variables),
name, INTERNAL_USE_LV);
lvar->comment_on_use = comment;
}
}
#line 295 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__add_table_lookup(void) {
LocalVariables__add_internal_local_c("ct_0", "currently selected table");
LocalVariables__add_internal_local_c("ct_1", "currently selected row");
LOGIF(LOCAL_VARIABLES, "Stack frame acquires CT locals\n");
}
#line 304 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__add_switch_value(kind *K) {
LocalVariables__add_internal_local_c("sw_v", "switch value");
LOGIF(LOCAL_VARIABLES, "Stack frame acquires switch value\n");
}
#line 313 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__options_parameter_is_needed(ph_stack_frame *phsf) {
LocalVariables__add_internal(&(phsf->local_value_variables),
"phrase_options", OTHER_CALL_PARAMETER_LV);
}
#line 323 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__deallocate(local_variable *lvar) {
if (lvar->lv_purpose != LET_VALUE_LV)
internal_error("only let variables can be deallocated");
lvar->allocated = FALSE;
lvar->varname = EMPTY_WORDING;
lvar->name_hash = 0;
lvar->block_scope = 0;
lvar->free_at_end_of_scope = FALSE;
}
#line 336 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__deallocate_all(ph_stack_frame *phsf) {
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
if ((lvar->lv_purpose == LET_VALUE_LV) && (lvar->allocated))
LocalVariables__deallocate(lvar);
}
#line 346 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__count(ph_stack_frame *phsf) {
int ct = 0;
if (phsf) {
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
ct++;
}
return ct;
}
#line 366 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__copy(ph_stack_frame *phsf_to, ph_stack_frame *phsf_from) {
locals_slate *slate_from = &(phsf_from->local_value_variables);
locals_slate *slate_to = &(phsf_to->local_value_variables);
local_variable *lvar;
for (lvar = slate_from->local_variable_allocation; lvar; lvar = lvar->next) {
local_variable *copied = LocalVariables__add_to_locals_slate(slate_to,
lvar->lv_purpose, lvar->varname, lvar->kind_as_declared,
lvar->lv_lvalue, lvar->index_with_this_purpose);
strcpy(copied->lv_lvalue, lvar->lv_lvalue);
}
slate_to->it_variable_exists = slate_from->it_variable_exists;
slate_to->its_form_allowed = slate_from->its_form_allowed;
slate_to->it_pseudonym = slate_from->it_pseudonym;
phsf_to->local_stvol = phsf_from->local_stvol;
}
#line 389 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__find_i6_var(locals_slate *slate, char *name, int purpose) {
local_variable *lvar;
for (lvar = slate->local_variable_allocation; lvar; lvar = lvar->next)
if ((lvar->lv_purpose == purpose) &&
(strcmp(lvar->lv_lvalue, name) == 0))
return lvar;
return NULL;
}
#line 401 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__by_name(char *name) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) return FALSE;
return LocalVariables__find_i6_var(&(phsf->local_value_variables), name, INTERNAL_USE_LV);
}
#line 410 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__are_we_using_table_lookup(void) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) return FALSE;
if (LocalVariables__find_i6_var(&(phsf->local_value_variables), "ct_0", INTERNAL_USE_LV)) return TRUE;
return FALSE;
}
#line 422 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__get_ith_parameter(int i) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) internal_error("no stack frame exists");
local_variable *lvar;
int c = 0;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
if (lvar->lv_purpose == TOKEN_CALL_PARAMETER_LV)
if (c++ == i)
return lvar;
return NULL;
}
#line 446 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__parse(ph_stack_frame *phsf, wording W) {
if (phsf == NULL) return NULL;
local_variable *lvar = LocalVariables__parse_inner(phsf, W);
if (lvar) lvar->parsed_recently = TRUE;
return lvar;
}
local_variable *LocalVariables__parse_inner(ph_stack_frame *phsf, wording W) {
if ((phsf->local_value_variables.it_variable_exists) && (Preform__parse_nt_against_word_range(pronoun_NTM, W, NULL, NULL)))
return LocalVariables__it_variable();
if (Preform__parse_nt_against_word_range(definite_article_NTM, W, NULL, NULL)) return NULL;
W = Articles__remove_the(W);
if ((Wordings__nonempty(phsf->local_value_variables.it_pseudonym)) &&
(Wordings__match(W, phsf->local_value_variables.it_pseudonym)))
return LocalVariables__it_variable();
{
#line 476 "inform7/Chapter 30/Local Variables.w"
int h = Wordings__hash_code(W);
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
if ((Wordings__nonempty(lvar->varname)) &&
(h == lvar->name_hash) &&
(lvar->allocated == TRUE) &&
(Wordings__match(W, lvar->varname)))
return lvar;
}
#line 464 "inform7/Chapter 30/Local Variables.w"
;
return NULL;
}
#line 488 "inform7/Chapter 30/Local Variables.w"
int stack_selection_used_recently = FALSE;
void LocalVariables__monitor_local_parsing(ph_stack_frame *phsf) {
if (phsf) {
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
lvar->parsed_recently = FALSE;
}
stack_selection_used_recently = FALSE;
}
void LocalVariables__used_stack_selection(void) {
stack_selection_used_recently = TRUE;
}
int LocalVariables__local_parsed_recently(ph_stack_frame *phsf) {
if (phsf) {
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
if (lvar->parsed_recently) return TRUE;
}
if (stack_selection_used_recently) return TRUE;
return FALSE;
}
#line 520 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__it_variable(void) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf) return LocalVariables__get_ith_parameter(0);
return LocalVariables__add_to_locals_slate(NULL, TOKEN_CALL_PARAMETER_LV,
EMPTY_WORDING, K_value, NULL, 0);
}
#line 530 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__is_possessive_form_of_it_enabled(void) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf) return phsf->local_value_variables.its_form_allowed;
return FALSE;
}
void LocalVariables__enable_possessive_form_of_it(void) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) internal_error("no stack frame exists");
phsf->local_value_variables.its_form_allowed = TRUE;
}
void LocalVariables__add_pronoun(ph_stack_frame *phsf, wording W, kind *K) {
phsf->local_value_variables.it_variable_exists = TRUE;
LocalVariables__add_call_parameter(phsf, W, K);
}
void LocalVariables__alias_pronoun(ph_stack_frame *phsf, wording W) {
phsf->local_value_variables.it_pseudonym = W;
}
#line 558 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__compile_storage(OUTPUT_STREAM, ph_stack_frame *phsf) {
local_variable *lvar;
int j=0;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
WRITE("(LocalParking-->%d=%s),",
j++,
LocalVariables__lvalue(lvar));
}
#line 571 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__compile_retrieval(OUTPUT_STREAM, ph_stack_frame *phsf) {
local_variable *lvar;
int j=0;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
WRITE("%s=LocalParking-->%d;\n",
LocalVariables__lvalue(lvar),
j++);
}
#line 584 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__make_available_to_equation(equation *eqn) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf) {
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
if (lvar->allocated)
Equations__declare_local(eqn, lvar->varname, lvar->kind_as_declared);
}
}
#line 599 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__ensure_called_local(wording W, kind *K) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) return NULL; /* in case callings are made from parsing alone */
Preform__parse_nt_against_word_range(new_called_name_NTM, W, NULL, NULL);
local_variable *lvar = most_recent_result_p;
if ((lvar) && (K)) LocalVariables__set_kind(lvar, K);
return lvar;
}
#line 611 "inform7/Chapter 30/Local Variables.w"
wording last_mnc_wording = EMPTY_WORDING_INIT;
wording PM_CalledWithDash_wording = EMPTY_WORDING_INIT;
void LocalVariables__make_necessary_callings(wording W) {
if (Wordings__within(W, last_mnc_wording)) return;
last_mnc_wording = W;
while (Wordings__nonempty(W)) {
if (Preform__parse_nt_against_word_range(text_including_a_calling_NTM, W, NULL, NULL)) {
wording V = GET_RW(text_including_a_calling_NTM, 2);
W = GET_RW(text_including_a_calling_NTM, 3);
LocalVariables__ensure_called_local(V, K_object);
} else break;
}
}
#line 638 "inform7/Chapter 30/Local Variables.w"
int new_called_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = *X = R[2]; *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 641 "inform7/Chapter 30/Local Variables.w"
int new_called_name_unarticled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 657 "inform7/Chapter 30/Local Variables.w"
*X = 0; *XP = NULL;
if (!(Wordings__eq(PM_CalledWithDash_wording, W))) {
PM_CalledWithDash_wording = W;
Problems__Issue__sentence_problem(_p_(PM_CalledWithDash),
"a '(called ...)' name is not allowed to include a hyphen",
"since this would look misleadingly like a declaration of kind of value it has.");
}
}
#line 643 "inform7/Chapter 30/Local Variables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 668 "inform7/Chapter 30/Local Variables.w"
parse_node *already = most_recent_result_p;
if (LocalVariables__permit_as_new_local(already, TRUE) == FALSE) {
LOG("Meaning already existing: $T\n", already);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
if (Specifications__is_kind_like(already))
Problems__quote_text(3, "a kind");
else
Problems__quote_kind_of(3, already);
Problems__Issue__handmade_problem(_p_(PM_CalledOverloaded));
Problems__issue_problem_segment(
"In %1, it looks as if '%2' is going to be a temporary name which something "
"will be called. But I can't allow that, because it already has a meaning "
"as %3.");
Problems__issue_problem_end();
*X = 0; *XP = NULL;
} else return FALSE;
}
#line 645 "inform7/Chapter 30/Local Variables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 689 "inform7/Chapter 30/Local Variables.w"
ph_stack_frame *phsf = Frames__current_stack_frame();
*X = 0;
*XP = (phsf)?(LocalVariables__new(W, K_object)):NULL;
}
#line 646 "inform7/Chapter 30/Local Variables.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 647 "inform7/Chapter 30/Local Variables.w"
int existing_local_name_NTMR(wording W, int *X, void **XP) {
#line 649 "inform7/Chapter 30/Local Variables.w"
*XP = LocalVariables__parse(Frames__current_stack_frame(), W);
if (*XP) return TRUE;
return FALSE;
}
#line 723 "inform7/Chapter 30/Local Variables.w"
int LocalVariables__permit_as_new_local(parse_node *found, int as_calling) {
if (ParseTree__is(found, AMBIGUITY_NT)) found = found->down;
if ((Specifications__is_kind_like(found)) &&
(Kinds__Compare__le(Specifications__to_kind(found), K_object) == FALSE)) return FALSE;
if ((ParseTree__is(found, UNKNOWN_VNT)) ||
(ParseTree__is(found, NONLOCAL_VARIABLE_VNT)) ||
(Specifications__is_description(found)) ||
(Rvalues__is_object(found)) ||
(Rvalues__to_instance(found)) ||
(Rvalues__is_CONSTANT_construction(found, CON_table_column)) ||
(Rvalues__is_CONSTANT_construction(found, CON_property))) return TRUE;
if (as_calling)
if (ParseTree__is_phrasal(found)) return TRUE;
return FALSE;
}
#line 742 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__log(local_variable *lvar) {
if (lvar->allocated == FALSE) { LOG("LV<unallocated>"); return; }
if (Wordings__nonempty(lvar->varname)) LOG("LV\"$w\"", lvar->varname);
else LOG("LV<nameless>");
LOG("-$u", lvar->kind_as_declared);
}
#line 752 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__describe_repetition_local(OUTPUT_STREAM, local_variable *lvar) {
if ((lvar) && (lvar->lv_purpose == LET_VALUE_LV)) { /* should always be true */
WRITE("[repetition with ");
Wordings__to_stream_raw(OUT, lvar->varname);
WRITE(" set to \", (%s) %s, \"]^\";\n",
Kinds__Behaviour__get_name_of_printing_rule(lvar->kind_as_declared),
LocalVariables__lvalue(lvar));
}
}
#line 766 "inform7/Chapter 30/Local Variables.w"
kind *LocalVariables__kind(local_variable *lvar) {
if (lvar == NULL) internal_error("Tried to find kind of nonexistent local variable");
return lvar->kind_as_declared;
}
kind *LocalVariables__unproblematic_kind(local_variable *lvar) {
if (lvar) return LocalVariables__kind(lvar);
return NULL;
}
#line 780 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__set_kind(local_variable *lvar, kind *K) {
if (lvar == NULL) internal_error("Tried to set kind of nonexistent local variable");
LOGIF(LOCAL_VARIABLES, "Kind of local $k set to $u\n", lvar, K);
lvar->kind_as_declared = K;
}
#line 794 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__unprotect(local_variable *lvar) {
if (lvar->lv_purpose == LET_VALUE_LV)
lvar->protected = FALSE;
}
int LocalVariables__protected(local_variable *lvar) {
if ((lvar->lv_purpose == LET_VALUE_LV) && (lvar->protected)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, lvar->varname);
Problems__Issue__handmade_problem(_p_(PM_ProtectedFromLet));
Problems__issue_problem_segment(
"In %1, it looks as if you want to use 'let' to change the value of "
"the temporary variable '%2'. Ordinarily that would be fine, but it's "
"not allowed when the variable is used as the counter in a 'repeat' "
"loop, or has some other do-not-disturb purpose - this could cause "
"chaotic effects. The rule is: you can only change an existing value "
"with 'let' if it was created by 'let' in the first place.");
Problems__issue_problem_end();
return TRUE;
}
return FALSE;
}
#line 823 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__set_scope_to(local_variable *lvar, int s) {
if ((s > 0) && (lvar) && (lvar->lv_purpose == LET_VALUE_LV)) {
lvar->block_scope = s;
LOGIF(LOCAL_VARIABLES, "Setting scope of $k to block level %d\n", lvar, s);
}
}
#line 833 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__mark_to_free_at_end_of_scope(local_variable *lvar) {
lvar->free_at_end_of_scope = TRUE;
}
void LocalVariables__end_scope(OUTPUT_STREAM, int s) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) internal_error("relinquishing locals where no stack frame exists");
if (s <= 0) internal_error("the outermost scope cannot end");
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
if ((lvar->lv_purpose == LET_VALUE_LV) &&
(lvar->allocated) && (lvar->block_scope >= s)) {
LOGIF(LOCAL_VARIABLES, "De-allocating $k at end of block\n", lvar);
if (lvar->free_at_end_of_scope) {
WRITE("BlkValueFree(%s);\n", lvar->lv_lvalue);
}
LocalVariables__deallocate(lvar);
}
SParser__warn_expression_cache();
}
#line 860 "inform7/Chapter 30/Local Variables.w"
local_variable *LocalVariables__latest_repeat_variable(void) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf) {
int s = Frames__Blocks__current_block_level();
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
if ((lvar->lv_purpose == LET_VALUE_LV) &&
(lvar->allocated) && (lvar->block_scope == s))
return lvar;
}
return NULL;
}
#line 886 "inform7/Chapter 30/Local Variables.w"
int current_session_number = -1;
int callings_in_condition_sp = 0;
int callings_session_number[MAX_CALLINGS_IN_MATCH];
local_variable *callings_in_condition[MAX_CALLINGS_IN_MATCH];
void LocalVariables__begin_condition(OUTPUT_STREAM) {
current_session_number++;
WRITE("((");
}
void LocalVariables__add_calling_to_condition(local_variable *lvar) {
if (current_session_number < 0) internal_error("no PM session");
if (callings_in_condition_sp + 1 == MAX_CALLINGS_IN_MATCH)
Problems__Issue__sentence_problem(_p_(BelievedImpossible), /* or very hard, anyway */
"that makes too complicated a condition to test",
"with all of those clauses involving 'called' values.");
else {
callings_session_number[callings_in_condition_sp] = current_session_number;
callings_in_condition[callings_in_condition_sp++] = lvar;
}
}
void LocalVariables__end_condition(OUTPUT_STREAM) {
if (current_session_number < 0) internal_error("unstarted PM session");
WRITE(")");
int any_made = FALSE;
while ((callings_in_condition_sp > 0) &&
(callings_session_number[callings_in_condition_sp-1] == current_session_number)) {
if (any_made == FALSE) { WRITE(" || ("); any_made = TRUE; }
local_variable *lvar = callings_in_condition[callings_in_condition_sp-1];
WRITE("%s = ", LocalVariables__lvalue(lvar));
kind *K = LocalVariables__kind(lvar);
if ((K == NULL) || (Kinds__Compare__le(K, K_object)) ||
(Kinds__Behaviour__definite(K) == FALSE) ||
(Kinds__Behaviour__compile_default_value(OUT, K, EMPTY_WORDING, "'called' value") != TRUE))
WRITE("0");
WRITE(",");
callings_in_condition_sp--;
}
if (any_made) WRITE("false)");
WRITE(")");
current_session_number--;
}
#line 936 "inform7/Chapter 30/Local Variables.w"
char *LocalVariables__lvalue(local_variable *lvar) {
return lvar->lv_lvalue;
}
#line 944 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__compile_parameter_list(OUTPUT_STREAM, ph_stack_frame *phsf, int no_vars) {
int purpose;
for (purpose = TOKEN_CALL_PARAMETER_LV; purpose <= OTHER_CALL_PARAMETER_LV; purpose++) {
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
if (lvar->lv_purpose == purpose) {
if (no_vars++ > 0) WRITE(", ");
WRITE("%s", LocalVariables__lvalue(lvar));
}
}
}
#line 960 "inform7/Chapter 30/Local Variables.w"
void LocalVariables__declare(OUTPUT_STREAM, ph_stack_frame *phsf, int call_pars_only) {
int lines = 0;
int purpose, from = TOKEN_CALL_PARAMETER_LV, to = INTERNAL_USE_LV;
if (call_pars_only) to = OTHER_CALL_PARAMETER_LV;
INDENT;
if (phsf)
for (purpose = from; purpose <= to; purpose++) {
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next)
if (lvar->lv_purpose == purpose) {
WRITE("\n%s", LocalVariables__lvalue(lvar));
{
#line 982 "inform7/Chapter 30/Local Variables.w"
switch (purpose) {
case TOKEN_CALL_PARAMETER_LV:
if (Wordings__nonempty(lvar->varname)) {
WRITE(" ! Call parameter '");
Wordings__to_stream_raw(OUT, lvar->varname);
WRITE("': ");
} else {
WRITE(" ! Call parameter: ");
}
Kinds__Textual__write(OUT, lvar->kind_as_declared);
break;
case OTHER_CALL_PARAMETER_LV:
WRITE(" ! Implied call parameter");
break;
case LET_VALUE_LV:
WRITE(" ! Let/loop value");
if (Wordings__nonempty(lvar->varname)) {
WRITE(", e.g., '");
Wordings__to_stream_raw(OUT, lvar->varname);
WRITE("'");
}
if (lvar->allocated) {
WRITE(": ");
Kinds__Textual__write(OUT, lvar->kind_as_declared);
} else {
WRITE(" (deallocated by end of phrase)");
}
break;
case INTERNAL_USE_LV:
if (lvar->comment_on_use)
WRITE(" ! %s", lvar->comment_on_use);
else
WRITE(" ! internal use only");
break;
}
}
#line 971 "inform7/Chapter 30/Local Variables.w"
;
lines++;
}
}
if (lines > 0) WRITE("\n");
if (call_pars_only == FALSE) WRITE(";\n"); OUTDENT;
}
#line 50 "inform7/Chapter 30/Phrase Blocks.w"
block_stack current_block_stack;
phrase_block *block_being_compiled = NULL; /* the one being compiled, if any */
phrase_block *block_being_opened = NULL; /* the one about to open, if any */
#line 58 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__empty_stack(void) {
current_block_stack.pb_sp = 0;
block_being_compiled = NULL;
block_being_opened = NULL;
}
#line 68 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__prepush_stack(void) {
block_being_opened = &(current_block_stack.pb_stack[current_block_stack.pb_sp]);
}
#line 75 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__push_stack(void) {
current_block_stack.pb_sp++;
block_being_compiled = block_being_opened;
block_being_opened = NULL;
}
#line 84 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__pop_stack(void) {
current_block_stack.pb_sp--;
if (current_block_stack.pb_sp > 0)
block_being_compiled = &(current_block_stack.pb_stack[current_block_stack.pb_sp - 1]);
else
block_being_compiled = NULL;
block_being_opened = NULL; /* which should be true anyway */
}
#line 98 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__begin_code_blocks(void) {
if (Frames__current_stack_frame() == NULL)
internal_error("tried to use blocks outside stack frame");
if (block_being_compiled)
internal_error("tried to begin block stack already in use");
Frames__Blocks__empty_stack(); /* which it should be anyway */
LOGIF(LOCAL_VARIABLES, "Block stack now active\n");
}
#line 112 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__end_code_blocks(void) {
while (block_being_compiled) {
current_sentence = block_being_compiled->block_location;
Frames__Blocks__pop_stack();
}
block_being_compiled = NULL;
LOGIF(LOCAL_VARIABLES, "Block stack now inactive\n");
}
#line 133 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__beginning_block_phrase(OUTPUT_STREAM, control_structure_phrase *csp) {
if (current_block_stack.pb_sp == MAX_BLOCK_NESTING) {
if (problem_count == 0) internal_error("block stack overflow");
Frames__Blocks__pop_stack();
}
Frames__Blocks__prepush_stack();
{
#line 149 "inform7/Chapter 30/Phrase Blocks.w"
block_being_opened->switch_kind = NULL;
block_being_opened->tail_stream = NULL;
block_being_opened->block_location = current_sentence;
block_being_opened->from_structure = csp;
block_being_opened->label_following = -1;
}
#line 139 "inform7/Chapter 30/Phrase Blocks.w"
;
}
#line 158 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__supply_kind_and_stream(kind *K, text_stream *TAIL) {
block_being_opened->switch_kind = K;
block_being_opened->tail_stream = TAIL;
}
#line 167 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__open_code_block(OUTPUT_STREAM) {
WRITE("{");
if (current_block_stack.pb_sp != MAX_BLOCK_NESTING) Frames__Blocks__push_stack();
LOGIF(LOCAL_VARIABLES, "Start of block level %d\n", current_block_stack.pb_sp);
}
#line 177 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__make_indentation_follow_code(OUTPUT_STREAM) {
int indent_level = current_block_stack.pb_sp + 1;
SET_INDENT(indent_level);
}
#line 187 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__divide_code_block(OUTPUT_STREAM) {
if (block_being_compiled == NULL) return; /* for problem recovery only */
LOGIF(LOCAL_VARIABLES, "Division in block level %d\n", current_block_stack.pb_sp);
LocalVariables__end_scope(OUT, current_block_stack.pb_sp);
}
#line 196 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__close_code_block(OUTPUT_STREAM) {
if (block_being_compiled == NULL) return; /* for problem recovery only */
WRITE("}\n");
if (block_being_compiled->label_following >= 0)
WRITE(".loop_break_%d;", block_being_compiled->label_following);
LOGIF(LOCAL_VARIABLES, "End of block level %d\n", current_block_stack.pb_sp);
LocalVariables__end_scope(OUT, current_block_stack.pb_sp);
if (block_being_compiled->tail_stream) {
STREAM_COPY(OUT, block_being_compiled->tail_stream);
STREAM_CLOSE(block_being_compiled->tail_stream);
}
Frames__Blocks__pop_stack();
}
#line 214 "inform7/Chapter 30/Phrase Blocks.w"
int Frames__Blocks__inside_a_loop_body(void) {
int i;
for (i = current_block_stack.pb_sp-1; i >= 0; i--)
if (Sentences__RuleSubtrees__is_a_loop(current_block_stack.pb_stack[i].from_structure))
return TRUE;
return FALSE;
}
#line 230 "inform7/Chapter 30/Phrase Blocks.w"
int Frames__Blocks__current_block_level(void) {
return current_block_stack.pb_sp;
}
char *Frames__Blocks__name_of_current_block(void) {
if (block_being_compiled == NULL) return NULL;
return Sentences__RuleSubtrees__incipit(block_being_compiled->from_structure);
}
parse_node *Frames__Blocks__start_of_current_block(void) {
if (block_being_compiled == NULL) return NULL;
return block_being_compiled->block_location;
}
kind *Frames__Blocks__switch_value_kind(void) {
if (block_being_compiled == NULL) return NULL;
return block_being_compiled->switch_kind;
}
#line 257 "inform7/Chapter 30/Phrase Blocks.w"
int unique_breakage_count = 0;
void Frames__Blocks__compile_break(OUTPUT_STREAM) {
int i;
for (i = current_block_stack.pb_sp-1; i >= 0; i--)
if (Sentences__RuleSubtrees__permits_break(current_block_stack.pb_stack[i].from_structure)) {
if (current_block_stack.pb_stack[i].label_following == -1)
current_block_stack.pb_stack[i].label_following =
unique_breakage_count++;
WRITE("jump loop_break_%d;",
current_block_stack.pb_stack[i].label_following);
return;
}
internal_error("not inside a loop block");
}
#line 276 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__set_variable_scope(local_variable *lvar) {
if (Frames__current_stack_frame())
LocalVariables__set_scope_to(lvar,
current_block_stack.pb_sp);
}
#line 287 "inform7/Chapter 30/Phrase Blocks.w"
void Frames__Blocks__set_scope_to_block_about_to_open(local_variable *lvar) {
if (Frames__current_stack_frame())
LocalVariables__set_scope_to(lvar,
current_block_stack.pb_sp + 1);
}
#line 67 "inform7/Chapter 30/Stack Frames.w"
ph_stack_frame Frames__new(void) {
ph_stack_frame phsf;
phsf.local_value_variables = LocalVariables__blank_slate();
phsf.local_kind_variables = NULL;
phsf.local_stvol = NULL;
phsf.determines_past_conditions = FALSE;
phsf.allocated_pointers = NULL;
phsf.kind_returned = NULL;
phsf.no_formal_parameters_needed = 0;
return phsf;
}
#line 84 "inform7/Chapter 30/Stack Frames.w"
int nonphrasal_stack_frame_is_current = FALSE;
ph_stack_frame nonphrasal_stack_frame;
ph_stack_frame *Frames__new_nonphrasal(void) {
if (nonphrasal_stack_frame_is_current)
internal_error("can't nest nonphrasal stack frames");
nonphrasal_stack_frame = Frames__new();
nonphrasal_stack_frame_is_current = TRUE;
Frames__make_current(&nonphrasal_stack_frame);
return &nonphrasal_stack_frame;
}
void Frames__remove_nonphrase_stack_frame(void) {
nonphrasal_stack_frame = Frames__new(); /* to prevent accidental lucky misuse */
nonphrasal_stack_frame_is_current = FALSE;
Frames__remove_current();
}
#line 105 "inform7/Chapter 30/Stack Frames.w"
ph_stack_frame *Frames__boxed_frame(ph_stack_frame *phsf) {
if (phsf == NULL) return NULL;
ph_stack_frame_box *phsfb;
phsfb = CREATE(ph_stack_frame_box);
phsfb->boxed_phsf = *phsf;
LocalVariables__deep_copy_locals_slate(&(phsfb->boxed_phsf.local_value_variables),
&(phsf->local_value_variables));
return &(phsfb->boxed_phsf);
}
#line 121 "inform7/Chapter 30/Stack Frames.w"
ph_stack_frame *current_frame = NULL;
ph_stack_frame *Frames__current_stack_frame(void) {
return current_frame;
}
void Frames__make_current(ph_stack_frame *phsf) {
if (phsf == NULL) internal_error("can't select null stack frame");
current_frame = phsf;
}
void Frames__remove_current(void) {
current_frame = NULL;
}
#line 140 "inform7/Chapter 30/Stack Frames.w"
void Frames__set_kind_returned(ph_stack_frame *phsf, kind *K) {
phsf->kind_returned = K;
}
kind *Frames__get_kind_returned(void) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) return NULL;
return phsf->kind_returned;
}
#line 153 "inform7/Chapter 30/Stack Frames.w"
void Frames__set_kind_variables(ph_stack_frame *phsf, kind **vars) {
phsf->local_kind_variables = vars;
}
kind *Frames__get_kind_variable(int N) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if ((phsf) && (phsf->local_kind_variables))
return phsf->local_kind_variables[N];
return NULL;
}
kind **Frames__temporarily_set_kvs(kind **vars) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) return NULL;
kind **prev = phsf->local_kind_variables;
phsf->local_kind_variables = vars;
return prev;
}
#line 175 "inform7/Chapter 30/Stack Frames.w"
void Frames__set_stvol(ph_stack_frame *phsf, stacked_variable_owner_list *stvol) {
phsf->local_stvol = stvol;
}
stacked_variable_owner_list *Frames__get_stvol(void) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf) return phsf->local_stvol;
return NULL;
}
#line 190 "inform7/Chapter 30/Stack Frames.w"
void Frames__determines_the_past(void) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) internal_error(
"tried to determine past where no stack frame exists");
phsf->determines_past_conditions = TRUE;
LOGIF(LOCAL_VARIABLES, "Stack frame determines past\n");
}
int Frames__used_for_past_tense(void) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) return FALSE;
if (phsf->determines_past_conditions) return TRUE;
return FALSE;
}
#line 208 "inform7/Chapter 30/Stack Frames.w"
void Frames__log(ph_stack_frame *phsf) {
if (phsf == NULL) { LOG("<null stack frame>\n"); return; }
LOG("Stack frame at %08x: it:%s, dpc:%s\n",
phsf,
(phsf->local_value_variables.it_variable_exists)?"yes":"no",
(phsf->determines_past_conditions)?"yes":"no");
local_variable *lvar;
for (lvar = phsf->local_value_variables.local_variable_allocation; lvar; lvar = lvar->next) {
switch (lvar->lv_purpose) {
case LET_VALUE_LV: LOG("Let/loop value: "); break;
case TOKEN_CALL_PARAMETER_LV: LOG("Call value: "); break;
case INTERNAL_USE_LV: LOG("Internal use: "); break;
default: LOG("Other: "); break;
}
LOG("%s: ", LocalVariables__lvalue(lvar));
LocalVariables__log(lvar); LOG("\n");
}
}
#line 232 "inform7/Chapter 30/Stack Frames.w"
void Frames__need_at_least_this_many_formals(int N) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL)
internal_error("requested formal parameters outside all stack frames");
if (N > phsf->no_formal_parameters_needed)
phsf->no_formal_parameters_needed = N;
}
#line 249 "inform7/Chapter 30/Stack Frames.w"
pointer_allocation *Frames__add_allocation(kind *K, char *proto) {
ph_stack_frame *phsf = Frames__current_stack_frame();
if (phsf == NULL) {
LOG("Tried to allocate: $u\n", K);
internal_error("tried to allocate block kind outside all stack frames");
}
pointer_allocation *pall = CREATE(pointer_allocation);
pall->next_in_frame = phsf->allocated_pointers;
phsf->allocated_pointers = pall;
if (pall->next_in_frame == NULL) pall->offset_index = 0;
else pall->offset_index = pall->next_in_frame->offset_past;
pall->offset_past = pall->offset_index + Kinds__Behaviour__get_small_block_size(K);
{
#line 280 "inform7/Chapter 30/Stack Frames.w"
TEMPORARY_STREAM;
Kinds__RunTime__compile_heap_allocation(TEMP, K, 0, pall->offset_index);
Extensions__IDs__truncated_strcpy(pall->allocation_code, STREAM_TEXT(TEMP), 127);
CLOSE_TEMPORARY_STREAM;
}
#line 262 "inform7/Chapter 30/Stack Frames.w"
;
{
#line 289 "inform7/Chapter 30/Stack Frames.w"
if (pall->offset_index == 0) {
sprintf(pall->local_reference_code, "I7SFRAME");
sprintf(pall->escaped_local_reference_code, "I7SFRAME");
} else if (pall->offset_index == 1) {
sprintf(pall->local_reference_code, "(I7SFRAME+WORDSIZE)");
sprintf(pall->escaped_local_reference_code, "(I7SFRAME+WORDSIZE)");
} else {
sprintf(pall->local_reference_code, "(I7SFRAME+WORDSIZE*%d)",
pall->offset_index);
sprintf(pall->escaped_local_reference_code, "(I7SFRAME+WORDSIZE**%d)",
pall->offset_index);
}
}
#line 263 "inform7/Chapter 30/Stack Frames.w"
;
{
#line 305 "inform7/Chapter 30/Stack Frames.w"
if (proto == NULL) pall->schema_for_promotion[0] = 0;
else {
int i, j;
for (i=0, j=0; proto[i]; i++) {
if ((proto[i] == '*') && (proto[i+1] == '#') && (proto[i+2] == '#')) {
strcpy(pall->schema_for_promotion + j, pall->escaped_local_reference_code);
j = Platform__strlen(pall->schema_for_promotion);
i+=2;
continue;
}
pall->schema_for_promotion[j++] = proto[i];
}
pall->schema_for_promotion[j++] = 0;
}
}
#line 264 "inform7/Chapter 30/Stack Frames.w"
;
return pall;
}
void Frames__compile_allocation(OUTPUT_STREAM, kind *K) {
if (divert_constant_text_bibliographically == FALSE) {
pointer_allocation *pall = Frames__add_allocation(K, NULL);
WRITE("%s", Frames__pall_get_local_reference(pall));
}
}
#line 323 "inform7/Chapter 30/Stack Frames.w"
char *Frames__pall_get_local_reference(pointer_allocation *pall) {
return pall->local_reference_code;
}
char *Frames__pall_get_expanded_schema(pointer_allocation *pall) {
return pall->schema_for_promotion;
}
#line 41 "inform7/Chapter 30/Chronology.w"
int no_past_tenses = 0, no_past_actions = 0;
int too_late_for_past_tenses = FALSE;
void Chronology__ap_compile_forced_to_present(OUTPUT_STREAM, action_pattern ap) {
PL__Actions__Patterns__convert_to_present_tense(&ap); /* prevent recursion */
TEMPORARY_STREAM;
PL__Actions__Patterns__compile_pattern_match(TEMP, ap, FALSE);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
void Chronology__compile_past_action_pattern(OUTPUT_STREAM, time_period duration,
action_pattern ap) {
char *op = duration.inform6_operator;
past_tense_action_record *pta;
LOGIF(TIME_PERIODS,
"Chronology__compile_past_action_pattern on: $A\nat: $t\n", &ap, &duration);
if (PL__Actions__Patterns__makes_callings(&ap)) {
Problems__Issue__sentence_problem(_p_(PM_PTAPMakesCallings),
"a description of an action cannot both refer to past history "
"and also use '(called ...)'",
"because that would require Inform in general to remember "
"too much information about past events.");
}
if (too_late_for_past_tenses) internal_error("too late for a PAP");
if (op == NULL) op = "==";
WRITE("(PAPR_%d() && ", no_past_actions);
int L = duration.length; if (L < 0) L = 0;
if (duration.until >= 0) {
if (duration.units == TIMES_UNIT)
WRITE("((%d <= (TimesActionHasHappened-->%d)) && "
"(%d >= (TimesActionHasHappened-->%d)) && "
"(ActionCurrentlyHappeningFlag->%d))",
L, no_past_actions,
duration.until, no_past_actions, no_past_actions);
else
WRITE("((%d <= (TurnsActionHasBeenHappening-->%d)) && "
"(%d >= (TurnsActionHasBeenHappening-->%d))) ",
L, no_past_actions,
duration.until, no_past_actions);
} else {
if (duration.units == TIMES_UNIT)
WRITE("(((TimesActionHasHappened-->%d) %s %d) && "
"(ActionCurrentlyHappeningFlag->%d))",
no_past_actions, op, L, no_past_actions);
else
WRITE("((TurnsActionHasBeenHappening-->%d) %s %d)",
no_past_actions, op, L);
}
WRITE(")");
pta = CREATE(past_tense_action_record);
pta->where_pta_tested = current_sentence;
pta->historic_action = ap;
no_past_actions++;
}
void Chronology__compile_past_tense_condition(OUTPUT_STREAM, parse_node *spec) {
time_period duration = *(ParseTree__get_condition_tense(spec));
spec = spec->down;
LOGIF(TIME_PERIODS,
"Chronology__compile_past_tense_condition on:\n$T\nat: $t\nNPT: %d\n",
spec, &duration, no_past_tenses);
action_pattern *ap = NULL;
if (ParseTree__is(spec, TEST_VALUE_VNT)) ap = Rvalues__to_action_pattern(spec->down);
int pasturise = FALSE;
if ((ap) && (duration.tense != IS_TENSE)) {
if ((duration.units == TIMES_UNIT) && (duration.length >= 2)) {
Problems__Issue__sentence_problem(_p_(PM_NoMoreRonNewcombMoment),
"a condition like 'we have X', where X is an action, has either "
"happened for one spell or never happened at all",
"so it can't make sense to ask if it has happened two or more "
"times. For instance, at the start of play 'we have jumped' is "
"false, but once the player types JUMP, 'we have jumped' will "
"then be true for the rest of time. 'We have jumped for the "
"second time' doesn't mean the jumping happened twice, it "
"means the having-jumped has happened twice, which is "
"impossible.");
return;
}
if ((duration.length == -1) && (duration.until == -1)) {
PL__Actions__Patterns__compile_past_tense(OUT, ap);
return;
}
pasturise = TRUE;
duration.tense = IS_TENSE;
}
int turns_flag = 0,
perfect_flag = ((duration.tense)/2)%2,
past_flag = (duration.tense)%2;
char *op = duration.inform6_operator;
past_tense_condition_record *ptc;
if (too_late_for_past_tenses) internal_error("too late for a PTC");
if (duration.units == TURNS_UNIT) turns_flag = 1;
if ((past_flag == 0) && (perfect_flag == 0) && (op == NULL)) op = "==";
else if (op == NULL) op = ">=";
parse_node *cond = spec;
int output_wanted = 1 + turns_flag;
WRITE("(TestSinglePastState(%d, %d, false, %d)",
past_flag, no_past_tenses, output_wanted + 4*perfect_flag);
if (TimePeriods__is_valid(&duration))
if ((duration.inform6_operator != NULL) || (duration.length >= 0))
WRITE(" %s %d ", op, duration.length);
WRITE(")");
if (no_past_tenses >= 1024) { /* limit imposed by the Z-machine implementation */
Problems__Issue__limit_problem(_p_(Untestable), /* well, not conveniently */
"conditions written in the past tense", 1024);
return;
}
ptc = CREATE(past_tense_condition_record);
ptc->where_ptc_tested = current_sentence;
if (pasturise) {
ptc->condition = NULL;
ptc->ap_to_test = ap;
LOG("Pasturising at $T\n", current_sentence);
} else {
ptc->condition = cond;
ptc->ap_to_test = NULL;
}
no_past_tenses++;
}
#line 179 "inform7/Chapter 30/Chronology.w"
void Chronology__allow_no_further_past_tenses(void) {
too_late_for_past_tenses = TRUE;
}
#line 209 "inform7/Chapter 30/Chronology.w"
void Chronology__past_actions_i6_routines(OUTPUT_STREAM) {
int once_only = TRUE;
past_tense_action_record *pta;
LOOP_OVER(pta, past_tense_action_record) {
int pt = pta->allocation_id;
current_sentence = pta->where_pta_tested; /* ensure problems reported correctly */
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "PAPR_%d", pt);
OUT = Routines__begin(OUT, i6_routine_identifier);
WRITE("if (");
Chronology__ap_compile_forced_to_present(OUT, pta->historic_action);
WRITE(") rtrue;\n");
WRITE("rfalse;\n");
if ((LocalVariables__are_we_using_table_lookup()) && (once_only)) {
once_only = FALSE;
Problems__Issue__sentence_problem(_p_(PM_PastTableLookup),
"it's not safe to look up table entries in a way referring "
"to past history",
"because it leads to dangerous ambiguities. For instance, "
"does 'taking an item listed in the Table of Treasure "
"for the first time' mean that this is the first time taking "
"any of the things in the table, or only the first time "
"this one? And so on.");
}
OUT = Routines__end(OUT);
}
WRITE("Array PastActionsI6Routines --> ");
LOOP_OVER(pta, past_tense_action_record) {
WRITE("PAPR_%d ", pta->allocation_id);
}
WRITE("0 0;\n");
}
#line 252 "inform7/Chapter 30/Chronology.w"
void Chronology__past_tenses_i6_escape(OUTPUT_STREAM) {
int once_only = TRUE;
past_tense_condition_record *ptc;
LOGIF(TIME_PERIODS,
"Creating %d past tense conditions in TestSinglePastState\n",
NUMBER_CREATED(past_tense_condition_record));
OUT = Routines__begin(OUT, "TestSinglePastState");
LocalVariables__add_named_call("past_flag");
LocalVariables__add_named_call("pt");
LocalVariables__add_named_call("turn_end");
LocalVariables__add_named_call("wanted");
LocalVariables__add_internal_local("old");
LocalVariables__add_internal_local("new");
LocalVariables__add_internal_local("trips");
LocalVariables__add_internal_local("consecutives");
Frames__determines_the_past();
WRITE("if (past_flag) {\n"); INDENT;
WRITE("new = (past_chronological_record-->pt) & 1;\n");
WRITE("trips = ((past_chronological_record-->pt) & $$11111110)/2;\n");
WRITE("consecutives = ((past_chronological_record-->pt) & $$111111100000000)/256;\n");
OUTDENT; WRITE("} else {\n"); INDENT;
WRITE("old = (present_chronological_record-->pt) & 1;\n");
WRITE("trips = ((present_chronological_record-->pt) & $$11111110)/2;\n");
WRITE("consecutives = ((present_chronological_record-->pt) & $$111111100000000)/256;\n");
WRITE("switch(pt) {\n"); INDENT;
LOOP_OVER(ptc, past_tense_condition_record) {
WRITE("%d: ", ptc->allocation_id);
current_sentence = ptc->where_ptc_tested; /* ensure problems reported correctly */
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
{
#line 331 "inform7/Chapter 30/Chronology.w"
TEMPORARY_STREAM;
WRITE("new = ");
if (ptc->condition) {
parse_node *spec = ptc->condition;
LOGIF(TIME_PERIODS, "Number %d: proposition $D\n",
ptc->allocation_id, Specifications__to_proposition(spec));
if (Calculus__Propositions__contains_callings(Specifications__to_proposition(spec))) {
Problems__Issue__sentence_problem(_p_(PM_PastCallings),
"it's not safe to use '(called ...)' in a way referring "
"to past history",
"because this would make a temporary value to hold the "
"quantity in question, but at a different time from when "
"it would be needed.");
} else {
Specifications__Compiler__compile(TEMP, spec);
}
} else {
LOG("Picked up past $A\n", ptc->ap_to_test);
PL__Actions__Patterns__compile_past_tense(TEMP, ptc->ap_to_test);
}
STREAM_COPY(OUT, TEMP);
WRITE(";\n");
CLOSE_TEMPORARY_STREAM;
}
#line 284 "inform7/Chapter 30/Chronology.w"
;
END_COMPILATION_MODE;
if ((LocalVariables__are_we_using_table_lookup()) && (once_only)) {
once_only = FALSE;
Problems__Issue__sentence_problem(_p_(PM_PastTableEntries),
"it's not safe to look up table entries in a way referring "
"to past history",
"because it leads to dangerous ambiguities. For instance, "
"does 'taking an item listed in the Table of Treasure "
"for the first time' mean that this is the first time taking "
"any of the things in the table, or only the first time "
"this one? And so on.");
}
}
WRITE("default: print \"*** No such past tense condition ***^\"; new = false;\n");
OUTDENT; WRITE("}\n");
WRITE("if (new) {\n"); INDENT;
WRITE("if (old == false) { trips++; if (trips > 127) trips = 127; }\n");
WRITE("if (turn_end) { consecutives++; if (consecutives > 127) consecutives = 127; }\n");
OUTDENT; WRITE("} else {\n"); INDENT;
WRITE("consecutives = 0;\n");
OUTDENT; WRITE("}\n");
WRITE("present_chronological_record-->pt = new + 2*trips + 256*consecutives;\n");
OUTDENT; WRITE("}\n");
WRITE("switch(wanted) {\n"); INDENT;
WRITE("0: if (new) return new;\n");
WRITE("1: if (new) return trips;\n");
WRITE("2: if (new) return consecutives+1; ! Plus one because we count the current turn\n");
WRITE("4: return new;\n");
WRITE("5: return trips;\n");
WRITE("6: return consecutives;\n");
OUTDENT; WRITE("}\n");
WRITE("return 0;\n");
OUT = Routines__end(OUT);
LOGIF(TIME_PERIODS,
"Creation of past tense conditions complete\n");
}
#line 364 "inform7/Chapter 30/Chronology.w"
void Chronology__chronology_extents_i6_escape(OUTPUT_STREAM) {
WRITE("Constant NO_PAST_TENSE_CONDS %d;\n", no_past_tenses);
WRITE("Constant NO_PAST_TENSE_ACTIONS %d;\n", no_past_actions);
}
#line 145 "inform7/Chapter 31/Invocations.w"
parse_node *Invocations__new(void) {
parse_node *inv = ParseTree__new(INVOCATION_NT);
ParseTree__set_phrase_invoked(inv, NULL);
ParseTree__set_say_verb(inv, NULL);
ParseTree__set_modal_verb(inv, NULL);
ParseTree__set_say_adjective(inv, NULL);
ParseTree__set_kind_resulting(inv, NULL);
ParseTree__set_phrase_options_invoked(inv, NULL);
ParseTree__set_kind_variable_declarations(inv, NULL);
ParseTree__annotate_int(inv, ssp_closing_segment_wn_ANNOT, -1);
return inv;
}
#line 161 "inform7/Chapter 31/Invocations.w"
void Invocations__log(parse_node *inv) {
int i;
if (inv == NULL) { LOG("<null invocation>"); return; }
if (inv->node_type != INVOCATION_NT) { LOG("$P", inv); return; }
char *verdict = Dash__verdict_to_text(inv);
LOG("[%04d%s] %8s ",
Routines__ToPhrases__sequence_count(ParseTree__get_phrase_invoked(inv)),
(Invocations__is_marked_to_save_self(inv))?"-save-self":"",
verdict);
if (ParseTree__get_say_verb(inv)) {
LOG("verb:%d", ParseTree__get_say_verb(inv)->allocation_id);
if (ParseTree__get_modal_verb(inv)) LOG("modal:%d", ParseTree__get_modal_verb(inv)->allocation_id);
} else if (ParseTree__get_say_adjective(inv)) {
LOG("adj:%d", ParseTree__get_say_adjective(inv)->allocation_id);
} else {
Phrases__log_briefly(ParseTree__get_phrase_invoked(inv));
for (i=0; i<Invocations__get_no_tokens(inv); i++) {
LOG(" ($P", Invocations__get_token_as_parsed(inv, i));
if (Invocations__get_token_check_to_do(inv, i))
LOG(" =? $P", Invocations__get_token_check_to_do(inv, i));
LOG(")");
}
wording OW = Invocations__get_phrase_options(inv);
if (Wordings__nonempty(OW))
LOG(" [0x%x $w]", Invocations__get_phrase_options_bitmap(inv), OW);
kind_variable_declaration *kvd = ParseTree__get_kind_variable_declarations(inv);
for (; kvd; kvd=kvd->next) LOG(" %c=$u", 'A'+kvd->kv_number-1, kvd->kv_value);
}
}
#line 195 "inform7/Chapter 31/Invocations.w"
void Invocations__mark_to_save_self(parse_node *inv) {
ParseTree__annotate_int(inv, save_self_ANNOT, TRUE);
}
int Invocations__is_marked_to_save_self(parse_node *inv) {
return ParseTree__int_annotation(inv, save_self_ANNOT);
}
void Invocations__mark_unproven(parse_node *inv) {
ParseTree__annotate_int(inv, unproven_ANNOT, TRUE);
}
int Invocations__is_marked_unproven(parse_node *inv) {
return ParseTree__int_annotation(inv, unproven_ANNOT);
}
#line 214 "inform7/Chapter 31/Invocations.w"
void Invocations__set_word_range(parse_node *inv, wording W) {
if (inv == NULL) internal_error("tried to set word range of null inv");
ParseTree__set_text(inv, W);
}
#line 222 "inform7/Chapter 31/Invocations.w"
void Invocations__set_verb_conjugation(parse_node *inv,
verb_conjugation *vc, verb_conjugation *modal, int neg) {
if (inv == NULL) internal_error("tried to set VC of null inv");
ParseTree__set_say_verb(inv, vc);
ParseTree__set_modal_verb(inv, modal);
ParseTree__annotate_int(inv, say_verb_negated_ANNOT, neg);
}
#line 233 "inform7/Chapter 31/Invocations.w"
void Invocations__set_adjectival_phrase(parse_node *inv, adjectival_phrase *aph) {
if (inv == NULL) internal_error("tried to set ADJ of null inv");
ParseTree__set_say_adjective(inv, aph);
}
#line 242 "inform7/Chapter 31/Invocations.w"
parse_node *Invocations__new_token(node_type_t t) {
parse_node *it = ParseTree__new(t);
ParseTree__set_token_check_to_do(it, NULL);
ParseTree__set_token_to_be_parsed_against(it, NULL);
ParseTree__set_kind_of_new_variable(it, NULL);
return it;
}
#line 254 "inform7/Chapter 31/Invocations.w"
void Invocations__make_token(parse_node *inv, int i, node_type_t t, wording W, kind *K) {
int k;
parse_node *itl;
if (i<0) internal_error("tried to set token out of range");
if (inv->down == NULL) inv->down = Invocations__new_token(t);
for (itl = inv->down, k = 0; itl; itl = itl->next, k++) {
if (k == i) {
ParseTree__set_text(itl, W);
ParseTree__set_type(itl, t);
ParseTree__set_kind_required_by_context(itl, K);
return;
}
if (itl->next == NULL) itl->next = Invocations__new_token(t);
}
}
void Invocations__set_token_check_to_do(parse_node *inv, int i, parse_node *spec) {
int k;
parse_node *itl;
if (i<0) internal_error("tried to set token out of range");
if (inv->down == NULL) inv->down = Invocations__new_token(INVALID_NT);
for (itl = inv->down, k = 0; itl; itl = itl->next, k++) {
if (k == i) { ParseTree__set_token_check_to_do(itl, spec); return; }
if (itl->next == NULL) itl->next = Invocations__new_token(INVALID_NT);
}
}
void Invocations__set_token_as_parsed(parse_node *inv, int i, parse_node *spec) {
int k;
parse_node *itl;
if (i<0) internal_error("tried to set token out of range");
if (inv->down == NULL) inv->down = Invocations__new_token(INVALID_NT);
for (itl = inv->down, k = 0; itl; itl = itl->next, k++) {
if (k == i) { itl->down = spec; return; }
if (itl->next == NULL) itl->next = Invocations__new_token(INVALID_NT);
}
}
void Invocations__set_token_to_be_parsed_against(parse_node *inv, int i, parse_node *spec) {
int k;
parse_node *itl;
if (i<0) internal_error("tried to set token out of range");
if (inv->down == NULL) inv->down = Invocations__new_token(INVALID_NT);
for (itl = inv->down, k = 0; itl; itl = itl->next, k++) {
if (k == i) { ParseTree__set_token_to_be_parsed_against(itl, spec); return; }
if (itl->next == NULL) itl->next = Invocations__new_token(INVALID_NT);
}
}
void Invocations__set_token_variable_kind(parse_node *inv, int i, kind *K) {
int k;
parse_node *itl;
if (i<0) internal_error("tried to set token out of range");
if (inv->down == NULL) inv->down = Invocations__new_token(INVALID_NT);
for (itl = inv->down, k = 0; itl; itl = itl->next, k++) {
if (k == i) { ParseTree__set_kind_of_new_variable(itl, K); return; }
if (itl->next == NULL) itl->next = Invocations__new_token(INVALID_NT);
}
}
#line 317 "inform7/Chapter 31/Invocations.w"
parse_node *Invocations__get_token(parse_node *inv, int i) {
int k;
parse_node *itl;
for (itl = inv->down, k = 0; itl; itl = itl->next, k++)
if (k == i) return itl;
return NULL;
}
parse_node *Invocations__get_token_check_to_do(parse_node *inv, int i) {
int k;
parse_node *itl;
for (itl = inv->down, k = 0; itl; itl = itl->next, k++)
if (k == i) return ParseTree__get_token_check_to_do(itl);
return NULL;
}
parse_node *Invocations__get_token_as_parsed(parse_node *inv, int i) {
int k;
parse_node *itl;
for (itl = inv->down, k = 0; itl; itl = itl->next, k++)
if (k == i) return itl->down;
return NULL;
}
parse_node *Invocations__get_token_to_be_parsed_against(parse_node *inv, int i) {
int k;
parse_node *itl;
for (itl = inv->down, k = 0; itl; itl = itl->next, k++)
if (k == i) return ParseTree__get_token_to_be_parsed_against(itl);
return NULL;
}
kind *Invocations__get_token_variable_kind(parse_node *inv, int i) {
int k;
parse_node *itl;
for (itl = inv->down, k = 0; itl; itl = itl->next, k++)
if (k == i) return ParseTree__get_kind_of_new_variable(itl);
return NULL;
}
int Invocations__get_no_tokens(parse_node *inv) {
int k;
parse_node *itl;
for (itl = inv->down, k = 0; itl; itl = itl->next, k++) ;
return k;
}
#line 368 "inform7/Chapter 31/Invocations.w"
int Invocations__get_no_tokens_needed(parse_node *inv) {
if (inv == NULL) internal_error("tried to read NTI of null inv");
if (ParseTree__get_phrase_invoked(inv))
return Phrases__TypeData__get_no_tokens(
&(ParseTree__get_phrase_invoked(inv)->type_data));
return 0;
}
#line 379 "inform7/Chapter 31/Invocations.w"
void Invocations__set_phrase_options(parse_node *inv, wording W) {
invocation_options *invo = ParseTree__get_phrase_options_invoked(inv);
if (invo == NULL) {
invo = CREATE(invocation_options);
invo->options = 0;
ParseTree__set_phrase_options_invoked(inv, invo);
}
invo->options_invoked_text = W;
}
#line 392 "inform7/Chapter 31/Invocations.w"
wording Invocations__get_phrase_options(parse_node *inv) {
invocation_options *invo = ParseTree__get_phrase_options_invoked(inv);
if (invo == NULL) return EMPTY_WORDING;
return invo->options_invoked_text;
}
#line 402 "inform7/Chapter 31/Invocations.w"
int Invocations__get_phrase_options_bitmap(parse_node *inv) {
invocation_options *invo = ParseTree__get_phrase_options_invoked(inv);
if (invo == NULL) return 0;
return invo->options;
}
void Invocations__set_phrase_options_bitmap(parse_node *inv, int further_bits) {
if (further_bits == 0) return;
invocation_options *invo = ParseTree__get_phrase_options_invoked(inv);
if (invo == NULL) {
invo = CREATE(invocation_options);
invo->options_invoked_text = EMPTY_WORDING;
invo->options = 0;
ParseTree__set_phrase_options_invoked(inv, invo);
}
invo->options |= further_bits;
}
#line 424 "inform7/Chapter 31/Invocations.w"
int Invocations__implies_newline(parse_node *inv) {
if (!(Phrases__TypeData__is_a_say_phrase(ParseTree__get_phrase_invoked(inv)))) return FALSE;
if (!(TEST_COMPILATION_MODE(IMPLY_NEWLINES_IN_SAY_CMODE))) return FALSE;
return TRUE;
}
#line 434 "inform7/Chapter 31/Invocations.w"
parse_node *Invocations__add_to_list(parse_node *invl, parse_node *inv) {
if (invl == NULL) return inv;
parse_node *p = invl;
while (p->next_alternative) p = p->next_alternative;
p->next_alternative = inv;
return invl;
}
#line 445 "inform7/Chapter 31/Invocations.w"
int Invocations__length_of_list(parse_node *invl) {
int L = 0;
for (parse_node *p = invl; p; p = p->next_alternative) L++;
return L;
}
#line 454 "inform7/Chapter 31/Invocations.w"
parse_node *Invocations__first_in_list(parse_node *invl) {
return invl;
}
#line 465 "inform7/Chapter 31/Invocations.w"
invocation_sort_block *pigeon_holes = NULL;
int number_of_pigeon_holes = 0;
parse_node *Invocations__sort_list(parse_node *invl) {
int L = Invocations__length_of_list(invl);
if (L > 0) {
{
#line 496 "inform7/Chapter 31/Invocations.w"
if (L > number_of_pigeon_holes) {
number_of_pigeon_holes = 2*L;
if (number_of_pigeon_holes < 1000)
number_of_pigeon_holes = 1000;
pigeon_holes =
Memory__I7_calloc(number_of_pigeon_holes, sizeof(invocation_sort_block), INV_LIST_MREASON);
}
}
#line 471 "inform7/Chapter 31/Invocations.w"
;
parse_node *ent=invl;
for (int i=0; (i<L) && (ent); i++, ent=ent->next_alternative) {
pigeon_holes[i].inv_data = ent;
pigeon_holes[i].unsorted_position = i;
}
qsort(pigeon_holes, (size_t) L, sizeof(invocation_sort_block), Invocations__comparison);
parse_node *tail = NULL; invl = NULL;
for (int i=0; i<L; i++) {
parse_node *i_n = pigeon_holes[i].inv_data; i_n->next_alternative = NULL;
if (tail) tail->next_alternative = i_n; else invl = i_n;
tail = i_n;
}
}
return invl;
}
#line 525 "inform7/Chapter 31/Invocations.w"
int Invocations__comparison(const void *i1, const void *i2) {
invocation_sort_block *inv1 = (invocation_sort_block *) i1;
invocation_sort_block *inv2 = (invocation_sort_block *) i2;
/* (a) sort by logical priority */
int delta =
Routines__ToPhrases__sequence_count(ParseTree__get_phrase_invoked(inv1->inv_data)) -
Routines__ToPhrases__sequence_count(ParseTree__get_phrase_invoked(inv2->inv_data));
if (delta != 0) return delta;
/* (b) sort by creation sequence */
return inv1->unsorted_position - inv2->unsorted_position;
}
#line 542 "inform7/Chapter 31/Invocations.w"
int Invocations__eq(parse_node *inv1, parse_node *inv2) {
if ((inv1) && (inv2 == NULL)) return FALSE;
if ((inv1 == NULL) && (inv2)) return FALSE;
if (inv1 == NULL) return TRUE;
if (ParseTree__get_phrase_invoked(inv1) != ParseTree__get_phrase_invoked(inv2))
return FALSE;
if (Invocations__get_no_tokens(inv1) != Invocations__get_no_tokens(inv2))
return FALSE;
for (int i=0; i<Invocations__get_no_tokens(inv1); i++) {
parse_node *m1 = Invocations__get_token_to_be_parsed_against(inv1, i);
parse_node *m2 = Invocations__get_token_to_be_parsed_against(inv2, i);
if (ParseTree__get_type(m1) != ParseTree__get_type(m2)) return FALSE;
parse_node *v1 = Invocations__get_token_as_parsed(inv1, i);
parse_node *v2 = Invocations__get_token_as_parsed(inv2, i);
if (ParseTree__get_type(v1) != ParseTree__get_type(v2)) return FALSE;
if (!Wordings__eq(ParseTree__get_text(v1), ParseTree__get_text(v2))) return FALSE;
}
return TRUE;
}
#line 573 "inform7/Chapter 31/Invocations.w"
void Invocations__log_list(parse_node *invl) {
parse_node *inv;
LOG("Invocation list (%d):\n", Invocations__length_of_list(invl));
int n = 0;
LOOP_THROUGH_INVOCATION_LIST(inv, invl)
LOG("P%d: $e\n", n++, inv);
}
#line 585 "inform7/Chapter 31/Invocations.w"
void Invocations__log_list_in_detail(parse_node *invl) {
parse_node *inv;
LOG("Invocation list in detail (%d):\n", Invocations__length_of_list(invl));
int n = 0;
LOOP_THROUGH_INVOCATION_LIST(inv, invl) {
int j;
LOG("P%d: $e\n", n++, inv);
for (j=0; j<Invocations__get_no_tokens(inv); j++) {
parse_node *tok = Invocations__get_token_as_parsed(inv, j);
LOG(" %d: $P\n", j, tok);
if (ParseTree__is(tok->down, INVOCATION_LIST_NT)) {
LOG_INDENT;
Invocations__log_list_in_detail(tok->down->down);
LOG_OUTDENT;
}
}
}
}
#line 16 "inform7/Chapter 31/Parse Invocations.w"
int end_phrase_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 18 "inform7/Chapter 31/Parse Invocations.w"
#line 33 "inform7/Chapter 31/Parse Invocations.w"
void Phrases__Parser__register_excerpt(phrase *ph) {
ph_type_data *phtd = &(ph->type_data);
if (Wordings__empty(phtd->registration_text)) return;
LOGIF(PHRASE_REGISTRATION, "Register phrase <$w> with type:\n$h", phtd->registration_text, phtd);
wording W = phtd->registration_text;
switch(phtd->manner_of_return) {
case DECIDES_NOTHING_MOR:
if (Phrases__TypeData__is_a_say_phrase(ph))
Phrases__Parser__register_phrasal(SAY_PHRASE_MC, ph, Wordings__trim_first_word(W));
else if (phtd->as_inline.block_follows != NO_BLOCK_FOLLOWS)
Phrases__Parser__register_phrasal(VOID_PHRASE_MC, ph, Wordings__trim_last_word(W));
else
Phrases__Parser__register_phrasal(VOID_PHRASE_MC, ph, W);
break;
case DECIDES_CONDITION_MOR: Phrases__Parser__register_phrasal(COND_PHRASE_MC, ph, W); break;
case DECIDES_VALUE_MOR: Phrases__Parser__register_phrasal(VALUE_PHRASE_MC, ph, W); break;
}
}
#line 56 "inform7/Chapter 31/Parse Invocations.w"
phrase *last_phrase_where_rp_problemed = NULL;
void Phrases__Parser__register_phrasal(unsigned int phrase_mc, phrase *ph, wording W) {
LOGIF(PHRASE_REGISTRATION, "Register phrasal on <$w>: $u\n", W,
Phrases__TypeData__kind(&(ph->type_data)));
{
#line 71 "inform7/Chapter 31/Parse Invocations.w"
int bl = 0, fixed_words = 0;
if (phrase_mc == SAY_PHRASE_MC) fixed_words++;
LOOP_THROUGH_WORDING(i, W) {
if (Lexer__word(i) == OPENBRACKET_V) bl++;
else if (Lexer__word(i) == CLOSEBRACKET_V) bl--;
else if (bl == 0) {
fixed_words++;
if (Vocabulary__test_flags(i, TEXT_MC+TEXTWITHSUBS_MC))
{
#line 89 "inform7/Chapter 31/Parse Invocations.w"
if (ph != last_phrase_where_rp_problemed) {
Problems__Issue__sentence_problem(_p_(PM_QuotedInPhrase),
"phrases can't be defined with quoted text as part of the fixed wording",
"so something like 'To go \"voluntarily\" to jail: ...' is not allowed.");
last_phrase_where_rp_problemed = ph;
}
return;
}
#line 79 "inform7/Chapter 31/Parse Invocations.w"
;
}
if ((i<Wordings__last_wn(W)) && (Lexer__word(i) == CLOSEBRACKET_V) && (Lexer__word(i+1) == OPENBRACKET_V))
{
#line 100 "inform7/Chapter 31/Parse Invocations.w"
if (ph != last_phrase_where_rp_problemed) {
Problems__Issue__sentence_problem(_p_(PM_AdjacentTokens),
"phrases can't be defined so that they have two bracketed varying elements "
"immediately next to each other",
"but instead need at least one fixed word in between. Thus 'To combine "
"(X - a number) (Y - a number)' is not allowed, but 'To combine (X - a "
"number) with (Y - a number)' works because of the 'with' dividing the "
"bracketed terms X and Y.");
last_phrase_where_rp_problemed = ph;
}
return;
}
#line 82 "inform7/Chapter 31/Parse Invocations.w"
;
}
if (fixed_words == 0)
{
#line 115 "inform7/Chapter 31/Parse Invocations.w"
if (ph != last_phrase_where_rp_problemed) {
Problems__Issue__sentence_problem(_p_(PM_MustBeOneWord),
"a 'To...' phrase must contain at least one fixed word",
"that is, one word other than the bracketed variables. So a declaration "
"like 'To (N - number): ...' is not allowed.");
last_phrase_where_rp_problemed = ph;
}
return;
}
#line 84 "inform7/Chapter 31/Parse Invocations.w"
;
}
#line 61 "inform7/Chapter 31/Parse Invocations.w"
;
{
#line 131 "inform7/Chapter 31/Parse Invocations.w"
int bl = 0;
LOOP_THROUGH_WORDING(i, W) {
if (Lexer__word(i) == OPENBRACKET_V) bl++;
else if (Lexer__word(i) == CLOSEBRACKET_V) bl--;
else if (bl == 0) {
char *p;
if (phrase_mc == SAY_PHRASE_MC) p = Lexer__word_raw_text(i);
else p = Lexer__word_text(i);
int j;
for (j=0; p[j]; j++)
if ((j>0) && (p[j-1] != '/') && (p[j] == '/') &&
(p[j+1]) && (p[j+1] != '/'))
{
#line 165 "inform7/Chapter 31/Parse Invocations.w"
char a_form[MAX_WORD_LENGTH], b_form[MAX_WORD_LENGTH];
{
#line 178 "inform7/Chapter 31/Parse Invocations.w"
int k;
for (k=0; k<j; k++) a_form[k] = p[k]; a_form[k] = 0;
for (k=j+1; p[k]; k++) b_form[k-j-1] = p[k]; b_form[k-j-1] = 0;
if (strcmp(a_form, "--") == 0) *a_form = 0;
if (strcmp(b_form, "--") == 0) *b_form = 0;
}
#line 166 "inform7/Chapter 31/Parse Invocations.w"
;
{
#line 192 "inform7/Chapter 31/Parse Invocations.w"
if ((strcmp(a_form, "say") == 0) && (i == Wordings__first_wn(W)) && (phrase_mc != SAY_PHRASE_MC))
if (ph != last_phrase_where_rp_problemed) {
Problems__Issue__sentence_problem(_p_(PM_SaySlashed),
"'say' is not allowed as the first word of a phrase",
"even when presented as one of a number of slashed alternatives. "
"(This is because 'say' is reserved for creating text substitutions.)");
last_phrase_where_rp_problemed = ph;
}
}
#line 167 "inform7/Chapter 31/Parse Invocations.w"
;
wording AW = EMPTY_WORDING, BW = EMPTY_WORDING;
{
#line 204 "inform7/Chapter 31/Parse Invocations.w"
feed_t id = Feeds__begin();
if (i > Wordings__first_wn(W)) Feeds__feed_wording(Wordings__up_to(W, i-1));
if (a_form[0]) Feeds__feed_text_expanding_strings(a_form);
if (i < Wordings__last_wn(W)) Feeds__feed_wording(Wordings__from(W, i+1));
AW = Feeds__end(id);
id = Feeds__begin();
if (i > Wordings__first_wn(W)) Feeds__feed_wording(Wordings__up_to(W, i-1));
if (b_form[0]) Feeds__feed_text_expanding_strings(b_form);
if (i < Wordings__last_wn(W)) Feeds__feed_wording(Wordings__from(W, i+1));
BW = Feeds__end(id);
}
#line 170 "inform7/Chapter 31/Parse Invocations.w"
;
if (Wordings__nonempty(AW)) Phrases__Parser__register_phrasal(phrase_mc, ph, AW);
if (Wordings__nonempty(BW)) Phrases__Parser__register_phrasal(phrase_mc, ph, BW);
return;
}
#line 143 "inform7/Chapter 31/Parse Invocations.w"
;
}
}
}
#line 62 "inform7/Chapter 31/Parse Invocations.w"
;
Semantics__Nouns__ExcerptMeanings__register(phrase_mc, W,
STORE_POINTER_phrase(ph));
}
#line 246 "inform7/Chapter 31/Parse Invocations.w"
parse_node *Phrases__Parser__parse_against(phrase *ph, parse_node *p) {
if (p == NULL) internal_error("parse against null subtree");
wording WW = EMPTY_WORDING;
wording OW = EMPTY_WORDING;
wording token_text[15]; int no_tokens = 0;
{
#line 273 "inform7/Chapter 31/Parse Invocations.w"
WW = ParseTree__get_text(p);
p = p->down;
if (p && (ParseTree__int_annotation(p, is_phrase_option_ANNOT))) {
OW = ParseTree__get_text(p);
p = p->next;
}
for (; ((p) && (no_tokens<15)); p = p->next) {
if (ParseTree__get_type(p) == UNKNOWN_VNT)
token_text[no_tokens++] = ParseTree__get_text(p);
else internal_error("Unexpected production in phrase args");
}
if (no_tokens > MAX_TOKENS_PER_PHRASE)
Problems__Fatal__issue("MAX_TOKENS_PER_PHRASE exceeded");
}
#line 251 "inform7/Chapter 31/Parse Invocations.w"
;
parse_node *inv = Invocations__new();
Invocations__set_word_range(inv, WW);
ParseTree__set_phrase_invoked(inv, ph);
PL__Actions__Patterns__suspend_validation(FALSE);
ph_type_data *phtd = &(ph->type_data);
int i;
for (i=0; i<no_tokens; i++)
{
#line 292 "inform7/Chapter 31/Parse Invocations.w"
parse_node *to_match = phtd->token_sequence[i].to_match;
wording X = Articles__remove_the(token_text[i]);
if (phtd->token_sequence[i].construct == NEW_LOCAL_PT_CONSTRUCT) {
to_match = Specifications__from_kind(K_value);
Invocations__make_token(inv, i, NEW_LOCAL_CONTEXT_NT, X, phtd->token_sequence[i].token_kind);
}
else if (phtd->token_sequence[i].construct == EXISTING_LOCAL_PT_CONSTRUCT) {
to_match = Specifications__from_kind(K_value);
Invocations__make_token(inv, i, LVALUE_LOCAL_CONTEXT_NT, X, phtd->token_sequence[i].token_kind);
}
else if (phtd->token_sequence[i].construct == STORAGE_PT_CONSTRUCT)
Invocations__make_token(inv, i, LVALUE_CONTEXT_NT, X, ParseTree__get_kind_of_value(to_match));
else if (phtd->token_sequence[i].construct == TABLE_REFERENCE_PT_CONSTRUCT)
Invocations__make_token(inv, i, LVALUE_TR_CONTEXT_NT, X, ParseTree__get_kind_of_value(to_match));
else if (phtd->token_sequence[i].construct == CONDITION_PT_CONSTRUCT)
Invocations__make_token(inv, i, CONDITION_CONTEXT_NT, X, NULL);
else if (phtd->token_sequence[i].construct == VOID_PT_CONSTRUCT)
Invocations__make_token(inv, i, VOID_CONTEXT_NT, X, NULL);
else if (Specifications__is_kind_like(to_match))
Invocations__make_token(inv, i, RVALUE_CONTEXT_NT, X, Specifications__to_kind(to_match));
else if (Specifications__is_description(to_match))
Invocations__make_token(inv, i, MATCHING_RVALUE_CONTEXT_NT, X, Specifications__to_kind(to_match));
else if (ParseTree__is(to_match, CONSTANT_VNT))
Invocations__make_token(inv, i, SPECIFIC_RVALUE_CONTEXT_NT, X, Specifications__to_kind(to_match));
else Invocations__make_token(inv, i, RVALUE_CONTEXT_NT, X, NULL); /* doesn't actually happen */
Invocations__set_token_to_be_parsed_against(inv, i, to_match);
parse_node *as_parsed = Specifications__new_UNKNOWN(X);
Invocations__set_token_as_parsed(inv, i, as_parsed);
}
#line 260 "inform7/Chapter 31/Parse Invocations.w"
;
if (Wordings__nonempty(OW)) Invocations__set_phrase_options(inv, OW);
PL__Actions__Patterns__suspend_validation(FALSE);
LOGIF(MATCHING, "Parse against to invocation: $e\n", inv);
return inv;
}
#line 326 "inform7/Chapter 31/Parse Invocations.w"
void Phrases__Parser__parse_within_inv(parse_node *inv) {
SParser__warn_expression_cache();
int N = Invocations__get_no_tokens(inv);
for (int i = 0; i < N; i++) {
parse_node *to_match = Invocations__get_token_to_be_parsed_against(inv, i);
int cons = -1;
phrase *ph = ParseTree__get_phrase_invoked(inv);
if (ph) cons = ph->type_data.token_sequence[i].construct;
if ((to_match) || (cons == CONDITION_PT_CONSTRUCT) || (cons == VOID_PT_CONSTRUCT)) {
parse_node *as_parsed = Invocations__get_token_as_parsed(inv, i);
wording XW = ParseTree__get_text(as_parsed);
int pto = permit_trying_omission;
if ((Specifications__is_kind_like(to_match)) &&
(Kinds__Compare__eq(Specifications__to_kind(to_match), K_stored_action))) {
permit_trying_omission = TRUE;
{
#line 356 "inform7/Chapter 31/Parse Invocations.w"
if (Preform__parse_nt_against_word_range(action_pattern_NTM, XW, NULL, NULL))
as_parsed = Conditions__new_TEST_ACTION(most_recent_result_p, XW);
else {
permit_trying_omission = FALSE;
{
#line 366 "inform7/Chapter 31/Parse Invocations.w"
kind *save_probable_noun_phrase_context = probable_noun_phrase_context;
int save_let_equation_mode = let_equation_mode;
probable_noun_phrase_context = NULL;
if (Specifications__is_kind_like(to_match))
probable_noun_phrase_context =
Specifications__to_kind(to_match);
let_equation_mode = Phrases__TypeData__is_a_let_equation(ph);
int t = FALSE; /* redundant assignment to keep |gcc| happy */
if (Specifications__is_description(to_match))
t = Preform__parse_nt_against_word_range(s_value_NTM, XW, NULL, NULL);
else if (cons == CONDITION_PT_CONSTRUCT)
t = Preform__parse_nt_against_word_range(s_condition_NTM, XW, NULL, NULL);
else if (cons == VOID_PT_CONSTRUCT)
t = Preform__parse_nt_against_word_range(s_command_NTM, XW, NULL, NULL);
else
t = Preform__parse_nt_against_word_range(s_value_NTM, XW, NULL, NULL);
if (t) as_parsed = most_recent_result_p;
else as_parsed = Specifications__new_UNKNOWN(XW);
LOGIF(MATCHING, "(%d/%d) Expected kind $u: parsed token $w (cons %d) to $P\n",
i+1, N, probable_noun_phrase_context, XW, cons, as_parsed);
probable_noun_phrase_context = save_probable_noun_phrase_context;
let_equation_mode = save_let_equation_mode;
}
#line 360 "inform7/Chapter 31/Parse Invocations.w"
;
}
}
#line 341 "inform7/Chapter 31/Parse Invocations.w"
;
} else {
permit_trying_omission = FALSE;
{
#line 366 "inform7/Chapter 31/Parse Invocations.w"
kind *save_probable_noun_phrase_context = probable_noun_phrase_context;
int save_let_equation_mode = let_equation_mode;
probable_noun_phrase_context = NULL;
if (Specifications__is_kind_like(to_match))
probable_noun_phrase_context =
Specifications__to_kind(to_match);
let_equation_mode = Phrases__TypeData__is_a_let_equation(ph);
int t = FALSE; /* redundant assignment to keep |gcc| happy */
if (Specifications__is_description(to_match))
t = Preform__parse_nt_against_word_range(s_value_NTM, XW, NULL, NULL);
else if (cons == CONDITION_PT_CONSTRUCT)
t = Preform__parse_nt_against_word_range(s_condition_NTM, XW, NULL, NULL);
else if (cons == VOID_PT_CONSTRUCT)
t = Preform__parse_nt_against_word_range(s_command_NTM, XW, NULL, NULL);
else
t = Preform__parse_nt_against_word_range(s_value_NTM, XW, NULL, NULL);
if (t) as_parsed = most_recent_result_p;
else as_parsed = Specifications__new_UNKNOWN(XW);
LOGIF(MATCHING, "(%d/%d) Expected kind $u: parsed token $w (cons %d) to $P\n",
i+1, N, probable_noun_phrase_context, XW, cons, as_parsed);
probable_noun_phrase_context = save_probable_noun_phrase_context;
let_equation_mode = save_let_equation_mode;
}
#line 344 "inform7/Chapter 31/Parse Invocations.w"
;
}
permit_trying_omission = pto;
ParseTree__set_text(as_parsed, XW);
Invocations__set_token_as_parsed(inv, i, as_parsed);
}
}
}
#line 40 "inform7/Chapter 31/Compile Invocations.w"
void Invocations__Compiler__compile_invocation_list(OUTPUT_STREAM, parse_node *invl, wording W) {
int wn = Wordings__first_wn(W);
if (Invocations__length_of_list(invl) > 0) {
LOGIF(MATCHING, "Compiling from %d invocations\n", Invocations__length_of_list(invl));
source_location sl = Lexer__word_location(wn);
if (Invocations__is_marked_to_save_self(Invocations__first_in_list(invl)))
WRITE("@push self; ");
if (Invocations__is_marked_unproven(Invocations__first_in_list(invl)))
{
#line 156 "inform7/Chapter 31/Compile Invocations.w"
phrase *ph = ParseTree__get_phrase_invoked(Invocations__first_in_list(invl));
int N = Invocations__get_no_tokens(Invocations__first_in_list(invl));
Frames__need_at_least_this_many_formals(N);
int void_mode = FALSE;
if (ph->type_data.manner_of_return == DECIDES_NOTHING_MOR) void_mode = TRUE;
WRITE("\n! Resolution of run-time phrase ambiguity%s:\n",
(void_mode)?" (to phrase)":" (deciding a value)"); INDENT;
{
#line 258 "inform7/Chapter 31/Compile Invocations.w"
if (void_mode) {
{
#line 296 "inform7/Chapter 31/Compile Invocations.w"
if (void_mode) {
int i;
for (i=0; i<N; i++) {
{
#line 314 "inform7/Chapter 31/Compile Invocations.w"
nonlocal_variable *nlv = NonlocalVariables__temporary_formal(i);
WRITE("%s = ", NonlocalVariables__lvalue_identifier(nlv));
if (ph->type_data.token_sequence[i].construct == KIND_NAME_PT_CONSTRUCT)
WRITE("0");
else {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
parse_node *value =
Invocations__get_token_as_parsed(Invocations__first_in_list(invl), i);
kind *to_be_used_as = Specifications__to_kind(
ph->type_data.token_sequence[i].to_match);
Specifications__Compiler__compile_to_kind(OUT, value, to_be_used_as);
END_COMPILATION_MODE;
}
}
#line 299 "inform7/Chapter 31/Compile Invocations.w"
; WRITE(";\n");
}
} else {
int i;
for (i=N-1; i>=0; i--) {
WRITE("(");
{
#line 314 "inform7/Chapter 31/Compile Invocations.w"
nonlocal_variable *nlv = NonlocalVariables__temporary_formal(i);
WRITE("%s = ", NonlocalVariables__lvalue_identifier(nlv));
if (ph->type_data.token_sequence[i].construct == KIND_NAME_PT_CONSTRUCT)
WRITE("0");
else {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
parse_node *value =
Invocations__get_token_as_parsed(Invocations__first_in_list(invl), i);
kind *to_be_used_as = Specifications__to_kind(
ph->type_data.token_sequence[i].to_match);
Specifications__Compiler__compile_to_kind(OUT, value, to_be_used_as);
END_COMPILATION_MODE;
}
}
#line 304 "inform7/Chapter 31/Compile Invocations.w"
; WRITE(")");
if (i>0) WRITE(" +");
WRITE("\n");
}
}
}
#line 259 "inform7/Chapter 31/Compile Invocations.w"
;
{
#line 353 "inform7/Chapter 31/Compile Invocations.w"
int no_conditions_tested = 0;
int pos = 0;
parse_node *last_inv = NULL;
parse_node *inv;
LOOP_THROUGH_INVOCATION_LIST(inv, invl) {
LOGIF(MATCHING, "RC%d: $e\n", pos, inv); pos++;
last_inv = inv;
if (no_conditions_tested > 0) {
if (void_mode) WRITE("else ");
else WRITE("|| ");
}
if (!void_mode) WRITE("(");
{
#line 386 "inform7/Chapter 31/Compile Invocations.w"
if (ParseTree__get_say_verb(inv))
Verbs__ConjugateVerb_invoke(OUT,
ParseTree__get_say_verb(inv),
ParseTree__get_modal_verb(inv),
ParseTree__int_annotation(inv, say_verb_negated_ANNOT));
else if (ParseTree__get_say_adjective(inv))
Adjectives__Meanings__invoke(OUT, ParseTree__get_say_adjective(inv));
else {
phrase *ph = ParseTree__get_phrase_invoked(inv);
tokens_packet tokens;
int brace_this = FALSE;
{
#line 91 "inform7/Chapter 31/Compile Invocations.w"
tokens.tokens_count = Invocations__get_no_tokens_needed(inv);
int i;
for (i=0; i<tokens.tokens_count; i++) {
parse_node *val = Invocations__get_token_as_parsed(inv, i);
kind *K = Specifications__to_kind(
ph->type_data.token_sequence[i].to_match);
if ((Phrases__TypeData__invoked_inline(ph) == FALSE) &&
(Kinds__Behaviour__definite(K) == FALSE))
tokens.kind_required[i] = Specifications__to_kind(val);
else
tokens.kind_required[i] = K;
if (ph->type_data.token_sequence[i].construct == KIND_NAME_PT_CONSTRUCT)
tokens.args[i] = Rvalues__new_nothing_object_constant();
else
tokens.args[i] = val;
}
kind *return_kind = ParseTree__get_kind_resulting(Invocations__first_in_list(invl));
if ((return_kind == NULL) && (ph)) return_kind = ph->type_data.return_kind;
tokens.as_requested =
Kinds__function_kind(tokens.tokens_count, tokens.kind_required, return_kind);
}
#line 397 "inform7/Chapter 31/Compile Invocations.w"
;
{
#line 408 "inform7/Chapter 31/Compile Invocations.w"
int i;
for (i=0; i<tokens.tokens_count; i++) {
nonlocal_variable *nlv = NonlocalVariables__temporary_formal(i);
NonlocalVariables__set_kind(nlv, tokens.kind_required[i]);
tokens.args[i] = Lvalues__new_actual_NONLOCAL_VARIABLE(nlv);
}
}
#line 398 "inform7/Chapter 31/Compile Invocations.w"
;
{
#line 418 "inform7/Chapter 31/Compile Invocations.w"
TEMPORARY_STREAM;
{
#line 435 "inform7/Chapter 31/Compile Invocations.w"
int i, condition_attached = FALSE;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
for (i=0; i<Invocations__get_no_tokens(inv); i++) {
parse_node *check_against = Invocations__get_token_check_to_do(inv, i);
if (check_against != NULL) {
if (condition_attached == FALSE) WRITE_TO(TEMP, "(");
else WRITE_TO(TEMP, " && ");
condition_attached = TRUE;
nonlocal_variable *nlv = NonlocalVariables__temporary_formal(i);
parse_node *spec = Lvalues__new_actual_NONLOCAL_VARIABLE(nlv);
{
#line 470 "inform7/Chapter 31/Compile Invocations.w"
if (Specifications__is_description(check_against)) {
WRITE_TO(TEMP, "(");
Calculus__Deferrals__compile_test_if_var_matches_description(TEMP,
spec, check_against);
WRITE_TO(TEMP, ")");
} else if (ParseTree__is_value(check_against)) {
pcalc_prop *prop = Calculus__Propositions__Abstract__to_set_relation(R_equality,
NULL, spec, NULL, check_against);
Calculus__Deferrals__compile_test_of_proposition(TEMP, NULL, prop);
} else {
LOG("Error on: $T", check_against);
internal_error("bad check-against in run-time type check");
}
}
#line 449 "inform7/Chapter 31/Compile Invocations.w"
;
}
}
if (condition_attached) WRITE_TO(TEMP, ")");
END_COMPILATION_MODE;
}
#line 419 "inform7/Chapter 31/Compile Invocations.w"
;
if (STREAM_EXTENT(TEMP) > 0) {
if (void_mode) {
WRITE("if ("); STREAM_COPY(OUT, TEMP); WRITE(")"); brace_this = TRUE;
} else {
WRITE("("); STREAM_COPY(OUT, TEMP); WRITE(") && ");
}
no_conditions_tested++;
} else if (Invocations__is_marked_unproven(inv))
internal_error("unable to compile a run-time kind check");
CLOSE_TEMPORARY_STREAM;
}
#line 399 "inform7/Chapter 31/Compile Invocations.w"
;
if (brace_this) WRITE(" { ");
{
#line 496 "inform7/Chapter 31/Compile Invocations.w"
if (!void_mode) WRITE("((\nformal_rv = ");
int returned_in_manner =
Invocations__Compiler__compile_single_invocation(OUT, inv, &sl, &tokens);
if (!void_mode) { WRITE(") | 1)\n"); }
if (returned_in_manner != DONT_KNOW_MOR)
{
#line 119 "inform7/Chapter 31/Compile Invocations.w"
int manner_expected = phrase_being_compiled->type_data.manner_of_return;
if ((returned_in_manner != manner_expected) &&
(manner_expected != DECIDES_NOTHING_AND_RETURNS_MOR)) {
LOG("C%d: $e: returned in manner %d\n", pos, inv, returned_in_manner);
LOG("vs Phrase being compiled: %d\n", manner_expected);
Problems__quote_source(1, current_sentence);
Problems__quote_text(2,
Phrases__TypeData__describe_manner_of_return(returned_in_manner, NULL, NULL));
kind *K = NULL;
Problems__quote_text(3,
Phrases__TypeData__describe_manner_of_return(manner_expected,
&(phrase_being_compiled->type_data), &K));
if (K) Problems__quote_kind(4, K);
Problems__Issue__handmade_problem(_p_(PM_WrongEndToPhrase));
if (K)
Problems__issue_problem_segment(
"The line %1 seems to be a way that the phrase you're defining can come "
"to an end, with %2, but it should always end up with a phrase to "
"decide %4.");
else
Problems__issue_problem_segment(
"The line %1 seems to be a way that the phrase you're defining can come "
"to an end, with %2, but it should always end up with %3.");
Problems__issue_problem_end();
return;
}
}
#line 501 "inform7/Chapter 31/Compile Invocations.w"
;
}
#line 401 "inform7/Chapter 31/Compile Invocations.w"
;
if (brace_this) WRITE(" }\n");
}
}
#line 365 "inform7/Chapter 31/Compile Invocations.w"
;
if (!void_mode) WRITE(")");
}
if (Invocations__is_marked_unproven(last_inv))
{
#line 374 "inform7/Chapter 31/Compile Invocations.w"
if (no_conditions_tested == 0) internal_error("condition proof error");
if (void_mode) WRITE("else ");
else WRITE("|| (");
extension_file *ef = SourceFiles__get_extension_corresponding(sl.file_of_origin);
WRITE("ArgumentTypeFailed(%d", sl.line_number);
if (ef) WRITE(", %d", ef->allocation_id + 1);
if (void_mode) WRITE(");\n");
else WRITE("))\n");
}
#line 369 "inform7/Chapter 31/Compile Invocations.w"
;
}
#line 260 "inform7/Chapter 31/Compile Invocations.w"
;
} else {
WRITE("(\n"); INDENT;
WRITE("! This value evaluates third (i.e., last)\n");
WRITE("formal_rv\n");
OUTDENT; WRITE("+\n"); INDENT;
WRITE("0*(\n"); INDENT;
WRITE("! The following condition evaluates second\n");
WRITE("((\n"); INDENT;
{
#line 353 "inform7/Chapter 31/Compile Invocations.w"
int no_conditions_tested = 0;
int pos = 0;
parse_node *last_inv = NULL;
parse_node *inv;
LOOP_THROUGH_INVOCATION_LIST(inv, invl) {
LOGIF(MATCHING, "RC%d: $e\n", pos, inv); pos++;
last_inv = inv;
if (no_conditions_tested > 0) {
if (void_mode) WRITE("else ");
else WRITE("|| ");
}
if (!void_mode) WRITE("(");
{
#line 386 "inform7/Chapter 31/Compile Invocations.w"
if (ParseTree__get_say_verb(inv))
Verbs__ConjugateVerb_invoke(OUT,
ParseTree__get_say_verb(inv),
ParseTree__get_modal_verb(inv),
ParseTree__int_annotation(inv, say_verb_negated_ANNOT));
else if (ParseTree__get_say_adjective(inv))
Adjectives__Meanings__invoke(OUT, ParseTree__get_say_adjective(inv));
else {
phrase *ph = ParseTree__get_phrase_invoked(inv);
tokens_packet tokens;
int brace_this = FALSE;
{
#line 91 "inform7/Chapter 31/Compile Invocations.w"
tokens.tokens_count = Invocations__get_no_tokens_needed(inv);
int i;
for (i=0; i<tokens.tokens_count; i++) {
parse_node *val = Invocations__get_token_as_parsed(inv, i);
kind *K = Specifications__to_kind(
ph->type_data.token_sequence[i].to_match);
if ((Phrases__TypeData__invoked_inline(ph) == FALSE) &&
(Kinds__Behaviour__definite(K) == FALSE))
tokens.kind_required[i] = Specifications__to_kind(val);
else
tokens.kind_required[i] = K;
if (ph->type_data.token_sequence[i].construct == KIND_NAME_PT_CONSTRUCT)
tokens.args[i] = Rvalues__new_nothing_object_constant();
else
tokens.args[i] = val;
}
kind *return_kind = ParseTree__get_kind_resulting(Invocations__first_in_list(invl));
if ((return_kind == NULL) && (ph)) return_kind = ph->type_data.return_kind;
tokens.as_requested =
Kinds__function_kind(tokens.tokens_count, tokens.kind_required, return_kind);
}
#line 397 "inform7/Chapter 31/Compile Invocations.w"
;
{
#line 408 "inform7/Chapter 31/Compile Invocations.w"
int i;
for (i=0; i<tokens.tokens_count; i++) {
nonlocal_variable *nlv = NonlocalVariables__temporary_formal(i);
NonlocalVariables__set_kind(nlv, tokens.kind_required[i]);
tokens.args[i] = Lvalues__new_actual_NONLOCAL_VARIABLE(nlv);
}
}
#line 398 "inform7/Chapter 31/Compile Invocations.w"
;
{
#line 418 "inform7/Chapter 31/Compile Invocations.w"
TEMPORARY_STREAM;
{
#line 435 "inform7/Chapter 31/Compile Invocations.w"
int i, condition_attached = FALSE;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
for (i=0; i<Invocations__get_no_tokens(inv); i++) {
parse_node *check_against = Invocations__get_token_check_to_do(inv, i);
if (check_against != NULL) {
if (condition_attached == FALSE) WRITE_TO(TEMP, "(");
else WRITE_TO(TEMP, " && ");
condition_attached = TRUE;
nonlocal_variable *nlv = NonlocalVariables__temporary_formal(i);
parse_node *spec = Lvalues__new_actual_NONLOCAL_VARIABLE(nlv);
{
#line 470 "inform7/Chapter 31/Compile Invocations.w"
if (Specifications__is_description(check_against)) {
WRITE_TO(TEMP, "(");
Calculus__Deferrals__compile_test_if_var_matches_description(TEMP,
spec, check_against);
WRITE_TO(TEMP, ")");
} else if (ParseTree__is_value(check_against)) {
pcalc_prop *prop = Calculus__Propositions__Abstract__to_set_relation(R_equality,
NULL, spec, NULL, check_against);
Calculus__Deferrals__compile_test_of_proposition(TEMP, NULL, prop);
} else {
LOG("Error on: $T", check_against);
internal_error("bad check-against in run-time type check");
}
}
#line 449 "inform7/Chapter 31/Compile Invocations.w"
;
}
}
if (condition_attached) WRITE_TO(TEMP, ")");
END_COMPILATION_MODE;
}
#line 419 "inform7/Chapter 31/Compile Invocations.w"
;
if (STREAM_EXTENT(TEMP) > 0) {
if (void_mode) {
WRITE("if ("); STREAM_COPY(OUT, TEMP); WRITE(")"); brace_this = TRUE;
} else {
WRITE("("); STREAM_COPY(OUT, TEMP); WRITE(") && ");
}
no_conditions_tested++;
} else if (Invocations__is_marked_unproven(inv))
internal_error("unable to compile a run-time kind check");
CLOSE_TEMPORARY_STREAM;
}
#line 399 "inform7/Chapter 31/Compile Invocations.w"
;
if (brace_this) WRITE(" { ");
{
#line 496 "inform7/Chapter 31/Compile Invocations.w"
if (!void_mode) WRITE("((\nformal_rv = ");
int returned_in_manner =
Invocations__Compiler__compile_single_invocation(OUT, inv, &sl, &tokens);
if (!void_mode) { WRITE(") | 1)\n"); }
if (returned_in_manner != DONT_KNOW_MOR)
{
#line 119 "inform7/Chapter 31/Compile Invocations.w"
int manner_expected = phrase_being_compiled->type_data.manner_of_return;
if ((returned_in_manner != manner_expected) &&
(manner_expected != DECIDES_NOTHING_AND_RETURNS_MOR)) {
LOG("C%d: $e: returned in manner %d\n", pos, inv, returned_in_manner);
LOG("vs Phrase being compiled: %d\n", manner_expected);
Problems__quote_source(1, current_sentence);
Problems__quote_text(2,
Phrases__TypeData__describe_manner_of_return(returned_in_manner, NULL, NULL));
kind *K = NULL;
Problems__quote_text(3,
Phrases__TypeData__describe_manner_of_return(manner_expected,
&(phrase_being_compiled->type_data), &K));
if (K) Problems__quote_kind(4, K);
Problems__Issue__handmade_problem(_p_(PM_WrongEndToPhrase));
if (K)
Problems__issue_problem_segment(
"The line %1 seems to be a way that the phrase you're defining can come "
"to an end, with %2, but it should always end up with a phrase to "
"decide %4.");
else
Problems__issue_problem_segment(
"The line %1 seems to be a way that the phrase you're defining can come "
"to an end, with %2, but it should always end up with %3.");
Problems__issue_problem_end();
return;
}
}
#line 501 "inform7/Chapter 31/Compile Invocations.w"
;
}
#line 401 "inform7/Chapter 31/Compile Invocations.w"
;
if (brace_this) WRITE(" }\n");
}
}
#line 365 "inform7/Chapter 31/Compile Invocations.w"
;
if (!void_mode) WRITE(")");
}
if (Invocations__is_marked_unproven(last_inv))
{
#line 374 "inform7/Chapter 31/Compile Invocations.w"
if (no_conditions_tested == 0) internal_error("condition proof error");
if (void_mode) WRITE("else ");
else WRITE("|| (");
extension_file *ef = SourceFiles__get_extension_corresponding(sl.file_of_origin);
WRITE("ArgumentTypeFailed(%d", sl.line_number);
if (ef) WRITE(", %d", ef->allocation_id + 1);
if (void_mode) WRITE(");\n");
else WRITE("))\n");
}
#line 369 "inform7/Chapter 31/Compile Invocations.w"
;
}
#line 269 "inform7/Chapter 31/Compile Invocations.w"
;
OUTDENT; WRITE("\n))\n");
OUTDENT; WRITE("+\n"); INDENT;
WRITE("! The following assignments evaluate first\n");
WRITE("(");
{
#line 296 "inform7/Chapter 31/Compile Invocations.w"
if (void_mode) {
int i;
for (i=0; i<N; i++) {
{
#line 314 "inform7/Chapter 31/Compile Invocations.w"
nonlocal_variable *nlv = NonlocalVariables__temporary_formal(i);
WRITE("%s = ", NonlocalVariables__lvalue_identifier(nlv));
if (ph->type_data.token_sequence[i].construct == KIND_NAME_PT_CONSTRUCT)
WRITE("0");
else {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
parse_node *value =
Invocations__get_token_as_parsed(Invocations__first_in_list(invl), i);
kind *to_be_used_as = Specifications__to_kind(
ph->type_data.token_sequence[i].to_match);
Specifications__Compiler__compile_to_kind(OUT, value, to_be_used_as);
END_COMPILATION_MODE;
}
}
#line 299 "inform7/Chapter 31/Compile Invocations.w"
; WRITE(";\n");
}
} else {
int i;
for (i=N-1; i>=0; i--) {
WRITE("(");
{
#line 314 "inform7/Chapter 31/Compile Invocations.w"
nonlocal_variable *nlv = NonlocalVariables__temporary_formal(i);
WRITE("%s = ", NonlocalVariables__lvalue_identifier(nlv));
if (ph->type_data.token_sequence[i].construct == KIND_NAME_PT_CONSTRUCT)
WRITE("0");
else {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
parse_node *value =
Invocations__get_token_as_parsed(Invocations__first_in_list(invl), i);
kind *to_be_used_as = Specifications__to_kind(
ph->type_data.token_sequence[i].to_match);
Specifications__Compiler__compile_to_kind(OUT, value, to_be_used_as);
END_COMPILATION_MODE;
}
}
#line 304 "inform7/Chapter 31/Compile Invocations.w"
; WRITE(")");
if (i>0) WRITE(" +");
WRITE("\n");
}
}
}
#line 274 "inform7/Chapter 31/Compile Invocations.w"
;
WRITE(")");
OUTDENT; WRITE(")\n");
OUTDENT; WRITE(")\n");
}
}
#line 166 "inform7/Chapter 31/Compile Invocations.w"
;
OUTDENT; WRITE("\n! Resolution complete\n");
}
#line 50 "inform7/Chapter 31/Compile Invocations.w"
else
{
#line 62 "inform7/Chapter 31/Compile Invocations.w"
int pos = 0;
parse_node *inv;
LOOP_THROUGH_INVOCATION_LIST(inv, invl) {
LOGIF(MATCHING, "C%d: $e\n", pos, inv); pos++;
if (ParseTree__get_say_verb(inv))
Verbs__ConjugateVerb_invoke(OUT,
ParseTree__get_say_verb(inv),
ParseTree__get_modal_verb(inv),
ParseTree__int_annotation(inv, say_verb_negated_ANNOT));
else if (ParseTree__get_say_adjective(inv))
Adjectives__Meanings__invoke(OUT, ParseTree__get_say_adjective(inv));
else
{
#line 80 "inform7/Chapter 31/Compile Invocations.w"
phrase *ph = ParseTree__get_phrase_invoked(inv);
tokens_packet tokens;
{
#line 91 "inform7/Chapter 31/Compile Invocations.w"
tokens.tokens_count = Invocations__get_no_tokens_needed(inv);
int i;
for (i=0; i<tokens.tokens_count; i++) {
parse_node *val = Invocations__get_token_as_parsed(inv, i);
kind *K = Specifications__to_kind(
ph->type_data.token_sequence[i].to_match);
if ((Phrases__TypeData__invoked_inline(ph) == FALSE) &&
(Kinds__Behaviour__definite(K) == FALSE))
tokens.kind_required[i] = Specifications__to_kind(val);
else
tokens.kind_required[i] = K;
if (ph->type_data.token_sequence[i].construct == KIND_NAME_PT_CONSTRUCT)
tokens.args[i] = Rvalues__new_nothing_object_constant();
else
tokens.args[i] = val;
}
kind *return_kind = ParseTree__get_kind_resulting(Invocations__first_in_list(invl));
if ((return_kind == NULL) && (ph)) return_kind = ph->type_data.return_kind;
tokens.as_requested =
Kinds__function_kind(tokens.tokens_count, tokens.kind_required, return_kind);
}
#line 82 "inform7/Chapter 31/Compile Invocations.w"
;
int returned_in_manner =
Invocations__Compiler__compile_single_invocation(OUT, inv, &sl, &tokens);
if ((phrase_being_compiled) && (returned_in_manner != DONT_KNOW_MOR))
{
#line 119 "inform7/Chapter 31/Compile Invocations.w"
int manner_expected = phrase_being_compiled->type_data.manner_of_return;
if ((returned_in_manner != manner_expected) &&
(manner_expected != DECIDES_NOTHING_AND_RETURNS_MOR)) {
LOG("C%d: $e: returned in manner %d\n", pos, inv, returned_in_manner);
LOG("vs Phrase being compiled: %d\n", manner_expected);
Problems__quote_source(1, current_sentence);
Problems__quote_text(2,
Phrases__TypeData__describe_manner_of_return(returned_in_manner, NULL, NULL));
kind *K = NULL;
Problems__quote_text(3,
Phrases__TypeData__describe_manner_of_return(manner_expected,
&(phrase_being_compiled->type_data), &K));
if (K) Problems__quote_kind(4, K);
Problems__Issue__handmade_problem(_p_(PM_WrongEndToPhrase));
if (K)
Problems__issue_problem_segment(
"The line %1 seems to be a way that the phrase you're defining can come "
"to an end, with %2, but it should always end up with a phrase to "
"decide %4.");
else
Problems__issue_problem_segment(
"The line %1 seems to be a way that the phrase you're defining can come "
"to an end, with %2, but it should always end up with %3.");
Problems__issue_problem_end();
return;
}
}
#line 86 "inform7/Chapter 31/Compile Invocations.w"
;
}
#line 74 "inform7/Chapter 31/Compile Invocations.w"
;
}
}
#line 52 "inform7/Chapter 31/Compile Invocations.w"
;
if (Invocations__is_marked_to_save_self(Invocations__first_in_list(invl)))
WRITE("@pull self; ");
}
}
#line 509 "inform7/Chapter 31/Compile Invocations.w"
int Invocations__Compiler__compile_single_invocation(OUTPUT_STREAM, parse_node *inv,
source_location *where_from, tokens_packet *tokens) {
LOGIF(MATCHING, "Compiling single invocation: $e\n", inv);
STREAM_MUST_BE_IN_MEMORY(OUT);
BEGIN_COMPILATION_MODE;
phrase *ph = ParseTree__get_phrase_invoked(inv);
int manner_of_return = DONT_KNOW_MOR;
if (ph->type_data.manner_of_return == DECIDES_CONDITION_MOR) WRITE("(");
{
#line 539 "inform7/Chapter 31/Compile Invocations.w"
if (Phrases__TypeData__invoked_inline(ph))
manner_of_return =
Invocations__Inline__csi_inline(OUT, inv, where_from, tokens);
else
Invocations__AsCalls__csi_by_call(OUT, inv, where_from, tokens);
}
#line 520 "inform7/Chapter 31/Compile Invocations.w"
;
if (ph->type_data.manner_of_return == DECIDES_CONDITION_MOR) WRITE(")");
{
#line 549 "inform7/Chapter 31/Compile Invocations.w"
if ((Invocations__implies_newline(inv)) &&
(tokens->tokens_count > 0) &&
(Rvalues__is_CONSTANT_of_kind(tokens->args[0], K_text)) &&
(Text__text_ending_sentence(Wordings__first_wn(ParseTree__get_text(tokens->args[0])))))
WRITE(" new_line;");
}
#line 523 "inform7/Chapter 31/Compile Invocations.w"
;
END_COMPILATION_MODE;
if (manner_of_return != DONT_KNOW_MOR)
LOGIF(MATCHING, "Single invocation return manner: %d\n", manner_of_return);
return manner_of_return;
}
#line 11 "inform7/Chapter 31/Compile Invocations As Calls.w"
void Invocations__AsCalls__csi_by_call(OUTPUT_STREAM, parse_node *inv,
source_location *where_from, tokens_packet *tokens) {
phrase *ph = ParseTree__get_phrase_invoked(inv);
char identifier[32];
Routines__Compile__identifier(identifier, ph,
Routines__ToPhrases__make_request(ph, tokens->as_requested,
ParseTree__get_kind_variable_declarations(inv), ParseTree__get_text(inv)));
LOGIF(MATCHING, "Calling routine %s with kind $u from $e\n", identifier,
tokens->as_requested, inv);
int options_supplied = Invocations__get_phrase_options_bitmap(inv);
if (ParseTree__get_phrase_options_invoked(inv) == NULL) options_supplied = -1;
Invocations__AsCalls__compile_function_call(OUT, tokens, identifier, options_supplied);
if (ph->type_data.manner_of_return == DECIDES_NOTHING_MOR) WRITE(";");
}
#line 35 "inform7/Chapter 31/Compile Invocations As Calls.w"
void Invocations__AsCalls__compile_function_call(OUTPUT_STREAM,
tokens_packet *tokens, char *identifier, int phrase_options) {
kind *return_kind = NULL;
{
#line 77 "inform7/Chapter 31/Compile Invocations As Calls.w"
kind *K = tokens->as_requested;
kind *args = NULL;
if (Kinds__get_construct(K) != CON_phrase) internal_error("no function kind");
Kinds__binary_construction_material(K, &args, &return_kind);
}
#line 39 "inform7/Chapter 31/Compile Invocations As Calls.w"
;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
WRITE("(");
WRITE("%s", identifier);
WRITE("(");
{
#line 59 "inform7/Chapter 31/Compile Invocations As Calls.w"
int count = 0;
if (Kinds__Behaviour__uses_pointer_values(return_kind)) {
Frames__compile_allocation(OUT, return_kind);
count = 1;
}
int k;
for (k=0; k<tokens->tokens_count; k++) {
if (count++ > 0) WRITE(",");
Specifications__Compiler__compile_to_kind(OUT, tokens->args[k], tokens->kind_required[k]);
}
if (phrase_options != -1) {
if (count++ > 0) WRITE(",");
WRITE("%d", phrase_options);
}
}
#line 47 "inform7/Chapter 31/Compile Invocations As Calls.w"
;
WRITE("))");
END_COMPILATION_MODE;
}
#line 34 "inform7/Chapter 31/Compile Invocations Inline.w"
int Invocations__Inline__csi_inline(OUTPUT_STREAM,
parse_node *inv, source_location *where_from, tokens_packet *tokens) {
phrase *ph = ParseTree__get_phrase_invoked(inv);
local_variable *my_vars[10]; /* the "my" variables 0 to 9 */
{
#line 62 "inform7/Chapter 31/Compile Invocations Inline.w"
int i; for (i=0; i<10; i++) my_vars[i] = NULL;
}
#line 40 "inform7/Chapter 31/Compile Invocations Inline.w"
;
{
#line 73 "inform7/Chapter 31/Compile Invocations Inline.w"
int i;
for (i=0; i<Invocations__get_no_tokens(inv); i++) {
parse_node *val = tokens->args[i];
kind *K = Invocations__get_token_variable_kind(inv, i);
if (K)
{
#line 83 "inform7/Chapter 31/Compile Invocations Inline.w"
local_variable *lvar = LocalVariables__new(ParseTree__get_text(val), K);
if (Phrases__TypeData__block_follows(ph) == LOOP_BODY_BLOCK_FOLLOWS)
Frames__Blocks__set_scope_to_block_about_to_open(lvar);
else
Frames__Blocks__set_variable_scope(lvar);
tokens->args[i] =
Lvalues__new_LOCAL_VARIABLE(ParseTree__get_text(val), lvar);
if (Kinds__Behaviour__uses_pointer_values(K)) {
WRITE("%s = ", LocalVariables__lvalue(lvar));
Frames__compile_allocation(OUT, K);
WRITE("; ");
}
}
#line 77 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
}
#line 41 "inform7/Chapter 31/Compile Invocations Inline.w"
;
text_stream *TAIL = NULL;
char head_defn[MAX_INLINE_DEFN_LENGTH];
char tail_defn[MAX_INLINE_DEFN_LENGTH];
{
#line 135 "inform7/Chapter 31/Compile Invocations Inline.w"
char *p = Phrases__get_inline_definition(ph);
Invocations__Inline__copy_and_trim(head_defn, p);
tail_defn[0] = 0;
int i;
for (i=0; head_defn[i]; i++)
if ((head_defn[i] == '\t') && (head_defn[i] == '\n'))
head_defn[i] = ' ';
if (Phrases__TypeData__block_follows(ph) != NO_BLOCK_FOLLOWS) {
int i;
for (i=0; head_defn[i]; i++)
if ((head_defn[i] == '{') &&
(head_defn[i+1] == '-') &&
(head_defn[i+2] == 'b') &&
(head_defn[i+3] == 'l') &&
(head_defn[i+4] == 'o') &&
(head_defn[i+5] == 'c') &&
(head_defn[i+6] == 'k') &&
(head_defn[i+7] == '}')) {
head_defn[i] = 0;
Invocations__Inline__copy_and_trim(tail_defn, head_defn+i+8);
Invocations__Inline__trim_tail(head_defn);
break;
}
}
}
#line 47 "inform7/Chapter 31/Compile Invocations Inline.w"
;
{
#line 165 "inform7/Chapter 31/Compile Invocations Inline.w"
Invocations__Inline__csi_inline_inner(OUT, head_defn,
inv, where_from, tokens, my_vars);
if (tail_defn[0]) {
TAIL = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(TAIL) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for tail text");
Invocations__Inline__csi_inline_inner(TAIL, tail_defn,
inv, where_from, tokens, my_vars);
}
}
#line 48 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (Phrases__TypeData__block_follows(ph))
{
#line 182 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *K = NULL;
if (Invocations__get_no_tokens(inv) > 0)
K = Specifications__to_kind(tokens->args[0]);
Frames__Blocks__supply_kind_and_stream(K, TAIL);
}
#line 50 "inform7/Chapter 31/Compile Invocations Inline.w"
else
{
#line 192 "inform7/Chapter 31/Compile Invocations Inline.w"
int i;
for (i=0; i<10; i++)
if (my_vars[i])
LocalVariables__deallocate(my_vars[i]);
}
#line 51 "inform7/Chapter 31/Compile Invocations Inline.w"
;
return ph->inline_mor;
}
#line 200 "inform7/Chapter 31/Compile Invocations Inline.w"
void Invocations__Inline__copy_and_trim(char *to, char *from) {
while ((from[0] == ' ') || (from[0] == '\t') || (from[0] == '\n')) from++;
Extensions__IDs__truncated_strcpy(to, from, MAX_INLINE_DEFN_LENGTH);
Invocations__Inline__trim_tail(to);
}
void Invocations__Inline__trim_tail(char *to) {
int n = Platform__strlen(to) - 1;
while ((n>=0) && ((to[n] == ' ') || (to[n] == '\t') || (to[n] == '\n'))) n--;
to[n+1] = 0;
}
#line 218 "inform7/Chapter 31/Compile Invocations Inline.w"
void Invocations__Inline__csi_inline_inner(OUTPUT_STREAM,
char *inline_definition, parse_node *inv, source_location *where_from,
tokens_packet *tokens, local_variable **my_vars) {
phrase *ph = ParseTree__get_phrase_invoked(inv);
int start_position = STREAM_EXTENT(OUT);
int definition_length = Platform__strlen(inline_definition);
int pos;
for (pos=0; pos<definition_length; pos++)
if (inline_definition[pos] == '{')
{
#line 238 "inform7/Chapter 31/Compile Invocations Inline.w"
int save_pos = pos++, accept = FALSE, k = 0;
char bracing[MAX_INLINE_DEFN_LENGTH];
while (inline_definition[pos]) {
bracing[k++] = inline_definition[pos];
if (bracing[k-1] == '}') { bracing[k-1] = 0; accept = TRUE; break; }
pos++;
}
if ((accept) &&
(bracing[0] != ' ') && (bracing[0] != '\t') && (bracing[0] != '\n') &&
(bracing[0] != '|'))
{
#line 281 "inform7/Chapter 31/Compile Invocations Inline.w"
char command[MAX_INLINE_DEFN_LENGTH];
char operand2[MAX_INLINE_DEFN_LENGTH];
property *extremal_property = NULL; /* that is, none given */
int extremal_property_sign = MEASURE_T_EXACTLY; /* that is, none given */
{
#line 316 "inform7/Chapter 31/Compile Invocations Inline.w"
command[0] = 0; operand2[0] = 0;
if (bracing[0] == '-') {
for (k=1; (bracing[k]) && (bracing[k] != ':'); k++)
command[k-1] = bracing[k];
command[k-1] = 0;
if (bracing[k] == 0) bracing[0] = 0;
else {
int k2; k++;
for (k2=k; bracing[k2]; k2++)
bracing[k2-k] = bracing[k2];
bracing[k2-k] = 0;
for (k2=0; bracing[k2]; k2++)
if (bracing[k2] == ':') {
bracing[k2] = 0;
strcpy(operand2, bracing+k2+1);
}
}
}
for (k=0; bracing[k]; k++) {
if (bracing[k] == '>') extremal_property_sign = MEASURE_T_OR_MORE;
if (bracing[k] == '<') extremal_property_sign = MEASURE_T_OR_LESS;
if (extremal_property_sign != MEASURE_T_EXACTLY) {
bracing[k] = 0;
wording W = Feeds__feed_text(bracing+k+1);
if (Preform__parse_nt_against_word_range(property_name_NTM, W, NULL, NULL)) extremal_property = most_recent_result_p;
break;
}
}
}
#line 286 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (command[0]) {
if (strcmp(command, "primitive-definition") == 0)
{
#line 1537 "inform7/Chapter 31/Compile Invocations Inline.w"
if (strcmp(bracing, "repeat-through") == 0)
Calculus__Deferrals__compile_repeat_through_domain_S(OUT,
tokens->args[1],
Lvalues__get_local_variable_if_any(tokens->args[0]));
else if (strcmp(bracing, "repeat-through-list") == 0)
Calculus__Deferrals__compile_loop_over_list_S(OUT,
tokens->args[1],
Lvalues__get_local_variable_if_any(tokens->args[0]));
else if (strcmp(bracing, "number-of") == 0)
Calculus__Deferrals__compile_number_of_S(OUT, tokens->args[0]);
else if (strcmp(bracing, "random-of") == 0)
Calculus__Deferrals__compile_random_of_S(OUT, tokens->args[0]);
else if (strcmp(bracing, "total-of") == 0)
Calculus__Deferrals__compile_total_of_S(OUT,
Rvalues__to_property(tokens->args[0]), tokens->args[1]);
else if (strcmp(bracing, "extremal") == 0) {
if ((extremal_property_sign != MEASURE_T_EXACTLY) && (extremal_property))
Calculus__Deferrals__compile_extremal_of_S(OUT, tokens->args[0],
extremal_property, extremal_property_sign);
else
Problems__Issue__inline_problem(_p_(PM_InlineExtremal), ph, inline_definition,
"In the '{-primitive-definition:extremal...}' command, there "
"should be a '<' or '>' sign then the name of a property.");
}
else if (strcmp(bracing, "function-application") == 0)
{
#line 1598 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node *fn = tokens->args[0];
kind *fn_kind = Specifications__to_kind(fn);
kind *X = NULL, *Y = NULL;
if (Kinds__get_construct(fn_kind) != CON_phrase) {
Problems__quote_spec(4, fn);
Problems__Issue__inline_problem(_p_(PM_InlineFunctionApplication),
ph, inline_definition,
"A function application only makes sense if the first token, "
"'%4', is a phrase: here it isn't.");
continue;
}
Kinds__binary_construction_material(fn_kind, &X, &Y);
int i;
for (i=1; i<tokens->tokens_count; i++) {
tokens->args[i-1] = tokens->args[i];
kind *head = NULL, *tail = NULL;
Kinds__binary_construction_material(X, &head, &tail);
X = tail;
tokens->kind_required[i-1] = NULL;
if ((Kinds__Behaviour__uses_pointer_values(head)) && (Kinds__Behaviour__definite(head)))
tokens->kind_required[i-1] = head;
}
tokens->tokens_count--;
TEMPORARY_STREAM;
WRITE_TO(TEMP, "(");
Specifications__Compiler__compile(TEMP, fn);
WRITE_TO(TEMP, "-->1)");
Invocations__AsCalls__compile_function_call(OUT, tokens, STREAM_TEXT(TEMP), -1);
CLOSE_TEMPORARY_STREAM;
}
#line 1567 "inform7/Chapter 31/Compile Invocations Inline.w"
else if (strcmp(bracing, "description-application") == 0)
{
#line 1632 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node *fn = tokens->args[1];
tokens->args[1] = tokens->args[0];
tokens->args[0] = Rvalues__from_int(-1, EMPTY_WORDING);
tokens->tokens_count = 2;
TEMPORARY_STREAM;
Specifications__Compiler__compile(TEMP, fn);
Invocations__AsCalls__compile_function_call(OUT, tokens, STREAM_TEXT(TEMP), -1);
CLOSE_TEMPORARY_STREAM;
}
#line 1568 "inform7/Chapter 31/Compile Invocations Inline.w"
else if (strcmp(bracing, "solve-equation") == 0)
{
#line 1644 "inform7/Chapter 31/Compile Invocations Inline.w"
if (Rvalues__is_CONSTANT_of_kind(tokens->args[1], K_equation))
Equations__compile_solution(OUT, ParseTree__get_text(tokens->args[0]),
Rvalues__to_equation(tokens->args[1]));
else {
Problems__Issue__sentence_problem(_p_(PM_SolvedNameless),
"only specific named equations can be solved",
"not equations arrived at by further calculations or choices. (Sorry: "
"but there would be no safe way to determine when an equation could "
"be used, because all equations have differing natures and variables.)");
}
WRITE(";\n");
}
#line 1570 "inform7/Chapter 31/Compile Invocations Inline.w"
else if (strcmp(bracing, "switch") == 0) Routines__Compile__switch_head(OUT, tokens->args[0]);
else if (strcmp(bracing, "break") == 0) Frames__Blocks__compile_break(OUT);
else if (strcmp(bracing, "verbose-checking") == 0) {
char *what = "";
if (tokens->tokens_count > 0) {
parse_node *aspect = tokens->args[0];
if (Wordings__nonempty(ParseTree__get_text(aspect))) {
int aw1 = Wordings__first_wn(ParseTree__get_text(aspect));
Text__dequote_word(aw1);
what = Lexer__word_text(aw1);
}
}
Log__tracing_phrases(what);
}
else {
Problems__quote_text(4, bracing);
Problems__Issue__inline_problem(_p_(PM_InlinePrimitive), ph, inline_definition,
"I don't know any primitive definition called '%4'.");
}
continue;
}
#line 289 "inform7/Chapter 31/Compile Invocations Inline.w"
;
{
#line 519 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__quote_text(4, bracing);
if (strcmp(command, "new") == 0)
{
#line 533 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *K = Invocations__Inline__parse_bracing_operand_as_kind(bracing, ParseTree__get_kind_variable_declarations(inv));
if (Kinds__Behaviour__uses_pointer_values(K)) Frames__compile_allocation(OUT, K);
else if (K == NULL)
{
#line 588 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__Issue__inline_problem(_p_(PM_InlineNew), ph, inline_definition,
"I don't know any kind called '%4'.");
}
#line 535 "inform7/Chapter 31/Compile Invocations Inline.w"
else if (Kinds__Behaviour__compile_default_value(OUT, K, EMPTY_WORDING, NULL) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(PM_NoNaturalDefault2));
Problems__issue_problem_segment(
"To achieve %1, we'd need to be able to store a default value of "
"the kind '%2', but there's no natural choice for this.");
Problems__issue_problem_end();
}
continue;
}
#line 520 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "new-list-of") == 0)
{
#line 557 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *K = Invocations__Inline__parse_bracing_operand_as_kind(bracing, ParseTree__get_kind_variable_declarations(inv));
Calculus__Deferrals__compile_list_of_S(OUT, tokens->args[0], K);
continue;
}
#line 521 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "printing-routine") == 0)
{
#line 564 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *K = Invocations__Inline__parse_bracing_operand_as_kind(bracing, ParseTree__get_kind_variable_declarations(inv));
if (K) WRITE("%s", Kinds__Behaviour__get_name_of_printing_rule(K));
else
{
#line 588 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__Issue__inline_problem(_p_(PM_InlineNew), ph, inline_definition,
"I don't know any kind called '%4'.");
}
#line 566 "inform7/Chapter 31/Compile Invocations Inline.w"
;
continue;
}
#line 522 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "strong-kind") == 0)
{
#line 572 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *K = Invocations__Inline__parse_bracing_operand_as_kind(bracing, ParseTree__get_kind_variable_declarations(inv));
if (K) Kinds__RunTime__compile_strong_id(OUT, K);
else
{
#line 588 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__Issue__inline_problem(_p_(PM_InlineNew), ph, inline_definition,
"I don't know any kind called '%4'.");
}
#line 574 "inform7/Chapter 31/Compile Invocations Inline.w"
;
continue;
}
#line 523 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "weak-kind") == 0)
{
#line 580 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *K = Invocations__Inline__parse_bracing_operand_as_kind(bracing, ParseTree__get_kind_variable_declarations(inv));
if (K) Kinds__RunTime__compile_weak_id(OUT, K);
else
{
#line 588 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__Issue__inline_problem(_p_(PM_InlineNew), ph, inline_definition,
"I don't know any kind called '%4'.");
}
#line 582 "inform7/Chapter 31/Compile Invocations Inline.w"
;
continue;
}
#line 524 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
#line 290 "inform7/Chapter 31/Compile Invocations Inline.w"
;
{
#line 596 "inform7/Chapter 31/Compile Invocations Inline.w"
if (strcmp(command, "backspace") == 0)
{
#line 606 "inform7/Chapter 31/Compile Invocations Inline.w"
STREAM_BACKSPACE(OUT);
continue;
}
#line 596 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "erase") == 0)
{
#line 612 "inform7/Chapter 31/Compile Invocations Inline.w"
STREAM_ERASE_BACK_TO(start_position);
continue;
}
#line 597 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "open-brace") == 0)
{
#line 619 "inform7/Chapter 31/Compile Invocations Inline.w"
WRITE("{");
continue;
}
#line 598 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "close-brace") == 0)
{
#line 625 "inform7/Chapter 31/Compile Invocations Inline.w"
WRITE("}");
continue;
}
#line 599 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
#line 291 "inform7/Chapter 31/Compile Invocations Inline.w"
;
{
#line 632 "inform7/Chapter 31/Compile Invocations Inline.w"
if (strcmp(command, "label") == 0)
{
#line 663 "inform7/Chapter 31/Compile Invocations Inline.w"
JumpLabels__write(OUT, bracing);
continue;
}
#line 632 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "counter") == 0)
{
#line 669 "inform7/Chapter 31/Compile Invocations Inline.w"
WRITE("%d", JumpLabels__read_counter(bracing, NOT_APPLICABLE));
continue;
}
#line 633 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "counter-up") == 0)
{
#line 675 "inform7/Chapter 31/Compile Invocations Inline.w"
JumpLabels__read_counter(bracing, TRUE);
continue;
}
#line 634 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "counter-down") == 0)
{
#line 682 "inform7/Chapter 31/Compile Invocations Inline.w"
JumpLabels__read_counter(bracing, FALSE);
continue;
}
#line 635 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "counter-makes-array") == 0)
{
#line 712 "inform7/Chapter 31/Compile Invocations Inline.w"
int words_per_count = 1;
if (operand2[0]) words_per_count = atoi(operand2);
JumpLabels__allocate_counter(bracing, words_per_count);
continue;
}
#line 636 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
#line 292 "inform7/Chapter 31/Compile Invocations Inline.w"
;
{
#line 993 "inform7/Chapter 31/Compile Invocations Inline.w"
if (strcmp(command, "my") == 0)
{
#line 1008 "inform7/Chapter 31/Compile Invocations Inline.w"
local_variable *lvar = NULL;
int n = bracing[0] - '0';
if ((bracing[1] == 0) && (n >= 0) && (n < 10))
{
#line 1038 "inform7/Chapter 31/Compile Invocations Inline.w"
lvar = my_vars[n];
if (lvar == NULL) {
my_vars[n] = LocalVariables__new(EMPTY_WORDING, K_number);
lvar = my_vars[n];
{
#line 1087 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *K = NULL;
if (operand2[0])
K = Invocations__Inline__parse_bracing_operand_as_kind(operand2, ParseTree__get_kind_variable_declarations(inv));
if (K == NULL) K = K_object;
LocalVariables__set_kind(lvar, K);
}
#line 1042 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (Phrases__TypeData__block_follows(ph))
Frames__Blocks__set_scope_to_block_about_to_open(lvar);
}
}
#line 1010 "inform7/Chapter 31/Compile Invocations Inline.w"
else
{
#line 1075 "inform7/Chapter 31/Compile Invocations Inline.w"
lvar = LocalVariables__add_internal_local(bracing);
{
#line 1087 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *K = NULL;
if (operand2[0])
K = Invocations__Inline__parse_bracing_operand_as_kind(operand2, ParseTree__get_kind_variable_declarations(inv));
if (K == NULL) K = K_object;
LocalVariables__set_kind(lvar, K);
}
#line 1076 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
#line 1011 "inform7/Chapter 31/Compile Invocations Inline.w"
;
WRITE("%s", LocalVariables__lvalue(lvar));
continue;
}
#line 993 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "unprotect") == 0)
{
#line 1110 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node *v =
Invocations__Inline__parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
local_variable *lvar = Lvalues__get_local_variable_if_any(v);
if (lvar) LocalVariables__unprotect(lvar);
else
{
#line 1659 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__quote_text(4, bracing);
Problems__Issue__inline_problem(_p_(PM_InlineNoSuch), ph, inline_definition,
"I don't know any local variable called '%4'.");
}
#line 1114 "inform7/Chapter 31/Compile Invocations Inline.w"
;
continue;
}
#line 994 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "copy") == 0)
{
#line 1194 "inform7/Chapter 31/Compile Invocations Inline.w"
int copy_form = 0;
parse_node *from = NULL, *to = NULL;
{
#line 1225 "inform7/Chapter 31/Compile Invocations Inline.w"
char *from_p = operand2, *to_p = bracing;
if (from_p[0] == '+') { copy_form = 1; from_p++; }
else if (from_p[0] == '-') { copy_form = -1; from_p++; }
if ((from_p[0] == 0) && (copy_form != 0))
from = Rvalues__from_int(1, EMPTY_WORDING);
else if (from_p[0])
from = Invocations__Inline__parse_bracing_operand_as_identifier(from_p, ph, tokens, my_vars);
to = Invocations__Inline__parse_bracing_operand_as_identifier(to_p, ph, tokens, my_vars);
if ((to == NULL) || (from == NULL)) {
Problems__quote_text(4, bracing);
Problems__quote_text(5, operand2);
Problems__Issue__inline_problem(_p_(PM_InlineCopy), ph, inline_definition,
"The command to {-copy:...}, which asks to copy '%5' into '%4', has "
"gone wrong: I couldn't work those out.");
continue;
}
}
#line 1196 "inform7/Chapter 31/Compile Invocations Inline.w"
;
{
#line 1251 "inform7/Chapter 31/Compile Invocations Inline.w"
nonlocal_variable *nlv = Lvalues__get_nonlocal_variable_if_any(to);
if ((nlv) && (NonlocalVariables__must_be_constant(nlv))) continue;
if (nlv) NonlocalVariables__warn_about_change(nlv);
local_variable *lvar = Lvalues__get_local_variable_if_any(to);
if ((lvar) && (LocalVariables__protected(lvar))) continue;
}
#line 1197 "inform7/Chapter 31/Compile Invocations Inline.w"
;
pcalc_term pt1 = Calculus__Terms__new_constant(to);
pcalc_term pt2 = Calculus__Terms__new_constant(from);
kind *K1 = Specifications__to_kind(to);
kind *K2 = Specifications__to_kind(from);
node_type_t storage_class = Lvalues__get_storage_form(to);
if (copy_form != 0)
{
#line 1261 "inform7/Chapter 31/Compile Invocations Inline.w"
if (Kinds__Behaviour__is_quasinumerical(K1) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K1);
Problems__Issue__handmade_problem(_p_(PM_CantIncrementKind));
Problems__issue_problem_segment(
"To achieve %1, we'd need to be able to add or subtract 1 from "
"a value of the kind '%2', but there's no good way to do this.");
Problems__issue_problem_end();
continue;
}
}
#line 1204 "inform7/Chapter 31/Compile Invocations Inline.w"
;
char *prototype = Kinds__Behaviour__interpret_store(storage_class, K1, K2, copy_form);
LOGIF(KIND_CHECKING, "Inline copy: %s\n", prototype);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(PERMIT_LOCALS_IN_TEXT_CMODE);
Calculus__Schemas__expand(Calculus__Schemas__new("%s;", prototype), OUT, &pt1, &pt2);
END_COMPILATION_MODE;
continue;
}
#line 995 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "initialise") == 0)
{
#line 1134 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node *V = Invocations__Inline__parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
local_variable *lvar = Lvalues__get_local_variable_if_any(V);
kind *K = NULL;
if (operand2[0])
K = Invocations__Inline__parse_bracing_operand_as_kind(operand2, ParseTree__get_kind_variable_declarations(inv));
else
K = Specifications__to_kind(V);
if (Kinds__Behaviour__uses_pointer_values(K)) {
if (Frames__Blocks__inside_a_loop_body()) {
WRITE("BlkValueCopy(%s, ", LocalVariables__lvalue(lvar));
Kinds__Behaviour__compile_default_value(OUT, K, ParseTree__get_text(V), "value");
WRITE("); ");
}
} else {
WRITE("%s = ", LocalVariables__lvalue(lvar));
if (Kinds__Behaviour__compile_default_value(OUT, K, ParseTree__get_text(V), "value") == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, K);
Problems__Issue__handmade_problem(_p_(PM_NoNaturalDefault));
Problems__issue_problem_segment(
"To achieve %1, we'd need to be able to store a default value of "
"the kind '%2', but there's no natural choice for this.");
Problems__issue_problem_end();
}
WRITE("; ");
}
continue;
}
#line 996 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "matches-description") == 0)
{
#line 1295 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node *to_match =
Invocations__Inline__parse_bracing_operand_as_identifier(operand2, ph, tokens, my_vars);
parse_node *to_test =
Invocations__Inline__parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
if ((to_test == NULL) || (to_match == NULL)) {
Problems__quote_text(4, bracing);
Problems__quote_text(5, operand2);
Problems__Issue__inline_problem(_p_(PM_InlineMatchesDescription), ph, inline_definition,
"The command {-matches-description:...}, which asks to test whether "
"'%5' is a valid description for '%4', has gone wrong: I couldn't "
"work those out.");
} else
Calculus__Deferrals__compile_substitution_test(OUT, to_test, to_match);
continue;
}
#line 997 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "now-matches-description") == 0)
{
#line 1314 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node *to_test =
Invocations__Inline__parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
parse_node *to_match =
Invocations__Inline__parse_bracing_operand_as_identifier(operand2, ph, tokens, my_vars);
if ((to_test == NULL) || (to_match == NULL)) {
Problems__quote_text(4, bracing);
Problems__quote_text(5, operand2);
Problems__Issue__inline_problem(_p_(PM_InlineNowMatchesDescription),
ph, inline_definition,
"The command {-now-matches-description:...}, which asks to change "
"'%4' so that '%5' becomes a valid description of it, has gone "
"wrong: I couldn't work those out.");
} else
Calculus__Deferrals__compile_substitution_now(OUT, to_test, to_match);
continue;
}
#line 998 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "arithmetic-operation") == 0)
{
#line 1333 "inform7/Chapter 31/Compile Invocations Inline.w"
int op = Phrases__TypeData__arithmetic_operation(ph);
int binary = TRUE;
if (Kinds__Dimensions__arithmetic_op_is_unary(op)) binary = FALSE;
parse_node *X = NULL, *Y = NULL;
kind *KX = NULL, *KY = NULL;
{
#line 1345 "inform7/Chapter 31/Compile Invocations Inline.w"
X = Invocations__Inline__parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
KX = Specifications__to_kind(X);
if (binary) {
Y = Invocations__Inline__parse_bracing_operand_as_identifier(operand2, ph, tokens, my_vars);
KY = Specifications__to_kind(Y);
}
}
#line 1338 "inform7/Chapter 31/Compile Invocations Inline.w"
;
Kinds__Dimensions__perform_arithmetic(OUT, op, NULL, X, NULL, KX, Y, NULL, KY);
continue;
}
#line 999 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "say") == 0)
{
#line 1359 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node *to_say =
Invocations__Inline__parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
if (to_say == NULL) {
{
#line 1659 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__quote_text(4, bracing);
Problems__Issue__inline_problem(_p_(PM_InlineNoSuch), ph, inline_definition,
"I don't know any local variable called '%4'.");
}
#line 1362 "inform7/Chapter 31/Compile Invocations Inline.w"
;
continue;
}
kind *K = Invocations__Inline__parse_bracing_operand_as_kind(operand2,
ParseTree__get_kind_variable_declarations(inv));
if (Kinds__Compare__eq(K, K_text))
{
#line 1384 "inform7/Chapter 31/Compile Invocations Inline.w"
wording SW = ParseTree__get_text(to_say);
if ((Rvalues__is_CONSTANT_of_kind(to_say, K_text)) &&
(Wordings__length(SW) == 1) &&
(Vocabulary__test_flags(Wordings__first_wn(SW), TEXTWITHSUBS_MC) == FALSE)) {
WRITE("print \"");
CompiledText__from_ISO_string(OUT, Lexer__word_text(Wordings__first_wn(SW)),
CT_DEQUOTE + CT_EXPAND_APOSTROPHES);
WRITE("\";");
} else {
kind *K = Specifications__to_kind(to_say);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
WRITE("print (");
if (K) WRITE("%s", Kinds__Behaviour__get_name_of_printing_rule(K));
WRITE(") "); Specifications__Compiler__compile_to_kind(OUT, to_say, K);
WRITE(";");
END_COMPILATION_MODE;
}
continue;
}
#line 1368 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (Kinds__Compare__eq(K, K_number))
{
#line 1407 "inform7/Chapter 31/Compile Invocations Inline.w"
WRITE("print (say__n=");
Specifications__Compiler__compile_to_kind(OUT, to_say, K);
WRITE(");");
continue;
}
#line 1369 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (Kinds__Compare__eq(K, K_unicode_character))
{
#line 1420 "inform7/Chapter 31/Compile Invocations Inline.w"
WRITE("unicode_temp = ");
Specifications__Compiler__compile_to_kind(OUT, to_say, K);
WRITE("; ");
WRITE("#ifdef TARGET_ZCODE; @print_unicode unicode_temp; #ifnot; @streamunichar unicode_temp; #endif;");
continue;
}
#line 1370 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (K) {
WRITE("%s(", Kinds__Behaviour__get_name_of_printing_rule(K));
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__Compiler__compile_to_kind(OUT, to_say, K);
END_COMPILATION_MODE;
WRITE(");");
} else
{
#line 588 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__Issue__inline_problem(_p_(PM_InlineNew), ph, inline_definition,
"I don't know any kind called '%4'.");
}
#line 1378 "inform7/Chapter 31/Compile Invocations Inline.w"
;
continue;
}
#line 1000 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "show-me") == 0)
{
#line 1430 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node *to_show =
Invocations__Inline__parse_bracing_operand_as_identifier(bracing, ph, tokens, my_vars);
if (to_show == NULL) {
{
#line 1659 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__quote_text(4, bracing);
Problems__Issue__inline_problem(_p_(PM_InlineNoSuch), ph, inline_definition,
"I don't know any local variable called '%4'.");
}
#line 1433 "inform7/Chapter 31/Compile Invocations Inline.w"
;
continue;
}
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
WRITE("#ifdef DEBUG;");
WRITE("print \"");
PL__Parsing__TestScripts__showme(OUT, to_show);
WRITE("^\";");
WRITE("#endif;\n");
END_COMPILATION_MODE;
continue;
}
#line 1001 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
#line 293 "inform7/Chapter 31/Compile Invocations Inline.w"
;
{
#line 1451 "inform7/Chapter 31/Compile Invocations Inline.w"
if (strcmp(command, "segment-count") == 0)
{
#line 1460 "inform7/Chapter 31/Compile Invocations Inline.w"
WRITE("%d", ParseTree__int_annotation(inv, ssp_segment_count_ANNOT));
continue;
}
#line 1451 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "final-segment-marker") == 0)
{
#line 1466 "inform7/Chapter 31/Compile Invocations Inline.w"
if (ParseTree__int_annotation(inv, ssp_closing_segment_wn_ANNOT) == -1) WRITE("NULL");
else {
char plenty[1024];
Wordings__to_string(plenty, Wordings__one_word(ParseTree__int_annotation(inv, ssp_closing_segment_wn_ANNOT)));
WRITE("%s", plenty);
}
continue;
}
#line 1452 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "list-together") == 0)
{
#line 1478 "inform7/Chapter 31/Compile Invocations Inline.w"
if (strcmp(bracing, "unarticled") == 0)
ListTogether__new(OUT, FALSE);
else if (strcmp(bracing, "articled") == 0)
ListTogether__new(OUT, TRUE);
else {
Problems__Issue__inline_problem(_p_(PM_InlineListTogether), ph, inline_definition,
"The only legal forms here are {-list-together:articled} and "
"{-list-together:unarticled}.");
}
continue;
}
#line 1453 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "rescale") == 0)
{
#line 1494 "inform7/Chapter 31/Compile Invocations Inline.w"
int op = Phrases__TypeData__arithmetic_operation(ph);
switch (op) {
case TIMES_OPERATION: {
kind *kindx = Specifications__to_kind(tokens->args[0]);
kind *kindy = Specifications__to_kind(tokens->args[1]);
Kinds__Dimensions__kind_rescale_multiplication(OUT, kindx, kindy);
break;
}
case DIVIDE_OPERATION: {
kind *kindx = Specifications__to_kind(tokens->args[0]);
kind *kindy = Specifications__to_kind(tokens->args[1]);
Kinds__Dimensions__kind_rescale_division(OUT, kindx, kindy);
break;
}
case ROOT_OPERATION: {
kind *K = Specifications__to_kind(tokens->args[0]);
Kinds__Dimensions__kind_rescale_root(OUT, K, 2);
break;
}
case CUBEROOT_OPERATION: {
kind *K = Specifications__to_kind(tokens->args[0]);
Kinds__Dimensions__kind_rescale_root(OUT, K, 3);
break;
}
default:
Problems__Issue__inline_problem(_p_(PM_InlineRescale), ph, inline_definition,
"Arithmetic rescaling with {-rescale} is allowed only in phrases "
"which multiply, divide or extract roots.");
break;
}
continue;
}
#line 1454 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
#line 294 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
wording BRW = Feeds__feed_text(bracing);
{
#line 406 "inform7/Chapter 31/Compile Invocations Inline.w"
phod_being_parsed = &(ph->options_data);
ph_being_parsed = ph;
Preform__parse_nt_against_word_range(inline_substitution_NTM, BRW, NULL, NULL);
int current_opts = Invocations__get_phrase_options_bitmap(inv);
switch (most_recent_result) {
case OPTS_INSUB:
WRITE("%d", current_opts);
break;
case OPT_INSUB:
if (current_opts & opt_NTMV) WRITE("true"); else WRITE("false");
break;
case LOCAL_INSUB: {
local_variable *lvar = local_variable_var_NTMV;
int tok = LocalVariables__get_parameter_number(lvar);
if (tok >= 0)
{
#line 430 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node *supplied = tokens->args[tok];
int by_value_not_reference = TRUE;
int require_to_be_lvalue = FALSE;
BEGIN_COMPILATION_MODE;
{
#line 723 "inform7/Chapter 31/Compile Invocations Inline.w"
int valid_annotation = FALSE;
if (strcmp(command, "by-reference") == 0)
{
#line 753 "inform7/Chapter 31/Compile Invocations Inline.w"
by_value_not_reference = FALSE;
valid_annotation = TRUE;
}
#line 725 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "lvalue-by-reference") == 0)
{
#line 765 "inform7/Chapter 31/Compile Invocations Inline.w"
by_value_not_reference = FALSE;
valid_annotation = TRUE;
require_to_be_lvalue = TRUE;
}
#line 726 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "by-value") == 0)
{
#line 772 "inform7/Chapter 31/Compile Invocations Inline.w"
by_value_not_reference = TRUE;
valid_annotation = TRUE;
}
#line 727 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "box-quotation-text") == 0)
{
#line 781 "inform7/Chapter 31/Compile Invocations Inline.w"
if (Rvalues__is_CONSTANT_of_kind(supplied, K_text) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_spec(2, supplied);
Problems__Issue__handmade_problem(_p_(PM_Misboxed));
Problems__issue_problem_segment(
"I attempted to compile %1, but the text '%2' supplied to be a "
"boxed quotation wasn't a constant piece of text in double-quotes. "
"I'm afraid that's the only sort of text allowed here.");
Problems__issue_problem_end();
continue;
} else {
COMPILATION_MODE_ENTER(COMPILE_TEXT_TO_QUOT_CMODE);
by_value_not_reference = FALSE;
valid_annotation = TRUE;
}
}
#line 729 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "try-action") == 0)
{
#line 901 "inform7/Chapter 31/Compile Invocations Inline.w"
if (Rvalues__is_CONSTANT_of_kind(supplied, K_stored_action)) {
action_pattern *ap = ParseTree__get_constant_action_pattern(supplied);
PL__Actions__Patterns__compile_try(OUT, ap, FALSE);
} else {
WRITE("STORED_ACTION_TY_Try(");
Specifications__Compiler__compile(OUT, supplied);
WRITE(");");
}
valid_annotation = TRUE;
continue; /* that is, don't use the regular token compiler: we've done it ourselves */
}
#line 731 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "try-action-silently") == 0)
{
#line 915 "inform7/Chapter 31/Compile Invocations Inline.w"
if (Rvalues__is_CONSTANT_of_kind(supplied, K_stored_action)) {
WRITE("@push keep_silent; keep_silent=1; @push say__p; @push say__pc;\n");
WRITE("ClearParagraphing(1);\n");
action_pattern *ap = ParseTree__get_constant_action_pattern(supplied);
PL__Actions__Patterns__compile_try(OUT, ap, FALSE);
WRITE("\nDivideParagraphPoint();\n");
WRITE("@pull say__pc; @pull say__p; AdjustParagraphPoint(); @pull keep_silent;\n");
} else {
WRITE("STORED_ACTION_TY_Try(");
Specifications__Compiler__compile(OUT, supplied);
WRITE(", true);");
}
valid_annotation = TRUE;
continue; /* that is, don't use the regular token compiler: we've done it ourselves */
}
#line 732 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "return-value") == 0)
{
#line 821 "inform7/Chapter 31/Compile Invocations Inline.w"
int returning_from_rule = FALSE;
{
#line 834 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *kind_needed;
if (returning_from_rule) kind_needed = Rulebooks__kind_from_context();
else kind_needed = Frames__get_kind_returned();
kind *kind_supplied = Specifications__to_kind(supplied);
int mor = Phrases__TypeData__get_mor(&(phrase_being_compiled->type_data));
int allow_me = ALWAYS_MATCH;
if ((kind_needed) && (Kinds__Compare__eq(kind_needed, K_nil) == FALSE))
allow_me = Kinds__Compare__compatible(kind_supplied, kind_needed);
else if ((mor == DECIDES_CONDITION_MOR) && (Kinds__Compare__eq(kind_supplied, K_truth_state)))
allow_me = ALWAYS_MATCH;
else
{
#line 861 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind_of(2, supplied);
if (returning_from_rule) {
Problems__Issue__handmade_problem(_p_(PM_RuleNotAllowedOutcome));
Problems__issue_problem_segment(
"You wrote %1 as something to be a successful outcome of a rule, which "
"has the kind %2; but this is not a rule which is allowed to have a value "
"as its outcome.");
Problems__issue_problem_end();
} else {
Problems__Issue__handmade_problem(_p_(PM_RedundantReturnKOV));
Problems__issue_problem_segment(
"You wrote %1 as the outcome of a phrase, %2, but in the definition of "
"something which was not a phrase to decide a value.");
Problems__issue_problem_end();
}
}
#line 846 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (allow_me == ALWAYS_MATCH)
Specifications__Compiler__compile_to_kind(OUT, supplied, kind_needed);
else if ((allow_me == SOMETIMES_MATCH) && (Kinds__Compare__le(kind_needed, K_object))) {
WRITE("CheckKindReturned(");
Specifications__Compiler__compile_to_kind(OUT, supplied, kind_needed);
WRITE(", %s)", Kinds__Behaviour__I6_classname(kind_needed));
} else
{
#line 881 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, kind_supplied);
Problems__quote_kind(3, kind_needed);
if (returning_from_rule) {
Problems__Issue__handmade_problem(_p_(PM_RuleOutcomeWrongKind));
Problems__issue_problem_segment(
"You wrote %1 as the outcome of a rule which produces a value, but this "
"was the wrong kind of value: %2 rather than %3.");
Problems__issue_problem_end();
} else {
Problems__Issue__handmade_problem(_p_(PM_ReturnWrongKind));
Problems__issue_problem_segment(
"You wrote %1 as the outcome of a phrase to decide a value, but this was "
"the wrong kind of value: %2 rather than %3.");
Problems__issue_problem_end();
}
}
#line 854 "inform7/Chapter 31/Compile Invocations Inline.w"
;
continue; /* that is, don't use the regular token compiler: we've done it ourselves */
}
#line 822 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
#line 734 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "return-value-from-rule") == 0)
{
#line 828 "inform7/Chapter 31/Compile Invocations Inline.w"
int returning_from_rule = TRUE;
{
#line 834 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *kind_needed;
if (returning_from_rule) kind_needed = Rulebooks__kind_from_context();
else kind_needed = Frames__get_kind_returned();
kind *kind_supplied = Specifications__to_kind(supplied);
int mor = Phrases__TypeData__get_mor(&(phrase_being_compiled->type_data));
int allow_me = ALWAYS_MATCH;
if ((kind_needed) && (Kinds__Compare__eq(kind_needed, K_nil) == FALSE))
allow_me = Kinds__Compare__compatible(kind_supplied, kind_needed);
else if ((mor == DECIDES_CONDITION_MOR) && (Kinds__Compare__eq(kind_supplied, K_truth_state)))
allow_me = ALWAYS_MATCH;
else
{
#line 861 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind_of(2, supplied);
if (returning_from_rule) {
Problems__Issue__handmade_problem(_p_(PM_RuleNotAllowedOutcome));
Problems__issue_problem_segment(
"You wrote %1 as something to be a successful outcome of a rule, which "
"has the kind %2; but this is not a rule which is allowed to have a value "
"as its outcome.");
Problems__issue_problem_end();
} else {
Problems__Issue__handmade_problem(_p_(PM_RedundantReturnKOV));
Problems__issue_problem_segment(
"You wrote %1 as the outcome of a phrase, %2, but in the definition of "
"something which was not a phrase to decide a value.");
Problems__issue_problem_end();
}
}
#line 846 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (allow_me == ALWAYS_MATCH)
Specifications__Compiler__compile_to_kind(OUT, supplied, kind_needed);
else if ((allow_me == SOMETIMES_MATCH) && (Kinds__Compare__le(kind_needed, K_object))) {
WRITE("CheckKindReturned(");
Specifications__Compiler__compile_to_kind(OUT, supplied, kind_needed);
WRITE(", %s)", Kinds__Behaviour__I6_classname(kind_needed));
} else
{
#line 881 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, kind_supplied);
Problems__quote_kind(3, kind_needed);
if (returning_from_rule) {
Problems__Issue__handmade_problem(_p_(PM_RuleOutcomeWrongKind));
Problems__issue_problem_segment(
"You wrote %1 as the outcome of a rule which produces a value, but this "
"was the wrong kind of value: %2 rather than %3.");
Problems__issue_problem_end();
} else {
Problems__Issue__handmade_problem(_p_(PM_ReturnWrongKind));
Problems__issue_problem_segment(
"You wrote %1 as the outcome of a phrase to decide a value, but this was "
"the wrong kind of value: %2 rather than %3.");
Problems__issue_problem_end();
}
}
#line 854 "inform7/Chapter 31/Compile Invocations Inline.w"
;
continue; /* that is, don't use the regular token compiler: we've done it ourselves */
}
#line 829 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
#line 735 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "property-holds-block-value") == 0)
{
#line 935 "inform7/Chapter 31/Compile Invocations Inline.w"
property *prn = Rvalues__to_property(supplied);
if ((prn == NULL) || (Properties__is_either_or(prn))) {
WRITE("false");
} else {
kind *K = Properties__Valued__kind(prn);
if (Kinds__Behaviour__uses_pointer_values(K)) WRITE("true"); else WRITE("false");
}
continue;
}
#line 737 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if (strcmp(command, "mark-event-used") == 0)
{
#line 957 "inform7/Chapter 31/Compile Invocations Inline.w"
if (Rvalues__is_CONSTANT_construction(supplied, CON_rule)) {
rule *R = Rvalues__to_rule(supplied);
phrase *ph = Rules__get_I7_definition(R);
if (ph) Phrases__Timed__note_usage(ph, current_sentence);
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(supplied));
Problems__Issue__handmade_problem(_p_(PM_NonconstantEvent));
Problems__issue_problem_segment(
"You wrote %1, but '%2' isn't the name of any timed event that "
"I know of. (These need to be set up in a special way, like so - "
"'At the time when stuff happens: ...' creates a timed event "
"called 'stuff happens'.)");
Problems__issue_problem_end();
}
valid_annotation = TRUE;
}
#line 738 "inform7/Chapter 31/Compile Invocations Inline.w"
;
if ((command[0]) && (valid_annotation == FALSE))
{
#line 977 "inform7/Chapter 31/Compile Invocations Inline.w"
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, command);
Problems__Issue__handmade_problem(_p_(PM_BadInlineTag));
Problems__issue_problem_segment(
"I attempted to compile %1 using its inline definition, "
"but this contained the invalid annotation '%2'.");
Problems__issue_problem_end();
continue;
}
#line 741 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
#line 436 "inform7/Chapter 31/Compile Invocations Inline.w"
;
kind *kind_vars_inline[27];
{
#line 452 "inform7/Chapter 31/Compile Invocations Inline.w"
kind_vars_inline[0] = NULL;
for (int i=1; i<=26; i++) kind_vars_inline[i] = Frames__get_kind_variable(i);
kind_variable_declaration *kvd = ParseTree__get_kind_variable_declarations(inv);
for (; kvd; kvd=kvd->next) kind_vars_inline[kvd->kv_number] = kvd->kv_value;
}
#line 438 "inform7/Chapter 31/Compile Invocations Inline.w"
;
kind **saved = Frames__temporarily_set_kvs(kind_vars_inline);
int changed = FALSE;
kind *kind_required =
Kinds__substitute(ph->type_data.token_sequence[tok].token_kind,
kind_vars_inline, &changed);
{
#line 460 "inform7/Chapter 31/Compile Invocations Inline.w"
if (require_to_be_lvalue) {
nonlocal_variable *nlv = Lvalues__get_nonlocal_variable_if_any(supplied);
if (((nlv) && (NonlocalVariables__is_constant(nlv))) ||
(ParseTree__is_lvalue(supplied) == FALSE)) {
Problems__quote_source(1, current_sentence);
if (nlv) Problems__quote_wording(2, nlv->name);
else Problems__quote_spec(2, supplied);
Problems__Issue__handmade_problem(_p_(PM_NotAnLvalue));
Problems__issue_problem_segment(
"You wrote %1, but that seems to mean changing '%2', which "
"is a constant and can't be altered.");
Problems__issue_problem_end();
}
}
}
#line 444 "inform7/Chapter 31/Compile Invocations Inline.w"
;
{
#line 497 "inform7/Chapter 31/Compile Invocations Inline.w"
if (Kinds__Compare__eq(kind_required, K_text))
COMPILATION_MODE_ENTER(PERMIT_LOCALS_IN_TEXT_CMODE);
if (by_value_not_reference == TRUE)
COMPILATION_MODE_ENTER(DEREFERENCE_POINTERS_CMODE);
if (by_value_not_reference == FALSE)
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
LOGIF(MATCHING, "Expanding $P into '$w' with %d, $u%s%s\n",
supplied, BRW, tok, kind_required,
changed?" (after kind substitution)":"",
by_value_not_reference?" (by value)":" (by reference)");
Specifications__Compiler__compile_to_kind(OUT, supplied, kind_required);
}
#line 445 "inform7/Chapter 31/Compile Invocations Inline.w"
;
Frames__temporarily_set_kvs(saved);
END_COMPILATION_MODE;
}
#line 420 "inform7/Chapter 31/Compile Invocations Inline.w"
;
break;
}
}
}
#line 298 "inform7/Chapter 31/Compile Invocations Inline.w"
;
}
#line 248 "inform7/Chapter 31/Compile Invocations Inline.w"
else { WRITE("{"); pos = save_pos; }
}
#line 227 "inform7/Chapter 31/Compile Invocations Inline.w"
else if ((inline_definition[pos] == '(') && (inline_definition[pos+1] == '+'))
{
#line 254 "inform7/Chapter 31/Compile Invocations Inline.w"
int save_pos = pos, accept = FALSE, k = 0;
char source_text_fragment[MAX_INLINE_DEFN_LENGTH];
pos += 2;
while (inline_definition[pos]) {
source_text_fragment[k++] = inline_definition[pos];
if ((source_text_fragment[k-2] == '+') && (source_text_fragment[k-1] == ')')) {
source_text_fragment[k-2] = 0; accept = TRUE; break;
}
pos++;
}
if (accept)
{
#line 270 "inform7/Chapter 31/Compile Invocations Inline.w"
if (source_text_fragment[0]) {
TEMPORARY_STREAM;
TemplateFiles__compile_I7_from_I6(TEMP, source_text_fragment);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
}
#line 264 "inform7/Chapter 31/Compile Invocations Inline.w"
else { WRITE("("); pos = save_pos; }
}
#line 229 "inform7/Chapter 31/Compile Invocations Inline.w"
else
WRITE("%c", inline_definition[pos]);
}
#line 366 "inform7/Chapter 31/Compile Invocations Inline.w"
int inline_substitution_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = OPTS_INSUB;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = OPT_INSUB; opt_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = LOCAL_INSUB; local_variable_var_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 388 "inform7/Chapter 31/Compile Invocations Inline.w"
*X = PROBLEM_INSUB;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_BadInlineExpansion));
Problems__issue_problem_segment(
"You wrote %1, but when I looked that phrase up I found that its inline "
"definition included the bracing {%2}. Text written in braces like this, "
"in an inline phrase definition, should be one of the following: a name "
"of one of the tokens in the phrase, or a phrase option, or the text "
"'phrase options' itself. %PThe ability to write inline phrases is really "
"intended only for the Standard Rules and a few other low-level system "
"extensions. A good rule of thumb is: if you can define a phrase without "
"using I6 insertions, do.");
Problems__issue_problem_end();
}
#line 370 "inform7/Chapter 31/Compile Invocations Inline.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 371 "inform7/Chapter 31/Compile Invocations Inline.w"
#line 375 "inform7/Chapter 31/Compile Invocations Inline.w"
int name_local_to_inline_stack_frame_NTMR(wording W, int *X, void **XP) {
#line 376 "inform7/Chapter 31/Compile Invocations Inline.w"
local_variable *lvar =
LocalVariables__parse(&(ph_being_parsed->stack_frame), W);
if (lvar) {
*XP = lvar; return TRUE;
}
return FALSE;
}
#line 1675 "inform7/Chapter 31/Compile Invocations Inline.w"
parse_node *Invocations__Inline__parse_bracing_operand_as_identifier(char *operand, phrase *ph,
tokens_packet *tokens, local_variable **my_vars) {
local_variable *lvar = NULL;
if ((operand[1] == 0) && (operand[0] >= '0') && (operand[0] <= '9'))
lvar = my_vars[operand[0] - '0'];
else {
wording LW = Feeds__feed_text(operand);
lvar = LocalVariables__parse(&(ph->stack_frame), LW);
if (lvar) {
int tok = LocalVariables__get_parameter_number(lvar);
if (tok >= 0) return tokens->args[tok];
}
lvar = LocalVariables__by_name(operand);
}
if (lvar) return Lvalues__new_LOCAL_VARIABLE(EMPTY_WORDING, lvar);
return NULL;
}
#line 1711 "inform7/Chapter 31/Compile Invocations Inline.w"
kind *Invocations__Inline__parse_bracing_operand_as_kind(char *operand, kind_variable_declaration *kvd) {
if (strcmp(operand, "return-kind") == 0)
return Frames__get_kind_returned();
if (strcmp(operand, "rule-return-kind") == 0)
return Rulebooks__kind_from_context();
kind *kind_vars_inline[27];
for (int i=0; i<27; i++) kind_vars_inline[i] = NULL;
for (; kvd; kvd=kvd->next) kind_vars_inline[kvd->kv_number] = kvd->kv_value;
kind **saved = Frames__temporarily_set_kvs(kind_vars_inline);
wording KW = Feeds__feed_text(operand);
parse_node *spec = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, KW, NULL, NULL)) spec = most_recent_result_p;
Frames__temporarily_set_kvs(saved);
kind *K = Specifications__to_kind(spec);
return K;
}
#line 30 "inform7/Chapter 31/Compile Phrases.w"
void Routines__Compile__routine(OUTPUT_STREAM, phrase *ph,
stacked_variable_owner_list *legible, to_phrase_request *req,
applicability_condition *acl) {
if ((ph->declaration_node == NULL) ||
(ParseTree__get_type(ph->declaration_node) != ROUTINE_NT) ||
(Wordings__empty(ParseTree__get_text(ph->declaration_node))))
internal_error("tried to compile phrase with bad ROUTINE node");
LOGIF(PHRASE_COMPILATION, "Compiling phrase:\n$T", ph->declaration_node);
phrase_being_compiled = ph;
{
#line 72 "inform7/Chapter 31/Compile Phrases.w"
ph_stack_frame *phsf = &(ph->stack_frame);
ph_type_data *phtd = &(ph->type_data);
Frames__make_current(phsf);
kind *version_kind = NULL;
if (req) version_kind = Routines__ToPhrases__kind_of_request(req);
else version_kind = Phrases__TypeData__kind(phtd);
Phrases__TypeData__into_stack_frame(phsf, phtd, version_kind, FALSE);
if (req) Frames__set_kind_variables(phsf,
Routines__ToPhrases__kind_variables_for_request(req));
else Frames__set_kind_variables(phsf, NULL);
Frames__set_stvol(phsf, legible);
LocalVariables__deallocate_all(phsf); /* in case any are left from an earlier compile */
SParser__warn_expression_cache(); /* that local variables may have changed */
}
#line 41 "inform7/Chapter 31/Compile Phrases.w"
;
{
#line 60 "inform7/Chapter 31/Compile Phrases.w"
heading *definition_area =
Wordings__heading_of(ParseTree__get_text(ph->declaration_node));
extension_file *definition_extension =
Sentences__Headings__get_extension_containing(definition_area);
if (definition_extension)
Extensions__Files__write_I6_comment_describing(definition_extension, OUT);
Routines__ToPhrases__comment_on_request(req, OUT);
Phrases__Usage__write_I6_comment_describing(&(ph->usage_data), OUT);
}
#line 43 "inform7/Chapter 31/Compile Phrases.w"
;
char i6_routine_identifier[32];
Routines__Compile__identifier(i6_routine_identifier, ph, req);
OUT = Routines__begin_framed(OUT, i6_routine_identifier, &(ph->stack_frame));
{
#line 93 "inform7/Chapter 31/Compile Phrases.w"
current_sentence = ph->declaration_node;
Phrases__Context__compile_test_head(OUT, ph, acl);
if (ph->declaration_node) {
ParseTree__verify_structure(ph->declaration_node);
Routines__Compile__code_block(OUT, 1, ph->declaration_node->down, TRUE);
ParseTree__verify_structure(ph->declaration_node);
}
current_sentence = ph->declaration_node;
Phrases__Context__compile_test_tail(OUT, ph, acl);
{
#line 111 "inform7/Chapter 31/Compile Phrases.w"
kind *K = Frames__get_kind_returned();
if (K) {
WRITE("return ");
if (Kinds__Behaviour__compile_default_value(OUT, K, EMPTY_WORDING,
"value decided by this phrase") != TRUE)
Problems__Issue__sentence_problem(_p_(PM_DefaultDecideFails),
"it's not possible to decide such a value",
"so this can't be allowed.");
WRITE(";");
} else {
WRITE("rfalse;"); /* that is, return "false" */
}
WRITE("\n");
}
#line 103 "inform7/Chapter 31/Compile Phrases.w"
;
}
#line 49 "inform7/Chapter 31/Compile Phrases.w"
;
OUT = Routines__end(OUT);
phrase_being_compiled = NULL;
current_sentence = NULL;
}
#line 130 "inform7/Chapter 31/Compile Phrases.w"
void Routines__Compile__identifier(char *identifier, phrase *ph, to_phrase_request *req) {
if (req)
sprintf(identifier, "%s_r%d ",
Phrases__identifier(ph), req->allocation_id);
else
strcpy(identifier, Phrases__identifier(ph));
}
#line 141 "inform7/Chapter 31/Compile Phrases.w"
int disallow_let_assignments = FALSE;
int Routines__Compile__disallow_let(void) {
return disallow_let_assignments;
}
int Routines__Compile__code_block(OUTPUT_STREAM, int statement_count, parse_node *pn, int top_level) {
if (pn) {
int m = s_value_uncached_NTM->multiplicitous;
s_value_uncached_NTM->multiplicitous = TRUE;
if (ParseTree__get_type(pn) != CODE_BLOCK_NT) internal_error("not a code block");
if ((top_level == FALSE) && (pn->down) && (pn->down->next == NULL) && (pn->down->down == NULL))
disallow_let_assignments = TRUE;
for (parse_node *p = pn->down; p; p = p->next)
statement_count = Routines__Compile__code_line(OUT, statement_count, p);
disallow_let_assignments = FALSE;
s_value_uncached_NTM->multiplicitous = m;
}
return statement_count;
}
int Routines__Compile__code_line(OUTPUT_STREAM, int statement_count, parse_node *p) {
Frames__Blocks__make_indentation_follow_code(OUT);
control_structure_phrase *csp = ParseTree__get_control_structure_used(p);
parse_node *to_compile = p;
if (Sentences__RuleSubtrees__opens_block(csp)) {
Frames__Blocks__beginning_block_phrase(OUT, csp);
to_compile = p->down;
}
statement_count++;
{
#line 180 "inform7/Chapter 31/Compile Phrases.w"
if (Wordings__nonempty(ParseTree__get_text(to_compile))) {
WRITE("! [%d: ", statement_count);
CompiledText__comment(OUT, ParseTree__get_text(to_compile));
WRITE("]\n");
}
}
#line 170 "inform7/Chapter 31/Compile Phrases.w"
;
{
#line 189 "inform7/Chapter 31/Compile Phrases.w"
if (csp == say_CSP) {
current_sentence = to_compile;
{
#line 197 "inform7/Chapter 31/Compile Phrases.w"
for (parse_node *say_node = p->down, *prev_sn = NULL; say_node; prev_sn = say_node, say_node = say_node->next) {
SParser__parse_say_term(say_node);
parse_node *inv = Invocations__first_in_list(say_node->down);
if (inv) {
if (prev_sn) {
if ((ParseTree__get_say_verb(inv)) ||
(ParseTree__get_say_adjective(inv)) ||
((Phrases__TypeData__is_a_say_phrase(ParseTree__get_phrase_invoked(inv))) &&
(ParseTree__get_phrase_invoked(inv)->type_data.as_say.say_phrase_running_on)))
ParseTree__annotate_int(prev_sn, suppress_newlines_ANNOT, TRUE);
}
}
}
WRITE("say__p=1;"); /* warn the paragraph breaker: this will print */
Routines__Compile__verify_say_node_list(p->down);
}
#line 191 "inform7/Chapter 31/Compile Phrases.w"
;
}
}
#line 171 "inform7/Chapter 31/Compile Phrases.w"
;
{
#line 216 "inform7/Chapter 31/Compile Phrases.w"
if (ParseTree__get_type(to_compile) == INVOCATION_LIST_SAY_NT)
{
#line 227 "inform7/Chapter 31/Compile Phrases.w"
BEGIN_COMPILATION_MODE;
if (ParseTree__int_annotation(to_compile, suppress_newlines_ANNOT))
COMPILATION_MODE_EXIT(IMPLY_NEWLINES_IN_SAY_CMODE);
Routines__Compile__line(OUT, to_compile, TRUE);
END_COMPILATION_MODE;
}
#line 216 "inform7/Chapter 31/Compile Phrases.w"
else if (csp == now_CSP)
{
#line 238 "inform7/Chapter 31/Compile Phrases.w"
current_sentence = to_compile;
wording XW = ParseTree__get_text(p->down);
parse_node *cs = NULL;
if (Preform__parse_nt_against_word_range(s_condition_NTM, XW, NULL, NULL)) cs = most_recent_result_p; else cs = Specifications__new_UNKNOWN(XW);
LOGIF(MATCHING, "Now cond is $T\n", cs);
int rv = Dash__check_condition(cs);
LOGIF(MATCHING, "After Dash, it's $T\n", cs);
if (ParseTree__is(cs, TEST_PROPOSITION_VNT)) {
if (rv != NEVER_MATCH) {
pcalc_prop *prop = Specifications__to_proposition(cs);
if (prop) {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(PERMIT_LOCALS_IN_TEXT_CMODE);
Calculus__Deferrals__compile_now_proposition(OUT, prop, TRUE);
END_COMPILATION_MODE;
}
}
} else if (ParseTree__is_condition(cs))
{
#line 264 "inform7/Chapter 31/Compile Phrases.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cs));
if (ParseTree__is(cs, TEST_VALUE_VNT)) {
Problems__Issue__handmade_problem(_p_(PM_BadNow1));
Problems__issue_problem_segment(
"You wrote %1, but although '%2' is a condition which it is legal "
"to test with 'if', 'when', and so forth, it is not something I "
"can arrange to happen on request. Whether it is true or not "
"depends on current circumstances: so to make it true, you will "
"need to adjust those circumstances.");
Problems__issue_problem_end();
} else if (ParseTree__is(cs, LOGICAL_AND_VNT)) {
Problems__Issue__handmade_problem(_p_(PM_BadNow2));
Problems__issue_problem_segment(
"You wrote %1, but 'now' does not work with the condition '%2' "
"because it can only make one wish come true at a time: so it "
"doesn't like the 'and'. Try rewriting as two 'now's in a row?");
Problems__issue_problem_end();
} else {
Problems__Issue__handmade_problem(_p_(PM_BadNow3));
Problems__issue_problem_segment(
"You wrote %1, but '%2' isn't the sort of condition which can be "
"made to be true, in the way that 'the ball is on the table' can be "
"made true with a straightforward movement of one object (the ball).");
Problems__issue_problem_end();
}
}
#line 257 "inform7/Chapter 31/Compile Phrases.w"
else if (rv != NEVER_MATCH)
{
#line 294 "inform7/Chapter 31/Compile Phrases.w"
LOG("$T\n", current_sentence);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cs));
Problems__Issue__handmade_problem(_p_(...));
Problems__issue_problem_segment(
"You wrote %1, but '%2' isn't a condition, so I can't see how to "
"make it true from here on.");
Problems__issue_problem_end();
}
#line 258 "inform7/Chapter 31/Compile Phrases.w"
;
WRITE("\n");
}
#line 217 "inform7/Chapter 31/Compile Phrases.w"
else if ((csp != say_CSP) && (csp != instead_CSP)) {
if (Preform__parse_nt_against_word_range(named_rulebook_outcome_NTM, ParseTree__get_text(to_compile), NULL, NULL))
{
#line 316 "inform7/Chapter 31/Compile Phrases.w"
current_sentence = to_compile;
named_rulebook_outcome *nrbo = most_recent_result_p;
if (phrase_being_compiled) {
int ram = Phrases__Usage__get_effect(&(phrase_being_compiled->usage_data));
if ((ram != RULE_IN_RULEBOOK_EFF) &&
(ram != RULE_NOT_IN_RULEBOOK_EFF)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(to_compile));
Problems__Issue__handmade_problem(_p_(PM_MisplacedRulebookOutcome2));
Problems__issue_problem_segment(
"You wrote %1, but this is a rulebook outcome which can only be used "
"within rulebooks which recognise it. You've used it in a definition "
"which isn't for use in rulebooks at all, so it must be wrong here.");
Problems__issue_problem_end();
}
}
rulebook *rb = Rulebooks__Outcomes__allow_outcome(nrbo);
if (rb) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(to_compile));
Problems__quote_wording(3, rb->primary_name);
Problems__Issue__handmade_problem(_p_(PM_MisplacedRulebookOutcome));
Problems__issue_problem_segment(
"You wrote %1, but this is a rulebook outcome which can only be used "
"within rulebooks which recognise it. You've used it in a rule which "
"has to be listed in the '%3' rulebook, where '%2' doesn't have a meaning.");
Problems__issue_problem_end();
}
Rulebooks__Outcomes__compile_outcome(OUT, nrbo);
WRITE("\n");
}
#line 220 "inform7/Chapter 31/Compile Phrases.w"
else
{
#line 350 "inform7/Chapter 31/Compile Phrases.w"
current_sentence = to_compile;
Routines__Compile__line(OUT, to_compile, FALSE);
WRITE("\n");
}
#line 221 "inform7/Chapter 31/Compile Phrases.w"
;
}
}
#line 172 "inform7/Chapter 31/Compile Phrases.w"
;
{
#line 357 "inform7/Chapter 31/Compile Phrases.w"
if (csp == if_CSP)
{
#line 366 "inform7/Chapter 31/Compile Phrases.w"
Frames__Blocks__open_code_block(OUT);
statement_count = Routines__Compile__code_block(OUT, statement_count, p->down->next, FALSE);
if (p->down->next->next) {
Frames__Blocks__divide_code_block(OUT);
WRITE("} else {\n");
statement_count = Routines__Compile__code_block(OUT, statement_count, p->down->next->next, FALSE);
}
Frames__Blocks__close_code_block(OUT);
}
#line 357 "inform7/Chapter 31/Compile Phrases.w"
else if (csp == switch_CSP)
{
#line 380 "inform7/Chapter 31/Compile Phrases.w"
Frames__Blocks__open_code_block(OUT);
kind *switch_kind = Frames__Blocks__switch_value_kind();
int pointery = FALSE;
if (Kinds__Behaviour__uses_pointer_values(switch_kind)) pointery = TRUE;
int c = 0;
for (parse_node *ow_node = p->down->next->next; ow_node; ow_node = ow_node->next, c++) {
current_sentence = ow_node;
Frames__Blocks__divide_code_block(OUT);
if (ow_node != p->down->next->next) WRITE(";\n");
if (ParseTree__get_control_structure_used(ow_node) == default_case_CSP) {
if (pointery == FALSE) WRITE("default:");
else {
if (c > 0) WRITE("} else ");
WRITE("{ ");
}
} else {
if (Preform__parse_nt_against_word_range(s_type_expression_or_value_NTM, ParseTree__get_text(ow_node), NULL, NULL)) {
parse_node *case_spec = most_recent_result_p;
case_spec = NonlocalVariables__substitute_constants(case_spec);
ParseTree__set_evaluation(ow_node, case_spec);
if (Dash__check_value(case_spec, NULL) != NEVER_MATCH) {
kind *case_kind = Specifications__to_kind(case_spec);
instance *I = Rvalues__to_object_instance(case_spec);
if (I) case_kind = Instances__to_kind(I);
LOGIF(MATCHING, "(h.3) switch kind is $u, case kind is $u\n", switch_kind, case_kind);
if ((ParseTree__get_kind_of_value(case_spec) == NULL) && (I == NULL)) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, switch_kind);
Problems__Issue__handmade_problem(_p_(PM_CaseValueNonConstant));
Problems__issue_problem_segment(
"The case %1 is required to be a constant value, rather than "
"something which has different values at different times: "
"specifically, it has to be %2.");
Problems__issue_problem_end();
case_spec = Rvalues__new_nothing_object_constant();
} else if (Kinds__Compare__compatible(case_kind, switch_kind) != ALWAYS_MATCH) {
Problems__quote_source(1, current_sentence);
Problems__quote_kind(2, case_kind);
Problems__quote_kind(3, switch_kind);
Problems__Issue__handmade_problem(_p_(PM_CaseValueMismatch));
Problems__issue_problem_segment(
"The case %1 has the wrong kind of value for the possibilities "
"being chosen from: %2 instead of %3.");
Problems__issue_problem_end();
case_spec = Rvalues__new_nothing_object_constant();
} else {
if (pointery) {
if (c > 0) { WRITE("} else "); }
WRITE("if (");
local_variable *lv = LocalVariables__by_name("sw_v");
LocalVariables__set_kind(lv, switch_kind);
parse_node *sw_v = Lvalues__new_LOCAL_VARIABLE(EMPTY_WORDING, lv);
pcalc_prop *prop = Calculus__Propositions__Abstract__to_set_relation(
R_equality, NULL, sw_v, NULL, case_spec);
Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_no_problem_reporting());
Calculus__Deferrals__compile_test_of_proposition(OUT, NULL, prop);
WRITE(") {");
} else {
Specifications__Compiler__compile(OUT, case_spec);
WRITE(":\n");
}
}
} else
{
#line 471 "inform7/Chapter 31/Compile Phrases.w"
Problems__Issue__sentence_problem(_p_(PM_CaseValueUnknown),
"I don't recognise this case value",
"that is, the value written after the '--'.");
}
#line 443 "inform7/Chapter 31/Compile Phrases.w"
} else
{
#line 471 "inform7/Chapter 31/Compile Phrases.w"
Problems__Issue__sentence_problem(_p_(PM_CaseValueUnknown),
"I don't recognise this case value",
"that is, the value written after the '--'.");
}
#line 444 "inform7/Chapter 31/Compile Phrases.w"
;
}
statement_count = Routines__Compile__code_block(OUT, statement_count, ow_node, FALSE);
}
if (pointery) WRITE("}\n");
Frames__Blocks__close_code_block(OUT);
if (problem_count == 0)
for (parse_node *A = p->down->next->next; A; A = A->next) {
int dup = FALSE;
for (parse_node *B = A->next; B; B = B->next)
if (Rvalues__compare_CONSTANT(
ParseTree__get_evaluation(A), ParseTree__get_evaluation(B)))
dup = TRUE;
if (dup) {
current_sentence = A;
Problems__quote_source(1, A);
Problems__quote_spec(2, ParseTree__get_evaluation(A));
Problems__Issue__handmade_problem(_p_(PM_CaseValueDuplicated));
Problems__issue_problem_segment(
"The case %1 occurs more than once in this 'if' switch.");
Problems__issue_problem_end();
}
}
}
#line 358 "inform7/Chapter 31/Compile Phrases.w"
else if (csp == say_CSP)
{
#line 483 "inform7/Chapter 31/Compile Phrases.w"
statement_count = Routines__Compile__code_block(OUT, statement_count, p, FALSE);
WRITE(" .");
JumpLabels__write(OUT, "Say");
JumpLabels__read_counter("Say", TRUE);
WRITE(";");
WRITE(" .");
JumpLabels__write(OUT, "SayX");
JumpLabels__read_counter("SayX", TRUE);
WRITE(";");
}
#line 359 "inform7/Chapter 31/Compile Phrases.w"
else if (csp == instead_CSP)
{
#line 496 "inform7/Chapter 31/Compile Phrases.w"
WRITE("rtrue;\n");
}
#line 360 "inform7/Chapter 31/Compile Phrases.w"
else if (Sentences__RuleSubtrees__opens_block(csp))
{
#line 501 "inform7/Chapter 31/Compile Phrases.w"
Frames__Blocks__open_code_block(OUT);
statement_count = Routines__Compile__code_block(OUT, statement_count, p->down->next, FALSE);
Frames__Blocks__close_code_block(OUT);
}
#line 361 "inform7/Chapter 31/Compile Phrases.w"
;
}
#line 173 "inform7/Chapter 31/Compile Phrases.w"
;
return statement_count;
}
#line 508 "inform7/Chapter 31/Compile Phrases.w"
void Routines__Compile__switch_head(OUTPUT_STREAM, parse_node *val) {
kind *key_kind = Specifications__to_kind(val);
if (Kinds__Behaviour__uses_pointer_values(key_kind)) {
LocalVariables__add_switch_value(key_kind);
WRITE("sw_v = ");
Specifications__Compiler__compile(OUT, val);
WRITE(";\nif (true) ");
} else {
WRITE("switch (");
Specifications__Compiler__compile(OUT, val);
WRITE(") ");
}
}
#line 526 "inform7/Chapter 31/Compile Phrases.w"
parse_node *void_phrase_please = NULL; /* instructions for the typechecker */
void Routines__Compile__line(OUTPUT_STREAM, parse_node *p, int already_parsed) {
int initial_problem_count = problem_count;
LOGIF(EXPRESSIONS, "\n-- -- Evaluating <$w> -- --\n", ParseTree__get_text(p));
LOGIF(EXPRESSIONS, "(a) Parsing:\n");
if (already_parsed) {
parse_node *inv = Invocations__first_in_list(p->down);
if ((inv) &&
(ParseTree__get_phrase_invoked(inv)) &&
(Phrases__TypeData__is_a_say_phrase(ParseTree__get_phrase_invoked(inv))) &&
(ParseTree__get_phrase_invoked(inv)->type_data.as_say.say_control_structure == NO_SAY_CS))
WRITE("ParaContent(); ");
} else {
SParser__parse_void_phrase(p);
}
if (initial_problem_count == problem_count) {
LOGIF(EXPRESSIONS, "(b) Type checking:\n$E", p->down);
Dash__check_invl(p);
}
if (initial_problem_count == problem_count) {
LOGIF(EXPRESSIONS, "(c) Compilation:\n$E", p->down);
Invocations__Compiler__compile_invocation_list(OUT,
p->down, ParseTree__get_text(p));
}
if (initial_problem_count == problem_count) {
LOGIF(EXPRESSIONS, "-- -- Completed -- --\n");
} else {
LOGIF(EXPRESSIONS, "-- -- Failed -- --\n");
}
}
#line 566 "inform7/Chapter 31/Compile Phrases.w"
parse_node *Routines__Compile__line_being_compiled(void) {
if (phrase_being_compiled) return current_sentence;
return NULL;
}
#line 601 "inform7/Chapter 31/Compile Phrases.w"
int Routines__Compile__verify_say_node_list(parse_node *say_node_list) {
int problem_issued = FALSE;
int say_invocations_found = 0;
{
#line 619 "inform7/Chapter 31/Compile Phrases.w"
int it_was_not_worth_adding = it_is_not_worth_adding;
it_is_not_worth_adding = TRUE;
int SSP_sp = 0;
int SSP_stack[MAX_COMPLEX_SAY_DEPTH];
int SSP_stack_otherwised[MAX_COMPLEX_SAY_DEPTH];
parse_node *SSP_invocations[MAX_COMPLEX_SAY_DEPTH];
int say_if_nesting = 0;
for (parse_node *say_node = say_node_list; say_node; say_node = say_node->next) {
parse_node *invl = say_node->down;
if (invl) {
parse_node *inv;
LOOP_THROUGH_INVOCATION_LIST(inv, invl) {
phrase *ph = ParseTree__get_phrase_invoked(inv);
if ((ParseTree__get_phrase_invoked(inv)) &&
(Phrases__TypeData__is_a_say_phrase(ph))) {
int say_cs, ssp_tok, ssp_ctok, ssp_pos;
Phrases__TypeData__get_say_data(&(ph->type_data.as_say),
&say_cs, &ssp_tok, &ssp_ctok, &ssp_pos);
if (ssp_pos == SSP_START)
{
#line 666 "inform7/Chapter 31/Compile Phrases.w"
if (SSP_sp >= MAX_COMPLEX_SAY_DEPTH) {
{
#line 780 "inform7/Chapter 31/Compile Phrases.w"
if (problem_issued == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_SayOverComplex),
"this is too complex a text substitution",
"and needs to be simplified. You might find it helful to define "
"a new text substitution of your own ('To say fiddly details: "
"...') and then use it in this text by including the '[fiddly details]'.");
problem_issued = TRUE;
}
}
#line 667 "inform7/Chapter 31/Compile Phrases.w"
;
} else {
SSP_invocations[SSP_sp] = inv;
SSP_stack_otherwised[SSP_sp] = FALSE;
SSP_stack[SSP_sp++] = ssp_tok;
}
}
#line 640 "inform7/Chapter 31/Compile Phrases.w"
;
if (ssp_pos == SSP_MIDDLE)
{
#line 677 "inform7/Chapter 31/Compile Phrases.w"
if ((SSP_sp > 0) && (SSP_stack[SSP_sp-1] != -1) &&
(compare_words(SSP_stack[SSP_sp-1], ssp_tok))) {
ParseTree__annotate_int(SSP_invocations[SSP_sp-1], ssp_segment_count_ANNOT,
ParseTree__int_annotation(SSP_invocations[SSP_sp-1], ssp_segment_count_ANNOT)+1);
ParseTree__annotate_int(inv, ssp_segment_count_ANNOT,
ParseTree__int_annotation(SSP_invocations[SSP_sp-1], ssp_segment_count_ANNOT));
} else
{
#line 735 "inform7/Chapter 31/Compile Phrases.w"
if (problem_issued == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(inv));
Problems__Issue__handmade_problem(_p_(PM_ComplicatedSayStructure));
Problems__issue_problem_segment(
"In the text at %1, the text substitution '[%2]' ought to occur as the "
"middle part of its construction, but it appears to be on its own.");
Routines__Compile__add_say_construction_to_error(ssp_tok);
Problems__issue_problem_end();
problem_issued = TRUE;
}
}
#line 683 "inform7/Chapter 31/Compile Phrases.w"
;
}
#line 641 "inform7/Chapter 31/Compile Phrases.w"
;
if (ssp_pos == SSP_END)
{
#line 688 "inform7/Chapter 31/Compile Phrases.w"
if ((SSP_sp > 0) && (SSP_stack[SSP_sp-1] != -1) &&
(compare_words(SSP_stack[SSP_sp-1], ssp_tok))) {
ParseTree__annotate_int(SSP_invocations[SSP_sp-1], ssp_segment_count_ANNOT,
ParseTree__int_annotation(SSP_invocations[SSP_sp-1], ssp_segment_count_ANNOT)+1);
ParseTree__annotate_int(SSP_invocations[SSP_sp-1], ssp_closing_segment_wn_ANNOT, ssp_ctok);
ParseTree__annotate_int(inv, ssp_segment_count_ANNOT,
ParseTree__int_annotation(SSP_invocations[SSP_sp-1], ssp_segment_count_ANNOT));
SSP_sp--;
} else
{
#line 750 "inform7/Chapter 31/Compile Phrases.w"
if (problem_issued == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(inv));
Problems__Issue__handmade_problem(_p_(PM_ComplicatedSayStructure2));
Problems__issue_problem_segment(
"In the text at %1, the text substitution '[%2]' ought to occur as the "
"ending part of its construction, but it appears to be on its own.");
Routines__Compile__add_say_construction_to_error(ssp_tok);
Problems__issue_problem_end();
problem_issued = TRUE;
}
}
#line 696 "inform7/Chapter 31/Compile Phrases.w"
;
}
#line 642 "inform7/Chapter 31/Compile Phrases.w"
;
if (say_cs == IF_SAY_CS)
{
#line 701 "inform7/Chapter 31/Compile Phrases.w"
if (say_if_nesting == 0) {
say_if_nesting++;
SSP_invocations[SSP_sp] = NULL;
SSP_stack_otherwised[SSP_sp] = FALSE;
SSP_stack[SSP_sp++] = -1;
} else
{
#line 765 "inform7/Chapter 31/Compile Phrases.w"
if (problem_issued == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_SayIfNested),
"a second '[if ...]' text substitution occurs inside an existing one",
"which makes this text too complicated. While a single text can contain "
"more than one '[if ...]', this can only happen if the old if is finished "
"with an '[end if]' or the new one is written '[otherwise if]'. If you "
"need more complicated variety than this allows, the best approach is "
"to define a new text substitution of your own ('To say fiddly details: "
"...') and then use it in this text by including the '[fiddly details]'.");
problem_issued = TRUE;
}
}
#line 706 "inform7/Chapter 31/Compile Phrases.w"
;
}
#line 644 "inform7/Chapter 31/Compile Phrases.w"
;
if ((say_cs == OTHERWISE_SAY_CS) || (say_cs == OTHERWISE_IF_SAY_CS))
{
#line 711 "inform7/Chapter 31/Compile Phrases.w"
if (say_if_nesting == 0)
{
#line 792 "inform7/Chapter 31/Compile Phrases.w"
if (problem_issued == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_SayOtherwiseWithoutIf),
"an '[otherwise]' text substitution occurs where there appears to be no "
"[if ...]",
"which doesn't make sense - there is nothing for it to be otherwise to.");
problem_issued = TRUE;
}
}
#line 712 "inform7/Chapter 31/Compile Phrases.w"
else if (SSP_sp > 0) {
if (SSP_stack[SSP_sp-1] != -1)
{
#line 803 "inform7/Chapter 31/Compile Phrases.w"
if (problem_issued == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(inv));
Problems__Issue__handmade_problem(_p_(PM_ComplicatedSayStructure5));
Problems__issue_problem_segment(
"In the text at %1, the '[%2]' ought to occur inside an [if ...], but "
"is cut off because it has been interleaved with a complicated say "
"construction.");
Routines__Compile__add_say_construction_to_error(SSP_stack[SSP_sp-1]);
Problems__issue_problem_end();
problem_issued = TRUE;
}
}
#line 715 "inform7/Chapter 31/Compile Phrases.w"
;
if (SSP_stack_otherwised[SSP_sp-1])
{
#line 819 "inform7/Chapter 31/Compile Phrases.w"
if (problem_issued == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_TwoSayOtherwises),
"there's already an (unconditional) \"[otherwise]\" or \"[else]\" "
"in this text substitution",
"so it doesn't make sense to follow that with a further one.");
problem_issued = TRUE;
}
}
#line 717 "inform7/Chapter 31/Compile Phrases.w"
if (say_cs == OTHERWISE_SAY_CS) SSP_stack_otherwised[SSP_sp-1] = TRUE;
}
}
#line 646 "inform7/Chapter 31/Compile Phrases.w"
;
if (say_cs == END_IF_SAY_CS)
{
#line 724 "inform7/Chapter 31/Compile Phrases.w"
if (say_if_nesting == 0)
{
#line 830 "inform7/Chapter 31/Compile Phrases.w"
if (problem_issued == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_SayEndIfWithoutSayIf),
"an '[end if]' text substitution occurs where there appears to be no "
"[if ...]",
"which doesn't make sense - there is nothing for it to end.");
problem_issued = TRUE;
}
}
#line 724 "inform7/Chapter 31/Compile Phrases.w"
else if ((SSP_sp > 0) && (SSP_stack[SSP_sp-1] != -1))
{
#line 841 "inform7/Chapter 31/Compile Phrases.w"
if (problem_issued == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(inv));
Problems__Issue__handmade_problem(_p_(PM_ComplicatedSayStructure4));
Problems__issue_problem_segment(
"In the text at %1, the '[%2]' is cut off from its [if ...], because "
"it has been interleaved with a complicated say construction.");
Routines__Compile__add_say_construction_to_error(SSP_stack[SSP_sp-1]);
Problems__issue_problem_end();
problem_issued = TRUE;
}
}
#line 726 "inform7/Chapter 31/Compile Phrases.w"
else {
say_if_nesting--;
SSP_sp--;
}
}
#line 647 "inform7/Chapter 31/Compile Phrases.w"
;
say_invocations_found++;
}
}
}
}
if (SSP_sp > 0) {
if ((SSP_sp == 1) && (SSP_stack[0] == -1)) {
/* an if without an end if, which uniquely is legal */
} else {
{
#line 856 "inform7/Chapter 31/Compile Phrases.w"
if (problem_issued == FALSE) {
parse_node *stinv = NULL;
int i, ssp_tok = -1;
for (i=0; i<SSP_sp; i++)
if (SSP_invocations[i]) {
stinv = SSP_invocations[i];
ssp_tok = SSP_stack[i];
}
if (stinv) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(stinv));
Problems__Issue__handmade_problem(_p_(PM_ComplicatedSayStructure3));
Problems__issue_problem_segment(
"In the text at %1, the text substitution '[%2]' seems to start a "
"complicated say construction, but it doesn't have a matching end.");
if (ssp_tok >= 0) Routines__Compile__add_say_construction_to_error(ssp_tok);
Problems__issue_problem_end();
problem_issued = TRUE;
}
}
}
#line 658 "inform7/Chapter 31/Compile Phrases.w"
;
}
}
it_is_not_worth_adding = it_was_not_worth_adding;
}
#line 604 "inform7/Chapter 31/Compile Phrases.w"
;
return say_invocations_found;
}
#line 880 "inform7/Chapter 31/Compile Phrases.w"
void Routines__Compile__add_say_construction_to_error(int ssp_tok) {
Problems__issue_problem_segment(" %P(The construction I'm thinking of is '");
Routines__Compile__add_scte_list(ssp_tok, SSP_START);
Problems__issue_problem_segment(" ... ");
Routines__Compile__add_scte_list(ssp_tok, SSP_MIDDLE);
Problems__issue_problem_segment(" ... ");
Routines__Compile__add_scte_list(ssp_tok, SSP_END);
Problems__issue_problem_segment("'.)");
}
void Routines__Compile__add_scte_list(int ssp_tok, int list_pos) {
phrase *ph; int ct = 0;
LOOP_OVER(ph, phrase) {
wording W;
if (Phrases__TypeData__ssp_matches(&(ph->type_data), ssp_tok, list_pos, &W)) {
Problems__quote_wording(3, W);
if (ct++ == 0) Problems__issue_problem_segment("[%3]");
else Problems__issue_problem_segment("/[%3]");
}
}
}
#line 89 "inform7/Chapter 32/Virtual Machines.w"
VM_identifier table_of_VM_data[] = {
{ Z_VM, -1, "z-machine", NULL, "zblorb", "Z-Machine", "vm_z.png", FALSE, 15, FALSE, "Parchment" },
{ Z_VM, 5*VMULT, NULL, "z5", "zblorb", "Z-Machine version 5", "vm_z5.png", FALSE, 15, FALSE, "Parchment" },
{ Z_VM, 6*VMULT, NULL, "z6", "zblorb", "Z-Machine version 6", "vm_z6.png", FALSE, 15, FALSE, "Parchment" },
{ Z_VM, 8*VMULT, NULL, "z8", "zblorb", "Z-Machine version 8", "vm_z8.png", FALSE, 15, FALSE, "Parchment" },
{ GLULX_VM, -1, "glulx", "ulx", "gblorb", "Glulx", "vm_glulx.png", TRUE, 256, FALSE, "Quixe" },
{ -1, 0, NULL, NULL, NULL, NULL, NULL, FALSE, 15, FALSE, "Parchment" }
};
#line 99 "inform7/Chapter 32/Virtual Machines.w"
#line 104 "inform7/Chapter 32/Virtual Machines.w"
int target_VM; /* an index in the above table, or -1 if unknown */
void VirtualMachines__set_identifier(char *file_extension) {
char lower_case_ext[32];
int i;
target_VM = -1;
if (file_extension == NULL) { target_VM = DEFAULT_TARGET_VM; return; }
if (file_extension[0] == '.') file_extension++;
strcpy(lower_case_ext, file_extension);
for (i=0; lower_case_ext[i]; i++) lower_case_ext[i] = Platform__tolower(lower_case_ext[i]);
for (i=0; table_of_VM_data[i].VM_code >= 0; i++)
if ((table_of_VM_data[i].VM_extension) &&
(strcmp(lower_case_ext, table_of_VM_data[i].VM_extension) == 0)) target_VM = i;
}
#line 123 "inform7/Chapter 32/Virtual Machines.w"
int VirtualMachines__is_16_bit(void) {
if (target_VM == -1) internal_error("target VM not set yet");
if (table_of_VM_data[target_VM].VM_is_32_bit) return FALSE;
return TRUE;
}
#line 133 "inform7/Chapter 32/Virtual Machines.w"
int VirtualMachines__allow_this_many_locals(int N) {
if (target_VM == -1) internal_error("target VM not set yet");
if ((table_of_VM_data[target_VM].max_locals >= 0) &&
(table_of_VM_data[target_VM].max_locals < N)) return FALSE;
return TRUE;
}
int VirtualMachines__allow_MAX_LOCAL_VARIABLES(void) {
if (target_VM == -1) internal_error("target VM not set yet");
if (table_of_VM_data[target_VM].max_locals > 15) return TRUE;
return FALSE;
}
#line 148 "inform7/Chapter 32/Virtual Machines.w"
int VirtualMachines__supports(kind *K) {
if (target_VM == -1) internal_error("target VM not set yet");
if ((Kinds__FloatingPoint__uses_floating_point(K)) &&
(table_of_VM_data[target_VM].VM_is_32_bit == FALSE)) return FALSE;
return TRUE;
}
#line 161 "inform7/Chapter 32/Virtual Machines.w"
char *VirtualMachines__get_blorbed_extension(void) {
if (target_VM == -1) internal_error("target VM not set yet");
return table_of_VM_data[target_VM].VM_blorbed_extension;
}
#line 171 "inform7/Chapter 32/Virtual Machines.w"
char *VirtualMachines__get_default_interpreter(void) {
if (target_VM == -1) internal_error("target VM not set yet");
return table_of_VM_data[target_VM].default_browser_interpreter;
}
#line 193 "inform7/Chapter 32/Virtual Machines.w"
int VM_matching_error_thrown = FALSE; /* an error occurred during parsing */
int most_recent_major_VM; /* most recent major VM which matched, or $-1$ */
int version_can_be_inferred; /* from earlier in the word range parsed */
void VirtualMachines__match_against(wording W) {
{
#line 207 "inform7/Chapter 32/Virtual Machines.w"
int i;
VM_matching_error_thrown = FALSE;
most_recent_major_VM = -1;
version_can_be_inferred = FALSE;
for (i=0; table_of_VM_data[i].VM_code >= 0; i++) table_of_VM_data[i].VM_matches = FALSE;
}
#line 198 "inform7/Chapter 32/Virtual Machines.w"
;
Preform__parse_nt_against_word_range(vm_description_list_NTM, W, NULL, NULL);
}
#line 222 "inform7/Chapter 32/Virtual Machines.w"
int vm_description_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 226 "inform7/Chapter 32/Virtual Machines.w"
int vm_description_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 230 "inform7/Chapter 32/Virtual Machines.w"
int vm_description_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 244 "inform7/Chapter 32/Virtual Machines.w"
{
#line 263 "inform7/Chapter 32/Virtual Machines.w"
int i;
for (i=0; table_of_VM_data[i].VM_code >= 0; i++)
if ((table_of_VM_data[i].VM_major_name) &&
(Text__compare_word_by_strcmp(Wordings__first_wn(W), table_of_VM_data[i].VM_major_name))) {
most_recent_major_VM = table_of_VM_data[i].VM_code;
version_can_be_inferred = FALSE;
W = Wordings__trim_first_word(W);
break;
}
}
#line 244 "inform7/Chapter 32/Virtual Machines.w"
;
{
#line 280 "inform7/Chapter 32/Virtual Machines.w"
if (most_recent_major_VM == -1) THROW_VM_MATCHING_ERROR_AND_RETURN;
}
#line 245 "inform7/Chapter 32/Virtual Machines.w"
;
if (Wordings__nonempty(W)) {
int version_specified = -1;
if (Preform__parse_nt_against_word_range(version_identification_NTM, W, NULL, NULL)) {
version_specified = VMULT * most_recent_result;
version_can_be_inferred = TRUE;
} else if ((version_can_be_inferred) && (Preform__parse_nt_against_word_range(cardinal_number_NTM, W, NULL, NULL))) {
version_specified = VMULT * most_recent_result;
} else THROW_VM_MATCHING_ERROR_AND_RETURN;
{
#line 297 "inform7/Chapter 32/Virtual Machines.w"
for (int i=0; table_of_VM_data[i].VM_code >= 0; i++)
if ((table_of_VM_data[i].VM_code == most_recent_major_VM) &&
(version_specified == table_of_VM_data[i].VM_version))
table_of_VM_data[i].VM_matches = TRUE;
}
#line 254 "inform7/Chapter 32/Virtual Machines.w"
;
} else {
{
#line 285 "inform7/Chapter 32/Virtual Machines.w"
for (int i=0; table_of_VM_data[i].VM_code >= 0; i++)
if (table_of_VM_data[i].VM_code == most_recent_major_VM)
table_of_VM_data[i].VM_matches = TRUE;
}
#line 256 "inform7/Chapter 32/Virtual Machines.w"
;
}
}
#line 232 "inform7/Chapter 32/Virtual Machines.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 233 "inform7/Chapter 32/Virtual Machines.w"
#line 238 "inform7/Chapter 32/Virtual Machines.w"
int version_identification_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 240 "inform7/Chapter 32/Virtual Machines.w"
#line 307 "inform7/Chapter 32/Virtual Machines.w"
int virtual_machine_NTMR(wording W, int *X, void **XP) {
#line 308 "inform7/Chapter 32/Virtual Machines.w"
if (target_VM == -1) internal_error("target VM not set yet");
VirtualMachines__match_against(W);
if (VM_matching_error_thrown) return FALSE;
if (table_of_VM_data[target_VM].VM_matches) *X = TRUE;
else *X = FALSE;
return TRUE;
}
#line 322 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__plot_icon(OUTPUT_STREAM, int minor) {
if (table_of_VM_data[minor].VM_image)
WRITE("<img border=0 src=inform:/doc_images/%s>&nbsp;",
table_of_VM_data[minor].VM_image);
}
void VirtualMachines__write_key(OUTPUT_STREAM) {
WRITE("Extensions compatible with specific story file formats only: ");
for (int i=0; table_of_VM_data[i].VM_code >= 0; i++) {
if (i>0) WRITE(", ");
VirtualMachines__plot_icon(OUT, i);
WRITE("%s", table_of_VM_data[i].VM_name);
}
WRITE("<p>");
}
#line 341 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__index_innards(void) {
VirtualMachines__write_current();
UseOptions__index();
INDEX("<p>");
Index__extra_link(3);
INDEX("See some technicalities for Inform maintainers only</p>");
Index__extra_div_open(3, 2, "e0e0e0");
Plugins__Manage__show_configuration(ifl);
INDEX("<p>Debugging log:</p><p>");
Log__paste_icons();
Index__extra_div_close("e0e0e0");
}
void VirtualMachines__write_current(void) {
if (target_VM == -1) internal_error("target VM not set yet");
Index__anchor("STORYFILE");
INDEX("<p>Story file format: ");
VirtualMachines__plot_icon(ifl, target_VM);
if (table_of_VM_data[target_VM].VM_name) INDEX(table_of_VM_data[target_VM].VM_name);
else INDEX("No name available\n");
INDEX("</p>");
if (VirtualMachines__is_16_bit()) {
INDEX("<p>"); Index__extra_link(1); INDEX("See estimates of memory usage</p>");
Index__extra_div_open(1, 1, "e0e0e0");
VirtualMachines__index_memory_usage();
Index__extra_div_close("e0e0e0");
}
}
#line 375 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__write_icons(OUTPUT_STREAM, wording W) {
VirtualMachines__match_against(W);
{
#line 389 "inform7/Chapter 32/Virtual Machines.w"
int everything_matches = TRUE;
for (int i=0; table_of_VM_data[i].VM_code >= 0; i++)
if (table_of_VM_data[i].VM_matches == FALSE)
everything_matches = FALSE;
if (everything_matches) return;
}
#line 377 "inform7/Chapter 32/Virtual Machines.w"
;
{
#line 401 "inform7/Chapter 32/Virtual Machines.w"
int every_Z_matches = TRUE;
for (int i=0; table_of_VM_data[i].VM_code >= 0; i++)
if ((table_of_VM_data[i].VM_code == Z_VM) &&
(table_of_VM_data[i].VM_matches == FALSE))
every_Z_matches = FALSE;
if (every_Z_matches)
{
#line 415 "inform7/Chapter 32/Virtual Machines.w"
for (int i=0; table_of_VM_data[i].VM_code >= 0; i++)
if (table_of_VM_data[i].VM_code == Z_VM) {
if (table_of_VM_data[i].VM_major_name) /* the major VM line for Z */
table_of_VM_data[i].VM_matches = TRUE;
else
table_of_VM_data[i].VM_matches = FALSE; /* one of the minor ones */
}
}
#line 407 "inform7/Chapter 32/Virtual Machines.w"
;
}
#line 378 "inform7/Chapter 32/Virtual Machines.w"
;
for (int i=0; table_of_VM_data[i].VM_code >= 0; i++)
if (table_of_VM_data[i].VM_matches)
VirtualMachines__plot_icon(OUT, i);
}
#line 430 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__note_usage(char *cat, wording W, char *name, int words, int bytes, int each) {
int b = bytes + words*((VirtualMachines__is_16_bit())?2:4);
if ((each == FALSE) && (b < NOTEWORTHY_USAGE_THRESHOLD)) return;
if (b == 0) return;
VM_usage_note *VMun = CREATE(VM_usage_note);
VMun->structure_name = W;
if (name)
Extensions__IDs__truncated_strcpy(VMun->usage_explained, name, MAX_USAGE_COLUMN_WIDTH);
else VMun->usage_explained[0] = 0;
VMun->usage_category = cat;
VMun->bytes_used = b;
VMun->each_flag = each;
}
#line 448 "inform7/Chapter 32/Virtual Machines.w"
void VirtualMachines__index_memory_usage(void) {
int nr = NUMBER_CREATED(VM_usage_note);
VM_usage_note **sorted = Memory__I7_calloc(nr, sizeof(VM_usage_note *), INDEX_SORTING_MREASON);
INDEX("<p>In a Z-machine story file, array memory can be very limited. "
"Switching to the Glulx setting removes all difficulty, but some authors "
"like to squeeze the very most out of the Z-machine instead. This "
"list shows about how much array space is used by some larger items "
"the source text has chosen to create.</p>");
{
#line 488 "inform7/Chapter 32/Virtual Machines.w"
int i = 0;
VM_usage_note *VMun;
LOOP_OVER(VMun, VM_usage_note) sorted[i++] = VMun;
qsort(sorted, (size_t) nr, sizeof(VM_usage_note *), VirtualMachines__compare_usage);
}
#line 456 "inform7/Chapter 32/Virtual Machines.w"
;
{
#line 465 "inform7/Chapter 32/Virtual Machines.w"
HTML__begin_plain_html_table(ifl);
int i;
VM_usage_note *VMun;
for (i=0; i<nr; i++) {
VMun = sorted[i];
HTML__first_html_column(ifl, 0);
INDEX("%s", VMun->usage_category);
HTML__next_html_column(ifl, 0);
if (VMun->each_flag) INDEX("each ");
if (VMun->usage_explained[0])
INDEX("%s", VMun->usage_explained);
else if (Wordings__first_wn(VMun->structure_name) >= 0)
Wordings__index(VMun->structure_name);
if (Wordings__first_wn(VMun->structure_name) >= 0) Index__link(Wordings__first_wn(VMun->structure_name));
HTML__next_html_column(ifl, 0);
INDEX("%d bytes", VMun->bytes_used);
HTML__end_html_row(ifl);
}
HTML__end_html_table(ifl);
}
#line 457 "inform7/Chapter 32/Virtual Machines.w"
;
Memory__I7_free(sorted, INDEX_SORTING_MREASON);
}
#line 497 "inform7/Chapter 32/Virtual Machines.w"
int VirtualMachines__compare_usage(const void *ent1, const void *ent2) {
const VM_usage_note *v1 = *((const VM_usage_note **) ent1);
const VM_usage_note *v2 = *((const VM_usage_note **) ent2);
if (v2->bytes_used != v1->bytes_used) return v2->bytes_used - v1->bytes_used;
return Wordings__first_wn(v1->structure_name) - Wordings__first_wn(v2->structure_name);
}
#line 517 "inform7/Chapter 32/Virtual Machines.w"
int next_free_resource_ID = 3;
int VirtualMachines__get_next_free_blorb_resource_ID(void) {
return next_free_resource_ID++;
}
#line 40 "inform7/Chapter 32/Inform 6 Inclusions.w"
int inclusion_side, section_inclusion_wn, segment_inclusion_wn;
#line 53 "inform7/Chapter 32/Inform 6 Inclusions.w"
int inform6_inclusion_location_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 69 "inform7/Chapter 32/Inform 6 Inclusions.w"
*X = SEGMENT_LEVEL_INC;
inclusion_side = R[1] - 1; segment_inclusion_wn = R[2];
}
#line 54 "inform7/Chapter 32/Inform 6 Inclusions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 75 "inform7/Chapter 32/Inform 6 Inclusions.w"
*X = SECTION_LEVEL_INC;
inclusion_side = R[1] - 1; section_inclusion_wn = R[2]; segment_inclusion_wn = R[3];
}
#line 55 "inform7/Chapter 32/Inform 6 Inclusions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = WHEN_DEFINING_INC; parse_node_s_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 81 "inform7/Chapter 32/Inform 6 Inclusions.w"
Problems__Issue__sentence_problem(_p_(PM_WhenDefiningUnknown),
"I do not understand what definition you're referring to",
"so I can't make an Inform 6 inclusion there.");
}
#line 57 "inform7/Chapter 32/Inform 6 Inclusions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 88 "inform7/Chapter 32/Inform 6 Inclusions.w"
Problems__Issue__sentence_problem(_p_(PM_BeforeTheLibrary),
"this syntax was withdrawn in January 2008",
"in favour of a more finely controlled I6 inclusion command. The effect "
"you want can probably be achieved by writing 'after \"Definitions.i6t\".' "
"instead of 'before the library.'");
}
#line 58 "inform7/Chapter 32/Inform 6 Inclusions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = AS_PREFORM_INC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 60 "inform7/Chapter 32/Inform 6 Inclusions.w"
int inclusion_side_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 65 "inform7/Chapter 32/Inform 6 Inclusions.w"
#line 99 "inform7/Chapter 32/Inform 6 Inclusions.w"
sentence_handler INFORM6CODE_SH_handler =
{ INFORM6CODE_NT, -1, 2, Config__Inclusions__inform_6_inclusion };
void Config__Inclusions__inform_6_inclusion(parse_node *PN) {
current_sentence = PN;
wording IW = ParseTree__get_text(PN);
/* skip to the instructions */
IW = Wordings__trim_first_word(Wordings__trim_first_word(Wordings__trim_first_word(IW)));
if (Wordings__empty(IW))
{
#line 137 "inform7/Chapter 32/Inform 6 Inclusions.w"
TemplateFiles__new_intervention(1, "Output.i6t", "I6 Inclusions",
(unsigned char *) Lexer__word_raw_text(Wordings__first_wn(ParseTree__get_text(PN)) + 2), NULL);
return;
}
#line 108 "inform7/Chapter 32/Inform 6 Inclusions.w"
;
int problem = TRUE;
if (Preform__parse_nt_against_word_range(inform6_inclusion_location_NTM, IW, NULL, NULL)) {
problem = FALSE;
switch (most_recent_result) {
case SEGMENT_LEVEL_INC:
{
#line 144 "inform7/Chapter 32/Inform 6 Inclusions.w"
Text__dequote_word(segment_inclusion_wn);
TemplateFiles__new_intervention(
inclusion_side, Lexer__word_text(segment_inclusion_wn), NULL,
(unsigned char *) Lexer__word_raw_text(Wordings__first_wn(ParseTree__get_text(PN)) + 2), NULL);
}
#line 114 "inform7/Chapter 32/Inform 6 Inclusions.w"
; break;
case SECTION_LEVEL_INC:
{
#line 152 "inform7/Chapter 32/Inform 6 Inclusions.w"
Text__dequote_word(section_inclusion_wn);
Text__dequote_word(segment_inclusion_wn);
TemplateFiles__new_intervention(
inclusion_side, Lexer__word_text(segment_inclusion_wn),
Lexer__word_text(section_inclusion_wn),
(unsigned char *) Lexer__word_raw_text(Wordings__first_wn(ParseTree__get_text(PN)) + 2), NULL);
}
#line 116 "inform7/Chapter 32/Inform 6 Inclusions.w"
; break;
case WHEN_DEFINING_INC:
{
#line 163 "inform7/Chapter 32/Inform 6 Inclusions.w"
parse_node *spec = parse_node_s_NTMV;
inference_subject *infs = InferenceSubjects__from_specification(spec);
if (infs) {
i6_inclusion_matter *inclm = CREATE(i6_inclusion_matter);
inclm->material_to_include = PN;
inclm->infs_to_include_with = infs;
} else problem = TRUE;
}
#line 118 "inform7/Chapter 32/Inform 6 Inclusions.w"
; break;
case AS_PREFORM_INC: return;
}
}
if (problem)
{
#line 174 "inform7/Chapter 32/Inform 6 Inclusions.w"
Problems__Issue__sentence_problem(_p_(PM_BadI6Inclusion),
"this is not a form of I6 code inclusion I recognise",
"because the clause at the end telling me where to put the code "
"excerpt is not one of the possibilities I know. The clause can "
"either be blank (in which case I'll find somewhere sensible to "
"put it), or 'when defining' plus the name of an object or kind "
"of object, or 'before', 'instead of' or 'after' a double-quoted "
"name of a template layer segment, or of a part of one. For "
"instance, 'before \"Parser.i6t\".' or 'after \"Pronouns\" in "
"\"Language.i6t\".'");
}
#line 122 "inform7/Chapter 32/Inform 6 Inclusions.w"
;
}
#line 189 "inform7/Chapter 32/Inform 6 Inclusions.w"
void Config__Inclusions__compile_inclusions_for_subject(OUTPUT_STREAM, inference_subject *infs) {
i6_inclusion_matter *inclm;
LOOP_OVER (inclm, i6_inclusion_matter)
if (inclm->infs_to_include_with == infs) {
TemplateFiles__interpret(OUT,
(unsigned char *) Lexer__word_raw_text(Wordings__first_wn(ParseTree__get_text(inclm->material_to_include)) + 2), NULL, -1);
WRITE("\n");
}
}
#line 72 "inform7/Chapter 32/Use Options.w"
sentence_handler USEMEANS_SH_handler =
{ SENTENCE_NT, USEMEANS_VB, 1, UseOptions__new_use_option };
void UseOptions__new_use_option(parse_node *p) {
if ((Preform__parse_nt_against_word_range(use_translates_as_sentence_object_NTM, ParseTree__get_text(p->down->next->next), NULL, NULL)) &&
(Preform__parse_nt_against_word_range(use_sentence_object_NTM, ParseTree__get_text(p->down->next), NULL, NULL))) {
wording OW = GET_RW(use_sentence_object_NTM, 1);
use_option *uo = CREATE(use_option);
uo->name = OW;
uo->option_expansion = p->down->next->next;
uo->option_used = FALSE;
if (most_recent_result > 0) uo->minimum_setting_value = most_recent_result;
else uo->minimum_setting_value = -1;
uo->source_file_scoped = FALSE;
if ((Preform__parse_nt_against_word_range(notable_use_option_name_NTM, OW, NULL, NULL)) && (most_recent_result == AUTHORIAL_MODESTY_UO))
uo->source_file_scoped = TRUE;
Semantics__Nouns__ExcerptMeanings__register_noun(
MISCELLANEOUS_MC, OW, Rvalues__from_use_option(uo));
}
}
#line 96 "inform7/Chapter 32/Use Options.w"
int use_translates_as_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 103 "inform7/Chapter 32/Use Options.w"
*X = FALSE;
Problems__Issue__sentence_problem(_p_(PM_UseTranslatesNotI6),
"that translates into something which isn't a simple I6 inclusion",
"placed in '(-' and '-)' markers.");
}
#line 98 "inform7/Chapter 32/Use Options.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 99 "inform7/Chapter 32/Use Options.w"
#line 112 "inform7/Chapter 32/Use Options.w"
use_option *UseOptions__parse_uo(wording OW) {
parse_node *p = SParser__parse_excerpt(MISCELLANEOUS_MC, OW);
if (Rvalues__is_CONSTANT_of_kind(p, K_use_option)) {
return Rvalues__to_use_option(p);
}
return NULL;
}
#line 129 "inform7/Chapter 32/Use Options.w"
int use_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = -R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 134 "inform7/Chapter 32/Use Options.w"
#line 140 "inform7/Chapter 32/Use Options.w"
int notable_use_option_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 153 "inform7/Chapter 32/Use Options.w"
#line 172 "inform7/Chapter 32/Use Options.w"
sentence_handler USE_SH_handler =
{ SENTENCE_NT, USE_VB, 0, UseOptions__handle_set_use_option };
void UseOptions__handle_set_use_option(parse_node *p) {
UseOptions__set_use_options(p->down->next);
}
void UseOptions__set_use_options(parse_node *p) {
if (ParseTree__get_type(p) == AND_NT) {
UseOptions__set_use_options(p->down);
UseOptions__set_use_options(p->down->next);
return;
}
if (Preform__parse_nt_against_word_range(use_sentence_object_NTM, ParseTree__get_text(p), NULL, NULL))
{
#line 196 "inform7/Chapter 32/Use Options.w"
int min_setting = -1;
if (most_recent_result < 0)
{
#line 234 "inform7/Chapter 32/Use Options.w"
int n = -most_recent_result, w1 = Wordings__first_wn(ParseTree__get_text(p));
i6_memory_setting *ms;
LOOP_OVER(ms, i6_memory_setting)
if (Text__compare_raw_word_by_strcmp(w1, ms->ICL_identifier)) {
if (ms->number < n) ms->number = n;
return;
}
ms = CREATE(i6_memory_setting);
if (Platform__strlen(Lexer__word_raw_text(w1)) > 63) {
Problems__Issue__sentence_problem(_p_(PM_BadICLIdentifier),
"that is too long to be an ICL identifier",
"so can't be the name of any I6 memory setting.");
} else strcpy(ms->ICL_identifier, Lexer__word_raw_text(w1));
ms->number = n;
return;
}
#line 197 "inform7/Chapter 32/Use Options.w"
;
if (most_recent_result > 0) min_setting = most_recent_result;
wording OW = GET_RW(use_sentence_object_NTM, 1);
use_option *uo = UseOptions__parse_uo(OW);
if (uo) {
extension_file *ef = NULL;
{
#line 221 "inform7/Chapter 32/Use Options.w"
if (uo->minimum_setting_value == -1) {
if (min_setting != -1)
Problems__Issue__sentence_problem(_p_(PM_UONotNumerical),
"that 'Use' option does not have a numerical setting",
"but is either used or not used.");
} else {
if (min_setting >= uo->minimum_setting_value)
uo->minimum_setting_value = min_setting;
}
}
#line 203 "inform7/Chapter 32/Use Options.w"
;
if (uo->source_file_scoped) {
ef = SourceFiles__get_extension_corresponding(Lexer__file_of_origin(Wordings__first_wn(OW)));
if (ef == NULL) { /* that is, if used in the main source text */
uo->option_used = TRUE;
uo->where_used = current_sentence;
}
} else {
uo->option_used = TRUE;
uo->where_used = current_sentence;
}
UseOptions__set_immediate_option_flags(OW, uo);
return;
}
}
#line 185 "inform7/Chapter 32/Use Options.w"
;
if (traverse == 1) return;
LOG("Used: $w\n", ParseTree__get_text(p));
Problems__Issue__sentence_problem(_p_(PM_UnknownUseOption),
"that isn't a 'Use' option known to me",
"and needs to be one of the ones listed in the documentation.");
}
#line 253 "inform7/Chapter 32/Use Options.w"
use_option *uo_being_set = NULL;
void UseOptions__set_immediate_option_flags(wording W, use_option *uo) {
uo_being_set = uo;
Preform__parse_nt_against_word_range(immediate_use_NTM, W, NULL, NULL);
}
#line 265 "inform7/Chapter 32/Use Options.w"
int immediate_use_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 269 "inform7/Chapter 32/Use Options.w"
int immediate_use_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 273 "inform7/Chapter 32/Use Options.w"
int immediate_use_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 281 "inform7/Chapter 32/Use Options.w"
switch (R[1]) {
case AUTHORIAL_MODESTY_UO: {
extension_file *ef =
SourceFiles__get_extension_corresponding(
Lexer__file_of_origin(Wordings__first_wn(W)));
if (ef == NULL) Extensions__Files__set_general_authorial_modesty();
else Extensions__Files__set_authorial_modesty(ef);
break;
}
case DYNAMIC_MEMORY_ALLOCATION_UO:
if (uo_being_set) dynamic_memory_allocation = uo_being_set->minimum_setting_value;
break;
case MEMORY_ECONOMY_UO: memory_economy_in_force = TRUE; break;
case NO_DEPRECATED_FEATURES_UO: no_deprecated_features = TRUE; break;
case NUMBERED_RULES_UO: Rules__set_numbered_rules(); break;
case TELEMETRY_RECORDING_UO: telemetry_recording = TRUE; break;
case SCORING_UO: scoring_option_set = TRUE; break;
case NO_SCORING_UO: scoring_option_set = FALSE; break;
case ENGINEERING_NOTATION_UO: allow_engineering_notation = TRUE; break;
case UNABBREVIATED_OBJECT_NAMES_UO: use_exact_parsing_option = TRUE; break;
case INDEX_FIGURE_THUMBNAILS_UO:
if (uo_being_set) index_figure_thumbnails = uo_being_set->minimum_setting_value;
break;
case GN_TESTING_VERSION_UO:
break;
}
}
#line 275 "inform7/Chapter 32/Use Options.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 277 "inform7/Chapter 32/Use Options.w"
#line 313 "inform7/Chapter 32/Use Options.w"
int UseOptions__get_dynamic_memory_allocation(void) {
return dynamic_memory_allocation;
}
#line 320 "inform7/Chapter 32/Use Options.w"
int UseOptions__get_index_figure_thumbnails(void) {
return index_figure_thumbnails;
}
#line 328 "inform7/Chapter 32/Use Options.w"
int UseOptions__uo_set_from(use_option *uo, int category, extension_file *ef) {
source_file *sf = (uo->where_used)?(Lexer__file_of_origin(Wordings__first_wn(ParseTree__get_text(uo->where_used)))):NULL;
extension_file *efo = (sf)?(SourceFiles__get_extension_corresponding(sf)):NULL;
switch (category) {
case 1: if ((sf) && (efo == NULL)) return TRUE; break;
case 2: if (sf == NULL) return TRUE; break;
case 3: if ((sf) && (efo == ef)) return TRUE; break;
}
return FALSE;
}
#line 347 "inform7/Chapter 32/Use Options.w"
void UseOptions__compile(OUTPUT_STREAM) {
use_option *uo;
LOOP_OVER(uo, use_option)
if ((uo->option_used) || (uo->minimum_setting_value >= 0)) {
WRITE("! Use option:\n");
TemplateFiles__interpret(OUT,
(unsigned char *) Lexer__word_raw_text(Wordings__first_wn(ParseTree__get_text(uo->option_expansion)) + 1),
NULL, uo->minimum_setting_value);
WRITE("\n");
}
if (existing_story_file) {
WRITE("#IFNDEF MEMORY_ECONOMY; Constant MEMORY_ECONOMY true; #ENDIF;\n");
}
}
#line 366 "inform7/Chapter 32/Use Options.w"
void UseOptions__compile_icl_commands(OUTPUT_STREAM) {
WRITE("!%% -s\n");
i6_memory_setting *ms;
LOOP_OVER(ms, i6_memory_setting) {
if ((strcmp(ms->ICL_identifier, "MAX_LOCAL_VARIABLES") == 0) &&
(VirtualMachines__allow_MAX_LOCAL_VARIABLES() == FALSE))
continue;
WRITE("!%% $%s=%d\n", ms->ICL_identifier, ms->number);
}
}
#line 384 "inform7/Chapter 32/Use Options.w"
void UseOptions__index(void) {
INDEX("<p>The following use options are in force:</p>");
UseOptions__index_options_in_force_from(MAIN_TEXT_UO_ORIGIN, NULL);
UseOptions__index_options_in_force_from(OPTIONS_FILE_UO_ORIGIN, NULL);
extension_file *ef;
LOOP_OVER(ef, extension_file) UseOptions__index_options_in_force_from(EXTENSION_UO_ORIGIN, ef);
int nt = 0;
use_option *uo;
LOOP_OVER(uo, use_option) {
if (uo->source_file_scoped) continue;
if ((uo->option_used == FALSE) && (uo->minimum_setting_value < 0)) nt++;
}
if (nt > 0) {
INDEX("<p>Whereas these are not in force:</p>");
HTML__open_para(ifl, 2, "tight");
LOOP_OVER(uo, use_option) {
if (uo->source_file_scoped) continue;
if ((uo->option_used == FALSE) && (uo->minimum_setting_value < 0)) {
{
#line 413 "inform7/Chapter 32/Use Options.w"
INDEX("<span style=\"white-space:nowrap\";>");
TEMPORARY_STREAM;
WRITE_TO(TEMP, "Use ");
Wordings__to_stream_raw(TEMP, uo->name);
WRITE_TO(TEMP, ".");
HTML__Javascript__paste(ifl, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
INDEX("&nbsp;");
Wordings__index_raw(uo->name);
INDEX("</span>");
}
#line 402 "inform7/Chapter 32/Use Options.w"
;
if (--nt > 0) INDEX(", ");
}
}
INDEX("</p>");
}
}
#line 427 "inform7/Chapter 32/Use Options.w"
void UseOptions__index_options_in_force_from(int category, extension_file *ef) {
int N = 0;
use_option *uo;
LOOP_OVER(uo, use_option) {
if (uo->source_file_scoped) continue;
if ((uo->option_used) && (uo->minimum_setting_value < 0) &&
(UseOptions__uo_set_from(uo, category, ef))) {
if (N++ == 0)
{
#line 451 "inform7/Chapter 32/Use Options.w"
HTML__open_para(ifl, 2, "tight");
INDEX("<font color=\"#888\">Set from ");
switch (category) {
case MAIN_TEXT_UO_ORIGIN:
INDEX("the source text"); break;
case OPTIONS_FILE_UO_ORIGIN:
INDEX("the Options.txt configuration file");
Index__DocReferences__link("OPTIONSFILE"); break;
case EXTENSION_UO_ORIGIN:
if (ef == standard_rules_extension) INDEX("the ");
else INDEX("the extension ");
Wordings__index_raw(ef->title_text);
break;
}
INDEX(":</font></p>");
}
#line 434 "inform7/Chapter 32/Use Options.w"
;
{
#line 470 "inform7/Chapter 32/Use Options.w"
HTML__open_para(ifl, 3, "tight");
INDEX("Use ");
Wordings__index_raw(uo->name);
if (uo->minimum_setting_value >= 0) INDEX(" of at least %d", uo->minimum_setting_value);
if (uo->where_used) Index__link(Wordings__first_wn(ParseTree__get_text(uo->where_used)));
if (uo->minimum_setting_value >= 0) {
INDEX("&nbsp;");
TEMPORARY_STREAM;
WRITE_TO(TEMP, "Use ");
Wordings__to_stream_raw(TEMP, uo->name);
WRITE_TO(TEMP, " of at least %d.", 2*(uo->minimum_setting_value));
HTML__Javascript__paste(ifl, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
INDEX("&nbsp;<i>Double this</i>");
}
INDEX("</p>");
}
#line 435 "inform7/Chapter 32/Use Options.w"
;
}
}
LOOP_OVER(uo, use_option) {
if (uo->source_file_scoped) continue;
if (((uo->option_used) && (uo->minimum_setting_value >= 0)) &&
(UseOptions__uo_set_from(uo, category, ef))) {
if (N++ == 0)
{
#line 451 "inform7/Chapter 32/Use Options.w"
HTML__open_para(ifl, 2, "tight");
INDEX("<font color=\"#888\">Set from ");
switch (category) {
case MAIN_TEXT_UO_ORIGIN:
INDEX("the source text"); break;
case OPTIONS_FILE_UO_ORIGIN:
INDEX("the Options.txt configuration file");
Index__DocReferences__link("OPTIONSFILE"); break;
case EXTENSION_UO_ORIGIN:
if (ef == standard_rules_extension) INDEX("the ");
else INDEX("the extension ");
Wordings__index_raw(ef->title_text);
break;
}
INDEX(":</font></p>");
}
#line 442 "inform7/Chapter 32/Use Options.w"
;
{
#line 470 "inform7/Chapter 32/Use Options.w"
HTML__open_para(ifl, 3, "tight");
INDEX("Use ");
Wordings__index_raw(uo->name);
if (uo->minimum_setting_value >= 0) INDEX(" of at least %d", uo->minimum_setting_value);
if (uo->where_used) Index__link(Wordings__first_wn(ParseTree__get_text(uo->where_used)));
if (uo->minimum_setting_value >= 0) {
INDEX("&nbsp;");
TEMPORARY_STREAM;
WRITE_TO(TEMP, "Use ");
Wordings__to_stream_raw(TEMP, uo->name);
WRITE_TO(TEMP, " of at least %d.", 2*(uo->minimum_setting_value));
HTML__Javascript__paste(ifl, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
INDEX("&nbsp;<i>Double this</i>");
}
INDEX("</p>");
}
#line 443 "inform7/Chapter 32/Use Options.w"
;
}
}
}
#line 492 "inform7/Chapter 32/Use Options.w"
void UseOptions__TestUseOption_routine(OUTPUT_STREAM) {
WRITE("Constant NO_USE_OPTIONS = %d;\n", NUMBER_CREATED(use_option));
{
#line 501 "inform7/Chapter 32/Use Options.w"
OUT = Routines__begin(OUT, "TestUseOption");
LocalVariables__add_named_call("UO");
use_option *uo;
LOOP_OVER(uo, use_option)
if ((uo->option_used) || (uo->minimum_setting_value >= 0))
WRITE("if (UO == %d) rtrue;\n", uo->allocation_id);
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
}
#line 494 "inform7/Chapter 32/Use Options.w"
;
{
#line 513 "inform7/Chapter 32/Use Options.w"
OUT = Routines__begin(OUT, "PrintUseOption");
LocalVariables__add_named_call("UO");
WRITE("switch(UO) {\n"); INDENT;
use_option *uo;
LOOP_OVER(uo, use_option) {
WRITE("%d: print \"", uo->allocation_id);
Wordings__to_stream_raw_within_i6_literal(OUT, uo->name);
WRITE(" option");
if (uo->minimum_setting_value > 0) WRITE(" [%d]", uo->minimum_setting_value);
WRITE("\";\n");
}
OUTDENT; WRITE("}\n");
OUT = Routines__end(OUT);
}
#line 495 "inform7/Chapter 32/Use Options.w"
;
}
#line 35 "inform7/Chapter 32/List Together.w"
void ListTogether__new(OUTPUT_STREAM, int include_articles) {
list_together_routine *ltr = CREATE(list_together_routine);
ltr->articles_bit = include_articles;
WRITE("LTR_%d", ltr->allocation_id);
}
#line 49 "inform7/Chapter 32/List Together.w"
list_together_routine *latest_ltr_compiled = NULL;
int ListTogether__compilation_coroutine(OUTPUT_STREAM) {
int N = 0;
while (TRUE) {
list_together_routine *ltr = FIRST_OBJECT(list_together_routine);
if (latest_ltr_compiled)
ltr = NEXT_OBJECT(latest_ltr_compiled, list_together_routine);
if (ltr == NULL) break;
{
#line 68 "inform7/Chapter 32/List Together.w"
WRITE("Array LTR_%d --> CONSTANT_PACKED_TEXT_STORAGE LTR_%d_R;\n",
ltr->allocation_id, ltr->allocation_id);
OUT = Routines__begin_numbered(OUT, "LTR_%d_R", ltr->allocation_id);
WRITE("if (inventory_stage == 1) {\n"); INDENT;
if (ltr->articles_bit)
WRITE("c_style = c_style | (ENGLISH_BIT);\n");
else
WRITE("c_style = c_style | (ENGLISH_BIT + NOARTICLE_BIT);\n");
WRITE("c_style = c_style &~ (NEWLINE_BIT + INDENT_BIT);\n");
OUTDENT; WRITE("}\n");
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
}
#line 58 "inform7/Chapter 32/List Together.w"
;
latest_ltr_compiled = ltr;
N++;
}
return N;
}
#line 42 "inform7/Chapter 32/Jump Labels.w"
label_namespace *JumpLabels__new_namespace(char *name) {
label_namespace *lns;
int i;
if (Platform__strlen(name) > MAX_NAMESPACE_PREFIX_LENGTH)
Problems__Issue__sentence_problem(_p_(PM_LabelNamespaceTooLong),
"a label namespace prefix is too long",
"and should be shortened to a few alphabetic characters.");
lns = CREATE(label_namespace);
for (i=0; (name[i]) && (i<MAX_NAMESPACE_PREFIX_LENGTH); i++)
lns->label_prefix[i] = name[i];
lns->label_prefix[i] = 0;
lns->label_counter = 0;
lns->allocate_storage = 0;
return lns;
}
#line 64 "inform7/Chapter 32/Jump Labels.w"
label_namespace *JumpLabels__namespace_by_prefix(char *name) {
label_namespace *lns;
LOOP_OVER(lns, label_namespace)
if (strcmp(name, lns->label_prefix) == 0)
return lns;
return NULL;
}
label_namespace *JumpLabels__read_or_create_namespace(char *name) {
label_namespace *lns = JumpLabels__namespace_by_prefix(name);
if (lns == NULL) lns = JumpLabels__new_namespace(name);
return lns;
}
#line 83 "inform7/Chapter 32/Jump Labels.w"
int JumpLabels__read_counter(char *namespace, int advance_flag) {
label_namespace *lns = JumpLabels__read_or_create_namespace(namespace);
int c = lns->label_counter;
if (advance_flag == TRUE) lns->label_counter++;
if (advance_flag == FALSE) {
lns->label_counter--;
if (lns->label_counter < 0) internal_error("label counter negative");
}
return c;
}
void JumpLabels__write(OUTPUT_STREAM, char *namespace) {
label_namespace *lns = JumpLabels__read_or_create_namespace(namespace);
WRITE("L_%s%d", lns->label_prefix, lns->label_counter);
}
#line 108 "inform7/Chapter 32/Jump Labels.w"
void JumpLabels__allocate_counter(char *namespace, int multiplier) {
label_namespace *lns = JumpLabels__read_or_create_namespace(namespace);
if (multiplier > lns->allocate_storage) lns->allocate_storage = multiplier;
}
void JumpLabels__compile_necessary_storage(OUTPUT_STREAM) {
label_namespace *lns;
LOOP_OVER(lns, label_namespace)
if (lns->allocate_storage > 0)
WRITE("Array I7_ST_%s --> %d;\n",
lns->label_prefix, (lns->allocate_storage)*(lns->label_counter)+2);
}
#line 14 "inform7/Chapter 32/Identifiers.w"
int Identifiers__valid(char *p) {
if ((Platform__strlen(p) == 0) || (Platform__strlen(p) > 31)) return FALSE;
for (int i=0; p[i]; i++)
if ((isdigit(p[i]) == 0) && (isalpha(p[i]) == 0) && (p[i] != '_'))
return FALSE;
if (isdigit(p[0])) return FALSE;
return TRUE;
}
#line 40 "inform7/Chapter 32/Identifiers.w"
void Identifiers__compose(char *ledger, char nature_character, int id_number, wording W) {
char identifier[64];
sprintf(identifier, "%c%d", nature_character, id_number);
if (Wordings__nonempty(W)) {
LOOP_THROUGH_WORDING(j, W) {
/* identifier is at this point 32 chars or fewer in length: add at most 30 more */
if (Platform__strlen(Lexer__word_text(j)) > 30)
sprintf(identifier + Platform__strlen(identifier), " etc");
else sprintf(identifier + Platform__strlen(identifier), " %s", Lexer__word_text(j));
if (Platform__strlen(identifier) > 32) break;
}
}
identifier[28] = 0; /* it was at worst 62 chars in size, but is now truncated to 28 */
Identifiers__purify(identifier);
strcpy(ledger, identifier);
}
#line 60 "inform7/Chapter 32/Identifiers.w"
void Identifiers__purify(char *identifier) {
int j;
for (j=0; identifier[j]; j++) {
int x = identifier[j];
if (!(((x >= '0') && (x <= '9')) ||
((x >= 'a') && (x <= 'z')) || ((x >= 'A') && (x <= 'Z')) || (x == '_')))
identifier[j] = '_';
}
}
#line 38 "inform7/Chapter 32/Dictionary Words.w"
void DictionaryWords__compile(OUTPUT_STREAM, char *p, int pluralise) {
int c, n = 0;
WRITE("'");
for (c=0; p[c] != 0; c++) {
switch(p[c]) {
case '/': if (p[1] == 0) WRITE("@{2F}"); else WRITE("/"); break;
case '\'': WRITE("^"); break;
case '^': WRITE("@{5E}"); break;
case '~': WRITE("@{7E}"); break;
case '@': WRITE("@{40}"); break;
default: WRITE("%c", p[c]);
}
if (n++ > 32) break;
}
if (pluralise) WRITE("//p");
else if (Platform__strlen(p) == 1) WRITE("//");
WRITE("'");
}
#line 35 "inform7/Chapter 32/Compiled Text.w"
void CompiledText__from_ISO_string(OUTPUT_STREAM, char *p, int options) {
int i, from = 0, to = Platform__strlen(p), esc_digit = FALSE;
if ((options & CT_DEQUOTE) && (p[0] == '"') && (p[to-1] == '"')) {
from++; to--;
}
if (options & CT_RAW) {
for (i=from; i<to; i++) {
if ((i == from) && (options & CT_CAPITALISE))
WRITE("%c", Platform__toupper(p[i]));
else
WRITE("%c", p[i]);
}
} else {
for (i=from; i<to; i++) {
switch(p[i]) {
case '\n':
if (options & CT_BOX_QUOTATION) WRITE("\"\n\"");
else WRITE(" ");
break;
case '\t':
if (options & CT_BOX_QUOTATION) WRITE("\"\n\"");
else WRITE(" ");
break;
case NEWLINE_IN_STRING:
if (options & CT_BOX_QUOTATION) WRITE("\"\n\"");
else WRITE("^"); break;
case '"': WRITE("~"); break;
case '@':
if (options & CT_FOR_ARRAY) WRITE("@{40}");
else { WRITE("@@64"); esc_digit = TRUE; continue; }
break;
case '^':
if (options & CT_BOX_QUOTATION) WRITE("\"\n\"");
else if (options & CT_FOR_ARRAY) WRITE("@{5E}");
else { WRITE("@@94"); esc_digit = TRUE; continue; }
break;
case '~':
if (options & CT_FOR_ARRAY) WRITE("@{7E}");
else { WRITE("@@126"); esc_digit = TRUE; continue; }
break;
case '\\': WRITE("@{5C}"); break;
case '\'':
if (options & CT_EXPAND_APOSTROPHES)
{
#line 109 "inform7/Chapter 32/Compiled Text.w"
unsigned char *up = (unsigned char *) p;
if ((i==from) && (p[i+1] == 's') && ((to == 3) || (p[i+2] == ' ')))
WRITE("'"); /* allow apostrophe if appending e.g. "'s nose" to "Jane" */
else if ((i>0) && (p[i+1]) &&
(CompiledText__alphabetic(up[i-1])) &&
(CompiledText__alphabetic(up[i+1])))
WRITE("'"); /* allow apostrophe sandwiched between two letters */
else WRITE("~"); /* and otherwise convert to double-quote */
}
#line 78 "inform7/Chapter 32/Compiled Text.w"
else WRITE("'");
break;
case '[':
if ((options & CT_RECOGNISE_APOSTROPHE_SUBSTITUTION) &&
(p[i+1] == '\'') && (p[i+2] == ']')) { i += 2; WRITE("'"); }
else if (options & CT_RECOGNISE_UNICODE_SUBSTITUTION) {
int n = CompiledText__expand_unisub(OUT, p, i);
if (n == -1) WRITE("["); else i = n;
} else WRITE("[");
break;
default:
if ((i==from) && (options & CT_CAPITALISE))
WRITE("%c", Platform__toupper(p[i]));
else if ((esc_digit) && (isdigit(p[i])))
WRITE("@{%02x}", p[i]);
else
WRITE("%c", p[i]);
break;
}
esc_digit = FALSE;
}
}
}
#line 121 "inform7/Chapter 32/Compiled Text.w"
int CompiledText__alphabetic(int letter) {
return isalpha(HTML__without_accent(letter));
}
#line 130 "inform7/Chapter 32/Compiled Text.w"
int CompiledText__expand_unisub(OUTPUT_STREAM, char *p, int i) {
if ((p[i+1] == 'u') && (p[i+2] == 'n') && (p[i+3] == 'i') && (p[i+4] == 'c')
&& (p[i+5] == 'o') && (p[i+6] == 'd') && (p[i+7] == 'e') && (p[i+8] == ' ')) {
char substitution_buffer[MAX_UNISUB_LENGTH];
int j = i+9, k = 0;
while (p[j] == ' ') j++;
while ((p[j]) && (p[j] != ']') && (k<MAX_UNISUB_LENGTH-1))
substitution_buffer[k++] = p[j++];
if (p[j] == ']') {
substitution_buffer[k] = 0;
wording XW = Feeds__feed_text(substitution_buffer);
if (Preform__parse_nt_against_word_range(s_unicode_character_NTM, XW, NULL, NULL) == FALSE) return -1;
PUT(Rvalues__to_Unicode_point(most_recent_result_p));
return j;
} else return -1;
} else return -1;
}
#line 151 "inform7/Chapter 32/Compiled Text.w"
void CompiledText__from_text_with_options(OUTPUT_STREAM, wording W, int opts, int raw) {
LOOP_THROUGH_WORDING(j, W) {
char *p;
if (raw) p = Lexer__word_raw_text(j); else p = Lexer__word_text(j);
CompiledText__from_ISO_string(OUT, p, opts);
if (j<Wordings__last_wn(W)) WRITE(" ");
}
}
#line 163 "inform7/Chapter 32/Compiled Text.w"
void CompiledText__comment(OUTPUT_STREAM, wording W) {
CompiledText__from_text_with_options(OUT, W, 0, FALSE);
}
void CompiledText__from_text(OUTPUT_STREAM, wording W) {
CompiledText__from_text_with_options(OUT, W, 0, TRUE);
}
#line 174 "inform7/Chapter 32/Compiled Text.w"
void CompiledText__divider_comment(OUTPUT_STREAM) {
WRITE("! -------------------------------------------------"
"---------------------------------------------------\n");
}
#line 25 "inform7/Chapter 32/Routines.w"
text_stream *Routines__begin(OUTPUT_STREAM, char *name) {
return Routines__begin_framed(OUT, name, NULL);
}
text_stream *Routines__begin_numbered(OUTPUT_STREAM, char *format, int id) {
char rname[33];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
sprintf(rname, format, id);
#pragma clang diagnostic pop
return Routines__begin_framed(OUT, rname, NULL);
}
#line 45 "inform7/Chapter 32/Routines.w"
text_stream routine_body_stream_struct;
text_stream *routine_body_stream = &routine_body_stream_struct;
#line 52 "inform7/Chapter 32/Routines.w"
text_stream *primary_routine_stream = NULL; /* the output stream to which the routine eventually goes */
char currently_compiling_identifier[32]; /* the I6 identifier name for this routine */
ph_stack_frame *currently_compiling_in_frame = NULL; /* the stack frame for this routine */
int currently_compiling_nnp = FALSE; /* is this a nonphrasal stack frame we made ourselves? */
int kernel_routines_counter = 0; /* number of kernel routines generated (see below) */
#line 61 "inform7/Chapter 32/Routines.w"
text_stream *Routines__begin_framed(OUTPUT_STREAM, char *name, ph_stack_frame *phsf) {
if ((name == NULL) || (name[0] == 0)) internal_error("nameless compiled routine");
if (Platform__strlen(name) > 31) {
LOG("Name is <%s>\n", name);
internal_error("bad compiled routine name");
}
strcpy(currently_compiling_identifier, name);
{
#line 85 "inform7/Chapter 32/Routines.w"
if (phsf == NULL) {
phsf = Frames__new_nonphrasal();
currently_compiling_nnp = TRUE;
} else {
currently_compiling_nnp = FALSE;
}
currently_compiling_in_frame = phsf;
Frames__make_current(phsf);
}
#line 69 "inform7/Chapter 32/Routines.w"
;
Frames__Blocks__begin_code_blocks();
if (STREAM_OPEN_IN_MEMORY(routine_body_stream) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for phrase definition");
primary_routine_stream = OUT; OUT = routine_body_stream;
INDENT; /* begin the routine body one tab stop in from the left margin */
return OUT;
}
#line 97 "inform7/Chapter 32/Routines.w"
text_stream *Routines__end(OUTPUT_STREAM) {
return Routines__end_retrieving(OUT, NULL);
}
text_stream *Routines__end_retrieving(OUTPUT_STREAM, ph_stack_frame *retrieve) {
OUT = primary_routine_stream; /* back to the stream where the routine goes */
int as_property = FALSE;
if (strcmp(currently_compiling_identifier, "*") == 0) as_property = TRUE;
if ((currently_compiling_in_frame->allocated_pointers) ||
(currently_compiling_in_frame->no_formal_parameters_needed > 0))
{
#line 140 "inform7/Chapter 32/Routines.w"
if (VirtualMachines__allow_this_many_locals(
LocalVariables__count(currently_compiling_in_frame) + 1) == FALSE)
{
#line 242 "inform7/Chapter 32/Routines.w"
Problems__Issue__sentence_problem(_p_(PM_TooManyLocals),
"there are too many temporarily-named values in this phrase",
"which may be a sign that it is complicated enough to need breaking up "
"into smaller phrases making use of each other. "
"The limit is 15 at a time for a Z-machine project (see the Settings) "
"and 256 at a time for Glulx. That has to include both values created in the "
"declaration of a phrase (e.g. the 'N' in 'To deduct (N - a number) points: "
"...', or the 'watcher' in 'Instead of taking something in the presence of "
"a man (called the watcher): ...'), and also values created with 'let' or "
"'repeat' (each 'repeat' loop claiming two such values) - not to mention "
"one or two values occasionally needed to work with Tables. Because of all "
"this, it's best to keep the complexity to a minimum within any single phrase.");
}
#line 142 "inform7/Chapter 32/Routines.w"
;
if (as_property) internal_error("property routines don't support outer shells");
char kernel_name[32];
sprintf(kernel_name, "KERNEL_%d", kernel_routines_counter++);
{
#line 154 "inform7/Chapter 32/Routines.w"
int returns_block_value =
Kinds__Behaviour__uses_pointer_values(currently_compiling_in_frame->kind_returned);
WRITE("[ %s ", currently_compiling_identifier);
{
#line 175 "inform7/Chapter 32/Routines.w"
if (returns_block_value) WRITE("I7RBLK ");
LocalVariables__declare(OUT, currently_compiling_in_frame, TRUE);
if (!returns_block_value) WRITE("I7RBLK");
WRITE(";\n");
}
#line 158 "inform7/Chapter 32/Routines.w"
;
INDENT;
int NBV = 0;
{
#line 183 "inform7/Chapter 32/Routines.w"
pointer_allocation *pall;
for (pall=currently_compiling_in_frame->allocated_pointers; pall; pall=pall->next_in_frame) {
if (pall->offset_past > NBV) NBV = pall->offset_past;
}
WRITE("@push I7SFRAME;\n");
WRITE("StackFrameCreate(%d);\n", NBV);
for (pall=currently_compiling_in_frame->allocated_pointers; pall; pall=pall->next_in_frame)
WRITE("%s;\n", pall->allocation_code);
int i;
for (i=0; i<currently_compiling_in_frame->no_formal_parameters_needed; i++)
WRITE("@push formal_par%d;\n", i);
}
#line 161 "inform7/Chapter 32/Routines.w"
;
{
#line 199 "inform7/Chapter 32/Routines.w"
WRITE("I7RBLK = ");
if (returns_block_value) WRITE("BlkValueCopy(I7RBLK, ");
WRITE("%s(", kernel_name);
LocalVariables__compile_parameter_list(OUT, currently_compiling_in_frame, 0);
WRITE(")");
if (returns_block_value) WRITE(")");
WRITE(";\n");
}
#line 162 "inform7/Chapter 32/Routines.w"
;
{
#line 212 "inform7/Chapter 32/Routines.w"
int i;
for (i=currently_compiling_in_frame->no_formal_parameters_needed-1; i>=0; i--)
WRITE("@pull formal_par%d;\n", i);
pointer_allocation *pall;
for (pall=currently_compiling_in_frame->allocated_pointers; pall; pall=pall->next_in_frame)
WRITE("BlkValueFreeOnStack(%d);\n", pall->offset_index);
WRITE("@pull I7SFRAME;\n");
}
#line 163 "inform7/Chapter 32/Routines.w"
;
{
#line 224 "inform7/Chapter 32/Routines.w"
WRITE("return I7RBLK; ! ");
Kinds__Textual__write(OUT, currently_compiling_in_frame->kind_returned);
WRITE("\n");
}
#line 164 "inform7/Chapter 32/Routines.w"
;
OUTDENT; WRITE("];\n");
}
#line 148 "inform7/Chapter 32/Routines.w"
;
{
#line 232 "inform7/Chapter 32/Routines.w"
WRITE("[ %s ", kernel_name);
LocalVariables__declare(OUT, currently_compiling_in_frame, FALSE);
WRITE(" ");
if (retrieve) LocalVariables__compile_retrieval(OUT, retrieve);
STREAM_COPY(OUT, routine_body_stream);
WRITE("];\n");
}
#line 149 "inform7/Chapter 32/Routines.w"
;
}
#line 109 "inform7/Chapter 32/Routines.w"
else
{
#line 125 "inform7/Chapter 32/Routines.w"
if (VirtualMachines__allow_this_many_locals(
LocalVariables__count(currently_compiling_in_frame)) == FALSE)
{
#line 242 "inform7/Chapter 32/Routines.w"
Problems__Issue__sentence_problem(_p_(PM_TooManyLocals),
"there are too many temporarily-named values in this phrase",
"which may be a sign that it is complicated enough to need breaking up "
"into smaller phrases making use of each other. "
"The limit is 15 at a time for a Z-machine project (see the Settings) "
"and 256 at a time for Glulx. That has to include both values created in the "
"declaration of a phrase (e.g. the 'N' in 'To deduct (N - a number) points: "
"...', or the 'watcher' in 'Instead of taking something in the presence of "
"a man (called the watcher): ...'), and also values created with 'let' or "
"'repeat' (each 'repeat' loop claiming two such values) - not to mention "
"one or two values occasionally needed to work with Tables. Because of all "
"this, it's best to keep the complexity to a minimum within any single phrase.");
}
#line 127 "inform7/Chapter 32/Routines.w"
;
WRITE("[ ");
if (as_property == FALSE) WRITE("%s ", currently_compiling_identifier);
LocalVariables__declare(OUT, currently_compiling_in_frame, FALSE);
WRITE(" ");
if (retrieve) LocalVariables__compile_retrieval(OUT, retrieve);
STREAM_COPY(OUT, routine_body_stream);
WRITE("]");
if (as_property == FALSE) WRITE(";\n");
}
#line 111 "inform7/Chapter 32/Routines.w"
;
STREAM_CLOSE(routine_body_stream); /* no longer needed */
Frames__Blocks__end_code_blocks();
if (currently_compiling_nnp) Frames__remove_nonphrase_stack_frame();
Frames__remove_current();
return OUT;
}
#line 26 "inform7/Chapter 33/Interactive Fiction ID.w"
char uuid_text[MAX_UUID_LENGTH];
int uuid_read = -1;
char *PL__Bibliographic__IFID__read_uuid(void) {
if (uuid_read >= 0) return uuid_text;
uuid_read = 0;
FILE *xf = Platform__iso_fopen(filename_of_uuid, "r");
if (xf == NULL) {
uuid_text[0] = 0; /* the UUID is the empty string if the file is missing */
return uuid_text;
}
int i=0; int c;
while (((c = fgetc(xf)) != EOF) /* the UUID file is plain text, not Unicode */
&& (i < MAX_UUID_LENGTH-1))
uuid_text[i++] = (char) toupper(c);
fclose(xf);
uuid_text[i] = 0;
uuid_read = i;
return uuid_text;
}
#line 55 "inform7/Chapter 33/Interactive Fiction ID.w"
void PL__Bibliographic__IFID__UUID_ARRAY_array(OUTPUT_STREAM) {
int i;
char *uuid = PL__Bibliographic__IFID__read_uuid();
WRITE("Array UUID_ARRAY string \"UUID://");
for (i=0; uuid[i]; i++) WRITE("%c", Platform__toupper(uuid[i]));
WRITE("//\";\n");
}
#line 41 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_VARIABLE_NOTIFY, PL__Bibliographic__bibliographic_new_variable_notify);
}
#line 52 "inform7/Chapter 33/Bibliographic Data.w"
int notable_bibliographic_variables_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 60 "inform7/Chapter 33/Bibliographic Data.w"
#line 72 "inform7/Chapter 33/Bibliographic Data.w"
int PL__Bibliographic__bibliographic_new_variable_notify(nonlocal_variable *q) {
if (Preform__parse_nt_against_word_range(notable_bibliographic_variables_NTM, q->name, NULL, NULL)) {
switch (most_recent_result) {
case STORY_TITLE_BIBV: story_title_VAR = q; break;
case STORY_AUTHOR_BIBV: story_author_VAR = q; break;
case STORY_HEADLINE_BIBV: story_headline_VAR = q; break;
case STORY_GENRE_BIBV: story_genre_VAR = q; break;
case STORY_DESCRIPTION_BIBV: story_description_VAR = q; break;
case STORY_CREATION_YEAR_BIBV: story_creation_year_VAR = q; break;
case RELEASE_NUMBER_BIBV: story_release_number_VAR = q; break;
}
NonlocalVariables__make_constant(q, TRUE);
}
return FALSE;
}
#line 92 "inform7/Chapter 33/Bibliographic Data.w"
int titling_line_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; *XP = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; *XP = NULL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 95 "inform7/Chapter 33/Bibliographic Data.w"
int plain_titling_line_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 99 "inform7/Chapter 33/Bibliographic Data.w"
#line 105 "inform7/Chapter 33/Bibliographic Data.w"
natural_language *PL__Bibliographic__scan_language(parse_node *PN) {
if (Preform__parse_nt_against_word_range(titling_line_NTM, ParseTree__get_text(PN), NULL, NULL)) return most_recent_result_p;
return NULL;
}
#line 116 "inform7/Chapter 33/Bibliographic Data.w"
sentence_handler BIBLIOGRAPHIC_SH_handler =
{ BIBLIOGRAPHIC_NT, -1, 2, PL__Bibliographic__bibliographic_data };
void PL__Bibliographic__bibliographic_data(parse_node *PN) {
if (Preform__parse_nt_against_word_range(titling_line_NTM, ParseTree__get_text(PN), NULL, NULL)) {
wording TW = GET_RW(plain_titling_line_NTM, 1);
wording AW = EMPTY_WORDING;
if (most_recent_result) AW = GET_RW(plain_titling_line_NTM, 2);
if ((story_title_VAR) && (story_author_VAR)) {
{
#line 140 "inform7/Chapter 33/Bibliographic Data.w"
parse_node *the_title;
if (Preform__parse_nt_against_word_range(s_value_NTM, TW, NULL, NULL)) the_title = most_recent_result_p;
else the_title = Specifications__new_UNKNOWN(TW);
Assertions__PropertyKnowledge__initialise_global_variable(story_title_VAR, the_title);
Strings__TextLiterals__suppress_quote_expansion(ParseTree__get_text(the_title));
}
#line 125 "inform7/Chapter 33/Bibliographic Data.w"
;
if (Wordings__nonempty(AW))
{
#line 154 "inform7/Chapter 33/Bibliographic Data.w"
char author_buffer[1024];
if (Preform__parse_nt_against_word_range(quoted_text_NTM, AW, NULL, NULL) == FALSE) {
author_buffer[0] = '\"';
Wordings__to_string_raw_truncated(author_buffer+1, 1020, AW);
int i;
for (i=1; author_buffer[i]; i++)
if (author_buffer[i] == '\"') author_buffer[i] = '\'';
sprintf(author_buffer+Platform__strlen(author_buffer), "\" ");
AW = Feeds__feed_text(author_buffer);
}
parse_node *the_author;
if (Preform__parse_nt_against_word_range(s_value_NTM, AW, NULL, NULL)) the_author = most_recent_result_p;
else the_author = Specifications__new_UNKNOWN(AW);
Assertions__PropertyKnowledge__initialise_global_variable(story_author_VAR, the_author);
}
#line 126 "inform7/Chapter 33/Bibliographic Data.w"
;
}
} else {
Problems__Issue__sentence_problem(_p_(PM_BadTitleSentence),
"the initial bibliographic sentence can only be a title in double-quotes",
"possibly followed with 'by' and the name of the author.");
}
}
#line 175 "inform7/Chapter 33/Bibliographic Data.w"
int PL__Bibliographic__story_author_is(char *p) {
if ((story_author_VAR) &&
(NonlocalVariables__has_initial_value_set(story_author_VAR))) {
parse_node *spec = NonlocalVariables__get_initial_value(story_author_VAR);
ParseTree__set_kind_of_value(spec, K_text);
int result = FALSE;
int save_dctb = divert_constant_text_bibliographically;
TEMPORARY_STREAM;
divert_constant_text_bibliographically = TRUE;
Specifications__Compiler__compile(TEMP, spec);
divert_constant_text_bibliographically = save_dctb;
if (strcmp(p, STREAM_TEXT(TEMP)) == 0) result = TRUE;
CLOSE_TEMPORARY_STREAM;
return result;
}
return FALSE;
}
#line 197 "inform7/Chapter 33/Bibliographic Data.w"
sentence_handler EPISODE_SH_handler =
{ SENTENCE_NT, EPISODE_VB, 1, PL__Bibliographic__set_episode_data };
#line 212 "inform7/Chapter 33/Bibliographic Data.w"
int episode_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; series_NTMV = R[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 219 "inform7/Chapter 33/Bibliographic Data.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_BadEpisode),
"this is not the right way to specify how the story "
"fits into a larger narrative",
"and should take the form 'The story is episode 2 of "
"\"Belt of Orion\", where the episode number has to be a "
"whole number 0, 1, 2, ... and the series name has to be "
"plain text without [substitutions].");
}
#line 214 "inform7/Chapter 33/Bibliographic Data.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 215 "inform7/Chapter 33/Bibliographic Data.w"
#line 231 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__set_episode_data(parse_node *pn) {
Preform__parse_nt_against_word_range(episode_sentence_object_NTM, ParseTree__get_text(pn->down->next->next), NULL, NULL);
if (most_recent_result >= 0) {
episode_number = most_recent_result;
Text__dequote_word(series_NTMV);
series_name = Lexer__word_text(series_NTMV);
}
}
#line 244 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__compile_constants(OUTPUT_STREAM) {
encode_constant_text_bibliographically = TRUE;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(COMPILE_TEXT_TO_I6_CMODE);
if (story_title_VAR)
{
#line 263 "inform7/Chapter 33/Bibliographic Data.w"
NonlocalVariables__treat_as_plain_text_word(story_title_VAR);
WRITE("Global Story = ");
if (NonlocalVariables__has_initial_value_set(story_title_VAR))
NonlocalVariables__compile_initial_value(OUT, story_title_VAR);
else
Strings__TextLiterals__compile_literal_from_text(OUT, "\"Welcome\"");
WRITE(";\n");
}
#line 249 "inform7/Chapter 33/Bibliographic Data.w"
;
if (story_headline_VAR)
{
#line 274 "inform7/Chapter 33/Bibliographic Data.w"
WRITE("Constant Headline ");
if (NonlocalVariables__has_initial_value_set(story_headline_VAR)) {
NonlocalVariables__treat_as_plain_text_word(story_headline_VAR);
NonlocalVariables__compile_initial_value(OUT, story_headline_VAR);
} else {
Strings__TextLiterals__compile_literal_from_text(OUT, "\"An Interactive Fiction\"");
}
WRITE(";\n");
}
#line 250 "inform7/Chapter 33/Bibliographic Data.w"
;
if (story_author_VAR)
{
#line 286 "inform7/Chapter 33/Bibliographic Data.w"
if (NonlocalVariables__has_initial_value_set(story_author_VAR)) {
WRITE("Constant Story_Author ");
NonlocalVariables__treat_as_plain_text_word(story_author_VAR);
NonlocalVariables__compile_initial_value(OUT, story_author_VAR);
WRITE(";\n");
}
}
#line 251 "inform7/Chapter 33/Bibliographic Data.w"
;
if (story_release_number_VAR)
{
#line 296 "inform7/Chapter 33/Bibliographic Data.w"
if (NonlocalVariables__has_initial_value_set(story_release_number_VAR)) {
WRITE("Release ");
NonlocalVariables__compile_initial_value(OUT, story_release_number_VAR);
WRITE(";\n");
}
}
#line 252 "inform7/Chapter 33/Bibliographic Data.w"
;
{
#line 307 "inform7/Chapter 33/Bibliographic Data.w"
int year_digits = (the_present->tm_year) % 100;
WRITE("Serial \"%02d%02d%02d\";\n",
year_digits, (the_present->tm_mon)+1, the_present->tm_mday);
}
#line 253 "inform7/Chapter 33/Bibliographic Data.w"
;
END_COMPILATION_MODE;
encode_constant_text_bibliographically = FALSE;
}
#line 316 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__index_library_card(void) {
INDEX("<p>");
Index__anchor("LCARD");
HTML__begin_html_table(ifl, "*bg_images/indexcard.png", FALSE, 0, 3, 3, 0, 0);
PL__Bibliographic__library_card_entry("Story title", story_title_VAR, "Untitled");
PL__Bibliographic__library_card_entry("Story author", story_author_VAR, "Anonymous");
PL__Bibliographic__library_card_entry("Story headline", story_headline_VAR, "An Interactive Fiction");
PL__Bibliographic__library_card_entry("Story genre", story_genre_VAR, "Fiction");
if (episode_number >= 0) {
char episode_text[MAX_STRING_LENGTH+20];
sprintf(episode_text, "%d of %s", episode_number, series_name);
PL__Bibliographic__library_card_entry("Episode", NULL, episode_text);
}
PL__Bibliographic__library_card_entry("Release number", story_release_number_VAR, "1");
PL__Bibliographic__library_card_entry("Story creation year", story_creation_year_VAR, "(This year)");
PL__Bibliographic__library_card_entry("Language of play", NULL, NaturalLanguages__get_name(language_of_play));
PL__Bibliographic__library_card_entry("IFID number", NULL, uuid_text);
PL__Bibliographic__library_card_entry("Story description", story_description_VAR, "None");
HTML__end_html_table(ifl);
INDEX("</p>");
}
#line 341 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__library_card_entry(char *field, nonlocal_variable *nlv, char *t) {
char *font = "<font face=\"courier\" size=2 color=\"#333\">";
if (nlv == story_title_VAR)
font = "<font face=\"courier\" size=2 color=\"#833\">";
HTML__first_html_column_nowrap(ifl, 0, NULL);
INDEX("%s%s</font>", font, field);
HTML__next_html_column(ifl, 0);
INDEX("%s<b>", font);
PL__Bibliographic__index_bibliographic_variable(nlv, t);
INDEX("</b></font>");
HTML__end_html_row(ifl);
}
#line 358 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__contents_heading(void) {
if ((story_title_VAR == NULL) || (story_author_VAR == NULL))
INDEX("Contents");
else {
PL__Bibliographic__index_bibliographic_variable(story_title_VAR, "Untitled");
INDEX(" by ");
PL__Bibliographic__index_bibliographic_variable(story_author_VAR, "Anonymous");
}
}
#line 371 "inform7/Chapter 33/Bibliographic Data.w"
void PL__Bibliographic__index_bibliographic_variable(nonlocal_variable *nlv, char *t) {
divert_constant_text_bibliographically = TRUE;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(COMPILE_TEXT_TO_XML_CMODE);
if ((nlv) && (NonlocalVariables__has_initial_value_set(nlv))) {
Strings__TextLiterals__compile_literal(ifl,
NonlocalVariables__treat_as_plain_text_word(nlv));
} else {
INDEX("%s", t);
}
END_COMPILATION_MODE;
divert_constant_text_bibliographically = FALSE;
}
#line 65 "inform7/Chapter 33/Release Instructions.w"
int release_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[2]; privacy_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 90 "inform7/Chapter 33/Release Instructions.w"
*X = BOOKLET_PAYLOAD; /* to recover harmlessly */
Problems__quote_wording_as_source(1, W);
Problems__Issue__handmade_problem(_p_(PM_NoSuchPublicRelease));
Problems__issue_problem_segment(
"I don't know how to release along with %1: the only features of "
"a release which can be marked as public or private are the 'source "
"text', 'solution' and 'library card'.");
Problems__issue_problem_end();
}
#line 67 "inform7/Chapter 33/Release Instructions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1]; privacy_NTMV = NOT_APPLICABLE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = COVER_ART_PAYLOAD; alttext_NTMV = R[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = COVER_ART_PAYLOAD; alttext_NTMV = -1;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = EXISTING_STORY_FILE_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = NAMED_EXISTING_STORY_FILE_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = AUXILIARY_FILE_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = HIDDEN_FILE_IN_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9: *X = HIDDEN_FILE_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10: *X = CSS_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11: *X = JAVASCRIPT_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12: *X = BOOKLET_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13: *X = POSTCARD_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14: *X = WEBSITE_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 15: *X = SEPARATE_FIGURES_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 16: *X = SEPARATE_SOUNDS_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 17: *X = THEMED_WEBSITE_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 18: *X = INTERPRETER_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 19: *X = THEMED_INTERPRETER_PAYLOAD;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 86 "inform7/Chapter 33/Release Instructions.w"
#line 104 "inform7/Chapter 33/Release Instructions.w"
int privacy_indicator_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 107 "inform7/Chapter 33/Release Instructions.w"
int exposed_innards_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 112 "inform7/Chapter 33/Release Instructions.w"
#line 116 "inform7/Chapter 33/Release Instructions.w"
sentence_handler RELEASE_SH_handler =
{ SENTENCE_NT, RELEASE_VB, 1, PL__Bibliographic__Release__handle_release_declaration };
void PL__Bibliographic__Release__handle_release_declaration(parse_node *p) {
PL__Bibliographic__Release__handle_release_declaration_inner(p->down->next);
}
void PL__Bibliographic__Release__handle_release_declaration_inner(parse_node *p) {
if (ParseTree__get_type(p) == AND_NT) {
PL__Bibliographic__Release__handle_release_declaration_inner(p->down);
PL__Bibliographic__Release__handle_release_declaration_inner(p->down->next);
return;
}
current_sentence = p;
if (Preform__parse_nt_against_word_range(release_sentence_object_NTM, ParseTree__get_text(p), NULL, NULL))
{
#line 159 "inform7/Chapter 33/Release Instructions.w"
int payload = most_recent_result;
switch (payload) {
case SOLUTION_PAYLOAD:
release_solution = TRUE;
if (privacy_NTMV != NOT_APPLICABLE) solution_public = privacy_NTMV;
break;
case SOURCE_TEXT_PAYLOAD:
release_source = TRUE;
if (privacy_NTMV != NOT_APPLICABLE) source_public = privacy_NTMV;
break;
case LIBRARY_CARD_PAYLOAD:
release_card = TRUE;
if (privacy_NTMV != NOT_APPLICABLE) card_public = privacy_NTMV;
break;
case COVER_ART_PAYLOAD:
release_cover = TRUE;
cover_alt_text = alttext_NTMV;
cover_filename_sentence = current_sentence;
break;
case EXISTING_STORY_FILE_PAYLOAD:
case NAMED_EXISTING_STORY_FILE_PAYLOAD:
if (VirtualMachines__is_16_bit() == FALSE) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible), /* not usefully testable */
"existing story files can only be used with the Z-machine",
"not with the Glulx setting.");
return;
}
if (payload == NAMED_EXISTING_STORY_FILE_PAYLOAD) {
wording SW = GET_RW(release_sentence_object_NTM, 1);
Text__dequote_word(Wordings__first_wn(SW));
filename_of_existing_story_file =
Filenames__in_folder(pathname_of_area[MATERIALS_FS_AREA],
Lexer__word_text(Wordings__first_wn(SW)));
}
existing_story_file = TRUE;
break;
case AUXILIARY_FILE_PAYLOAD: {
wording DW = GET_RW(release_sentence_object_NTM, 1);
wording LW = GET_RW(release_sentence_object_NTM, 2);
Text__dequote_word(Wordings__first_wn(LW));
Text__dequote_word(Wordings__first_wn(DW));
PL__Bibliographic__Release__create_aux_file(
Filenames__in_folder(pathname_of_area[MATERIALS_FS_AREA], Lexer__word_text(Wordings__first_wn(LW))),
pathname_of_materials_release,
Lexer__word_text(Wordings__first_wn(DW)),
payload);
break;
}
case CSS_PAYLOAD: case JAVASCRIPT_PAYLOAD: case HIDDEN_FILE_PAYLOAD: {
wording LW = GET_RW(release_sentence_object_NTM, 1);
Text__dequote_word(Wordings__first_wn(LW));
PL__Bibliographic__Release__create_aux_file(
Filenames__in_folder(pathname_of_area[MATERIALS_FS_AREA], Lexer__word_text(Wordings__first_wn(LW))),
pathname_of_materials_release,
"--",
payload);
break;
}
case HIDDEN_FILE_IN_PAYLOAD: {
wording LW = GET_RW(release_sentence_object_NTM, 1);
wording FW = GET_RW(release_sentence_object_NTM, 2);
Text__dequote_word(Wordings__first_wn(LW));
Text__dequote_word(Wordings__first_wn(FW));
PL__Bibliographic__Release__create_aux_file(
Filenames__in_folder(pathname_of_area[MATERIALS_FS_AREA], Lexer__word_text(Wordings__first_wn(LW))),
Pathnames__subfolder(pathname_of_materials_release, Lexer__word_text(Wordings__first_wn(FW))),
"--",
payload);
break;
}
case BOOKLET_PAYLOAD: release_booklet = TRUE; break;
case POSTCARD_PAYLOAD: release_postcard = TRUE; break;
case WEBSITE_PAYLOAD: release_website = TRUE; break;
case THEMED_WEBSITE_PAYLOAD: {
wording TW = GET_RW(release_sentence_object_NTM, 1);
Text__dequote_word(Wordings__first_wn(TW));
website_template_leafname = Lexer__word_text(Wordings__first_wn(TW));
release_website = TRUE;
break;
}
case INTERPRETER_PAYLOAD:
release_interpreter = TRUE; release_website = TRUE;
break;
case THEMED_INTERPRETER_PAYLOAD: {
wording TW = GET_RW(release_sentence_object_NTM, 1);
Text__dequote_word(Wordings__first_wn(TW));
interpreter_template_leafname = Lexer__word_text(Wordings__first_wn(TW));
release_interpreter = TRUE; release_website = TRUE;
break;
}
case SEPARATE_FIGURES_PAYLOAD:
PL__Figures__write_copy_commands();
break;
case SEPARATE_SOUNDS_PAYLOAD:
PL__Sounds__write_copy_commands();
break;
}
}
#line 131 "inform7/Chapter 33/Release Instructions.w"
else
{
#line 260 "inform7/Chapter 33/Release Instructions.w"
Problems__quote_source(1, p);
Problems__Issue__handmade_problem(_p_(PM_ReleaseAlong));
Problems__issue_problem_segment(
"I don't know how to release along with %1: the only forms I can "
"accept are - 'Release along with cover art', '...a website', "
"'the solution', 'the library card', 'the introductory booklet', "
"'the source text', 'an existing story file' or '...a file of "
"\"Something Useful\" called \"Something.pdf\"'.");
Problems__issue_problem_end();
}
#line 133 "inform7/Chapter 33/Release Instructions.w"
;
}
#line 273 "inform7/Chapter 33/Release Instructions.w"
auxiliary_file *PL__Bibliographic__Release__create_aux_file(filename *name,
pathname *fold, char *desc, int payload) {
auxiliary_file *af = CREATE(auxiliary_file);
af->name_of_original_file = name;
af->folder_to_release_to = fold;
af->brief_description = desc;
af->from_payload = payload;
return af;
}
#line 291 "inform7/Chapter 33/Release Instructions.w"
void PL__Bibliographic__Release__write_ifiction_and_blurb(void) {
{
#line 311 "inform7/Chapter 33/Release Instructions.w"
create_Materials = TRUE; /* thus making the next condition irrelevant */
if ((release_website) || (release_interpreter) || (release_booklet) || (release_postcard) ||
(release_cover) || (release_source) || (release_card) || (release_solution) ||
(existing_story_file) || (NUMBER_CREATED(blorb_figure) > 1)) {
create_Materials = TRUE;
}
if (create_Materials) {
{
#line 326 "inform7/Chapter 33/Release Instructions.w"
if (Pathnames__create_in_file_system(pathname_of_area[MATERIALS_FS_AREA]) == FALSE) {
Problems__Issue__release_problem_path(_p_(Untestable),
"In order to release the story file along with other "
"resources, I tried to create a folder alongside this "
"Inform project, but was unable to do so. The folder "
"was to have been called",
pathname_of_area[MATERIALS_FS_AREA]);
return;
}
}
#line 318 "inform7/Chapter 33/Release Instructions.w"
;
{
#line 339 "inform7/Chapter 33/Release Instructions.w"
if (Pathnames__create_in_file_system(pathname_of_materials_release) == FALSE) {
Problems__Issue__release_problem_path(_p_(Untestable),
"In order to release the story file along with other "
"resources, I tried to create a folder alongside this "
"Inform project, but was unable to do so. The folder "
"was to have been called",
pathname_of_materials_release);
return;
}
auxiliary_file *af;
LOOP_OVER(af, auxiliary_file)
if (Pathnames__create_in_file_system(af->folder_to_release_to) == FALSE) {
Problems__Issue__release_problem_path(_p_(Untestable),
"In order to release the story file along with other "
"resources, I tried to create a folder alongside this "
"Inform project, but was unable to do so. The folder "
"was to have been called",
af->folder_to_release_to);
return;
}
}
#line 319 "inform7/Chapter 33/Release Instructions.w"
;
if (release_interpreter)
{
#line 363 "inform7/Chapter 33/Release Instructions.w"
if (Pathnames__create_in_file_system(pathname_of_released_interpreter) == FALSE) {
Problems__Issue__release_problem_path(_p_(Untestable),
"In order to release the story file along with an "
"interpreter, I tried to create a folder alongside this "
"Inform project, but was unable to do so. The folder "
"was to have been called",
pathname_of_released_interpreter);
return;
}
}
#line 320 "inform7/Chapter 33/Release Instructions.w"
;
}
}
#line 292 "inform7/Chapter 33/Release Instructions.w"
;
int cover_picture_number = (release_cover)?1:0;
char *cover_art_format = NULL;
unsigned int width = 0, height = 0;
{
#line 377 "inform7/Chapter 33/Release Instructions.w"
if (release_cover) {
current_sentence = cover_filename_sentence;
cover_art_format = "";
filename *cover_filename = filename_of_large_cover_art_jpeg;
FILE *COVER_FILE = Platform__iso_fopen(cover_filename, "rb" );
if (COVER_FILE)
{
#line 395 "inform7/Chapter 33/Release Instructions.w"
cover_art_format = "jpg";
int rv = ImageFiles__get_JPEG_dimensions(COVER_FILE, &width, &height);
fclose(COVER_FILE);
if (rv == FALSE) {
Problems__Issue__release_problem(_p_(Untestable),
"The cover image seems not to be a JPEG despite the name",
cover_filename);
return;
}
}
#line 382 "inform7/Chapter 33/Release Instructions.w"
else {
cover_filename = filename_of_large_cover_art_png;
COVER_FILE = Platform__iso_fopen(cover_filename, "rb" );
if (COVER_FILE)
{
#line 408 "inform7/Chapter 33/Release Instructions.w"
cover_art_format = "png";
int rv = ImageFiles__get_PNG_dimensions(COVER_FILE, &width, &height);
fclose(COVER_FILE);
if (rv == FALSE) {
Problems__Issue__release_problem(_p_(Untestable),
"The cover image seems not to be a PNG despite the name",
cover_filename);
return;
}
}
#line 386 "inform7/Chapter 33/Release Instructions.w"
else
{
#line 421 "inform7/Chapter 33/Release Instructions.w"
Problems__Issue__release_problem_at_sentence(_p_(Untestable),
"The release instructions said that there is a cover image "
"to attach to the story file, but I was unable to find it, "
"having looked for both 'Cover.png' and 'Cover.jpg' in the "
"'.materials' folder for this project", cover_filename);
return;
}
#line 387 "inform7/Chapter 33/Release Instructions.w"
;
}
{
#line 431 "inform7/Chapter 33/Release Instructions.w"
if ((width < 120) || (width > 1200) || (height < 120) || (height > 1200)) {
Problems__Issue__release_problem(_p_(Untestable),
"The height and width of the cover image, in pixels, must be "
"between 120 and 1024 inclusive",
cover_filename);
return;
}
if ((width > 2*height) || (height > 2*width)) {
Problems__Issue__release_problem(_p_(Untestable),
"We recommend a square cover image, but at any rate it is "
"required to be no more rectangular than twice as wide as it "
"is high (or vice versa)",
cover_filename);
return;
}
}
#line 389 "inform7/Chapter 33/Release Instructions.w"
;
}
}
#line 297 "inform7/Chapter 33/Release Instructions.w"
;
char header[LENGTH_OF_STORY_FILE_HEADER]; /* a sequence of bytes, not a C string */
if (existing_story_file)
{
#line 450 "inform7/Chapter 33/Release Instructions.w"
if (this_is_a_release_compile == FALSE)
{
#line 475 "inform7/Chapter 33/Release Instructions.w"
Problems__Issue__unlocated_problem(_p_(PM_UnreleasedRelease),
"This is supposed to be a source text which only contains "
"release instructions to bind up an existing story file "
"(for instance, one produced using Inform 6). That's because "
"the instruction 'Release along with an existing story file' "
"is present. So the only way to build the project is to use "
"the Release option - not, for instance, Go or Replay, because "
"it would make no sense to translate the source text into "
"something to play. (Of course, you can play the released "
"story file using an interpreter such as Zoom or Windows "
"Frotz, etc.: just not here, within Inform.)");
return;
}
#line 451 "inform7/Chapter 33/Release Instructions.w"
;
FILE *STORYF = Platform__iso_fopen(filename_of_existing_story_file, "rb");
if (STORYF == NULL) {
char fn[MAX_FILENAME_LENGTH];
Filenames__to_string(fn, filename_of_existing_story_file);
Problems__Issue__unlocated_problem_on_file(
_p_(BelievedImpossible), /* i.e., not testable by intest */
"The instruction 'Release along with an existing story file' "
"means that I need to bind up a story file called '%1', in "
"the .materials folder for this project. But it doesn't seem "
"to be there.", fn);
return;
}
int i;
for (i=0; i<LENGTH_OF_STORY_FILE_HEADER; i++) {
int c = fgetc(STORYF);
if (c == EOF) header[i] = 0;
else header[i] = (char) c;
}
fclose(STORYF);
}
#line 300 "inform7/Chapter 33/Release Instructions.w"
if (problem_count == 0)
{
#line 491 "inform7/Chapter 33/Release Instructions.w"
divert_constant_text_bibliographically = TRUE;
{
#line 500 "inform7/Chapter 33/Release Instructions.w"
text_stream xf_struct; text_stream *xf = &xf_struct;
if (STREAM_OPEN_TO_FILE(xf, filename_of_ifiction_record, UTF8_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open metadata file", filename_of_ifiction_record);
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(COMPILE_TEXT_TO_XML_CMODE);
PL__Bibliographic__Release__write_ifiction_record(xf, header, cover_picture_number, cover_art_format, height, width);
END_COMPILATION_MODE;
STREAM_CLOSE(xf);
}
#line 492 "inform7/Chapter 33/Release Instructions.w"
;
{
#line 512 "inform7/Chapter 33/Release Instructions.w"
text_stream xf_struct; text_stream *xf = &xf_struct;
if (STREAM_OPEN_TO_FILE(xf, filename_of_blurb, UTF8_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open blurb file", filename_of_blurb);
PL__Bibliographic__Release__write_release_blurb(xf, cover_picture_number, cover_art_format);
STREAM_CLOSE(xf);
}
#line 493 "inform7/Chapter 33/Release Instructions.w"
;
{
#line 521 "inform7/Chapter 33/Release Instructions.w"
text_stream xf_struct; text_stream *xf = &xf_struct;
if (STREAM_OPEN_TO_FILE(xf, filename_of_manifest, UTF8_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open manifest file", filename_of_manifest);
PL__Figures__write_picture_manifest(xf, release_cover, cover_art_format);
STREAM_CLOSE(xf);
}
#line 494 "inform7/Chapter 33/Release Instructions.w"
;
divert_constant_text_bibliographically = FALSE;
}
#line 302 "inform7/Chapter 33/Release Instructions.w"
;
}
#line 530 "inform7/Chapter 33/Release Instructions.w"
void PL__Bibliographic__Release__write_ifiction_record(OUTPUT_STREAM, char *header,
int cover_picture_number, char *cover_art_format,
unsigned int height, unsigned int width) {
WRITE("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
WRITE("<ifindex version=\"1.0\" "
"xmlns=\"http://babel.ifarchive.org/protocol/iFiction/\">\n"); INDENT;
WRITE("<story>\n"); INDENT;
{
#line 545 "inform7/Chapter 33/Release Instructions.w"
char *story_format = "zcode";
if (strcmp(story_filename_extension, "ulx") == 0) story_format = "glulx";
{
#line 563 "inform7/Chapter 33/Release Instructions.w"
WRITE("<identification>\n"); INDENT;
WRITE("<ifid>%s</ifid>\n", PL__Bibliographic__IFID__read_uuid());
if (existing_story_file) {
WRITE("<ifid>ZCODE-%d-%c%c%c%c%c%c",
header[2]*256+header[3],
header[0x12], header[0x13], header[0x14],
header[0x15], header[0x16], header[0x17]);
if ((header[0x12] != '8') || (isdigit(header[0x12])))
WRITE("-%04x", header[0x1c]*256 + header[0x1d]);
WRITE("</ifid>\n");
}
WRITE("<format>%s</format>\n", story_format);
OUTDENT; WRITE("</identification>\n");
}
#line 548 "inform7/Chapter 33/Release Instructions.w"
;
{
#line 580 "inform7/Chapter 33/Release Instructions.w"
WRITE("<bibliographic>\n"); INDENT;
WRITE("<title>");
if (PL__Bibliographic__Release__write_var_to_XML(OUT, story_title_VAR, FALSE) == FALSE) WRITE("Untitled");
WRITE("</title>\n");
WRITE("<author>");
if (PL__Bibliographic__Release__write_var_to_XML(OUT, story_author_VAR, FALSE) == FALSE) WRITE("Anonymous");
WRITE("</author>\n");
WRITE("<headline>");
if (PL__Bibliographic__Release__write_var_to_XML(OUT, story_headline_VAR, FALSE) == FALSE)
WRITE("An Interactive Fiction");
WRITE("</headline>\n");
WRITE("<genre>");
if (PL__Bibliographic__Release__write_var_to_XML(OUT, story_genre_VAR, FALSE) == FALSE) WRITE("Fiction");
WRITE("</genre>\n");
WRITE("<firstpublished>");
if (PL__Bibliographic__Release__write_var_to_XML(OUT, story_creation_year_VAR, FALSE) == FALSE)
WRITE("%d", (the_present->tm_year)+1900);
WRITE("</firstpublished>\n");
if (NonlocalVariables__has_initial_value_set(story_description_VAR)) {
WRITE("<description>");
PL__Bibliographic__Release__write_var_to_XML(OUT, story_description_VAR, TRUE);
WRITE("</description>\n");
}
WRITE("<language>");
NaturalLanguages__write_language_code(OUT, language_of_play);
WRITE("</language>\n");
WRITE("<group>Inform</group>\n");
if (episode_number >= 0) {
WRITE("<seriesnumber>%d</seriesnumber>\n", episode_number);
WRITE("<series>%s</series>\n", series_name);
}
OUTDENT; WRITE("</bibliographic>\n");
}
#line 549 "inform7/Chapter 33/Release Instructions.w"
;
if (NUMBER_CREATED(auxiliary_file) > 0)
{
#line 616 "inform7/Chapter 33/Release Instructions.w"
auxiliary_file *af;
WRITE("<resources>\n"); INDENT;
LOOP_OVER(af, auxiliary_file) {
WRITE("<auxiliary>\n"); INDENT;
WRITE("<leafname>");
char rel[MAX_FILENAME_LENGTH];
Filenames__to_string_relative(rel, af->name_of_original_file, pathname_of_area[MATERIALS_FS_AREA]);
HTML__write_xml_safe_text(OUT, rel);
WRITE("</leafname>\n");
if (af->brief_description) {
WRITE("<description>");
HTML__write_xml_safe_text(OUT, af->brief_description);
WRITE("</description>\n");
}
OUTDENT; WRITE("</auxiliary>\n");
}
OUTDENT; WRITE("</resources>\n");
}
#line 551 "inform7/Chapter 33/Release Instructions.w"
;
if (release_cover)
{
#line 638 "inform7/Chapter 33/Release Instructions.w"
WRITE("<cover>\n"); INDENT;
WRITE("<format>%s</format>\n", cover_art_format);
WRITE("<height>%d</height>\n", height);
WRITE("<width>%d</width>\n", width);
char *desc = PL__Figures__description_of_cover_art();
if (cover_alt_text >= 0) {
LOG("CAT $w\n", Wordings__one_word(cover_alt_text));
Text__dequote_word(cover_alt_text);
desc = Lexer__word_text(cover_alt_text);
}
WRITE("<description>%s</description>\n", desc);
OUTDENT; WRITE("</cover>\n");
}
#line 553 "inform7/Chapter 33/Release Instructions.w"
;
{
#line 654 "inform7/Chapter 33/Release Instructions.w"
WRITE("<releases>\n"); INDENT;
WRITE("<attached>\n"); INDENT;
WRITE("<release>\n"); INDENT;
if (existing_story_file)
{
#line 670 "inform7/Chapter 33/Release Instructions.w"
WRITE("<releasedate>%s%c%c-%c%c-%c%c</releasedate>\n",
((isdigit(header[0x12])) &&
(header[0x12] != '8') && (header[0x12] != '9'))?"20":"19",
header[0x12], header[0x13], header[0x14],
header[0x15], header[0x16], header[0x17]);
WRITE("<version>%d</version>\n", header[2]*256+header[3]);
if ((isdigit(header[0x3c])) &&
((isdigit(header[0x3d])) || (header[0x3d] == '.')) &&
(isdigit(header[0x3e])) && (isdigit(header[0x3f]))) {
if (header[0x3d] == '.') {
WRITE("<compiler>Inform 6</compiler>\n");
WRITE("<compilerversion>%c%c%c%c</compilerversion>\n",
header[0x3c], header[0x3d], header[0x3e], header[0x3f]);
}
else {
WRITE("<compiler>Inform 1-5</compiler>\n");
WRITE("<compilerversion>%c%c%c%c</compilerversion>\n",
header[0x3c], header[0x3d], header[0x3e], header[0x3f]);
}
} else {
WRITE("<compiler>ZILCH</compiler>\n");
WRITE("<compilerversion>%d</compilerversion>\n", header[0x00]);
}
}
#line 657 "inform7/Chapter 33/Release Instructions.w"
else
{
#line 697 "inform7/Chapter 33/Release Instructions.w"
WRITE("<releasedate>%04d-%02d-%02d</releasedate>\n",
(the_present->tm_year)+1900, (the_present->tm_mon)+1, the_present->tm_mday);
if ((story_release_number_VAR != NULL) &&
(NonlocalVariables__has_initial_value_set(story_release_number_VAR))) {
WRITE("<version>");
NonlocalVariables__compile_initial_value(OUT, story_release_number_VAR);
WRITE("</version>\n");
} else WRITE("<version>1</version>\n");
WRITE("<compiler>Inform 7</compiler>\n");
WRITE("<compilerversion>%s</compilerversion>\n", NI_BUILD);
}
#line 658 "inform7/Chapter 33/Release Instructions.w"
;
OUTDENT; WRITE("</release>\n");
OUTDENT; WRITE("</attached>\n");
OUTDENT; WRITE("</releases>\n");
}
#line 554 "inform7/Chapter 33/Release Instructions.w"
;
{
#line 711 "inform7/Chapter 33/Release Instructions.w"
WRITE("<colophon>\n"); INDENT;
WRITE("<generator>Inform 7</generator>\n");
WRITE("<generatorversion>%s</generatorversion>\n", NI_BUILD);
WRITE("<originated>20%02d-%02d-%02d</originated>\n",
(the_present->tm_year)-100, (the_present->tm_mon)+1, the_present->tm_mday);
OUTDENT; WRITE("</colophon>\n");
}
#line 555 "inform7/Chapter 33/Release Instructions.w"
;
WRITE("<%s>\n", story_format); INDENT;
{
#line 722 "inform7/Chapter 33/Release Instructions.w"
if (existing_story_file) {
WRITE("<serial>%c%c%c%c%c%c</serial>\n",
header[0x12], header[0x13], header[0x14],
header[0x15], header[0x16], header[0x17]);
WRITE("<release>%d</release>\n", header[2]*256+header[3]);
WRITE("<checksum>%04x</checksum>\n", header[0x1c]*256 + header[0x1d]);
if ((isdigit(header[0x3c])) &&
((isdigit(header[0x3d])) || (header[0x3d] == '.')) &&
(isdigit(header[0x3e])) && (isdigit(header[0x3f]))) {
WRITE("<compiler>Inform v%c%c%c%c</compiler>\n",
header[0x3c], header[0x3d], header[0x3e], header[0x3f]);
} else {
WRITE("<compiler>Infocom ZIL</compiler>\n");
}
} else {
WRITE("<serial>%02d%02d%02d</serial>\n",
(the_present->tm_year)-100, (the_present->tm_mon)+1, the_present->tm_mday);
if ((story_release_number_VAR != NULL) &&
(NonlocalVariables__has_initial_value_set(story_release_number_VAR))) {
WRITE("<release>");
NonlocalVariables__compile_initial_value(OUT, story_release_number_VAR);
WRITE("</release>\n");
} else WRITE("<release>1</release>\n");
WRITE("<compiler>Inform 7 build %s</compiler>\n", NI_BUILD);
}
if (release_cover)
WRITE("<coverpicture>%d</coverpicture>\n", cover_picture_number);
}
#line 557 "inform7/Chapter 33/Release Instructions.w"
;
OUTDENT; WRITE("</%s>\n", story_format);
}
#line 537 "inform7/Chapter 33/Release Instructions.w"
;
OUTDENT; WRITE("</story>\n");
OUTDENT; WRITE("</ifindex>\n");
}
#line 753 "inform7/Chapter 33/Release Instructions.w"
int PL__Bibliographic__Release__write_var_to_XML(OUTPUT_STREAM, nonlocal_variable *nlv, int desc_mode) {
if ((nlv) && (NonlocalVariables__has_initial_value_set(nlv))) {
NonlocalVariables__treat_as_plain_text_word(nlv);
NonlocalVariables__compile_initial_value(OUT, nlv);
return TRUE;
}
return FALSE;
}
#line 790 "inform7/Chapter 33/Release Instructions.w"
void PL__Bibliographic__Release__write_release_blurb(OUTPUT_STREAM,
int cover_picture_number, char *cover_art_format) {
TEMPORARY_STREAM;
{
#line 803 "inform7/Chapter 33/Release Instructions.w"
if ((story_title_VAR != NULL) &&
(NonlocalVariables__has_initial_value_set(story_title_VAR))) {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(TRUNCATE_TEXT_CMODE);
NonlocalVariables__compile_initial_value(TEMP, story_title_VAR);
END_COMPILATION_MODE;
} else WRITE_TO(TEMP, "story");
WRITE_TO(TEMP, ".%s", VirtualMachines__get_blorbed_extension());
}
#line 793 "inform7/Chapter 33/Release Instructions.w"
;
WRITE("! Blurb file created by Inform build %s\n\n", NI_BUILD);
{
#line 815 "inform7/Chapter 33/Release Instructions.w"
{
#line 835 "inform7/Chapter 33/Release Instructions.w"
WRITE("status \"%f\" \"%f\"\n\n",
filename_of_cblorb_report_model,
filename_of_cblorb_report);
}
#line 815 "inform7/Chapter 33/Release Instructions.w"
;
WRITE("\n! Identification\n\n", NI_BUILD);
{
#line 842 "inform7/Chapter 33/Release Instructions.w"
WRITE("project folder \"%p\"\n", pathname_of_project);
if (create_Materials)
WRITE("release to \"%p\"\n", pathname_of_materials_release);
}
#line 817 "inform7/Chapter 33/Release Instructions.w"
;
WRITE("\n! Blorb instructions\n\n", NI_BUILD);
{
#line 849 "inform7/Chapter 33/Release Instructions.w"
WRITE("storyfile leafname \""); STREAM_COPY(OUT, TEMP); WRITE("\"\n");
if (existing_story_file)
WRITE("storyfile \"%f\" include\n", filename_of_existing_story_file);
else
WRITE("storyfile \"%f\" include\n", filename_of_story_file);
WRITE("ifiction \"%f\" include\n", filename_of_ifiction_record);
}
#line 819 "inform7/Chapter 33/Release Instructions.w"
;
{
#line 861 "inform7/Chapter 33/Release Instructions.w"
if (release_cover) {
filename *large = NULL;
if (strcmp(cover_art_format, "jpg") == 0)
large = filename_of_large_cover_art_jpeg;
else
large = filename_of_large_cover_art_png;
WRITE("cover \"%f\"\n", large);
WRITE("picture %d \"%f\"\n", cover_picture_number, large);
} else {
WRITE("cover \"%f\"\n", filename_of_large_default_cover_art);
WRITE("picture %d \"%f\"\n", 1, filename_of_large_default_cover_art);
if (release_website) {
WRITE("release file \"%f\"\n", filename_of_large_default_cover_art);
WRITE("release file \"%f\"\n", filename_of_small_default_cover_art);
}
}
}
#line 820 "inform7/Chapter 33/Release Instructions.w"
;
PL__Figures__write_blurb_commands(OUT);
PL__Sounds__write_blurb_commands(OUT);
WRITE("\n! Placeholder variables\n\n", NI_BUILD);
{
#line 884 "inform7/Chapter 33/Release Instructions.w"
WRITE("placeholder [IFID] = \"%s\"\n", PL__Bibliographic__IFID__read_uuid());
if (NonlocalVariables__has_initial_value_set(story_release_number_VAR)) {
WRITE("placeholder [RELEASE] = \"");
NonlocalVariables__compile_initial_value(OUT, story_release_number_VAR);
WRITE("\"\n");
} else WRITE("placeholder [RELEASE] = \"1\"\n");
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_ENTER(COMPILE_TEXT_TO_XML_CMODE);
if (NonlocalVariables__has_initial_value_set(story_creation_year_VAR)) {
WRITE("placeholder [YEAR] = \"");
NonlocalVariables__compile_initial_value(OUT, story_creation_year_VAR);
WRITE("\"\n");
} else WRITE("placeholder [YEAR] = \"%d\"\n", (the_present->tm_year)+1900);
if (NonlocalVariables__has_initial_value_set(story_title_VAR)) {
NonlocalVariables__treat_as_plain_text_word(story_title_VAR);
WRITE("placeholder [TITLE] = \"");
NonlocalVariables__compile_initial_value(OUT, story_title_VAR);
WRITE("\"\n");
} else WRITE("placeholder [TITLE] = \"Untitled\"\n");
if (NonlocalVariables__has_initial_value_set(story_author_VAR)) {
NonlocalVariables__treat_as_plain_text_word(story_author_VAR);
WRITE("placeholder [AUTHOR] = \"");
NonlocalVariables__compile_initial_value(OUT, story_author_VAR);
WRITE("\"\n");
} else WRITE("placeholder [AUTHOR] = \"Anonymous\"\n");
if (NonlocalVariables__has_initial_value_set(story_description_VAR)) {
NonlocalVariables__treat_as_plain_text_word(story_description_VAR);
WRITE("placeholder [BLURB] = \"");
NonlocalVariables__compile_initial_value(OUT, story_description_VAR);
WRITE("\"\n");
} else WRITE("placeholder [BLURB] = \"A work of interactive fiction.\"\n");
END_COMPILATION_MODE;
}
#line 824 "inform7/Chapter 33/Release Instructions.w"
;
WRITE("\n! Other material to release\n\n", NI_BUILD);
{
#line 927 "inform7/Chapter 33/Release Instructions.w"
if (release_source) {
if (source_public) WRITE("source public\n"); else WRITE("source\n");
}
if (release_solution) {
if (solution_public) WRITE("solution public\n"); else WRITE("solution\n");
}
if (release_card) {
if (card_public) WRITE("ifiction public\n"); else WRITE("ifiction\n");
}
}
#line 826 "inform7/Chapter 33/Release Instructions.w"
;
{
#line 943 "inform7/Chapter 33/Release Instructions.w"
auxiliary_file *af;
LOOP_OVER(af, auxiliary_file) {
char rel[MAX_FILENAME_LENGTH];
Pathnames__to_string_relative(rel, af->folder_to_release_to, pathname_of_materials_release);
WRITE("auxiliary \"%f\" \"%s\" \"%s\"\n",
af->name_of_original_file,
(af->brief_description)?(af->brief_description):"--",
(rel[0])?rel:"--");
}
if (release_booklet) {
WRITE("auxiliary \"%f\" \"Introduction to IF\" \"--\"\n", filename_of_intro_booklet);
}
if (release_postcard) {
WRITE("auxiliary \"%f\" \"IF Postcard\" \"--\"\n", filename_of_intro_postcard);
WRITE("placeholder [OTHERCREDITS] = \"The postcard was written by Andrew Plotkin "
"and designed by Lea Albaugh.\"\n");
}
}
#line 827 "inform7/Chapter 33/Release Instructions.w"
;
if (release_interpreter)
{
#line 965 "inform7/Chapter 33/Release Instructions.w"
WRITE("\n! Website instructions\n\n", NI_BUILD);
WRITE("placeholder [ENCODEDSTORYFILE] = \"");
STREAM_COPY(OUT, TEMP);
WRITE(".js\"\n");
{
#line 1007 "inform7/Chapter 33/Release Instructions.w"
for (int area=0; area<NO_FS_AREAS; area++)
WRITE("template path \"%p\"\n", pathname_of_website_templates[area]);
}
#line 969 "inform7/Chapter 33/Release Instructions.w"
;
if (interpreter_template_leafname == NULL)
interpreter_template_leafname = VirtualMachines__get_default_interpreter();
char *ext = VirtualMachines__get_blorbed_extension();
WRITE("placeholder [INTERPRETERSCRIPTS] = \" ");
auxiliary_file *af;
LOOP_OVER(af, auxiliary_file)
if (af->from_payload == JAVASCRIPT_PAYLOAD) {
char rel[MAX_FILENAME_LENGTH];
Filenames__to_string_relative(rel, af->name_of_original_file, pathname_of_area[MATERIALS_FS_AREA]);
WRITE("<script src='%s'></script>", rel);
}
LOOP_OVER(af, auxiliary_file)
if (af->from_payload == CSS_PAYLOAD) {
char rel[MAX_FILENAME_LENGTH];
Filenames__to_string_relative(rel, af->name_of_original_file, pathname_of_area[MATERIALS_FS_AREA]);
WRITE("<link rel='stylesheet' href='%s' type='text/css' media='all'></link>", rel);
}
WRITE("\"\n");
WRITE("interpreter \"%s\" \"%c\"\n", interpreter_template_leafname, ext[0]);
WRITE("base64 \"%f\" to \"%p%c",
filename_of_story_file, pathname_of_released_interpreter, FOLDER_SEPARATOR);
STREAM_COPY(OUT, TEMP);
WRITE(".js\"\n");
}
#line 828 "inform7/Chapter 33/Release Instructions.w"
;
if (release_website)
{
#line 998 "inform7/Chapter 33/Release Instructions.w"
WRITE("\n! Website instructions\n\n", NI_BUILD);
{
#line 1007 "inform7/Chapter 33/Release Instructions.w"
for (int area=0; area<NO_FS_AREAS; area++)
WRITE("template path \"%p\"\n", pathname_of_website_templates[area]);
}
#line 999 "inform7/Chapter 33/Release Instructions.w"
;
if (strcmp(website_template_leafname, "Classic") != 0) WRITE("css\n");
WRITE("website \"%s\"\n", website_template_leafname);
}
#line 829 "inform7/Chapter 33/Release Instructions.w"
;
{
#line 1016 "inform7/Chapter 33/Release Instructions.w"
ParseTree__traverse_with_stream(OUT, PL__Bibliographic__Release__visit_to_quote);
if (release_cover == FALSE) {
WRITE("status alternative ||Using 'Release along with cover art', to "
"provide something more distinctive than the default artwork above");
Index__DocReferences__link_to(OUT, "release_cover", FALSE);
WRITE("||\n");
}
if (release_website == FALSE) {
WRITE("status alternative ||Using 'Release along with a website'");
Index__DocReferences__link_to(OUT, "release_website", FALSE);
WRITE("||\n");
}
if (release_interpreter == FALSE) {
WRITE("status alternative ||Using 'Release along with an interpreter', "
"for in-browser play on your website");
Index__DocReferences__link_to(OUT, "release_interpreter", FALSE);
WRITE("||\n");
}
if (NUMBER_CREATED(auxiliary_file) == 0) {
WRITE("status alternative ||Using 'Release along with a file of "
"\"Such-and-Such\" called \"whatever.pdf\"', perhaps to add a "
"manual, or a welcoming note");
Index__DocReferences__link_to(OUT, "release_files", FALSE);
WRITE("||\n");
}
if (release_source == FALSE) {
WRITE("status alternative ||Using 'Release along with the source text'");
Index__DocReferences__link_to(OUT, "release_source", FALSE);
WRITE("||\n");
}
if (release_solution == FALSE) {
WRITE("status alternative ||Using 'Release along with a solution'");
Index__DocReferences__link_to(OUT, "release_solution", FALSE);
WRITE("||\n");
}
if (release_card == FALSE) {
WRITE("status alternative ||Using 'Release along with the library card'");
Index__DocReferences__link_to(OUT, "release_card", FALSE);
WRITE("||\n");
}
if (release_booklet == FALSE) {
WRITE("status alternative ||Using 'Release along with the introductory booklet'");
Index__DocReferences__link_to(OUT, "release_booklet", FALSE);
WRITE("||\n");
}
if (release_postcard == FALSE) {
WRITE("status alternative ||Using 'Release along with the introductory postcard'");
Index__DocReferences__link_to(OUT, "release_postcard", FALSE);
WRITE("||\n");
}
}
#line 830 "inform7/Chapter 33/Release Instructions.w"
;
}
#line 795 "inform7/Chapter 33/Release Instructions.w"
;
CLOSE_TEMPORARY_STREAM;
}
#line 1075 "inform7/Chapter 33/Release Instructions.w"
void PL__Bibliographic__Release__visit_to_quote(OUTPUT_STREAM, parse_node *p) {
if ((ParseTree__get_type(p) == SENTENCE_NT)
&& (p->down)
&& (ParseTree__int_annotation(p->down, verb_id_ANNOT) == RELEASE_VB)) {
TEMPORARY_STREAM;
Index__link_to(TEMP, Wordings__first_wn(ParseTree__get_text(p)), TRUE);
WRITE("status instruction ||");
STREAM_COPY(OUT, TEMP);
WRITE("||\n");
CLOSE_TEMPORARY_STREAM;
}
}
#line 38 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, PL__Naming__naming_new_property_notify);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, PL__Naming__naming_complete_model);
}
#line 49 "inform7/Chapter 34/The Naming Thicket.w"
int notable_naming_properties_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 60 "inform7/Chapter 34/The Naming Thicket.w"
#line 64 "inform7/Chapter 34/The Naming Thicket.w"
int PL__Naming__naming_new_property_notify(property *prn) {
if (Preform__parse_nt_against_word_range(notable_naming_properties_NTM, prn->name, NULL, NULL)) {
switch (most_recent_result) {
case 0: P_article = prn; break;
case 1: P_plural_named = prn; break;
case 2: P_proper_named = prn; break;
case 3: P_printed_name = prn; break;
case 4: P_printed_plural_name = prn; break;
case 5: Properties__exclude_from_index(prn); break;
case 6: P_privately_named = prn; /* this is the negation of "publicly named" */
Properties__exclude_from_index(prn); break;
case 7: P_adaptive_text_viewpoint = prn;
Properties__exclude_from_index(prn); break;
case 8: P_neuter = prn; break;
case 9: P_female = prn; break;
}
}
return FALSE;
}
#line 89 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__now_has_proper_name(inference_subject *infs) {
instance *wto = InferenceSubjects__as_object_instance(infs);
if (wto) PL__Naming__object_now_has_proper_name(wto);
}
void PL__Naming__object_now_has_proper_name(instance *I) {
if (P_proper_named)
Properties__EitherOr__assert(P_proper_named,
Instances__as_subject(I), TRUE, LIKELY_CE);
}
void PL__Naming__object_now_has_plural_name(instance *I) {
if (P_plural_named)
Properties__EitherOr__assert(P_plural_named,
Instances__as_subject(I), TRUE, LIKELY_CE);
}
#line 115 "inform7/Chapter 34/The Naming Thicket.w"
parse_node *text_of_word_the = NULL;
void PL__Naming__object_takes_definite_article(inference_subject *subj) {
if (text_of_word_the == NULL)
text_of_word_the = Rvalues__from_wording(Feeds__feed_text("\"the\""));
Properties__Valued__assert(P_article, subj, text_of_word_the, LIKELY_CE);
}
#line 127 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__transfer_details(inference_subject *from, inference_subject *to) {
instance *wto = InferenceSubjects__as_object_instance(to);
if (wto) {
if (World__Inferences__get_EO_state(from, P_proper_named) > 0)
PL__Naming__now_has_proper_name(to);
parse_node *art = World__Inferences__get_prop_state(from, P_article);
if (art) Properties__Valued__assert(P_article, to, art, LIKELY_CE);
}
}
instance *PL__Naming__object_this_is_named_after(instance *I) {
return InferenceSubjects__as_object_instance(
Assertions__Assemblies__what_this_is_named_after(
Instances__as_subject(I)));
}
#line 148 "inform7/Chapter 34/The Naming Thicket.w"
int PL__Naming__object_is_privately_named(instance *I) {
int certainty = World__Inferences__get_EO_state(Instances__as_subject(I), P_privately_named);
if (certainty > 0) return TRUE;
if (certainty < 0) return FALSE;
return NOT_APPLICABLE;
}
#line 160 "inform7/Chapter 34/The Naming Thicket.w"
int PL__Naming__naming_complete_model(int stage) {
if (stage == 3)
{
#line 169 "inform7/Chapter 34/The Naming Thicket.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__lt(K, K_object)) {
wording W = Kinds__Behaviour__get_name_in_play(K, FALSE);
wording PW = Kinds__Behaviour__get_name_in_play(K, TRUE);
inference_subject *subj = Kinds__Behaviour__as_subject(K);
{
#line 201 "inform7/Chapter 34/The Naming Thicket.w"
LOOP_THROUGH_WORDING(j, W) {
if (Lexer__word(j) == COMMA_V) {
Problems__Issue__subject_creation_problem(_p_(PM_CommaInName),
subj,
"has a comma in its name",
"which is forbidden. Perhaps you used a comma in "
"punctuating a sentence? Inform generally doesn't "
"like this because it reserves commas for specific "
"purposes such as dividing rules or 'if' phrases.");
break;
}
if (Vocabulary__test_flags(j, TEXT_MC+TEXTWITHSUBS_MC)) {
Problems__Issue__subject_creation_problem(_p_(BelievedImpossible),
subj,
"has some double-quoted text in its name",
"which is forbidden. Perhaps something odd happened "
"to do with punctuation between sentences? Or perhaps "
"you really do need the item to be described with "
"literal quotation marks on screen when the player "
"sees it. If so, try giving it a printed name: perhaps "
"'The printed name of Moby Dick is \"'Moby Dick'\".'");
break;
}
}
}
#line 175 "inform7/Chapter 34/The Naming Thicket.w"
;
{
#line 388 "inform7/Chapter 34/The Naming Thicket.w"
if ((Kinds__Compare__le(K, K_room) == FALSE) &&
(Kinds__Compare__eq(K, K_thing) == FALSE) &&
(World__Inferences__get_prop_state_without_inheritance(
subj, P_printed_plural_name, NULL) == NULL)) {
if (Wordings__nonempty(PW)) {
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for plural name text");
PL__Naming__compose_words_to_I6_naming_text(PROP, PW, FALSE, TRUE);
Properties__Valued__assert(P_printed_plural_name, subj,
Rvalues__from_unescaped_wording(Feeds__feed_text(STREAM_TEXT(PROP))), CERTAIN_CE);
}
}
}
#line 176 "inform7/Chapter 34/The Naming Thicket.w"
;
}
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
wording W = Instances__get_name_in_play(I, FALSE);
inference_subject *subj = Instances__as_subject(I);
int this_is_a_room = PL__Spatial__object_is_a_room(I);
int this_has_a_printed_name = PL__Naming__look_for_printed_name(subj);
int this_is_named_for_something_with_a_printed_name = FALSE;
if (PL__Naming__object_this_is_named_after(I))
if (PL__Naming__look_for_printed_name(
Instances__as_subject(PL__Naming__object_this_is_named_after(I))))
this_is_named_for_something_with_a_printed_name = TRUE;
{
#line 201 "inform7/Chapter 34/The Naming Thicket.w"
LOOP_THROUGH_WORDING(j, W) {
if (Lexer__word(j) == COMMA_V) {
Problems__Issue__subject_creation_problem(_p_(PM_CommaInName),
subj,
"has a comma in its name",
"which is forbidden. Perhaps you used a comma in "
"punctuating a sentence? Inform generally doesn't "
"like this because it reserves commas for specific "
"purposes such as dividing rules or 'if' phrases.");
break;
}
if (Vocabulary__test_flags(j, TEXT_MC+TEXTWITHSUBS_MC)) {
Problems__Issue__subject_creation_problem(_p_(BelievedImpossible),
subj,
"has some double-quoted text in its name",
"which is forbidden. Perhaps something odd happened "
"to do with punctuation between sentences? Or perhaps "
"you really do need the item to be described with "
"literal quotation marks on screen when the player "
"sees it. If so, try giving it a printed name: perhaps "
"'The printed name of Moby Dick is \"'Moby Dick'\".'");
break;
}
}
}
#line 189 "inform7/Chapter 34/The Naming Thicket.w"
;
if (this_has_a_printed_name == FALSE)
{
#line 229 "inform7/Chapter 34/The Naming Thicket.w"
if (this_has_a_printed_name == FALSE) {
wording W = Instances__get_name_in_play(I, FALSE);
if (Wordings__empty(W)) {
kind *k = Instances__to_kind(I);
W = Kinds__Behaviour__get_name_in_play(k, FALSE);
}
int begins_with_lower_case = FALSE;
if (Wordings__nonempty(W)) {
char *p = Lexer__word_raw_text(Wordings__first_wn(W));
if (islower(p[0])) begins_with_lower_case = TRUE;
}
{
#line 247 "inform7/Chapter 34/The Naming Thicket.w"
int faux = FALSE;
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for plural name text");
if (this_is_named_for_something_with_a_printed_name)
{
#line 329 "inform7/Chapter 34/The Naming Thicket.w"
faux = TRUE;
instance *owner = PL__Naming__object_this_is_named_after(I);
WRITE_TO(PROP, "SN_R_A_%d", sn_r_counter);
{
#line 375 "inform7/Chapter 34/The Naming Thicket.w"
if (SNAMES == NULL) {
SNAMES = &SNAMES_struct;
if (STREAM_OPEN_IN_MEMORY(SNAMES) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for names stream");
}
}
#line 332 "inform7/Chapter 34/The Naming Thicket.w"
;
WRITE_TO(SNAMES, "Array SN_R_A_%d --> CONSTANT_PACKED_TEXT_STORAGE SN_R_%d;\n",
sn_r_counter, sn_r_counter);
SNAMES = Routines__begin_numbered(SNAMES, "SN_R_%d", sn_r_counter++);
WRITE_TO(SNAMES, "print (name) %s, \"'s ",
Instances__identifier(owner));
wording NA = Assertions__Assemblies__get_named_after_text(subj);
LOOP_THROUGH_WORDING(j, NA) {
CompiledText__from_ISO_string(SNAMES, Lexer__word_raw_text(j), 0);
if (j<Wordings__last_wn(NA)) WRITE_TO(SNAMES, " ");
}
WRITE_TO(SNAMES, "\"; rtrue;");
SNAMES = Routines__end(SNAMES);
}
#line 253 "inform7/Chapter 34/The Naming Thicket.w"
else
{
#line 315 "inform7/Chapter 34/The Naming Thicket.w"
PL__Naming__compose_words_to_I6_naming_text(PROP, W, FALSE, (this_is_a_room)?FALSE:TRUE);
}
#line 254 "inform7/Chapter 34/The Naming Thicket.w"
;
if (Streams__all_text_accessible(PROP) == FALSE)
{
#line 270 "inform7/Chapter 34/The Naming Thicket.w"
Problems__Issue__subject_creation_problem(_p_(PM_NameTooLong),
subj,
"has too long a name",
"and will have to be cut down.");
}
#line 257 "inform7/Chapter 34/The Naming Thicket.w"
else {
if (faux)
Properties__Valued__assert(P_printed_name, subj,
Rvalues__from_permanent_STREAM(PROP), CERTAIN_CE);
else
Properties__Valued__assert(P_printed_name, subj,
Rvalues__from_unescaped_wording(Feeds__feed_text(STREAM_TEXT(PROP))), CERTAIN_CE);
}
}
#line 240 "inform7/Chapter 34/The Naming Thicket.w"
;
{
#line 281 "inform7/Chapter 34/The Naming Thicket.w"
int set_csn = TRUE, faux = FALSE;
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for plural name text");
if (this_is_named_for_something_with_a_printed_name) {
{
#line 349 "inform7/Chapter 34/The Naming Thicket.w"
faux = TRUE;
instance *owner = PL__Naming__object_this_is_named_after(I);
WRITE_TO(PROP, "SN_R_A_%d", sn_r_counter);
{
#line 375 "inform7/Chapter 34/The Naming Thicket.w"
if (SNAMES == NULL) {
SNAMES = &SNAMES_struct;
if (STREAM_OPEN_IN_MEMORY(SNAMES) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for names stream");
}
}
#line 352 "inform7/Chapter 34/The Naming Thicket.w"
;
WRITE_TO(SNAMES, "Array SN_R_A_%d --> CONSTANT_PACKED_TEXT_STORAGE SN_R_%d;\n",
sn_r_counter, sn_r_counter);
SNAMES = Routines__begin_numbered(SNAMES, "SN_R_%d", sn_r_counter++);
WRITE_TO(SNAMES,
"if (%s.&cap_short_name) PrintOrRun(%s, cap_short_name, true);\n",
Instances__identifier(owner),
Instances__identifier(owner));
WRITE_TO(SNAMES,
"else PrintOrRun(%s, short_name, true);\n",
Instances__identifier(owner));
WRITE_TO(SNAMES, "print \"'s ");
wording NA = Assertions__Assemblies__get_named_after_text(subj);
LOOP_THROUGH_WORDING(j, NA) {
CompiledText__from_ISO_string(SNAMES, Lexer__word_raw_text(j), 0);
if (j<Wordings__last_wn(NA)) WRITE_TO(SNAMES, " ");
}
WRITE_TO(SNAMES, "\"; rtrue;");
SNAMES = Routines__end(SNAMES);
}
#line 286 "inform7/Chapter 34/The Naming Thicket.w"
} else {
if ((World__Inferences__get_EO_state(subj, P_proper_named) > 0)
&& (begins_with_lower_case))
{
#line 320 "inform7/Chapter 34/The Naming Thicket.w"
PL__Naming__compose_words_to_I6_naming_text(PROP, W, TRUE, (this_is_a_room)?FALSE:TRUE);
}
#line 290 "inform7/Chapter 34/The Naming Thicket.w"
else set_csn = FALSE;
}
if (set_csn) {
if (P_cap_short_name == NULL)
P_cap_short_name = Properties__Valued__new_nameless(
"cap_short_name", K_text);
if (Streams__all_text_accessible(PROP) == FALSE)
{
#line 270 "inform7/Chapter 34/The Naming Thicket.w"
Problems__Issue__subject_creation_problem(_p_(PM_NameTooLong),
subj,
"has too long a name",
"and will have to be cut down.");
}
#line 298 "inform7/Chapter 34/The Naming Thicket.w"
else {
if (faux)
Properties__Valued__assert(P_cap_short_name, subj,
Rvalues__from_permanent_STREAM(PROP), CERTAIN_CE);
else
Properties__Valued__assert(P_cap_short_name, subj,
Rvalues__from_unescaped_wording(Feeds__feed_text(STREAM_TEXT(PROP))), CERTAIN_CE);
}
}
}
#line 241 "inform7/Chapter 34/The Naming Thicket.w"
;
}
}
#line 190 "inform7/Chapter 34/The Naming Thicket.w"
;
if (language_of_play != English_language)
{
#line 405 "inform7/Chapter 34/The Naming Thicket.w"
parse_node *spec = World__Inferences__get_prop_state(subj, P_grammatical_gender);
if (spec) {
int g = ParseTree__int_annotation(spec, constant_enumeration_ANNOT);
switch (g) {
case NEUTER_GENDER:
if (World__Permissions__grant(subj, P_neuter, TRUE))
Properties__EitherOr__assert(P_neuter, subj, TRUE, LIKELY_CE);
break;
case MASCULINE_GENDER:
if (World__Permissions__grant(subj, P_female, TRUE))
Properties__EitherOr__assert(P_female, subj, FALSE, LIKELY_CE);
break;
case FEMININE_GENDER:
if (World__Permissions__grant(subj, P_female, TRUE))
Properties__EitherOr__assert(P_female, subj, TRUE, LIKELY_CE);
break;
}
}
}
#line 192 "inform7/Chapter 34/The Naming Thicket.w"
;
}
}
#line 161 "inform7/Chapter 34/The Naming Thicket.w"
;
return FALSE;
}
#line 431 "inform7/Chapter 34/The Naming Thicket.w"
int PL__Naming__look_for_printed_name(inference_subject *subj) {
inference_subject *check;
for (check = subj; check; check = InferenceSubjects__narrowest_broader_subject(check)) {
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, check, PROPERTY_INF)
if (World__Inferences__added_in_construction(inf) == FALSE)
if (World__Inferences__get_property(inf) == P_printed_name)
return TRUE;
}
return FALSE;
}
#line 447 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__compose_words_to_I6_naming_text(OUTPUT_STREAM, wording W, int cap, int your_flag) {
WRITE("\"");
if (Wordings__nonempty(W)) {
LOOP_THROUGH_WORDING(j, W) {
int your_here = Preform__parse_nt_against_word_range(possessive_second_person_NTM, Wordings__one_word(j), NULL, NULL);
char *p = Lexer__word_raw_text(j);
if (cap) {
if ((j==Wordings__first_wn(W)) && (your_here) && (your_flag)) {
WRITE("%c", Platform__toupper(p[0]));
CompiledText__from_ISO_string(OUT, p+1, CT_RAW);
} else if (j==Wordings__first_wn(W)) {
CompiledText__from_ISO_string(OUT, p, CT_RAW + CT_CAPITALISE);
} else {
CompiledText__from_ISO_string(OUT, p, CT_RAW);
}
} else {
if ((j==Wordings__first_wn(W)) && (your_here) && (your_flag)) {
WRITE("%c", Platform__tolower(p[0]));
CompiledText__from_ISO_string(OUT, p+1, CT_RAW);
} else CompiledText__from_ISO_string(OUT, p, CT_RAW);
}
if (j<Wordings__last_wn(W)) WRITE(" ");
}
} else {
if (cap) WRITE("Object"); else WRITE("object");
}
WRITE("\"");
}
#line 479 "inform7/Chapter 34/The Naming Thicket.w"
void PL__Naming__compile_small_names(OUTPUT_STREAM) {
if (SNAMES) {
STREAM_COPY(OUT, SNAMES);
STREAM_CLOSE(SNAMES);
}
}
#line 38 "inform7/Chapter 34/Instance Counting.w"
void PL__Counting__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_SUBJECT_NOTIFY, PL__Counting__counting_new_subject_notify);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, PL__Counting__counting_complete_model);
PLUGIN_REGISTER(PLUGIN_COMPILE_MODEL_TABLES, PL__Counting__counting_compile_model_tables);
PLUGIN_REGISTER(PLUGIN_ESTIMATE_PROPERTY_USAGE, PL__Counting__counting_estimate_property_usage);
}
#line 49 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__counting_new_subject_notify(inference_subject *subj) {
CREATE_PF_DATA(counting, subj, PL__Counting__new_data);
return FALSE;
}
counting_data *PL__Counting__new_data(inference_subject *subj) {
counting_data *cd = CREATE(counting_data);
cd->instance_count_prop = NULL;
cd->instance_link_prop = NULL;
cd->has_instances = FALSE;
return cd;
}
#line 76 "inform7/Chapter 34/Instance Counting.w"
int *kind_instance_counts = NULL;
int max_kind_instance_count = 0;
void PL__Counting__make_instance_counts(void) {
{
#line 87 "inform7/Chapter 34/Instance Counting.w"
max_kind_instance_count = NUMBER_CREATED(inference_subject);
kind_instance_counts =
Memory__I7_calloc(max_kind_instance_count*max_kind_instance_count, sizeof(int),
INSTANCE_COUNTING_MREASON);
}
#line 80 "inform7/Chapter 34/Instance Counting.w"
;
{
#line 96 "inform7/Chapter 34/Instance Counting.w"
instance *I;
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__lt(K, K_object))
LOOP_OVER_OBJECT_INSTANCES(I)
INSTANCE_COUNT(I, K) = -1;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__lt(K, K_object)) {
int ix_count = 0;
LOOP_OVER_INSTANCES(I, K)
INSTANCE_COUNT(I, K) = ix_count++;
}
}
#line 81 "inform7/Chapter 34/Instance Counting.w"
;
}
#line 113 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__instance_count(instance *I, kind *K) {
if (kind_instance_counts == NULL) internal_error("instance counts not available");
if (K == NULL) internal_error("instance counts available only for objects");
return INSTANCE_COUNT(I, K);
}
#line 132 "inform7/Chapter 34/Instance Counting.w"
instance *PL__Counting__next_instance_of(instance *I, kind *k) {
if (k == NULL) return NULL;
int resuming = TRUE;
if (I == NULL) { I = FIRST_IN_COMPILATION_SEQUENCE; resuming = FALSE; }
while (I) {
if (resuming) I = NEXT_IN_COMPILATION_SEQUENCE(I);
resuming = TRUE;
if (I == NULL) break;
if (InferenceSubjects__aliased_but_diverted(Instances__as_subject(I)))
continue; /* |selfobj| may not count */
if (Instances__of_kind(I, k)) return I;
}
return NULL;
}
#line 150 "inform7/Chapter 34/Instance Counting.w"
parse_node *PL__Counting__next_instance_of_as_value(instance *I, kind *k) {
instance *next = PL__Counting__next_instance_of(I, k);
if (next) return Rvalues__from_instance(next);
return Rvalues__new_nothing_object_constant();
}
#line 166 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__counting_compile_model_tables(OUTPUT_STREAM) {
{
#line 183 "inform7/Chapter 34/Instance Counting.w"
WRITE("Array KindHierarchy --> K0_kind (0) ");
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__lt(K, K_object))
WRITE("%s (%d) ", Kinds__Behaviour__I6_classname(K),
PL__Counting__kind_of_object_count(Kinds__Compare__super(K)));
WRITE(";\n");
}
#line 167 "inform7/Chapter 34/Instance Counting.w"
;
{
#line 196 "inform7/Chapter 34/Instance Counting.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__lt(K, K_object)) {
WRITE("Constant IK%d_First = ", Kinds__Behaviour__I6_classnumber(K));
Specifications__Compiler__compile(OUT, PL__Counting__next_instance_of_as_value(NULL, K));
WRITE(";\n");
}
}
#line 168 "inform7/Chapter 34/Instance Counting.w"
;
return FALSE;
}
#line 207 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__kind_of_object_count(kind *K) {
int c = 0;
if (K == NULL) return 0;
kind *IK;
LOOP_OVER_BASE_KINDS(IK)
if (Kinds__Compare__lt(IK, K_object)) {
c++;
if (Kinds__Compare__eq(IK, K)) return c;
}
return 0;
}
#line 235 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__counting_complete_model(int stage) {
if (stage == 1) {
{
#line 251 "inform7/Chapter 34/Instance Counting.w"
P_vector = Properties__Valued__new_nameless("vector", K_number);
parse_node *zero = Rvalues__from_int(0, EMPTY_WORDING);
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
Properties__Valued__assert(P_vector,
Instances__as_subject(I), zero, CERTAIN_CE);
}
#line 237 "inform7/Chapter 34/Instance Counting.w"
;
}
if (stage == 4) {
{
#line 261 "inform7/Chapter 34/Instance Counting.w"
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__lt(K, K_object)) {
inference_subject *subj = Kinds__Behaviour__as_subject(K);
char pname[32];
sprintf(pname, "IK%d_Count", Kinds__Behaviour__I6_classnumber(K));
PF_S(counting, subj)->instance_count_prop =
Properties__Valued__new_nameless(pname, K_number);
sprintf(pname, "IK%d_Link", Kinds__Behaviour__I6_classnumber(K));
PF_S(counting, subj)->instance_link_prop =
Properties__Valued__new_nameless(pname, K_object);
}
P_KD_Count = Properties__Valued__new_nameless("KD_Count", K_number);
}
#line 240 "inform7/Chapter 34/Instance Counting.w"
;
PL__Counting__make_instance_counts();
{
#line 278 "inform7/Chapter 34/Instance Counting.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
{
#line 305 "inform7/Chapter 34/Instance Counting.w"
int ic = PL__Counting__kind_of_object_count(Instances__to_kind(I));
parse_node *the_count = Rvalues__from_int(ic, EMPTY_WORDING);
Properties__Valued__assert(
P_KD_Count, Instances__as_subject(I), the_count, CERTAIN_CE);
}
#line 280 "inform7/Chapter 34/Instance Counting.w"
;
inference_subject *infs;
for (infs = Kinds__Behaviour__as_subject(Instances__to_kind(I));
infs; infs = InferenceSubjects__narrowest_broader_subject(infs)) {
kind *K = InferenceSubjects__as_kind(infs);
if (Kinds__Compare__lt(K, K_object)) {
inference_subject *subj = Kinds__Behaviour__as_subject(K);
PF_S(counting, subj)->has_instances = TRUE;
{
#line 318 "inform7/Chapter 34/Instance Counting.w"
int ic = INSTANCE_COUNT(I, K);
parse_node *the_count = Rvalues__from_int(ic, EMPTY_WORDING);
Properties__Valued__assert(
PF_S(counting, subj)->instance_count_prop,
Instances__as_subject(I), the_count, CERTAIN_CE);
}
#line 288 "inform7/Chapter 34/Instance Counting.w"
;
{
#line 328 "inform7/Chapter 34/Instance Counting.w"
Properties__Valued__assert(
PF_S(counting, subj)->instance_link_prop,
Instances__as_subject(I), PL__Counting__next_instance_of_as_value(I, K), CERTAIN_CE);
}
#line 289 "inform7/Chapter 34/Instance Counting.w"
;
}
}
}
}
#line 242 "inform7/Chapter 34/Instance Counting.w"
;
}
return FALSE;
}
#line 337 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__counting_estimate_property_usage(kind *k, int *words_used) {
inference_subject *infs;
for (infs = InferenceSubjects__narrowest_broader_subject(Kinds__Behaviour__as_subject(k));
infs; infs = InferenceSubjects__narrowest_broader_subject(infs)) {
kind *k2 = InferenceSubjects__as_kind(infs);
if (Kinds__Compare__lt(k2, K_object))
*words_used += 4;
}
return FALSE;
}
#line 354 "inform7/Chapter 34/Instance Counting.w"
int PL__Counting__optimise_loop(i6_schema *sch, kind *K) {
if (Plugins__Manage__plugged_in(counting_plugin) == FALSE) return FALSE;
inference_subject *subj = Kinds__Behaviour__as_subject(K);
if (PF_S(counting, subj)->has_instances == FALSE) /* (to avoid writing misleading code) */
Calculus__Schemas__modify(sch,
"for (*1=nothing: false: )");
else
Calculus__Schemas__modify(sch,
"for (*1=IK%d_First: *1: *1=*1.IK%d_Link)",
Kinds__Behaviour__I6_classnumber(K), Kinds__Behaviour__I6_classnumber(K));
return TRUE;
}
#line 100 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL__Spatial__spatial_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_ACT_ON_SPECIAL_NPS, PL__Spatial__spatial_act_on_special_NPs);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, PL__Spatial__IF_complete_model);
PLUGIN_REGISTER(PLUGIN_DEFAULT_APPEARANCE, PL__Spatial__spatial_default_appearance);
PLUGIN_REGISTER(PLUGIN_INFERENCES_CONTRADICT, PL__Spatial__spatial_inferences_contradict);
PLUGIN_REGISTER(PLUGIN_EXPLAIN_CONTRADICTION, PL__Spatial__spatial_explain_contradiction);
PLUGIN_REGISTER(PLUGIN_LOG_INFERENCE_TYPE, PL__Spatial__spatial_log_inference_type);
PLUGIN_REGISTER(PLUGIN_NAME_TO_EARLY_INFS, PL__Spatial__spatial_name_to_early_infs);
PLUGIN_REGISTER(PLUGIN_NEW_SUBJECT_NOTIFY, PL__Spatial__spatial_new_subject_notify);
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, PL__Spatial__spatial_new_property_notify);
PLUGIN_REGISTER(PLUGIN_PARSE_COMPOSITE_NQS, PL__Spatial__spatial_parse_composite_NQs);
PLUGIN_REGISTER(PLUGIN_SET_KIND_NOTIFY, PL__Spatial__spatial_set_kind_notify);
PLUGIN_REGISTER(PLUGIN_SET_SUBKIND_NOTIFY, PL__Spatial__spatial_set_subkind_notify);
PLUGIN_REGISTER(PLUGIN_ADD_TO_WORLD_INDEX, PL__Spatial__spatial_add_to_World_index);
PLUGIN_REGISTER(PLUGIN_INTERVENE_IN_ASSERTION, PL__Spatial__spatial_intervene_in_assertion);
{
#line 138 "inform7/Chapter 34/Spatial Model.w"
infs_room = InferenceSubjects__new(global_constants,
FUND_SUB, NULL_GENERAL_POINTER, LIKELY_CE);
infs_thing = InferenceSubjects__new(global_constants,
FUND_SUB, NULL_GENERAL_POINTER, LIKELY_CE);
infs_supporter = InferenceSubjects__new(global_constants,
FUND_SUB, NULL_GENERAL_POINTER, LIKELY_CE);
infs_person = InferenceSubjects__new(global_constants,
FUND_SUB, NULL_GENERAL_POINTER, LIKELY_CE);
}
#line 116 "inform7/Chapter 34/Spatial Model.w"
;
}
#line 154 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_name_to_early_infs(wording W, inference_subject **infs) {
if (Preform__parse_nt_against_word_range(notable_spatial_kinds_NTM, W, NULL, NULL)) {
switch (most_recent_result) {
case 0: if (K_room == NULL) *infs = infs_room; break;
case 1: if (K_thing == NULL) *infs = infs_thing; break;
/* container isn't an early case, surprisingly */
case 3: if (K_supporter == NULL) *infs = infs_supporter; break;
case 4: if (K_person == NULL) *infs = infs_person; break;
}
}
return FALSE;
}
#line 170 "inform7/Chapter 34/Spatial Model.w"
spatial_data *PL__Spatial__new_data(inference_subject *subj) {
spatial_data *sd = CREATE(spatial_data);
sd->progenitor = NULL; sd->progenitor_set_at = NULL; sd->part_flag = FALSE;
sd->object_tree_parent = NULL; sd->object_tree_child = NULL; sd->object_tree_sibling = NULL;
sd->incorp_tree_child = NULL; sd->incorp_tree_sibling = NULL; sd->incorp_tree_parent = NULL;
sd->I6_definition_depth = 0;
sd->here_flag = FALSE;
return sd;
}
#line 186 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_log_inference_type(int it) {
switch(it) {
case CONTAINS_THINGS_INF: LOG("CONTAINS_THINGS_INF"); return TRUE;
case IS_ROOM_INF: LOG("IS_ROOM_INF"); return TRUE;
case PARENTAGE_HERE_INF: LOG("PARENTAGE_HERE_INF"); return TRUE;
case PARENTAGE_NOWHERE_INF: LOG("PARENTAGE_NOWHERE_INF"); return TRUE;
case PARENTAGE_INF: LOG("PARENTAGE_INF"); return TRUE;
case PART_OF_INF: LOG("PART_OF_INF"); return TRUE;
}
return FALSE;
}
int PL__Spatial__spatial_inferences_contradict(inference *A, inference *B, int similarity) {
if ((World__Inferences__get_inference_type(A) == PARENTAGE_INF) &&
(World__Inferences__get_reference_as_object(A) !=
World__Inferences__get_reference_as_object(B)))
return TRUE;
return FALSE;
}
int PL__Spatial__spatial_explain_contradiction(inference *A, inference *B, int similarity,
inference_subject *subj) {
if ((World__Inferences__get_inference_type(A) == PARENTAGE_INF) &&
(World__Inferences__get_reference_as_object(A) !=
World__Inferences__get_reference_as_object(B))) {
Problems__quote_source(1, World__Inferences__where_inferred(A));
Problems__quote_source(2, World__Inferences__where_inferred(B));
Problems__quote_subject(3, subj);
Problems__quote_object(4, World__Inferences__get_reference_as_object(A));
Problems__quote_object(5, World__Inferences__get_reference_as_object(B));
Problems__Issue__handmade_problem(_p_(PM_SpatialContradiction));
Problems__issue_problem_segment(
"You wrote %1, but also %2: that seems to be saying that the same "
"object (%3) must be in two different places (%4 and %5). This "
"looks like a contradiction. %P"
"This sometimes happens as a result of a sentence like 'Every person "
"carries a bag', when Inform doesn't know 'bag' as the name of any "
"kind - so that it makes only a single thing called 'bag', and then "
"the sentence looks as if it says everyone is carrying the same bag.");
Problems__issue_problem_end();
return TRUE;
}
return FALSE;
}
#line 237 "inform7/Chapter 34/Spatial Model.w"
int notable_spatial_kinds_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 243 "inform7/Chapter 34/Spatial Model.w"
#line 247 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_new_base_kind_notify(kind *new_base, char *name, wording W) {
if (Preform__parse_nt_against_word_range(notable_spatial_kinds_NTM, W, NULL, NULL)) {
switch (most_recent_result) {
case 0: K_room = new_base; return TRUE;
case 1: K_thing = new_base; return TRUE;
case 2: K_container = new_base; return TRUE;
case 3: K_supporter = new_base; return TRUE;
case 4: K_person = new_base; return TRUE;
}
}
return FALSE;
}
int PL__Spatial__spatial_new_subject_notify(inference_subject *subj) {
CREATE_PF_DATA(spatial, subj, PL__Spatial__new_data);
return FALSE;
}
#line 270 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_set_kind_notify(instance *I, kind *k) {
kind *kw = Instances__to_kind(I);
if ((!(Kinds__Compare__le(kw, K_room))) &&
(Kinds__Compare__le(k, K_room)))
World__Inferences__draw(IS_ROOM_INF, Instances__as_subject(I), CERTAIN_CE,
NULL, NULL);
return FALSE;
}
#line 283 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_set_subkind_notify(kind *sub, kind *super) {
if ((sub == K_thing) && (super != K_object)) {
if (problem_count == 0)
Problems__Issue__sentence_problem(_p_(PM_ThingAdrift),
"'thing' is not allowed to be a kind of anything (other than "
"'object')",
"because it's too fundamental to the way Inform uses rooms "
"and things to model the physical world.");
return TRUE;
}
if ((sub == K_room) && (super != K_object)) {
if (problem_count == 0)
Problems__Issue__sentence_problem(_p_(PM_RoomAdrift),
"'room' is not allowed to be a kind of anything (other than "
"'object')",
"because it's too fundamental to the way Inform uses rooms "
"and things to model the physical world.");
return TRUE;
}
if (((sub == K_container) && (super == K_supporter)) ||
((sub == K_supporter) && (super == K_container))) {
if (problem_count == 0)
Problems__Issue__sentence_problem(_p_(PM_ContainerAdrift),
"'container' and 'supporter' are not allowed to be kinds "
"of each other",
"because they're too fundamental to the way Inform models the "
"physical world. Both are kinds of 'thing', but they are "
"different, and no object is allowed to belong to both at once.");
return TRUE;
}
return FALSE;
}
#line 319 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__object_is_a_room(instance *I) {
if ((Plugins__Manage__plugged_in(spatial_plugin)) && (K_room) && (I) &&
(Instances__of_kind(I, K_room)))
return TRUE;
return FALSE;
}
#line 330 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__get_world_size(int *rooms, int *things) {
instance *I;
*rooms = 0; *things = 0;
LOOP_OVER_INSTANCES(I, K_room) (*rooms)++;
LOOP_OVER_INSTANCES(I, K_thing) (*things)++;
}
#line 348 "inform7/Chapter 34/Spatial Model.w"
int notable_spatial_properties_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 353 "inform7/Chapter 34/Spatial Model.w"
#line 357 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_new_property_notify(property *prn) {
if (Preform__parse_nt_against_word_range(notable_spatial_properties_NTM, prn->name, NULL, NULL)) {
switch (most_recent_result) {
case 0: P_initial_appearance = prn; break;
case 1: P_wearable = prn; break;
case 2: P_fixed_in_place = prn; break;
case 3: P_matching_key = prn;
Properties__set_translation(P_matching_key, "with_key");
break;
}
}
return FALSE;
}
#line 378 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_default_appearance(inference_subject *infs, parse_node *txt) {
if (InferenceSubjects__is_within(infs, Kinds__Behaviour__as_subject(K_object))) {
property *set_prn = P_description;
if (InferenceSubjects__is_within(infs, Kinds__Behaviour__as_subject(K_thing))) {
instance *I = InferenceSubjects__as_object_instance(infs);
if ((I) && (PL__Backdrops__object_is_scenery(I))) {
inference *inf;
KNOWLEDGE_LOOP(inf, infs, PROPERTY_INF) {
property *prn = World__Inferences__get_property(inf);
if (((prn) && (World__Inferences__get_certainty(inf) > 0)) &&
(prn == P_description)) {
{
#line 407 "inform7/Chapter 34/Spatial Model.w"
Problems__Issue__object_problem(_p_(PM_SceneryDoublyDescribed),
I,
"is scenery, which means that it cannot sensibly have any 'initial "
"appearance' property - being scenery, it isn't announced when the "
"player first sees it. That means the quoted text about it has to "
"be read as its 'description' instead, seen when the player examines "
"it. But the source text writes out its description, too",
"which means we have a subtle little contradiction here.");
}
#line 389 "inform7/Chapter 34/Spatial Model.w"
;
return TRUE;
}
}
} else set_prn = P_initial_appearance;
}
Properties__Valued__assert(set_prn, infs, txt, CERTAIN_CE);
return TRUE;
}
return FALSE;
}
#line 422 "inform7/Chapter 34/Spatial Model.w"
int spatial_specifying_nouns_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; kind_k_NTMV = K_thing;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; kind_k_NTMV = K_room;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; kind_k_NTMV = K_person;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; kind_k_NTMV = K_thing; quantifier_q_NTMV = for_all_quantifier;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 0; kind_k_NTMV = K_room; quantifier_q_NTMV = for_all_quantifier;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = 0; kind_k_NTMV = K_person; quantifier_q_NTMV = for_all_quantifier;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = 0; kind_k_NTMV = K_room; quantifier_q_NTMV = not_exists_quantifier;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = 0; kind_k_NTMV = K_person; quantifier_q_NTMV = not_exists_quantifier;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = 0; kind_k_NTMV = K_person; quantifier_q_NTMV = not_exists_quantifier;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 432 "inform7/Chapter 34/Spatial Model.w"
#line 448 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_parse_composite_NQs(wording *W, wording *DW,
quantifier **quant, kind **some_kind) {
if (K_thing) {
quantifier_q_NTMV = NULL; kind_k_NTMV = NULL;
if (Preform__parse_nt_against_word_range(spatial_specifying_nouns_NTM, *W, NULL, NULL)) {
*W = Wordings__from(*W, Wordings__first_wn(GET_RW(spatial_specifying_nouns_NTM, 1)));
*quant = quantifier_q_NTMV; *some_kind = kind_k_NTMV;
return TRUE;
}
}
return FALSE;
}
#line 466 "inform7/Chapter 34/Spatial Model.w"
int notable_spatial_noun_phrases_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 468 "inform7/Chapter 34/Spatial Model.w"
#line 472 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_act_on_special_NPs(parse_node *p) {
if ((Preform__parse_nt_against_word_range(notable_spatial_noun_phrases_NTM, ParseTree__get_text(p), NULL, NULL)) &&
(Text__unexpectedly_upper_case(Wordings__first_wn(ParseTree__get_text(p))) == FALSE) &&
(K_room)) {
Assertions__Refiner__noun_from_value(p, Rvalues__new_nothing_object_constant());
ParseTree__annotate_int(p, nowhere_ANNOT, TRUE);
return TRUE;
}
return FALSE;
}
#line 486 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_intervene_in_assertion(parse_node *px, parse_node *py) {
if (ParseTree__int_annotation(py, nowhere_ANNOT)) {
inference_subject *left_subject = ParseTree__get_subject(px);
if (left_subject) {
if (InferenceSubjects__domain(left_subject))
Problems__Issue__subject_problem_at_sentence(_p_(PM_KindNowhere),
left_subject,
"seems to be said to be 'nowhere' in some way",
"which doesn't make sense. An individual thing can be 'nowhere', "
"but here we're talking about a whole kind, and it's not allowed "
"to talk about general locations of a whole kind of things at once.");
else Calculus__Propositions__Assert__assert_true_about(
Calculus__Propositions__Abstract__to_put_nowhere(), left_subject, prevailing_mood);
return TRUE;
}
}
return FALSE;
}
#line 523 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__infer_presence_here(instance *I) {
inference_subject *infs = Instances__as_subject(I);
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, infs, PARENTAGE_HERE_INF) {
Problems__Issue__contradiction_problem(_p_(PM_DuplicateHere),
World__Inferences__where_inferred(inf),
current_sentence,
I,
"can only be said to be 'here' once",
"in a single assertion sentence. This avoids potential confusion, "
"since 'here' can mean different things in different sentences.");
}
World__Inferences__draw(PARENTAGE_HERE_INF, infs, CERTAIN_CE,
Assertions__Traverse__get_current_subject(), NULL);
World__Inferences__draw(IS_ROOM_INF, infs, IMPOSSIBLE_CE, NULL, NULL);
}
#line 544 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__infer_presence_nowhere(instance *I) {
World__Inferences__draw(PARENTAGE_NOWHERE_INF,
Instances__as_subject(I), CERTAIN_CE, NULL, NULL);
World__Inferences__draw(IS_ROOM_INF, Instances__as_subject(I), IMPOSSIBLE_CE,
NULL, NULL);
}
#line 556 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__IF_complete_model(int stage) {
switch(stage) {
case 1: PL__Spatial__spatial_stage_I(); break;
case 2: PL__Spatial__spatial_stage_II(); break;
case 3: PL__Spatial__spatial_stage_III(); break;
case 4: PL__Spatial__spatial_stage_IV(); break;
}
return FALSE;
}
#line 575 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_stage_I(void) {
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
{
#line 607 "inform7/Chapter 34/Spatial Model.w"
current_sentence = Instances__get_creating_sentence(I);
kind *designers_choice = NULL;
{
#line 630 "inform7/Chapter 34/Spatial Model.w"
kind *f = NULL;
inference_subject *infs;
for (infs = Kinds__Behaviour__as_subject(Instances__to_kind(I));
infs; infs = InferenceSubjects__narrowest_broader_subject(infs)) {
kind *K = InferenceSubjects__as_kind(infs);
if (Kinds__Compare__lt(K, K_object)) {
f = K;
if ((Kinds__Compare__eq(f, K_container)) ||
(Kinds__Compare__eq(f, K_supporter)) ||
(Kinds__Compare__eq(f, K_door)) ||
(Kinds__Compare__eq(f, K_person)))
designers_choice = f;
}
}
if (designers_choice == NULL) designers_choice = f;
}
#line 610 "inform7/Chapter 34/Spatial Model.w"
;
kind *geography_choice = NULL;
inference *geography_inference = NULL;
int geography_certainty = UNKNOWN_CE;
{
#line 651 "inform7/Chapter 34/Spatial Model.w"
inference *inf;
KNOWLEDGE_LOOP(inf, Instances__as_subject(I), CONTAINS_THINGS_INF)
if (World__Inferences__get_certainty(inf) > geography_certainty) {
geography_choice = K_container;
geography_certainty = World__Inferences__get_certainty(inf);
geography_inference = inf;
}
KNOWLEDGE_LOOP(inf, Instances__as_subject(I), IS_ROOM_INF)
if ((World__Inferences__get_certainty(inf) > UNKNOWN_CE) ||
(World__Inferences__get_certainty(inf) > geography_certainty)) {
geography_choice = K_room;
geography_certainty = World__Inferences__get_certainty(inf);
geography_inference = inf;
}
}
#line 615 "inform7/Chapter 34/Spatial Model.w"
;
if ((geography_choice) &&
(Kinds__Compare__eq(geography_choice, designers_choice) == FALSE))
{
#line 674 "inform7/Chapter 34/Spatial Model.w"
parse_node *sentence_setting_kind = Instances__get_kind_set_sentence(I);
if ((designers_choice == NULL) ||
((geography_certainty == CERTAIN_CE) &&
(Kinds__Compare__le(geography_choice, designers_choice))))
{
#line 687 "inform7/Chapter 34/Spatial Model.w"
LOGIF(KIND_CHANGES, "Accepting geography choice of kind of $O as $u\n",
I, geography_choice);
Calculus__Propositions__Abstract__assert_kind_of_object(I, geography_choice);
}
#line 678 "inform7/Chapter 34/Spatial Model.w"
else if ((geography_certainty == CERTAIN_CE) &&
(!((Kinds__Compare__eq(designers_choice, K_door)) &&
(Kinds__Compare__eq(geography_choice, K_room)))))
{
#line 694 "inform7/Chapter 34/Spatial Model.w"
LOG("Choices: designer $u, geography $u.\n", designers_choice, geography_choice);
parse_node *decider = Instances__get_creating_sentence(I);
if (sentence_setting_kind) decider = sentence_setting_kind;
if (Kinds__Compare__eq(designers_choice, K_person))
{
#line 708 "inform7/Chapter 34/Spatial Model.w"
Problems__Issue__contradiction_problem(_p_(PM_PersonContaining),
sentence_setting_kind,
World__Inferences__where_inferred(geography_inference), I,
"cannot contain or support things like something inanimate",
"which is what you are implying. Instead, people must carry or wear them: "
"so 'The briefcase is in Daphne.' is disallowed, but 'The briefcase is "
"carried by Daphne.' is fine, or indeed 'Daphne carries the briefcase.'");
}
#line 698 "inform7/Chapter 34/Spatial Model.w"
else if ((Kinds__Compare__eq(designers_choice, K_supporter)) &&
(Kinds__Compare__eq(geography_choice, K_container)))
{
#line 720 "inform7/Chapter 34/Spatial Model.w"
Problems__Issue__contradiction_problem(_p_(PM_CantContainAndSupport),
decider, World__Inferences__where_inferred(geography_inference), I,
"cannot both contain things and support things",
"which is what you're implying here. If you need both, the easiest way is "
"to make it either a supporter with a container attached or vice versa. "
"For instance: 'A desk is here. On the desk is a newspaper. An openable "
"container called the drawer is part of the desk. In the drawer is a "
"stapler.'");
}
#line 701 "inform7/Chapter 34/Spatial Model.w"
else
{
#line 732 "inform7/Chapter 34/Spatial Model.w"
Problems__Issue__contradiction_problem(_p_(PM_BothRoomAndSupporter),
decider,
World__Inferences__where_inferred(geography_inference), I,
"would need to have two different and incompatible kinds to make both "
"sentences true",
"and this is a contradiction.");
}
#line 703 "inform7/Chapter 34/Spatial Model.w"
;
}
#line 682 "inform7/Chapter 34/Spatial Model.w"
;
}
#line 619 "inform7/Chapter 34/Spatial Model.w"
;
if (Kinds__Compare__eq(Instances__to_kind(I), K_object))
Calculus__Propositions__Abstract__assert_kind_of_object(I, K_thing);
}
#line 578 "inform7/Chapter 34/Spatial Model.w"
;
return FALSE;
}
#line 750 "inform7/Chapter 34/Spatial Model.w"
instance *PL__Spatial__progenitor(instance *I) {
if (I == NULL) return NULL;
if (Plugins__Manage__plugged_in(spatial_plugin) == FALSE) return NULL;
return PF_I(spatial, I)->progenitor;
}
void PL__Spatial__set_progenitor(instance *of, instance *to, inference *reason) {
if (Plugins__Manage__plugged_in(spatial_plugin) == FALSE)
internal_error("spatial plugin inactive");
if (to == NULL) internal_error("set progenitor of nothing");
PF_I(spatial, of)->progenitor = to;
PF_I(spatial, of)->progenitor_set_at =
(reason)?World__Inferences__where_inferred(reason):NULL;
}
#line 768 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__void_progenitor(instance *of) {
if (Plugins__Manage__plugged_in(spatial_plugin) == FALSE)
internal_error("spatial plugin inactive");
PF_I(spatial, of)->progenitor = NULL;
PF_I(spatial, of)->progenitor_set_at = NULL;
}
#line 781 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_stage_II(void) {
{
#line 797 "inform7/Chapter 34/Spatial Model.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
PF_I(spatial, I)->here_flag = FALSE;
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), PARENTAGE_HERE_INF)
PF_I(spatial, I)->here_flag = TRUE;
}
}
#line 782 "inform7/Chapter 34/Spatial Model.w"
;
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PF_I(spatial, I)->here_flag == FALSE)
{
#line 834 "inform7/Chapter 34/Spatial Model.w"
inference *parent_setting_inference = NULL;
{
#line 850 "inform7/Chapter 34/Spatial Model.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), PARENTAGE_NOWHERE_INF)
{
#line 861 "inform7/Chapter 34/Spatial Model.w"
if (parent_setting_inference) {
Problems__Issue__contradiction_problem(_p_(PM_DuplicateParentage),
World__Inferences__where_inferred(parent_setting_inference),
World__Inferences__where_inferred(inf),
I,
"can only be given its position once",
"in a single assertion sentence.");
}
parent_setting_inference = inf;
}
#line 852 "inform7/Chapter 34/Spatial Model.w"
;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), PARENTAGE_HERE_INF)
{
#line 861 "inform7/Chapter 34/Spatial Model.w"
if (parent_setting_inference) {
Problems__Issue__contradiction_problem(_p_(PM_DuplicateParentage),
World__Inferences__where_inferred(parent_setting_inference),
World__Inferences__where_inferred(inf),
I,
"can only be given its position once",
"in a single assertion sentence.");
}
parent_setting_inference = inf;
}
#line 854 "inform7/Chapter 34/Spatial Model.w"
;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), PARENTAGE_INF)
{
#line 861 "inform7/Chapter 34/Spatial Model.w"
if (parent_setting_inference) {
Problems__Issue__contradiction_problem(_p_(PM_DuplicateParentage),
World__Inferences__where_inferred(parent_setting_inference),
World__Inferences__where_inferred(inf),
I,
"can only be given its position once",
"in a single assertion sentence.");
}
parent_setting_inference = inf;
}
#line 856 "inform7/Chapter 34/Spatial Model.w"
;
}
#line 835 "inform7/Chapter 34/Spatial Model.w"
;
if (parent_setting_inference) {
instance *whereabouts =
World__Inferences__get_reference_as_object(parent_setting_inference);
if (PF_I(spatial, I)->here_flag)
{
#line 874 "inform7/Chapter 34/Spatial Model.w"
if (PL__Spatial__object_is_a_room(whereabouts) == FALSE) whereabouts = NULL;
if (whereabouts == NULL) {
parse_node *here_sentence =
World__Inferences__where_inferred(parent_setting_inference);
{
#line 894 "inform7/Chapter 34/Spatial Model.w"
ParseTree__traverse_up_to_ip(here_sentence, PL__Spatial__seek_room, &whereabouts);
}
#line 878 "inform7/Chapter 34/Spatial Model.w"
;
if (whereabouts == NULL) {
current_sentence = here_sentence;
Problems__Issue__object_problem_at_sentence(_p_(PM_NoHere),
I,
"was described as being 'here', and there doesn't seem to be any "
"location being talked about at this point in the source text",
"so there's nowhere you can call 'here'.");
}
}
}
#line 839 "inform7/Chapter 34/Spatial Model.w"
;
if (whereabouts) {
PL__Spatial__set_progenitor(I, whereabouts, parent_setting_inference);
LOGIF(OBJECT_TREE, "Progenitor of $O is $O\n", I, whereabouts);
}
}
{
#line 899 "inform7/Chapter 34/Spatial Model.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), PART_OF_INF) {
if ((PL__Spatial__object_is_a_room(I)) || (PL__Map__object_is_a_door(I))) {
Problems__Issue__object_problem(_p_(PM_RoomOrDoorAsPart),
I,
"was set up as being part of something else, which doors and rooms "
"are not allowed to be",
"because they are part of the fixed map of the world - if they were "
"parts of something else, they might move around. (Of course, it's "
"easy to make a door look as if it's part of something to the player - "
"describing it as part of a wall, or bulkhead, or cottage, say - "
"and if there really is an entrance that needs to move around - say, "
"the hatchway on a tank - it's probably best to make it an enterable "
"container.)");
}
PF_I(spatial, I)->part_flag = TRUE;
}
}
#line 845 "inform7/Chapter 34/Spatial Model.w"
;
}
#line 786 "inform7/Chapter 34/Spatial Model.w"
;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PF_I(spatial, I)->here_flag)
{
#line 834 "inform7/Chapter 34/Spatial Model.w"
inference *parent_setting_inference = NULL;
{
#line 850 "inform7/Chapter 34/Spatial Model.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), PARENTAGE_NOWHERE_INF)
{
#line 861 "inform7/Chapter 34/Spatial Model.w"
if (parent_setting_inference) {
Problems__Issue__contradiction_problem(_p_(PM_DuplicateParentage),
World__Inferences__where_inferred(parent_setting_inference),
World__Inferences__where_inferred(inf),
I,
"can only be given its position once",
"in a single assertion sentence.");
}
parent_setting_inference = inf;
}
#line 852 "inform7/Chapter 34/Spatial Model.w"
;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), PARENTAGE_HERE_INF)
{
#line 861 "inform7/Chapter 34/Spatial Model.w"
if (parent_setting_inference) {
Problems__Issue__contradiction_problem(_p_(PM_DuplicateParentage),
World__Inferences__where_inferred(parent_setting_inference),
World__Inferences__where_inferred(inf),
I,
"can only be given its position once",
"in a single assertion sentence.");
}
parent_setting_inference = inf;
}
#line 854 "inform7/Chapter 34/Spatial Model.w"
;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), PARENTAGE_INF)
{
#line 861 "inform7/Chapter 34/Spatial Model.w"
if (parent_setting_inference) {
Problems__Issue__contradiction_problem(_p_(PM_DuplicateParentage),
World__Inferences__where_inferred(parent_setting_inference),
World__Inferences__where_inferred(inf),
I,
"can only be given its position once",
"in a single assertion sentence.");
}
parent_setting_inference = inf;
}
#line 856 "inform7/Chapter 34/Spatial Model.w"
;
}
#line 835 "inform7/Chapter 34/Spatial Model.w"
;
if (parent_setting_inference) {
instance *whereabouts =
World__Inferences__get_reference_as_object(parent_setting_inference);
if (PF_I(spatial, I)->here_flag)
{
#line 874 "inform7/Chapter 34/Spatial Model.w"
if (PL__Spatial__object_is_a_room(whereabouts) == FALSE) whereabouts = NULL;
if (whereabouts == NULL) {
parse_node *here_sentence =
World__Inferences__where_inferred(parent_setting_inference);
{
#line 894 "inform7/Chapter 34/Spatial Model.w"
ParseTree__traverse_up_to_ip(here_sentence, PL__Spatial__seek_room, &whereabouts);
}
#line 878 "inform7/Chapter 34/Spatial Model.w"
;
if (whereabouts == NULL) {
current_sentence = here_sentence;
Problems__Issue__object_problem_at_sentence(_p_(PM_NoHere),
I,
"was described as being 'here', and there doesn't seem to be any "
"location being talked about at this point in the source text",
"so there's nowhere you can call 'here'.");
}
}
}
#line 839 "inform7/Chapter 34/Spatial Model.w"
;
if (whereabouts) {
PL__Spatial__set_progenitor(I, whereabouts, parent_setting_inference);
LOGIF(OBJECT_TREE, "Progenitor of $O is $O\n", I, whereabouts);
}
}
{
#line 899 "inform7/Chapter 34/Spatial Model.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), PART_OF_INF) {
if ((PL__Spatial__object_is_a_room(I)) || (PL__Map__object_is_a_door(I))) {
Problems__Issue__object_problem(_p_(PM_RoomOrDoorAsPart),
I,
"was set up as being part of something else, which doors and rooms "
"are not allowed to be",
"because they are part of the fixed map of the world - if they were "
"parts of something else, they might move around. (Of course, it's "
"easy to make a door look as if it's part of something to the player - "
"describing it as part of a wall, or bulkhead, or cottage, say - "
"and if there really is an entrance that needs to move around - say, "
"the hatchway on a tank - it's probably best to make it an enterable "
"container.)");
}
PF_I(spatial, I)->part_flag = TRUE;
}
}
#line 845 "inform7/Chapter 34/Spatial Model.w"
;
}
#line 789 "inform7/Chapter 34/Spatial Model.w"
;
{
#line 808 "inform7/Chapter 34/Spatial Model.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
if ((PL__Spatial__progenitor(I)) &&
(Instances__of_kind(I, K_thing) == FALSE) &&
(Instances__of_kind(I, K_room) == FALSE) &&
(PL__Regions__object_is_a_region(I) == FALSE)) {
Problems__quote_source(1, Instances__get_creating_sentence(I));
Problems__quote_object(2, I);
Problems__quote_object(3, PL__Spatial__progenitor(I));
Problems__quote_kind(4, Instances__to_kind(I));
Problems__Issue__handmade_problem(_p_(PM_NonThingInModel));
Problems__issue_problem_segment(
"In the sentence %1, you create an object '%2' which you then seem "
"to place in or on or as part of '%3', but the kind of '%2' is %4. "
"Since %4 is not a kind of thing, it follows that %2 is not a thing, "
"so it doesn't represent something physical and can't be put in spatial "
"relationships like this. (For the same reason that you can't put "
"'southeast', the direction, inside a kitchen cupboard.)");
Problems__issue_problem_end();
}
}
}
#line 790 "inform7/Chapter 34/Spatial Model.w"
;
return FALSE;
}
#line 920 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__seek_room(parse_node *sent, instance **I) {
inference_subject *isub = ParseTree__get_interpretation_of_subject(sent);
instance *sub = InferenceSubjects__as_object_instance(isub);
if (PL__Spatial__object_is_a_room(sub)) *I = sub;
}
#line 945 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__log_object_tree(void) {
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PF_I(spatial, I)->object_tree_parent == NULL)
PL__Spatial__log_object_tree_recursively(I, 0);
}
void PL__Spatial__log_object_tree_recursively(instance *I, int depth) {
int i = depth;
while (i>0) { LOG(" "); i--; }
LOG("$O\n", I);
if (PF_I(spatial, I)->object_tree_child)
PL__Spatial__log_object_tree_recursively(PF_I(spatial, I)->object_tree_child, depth+1);
if (PF_I(spatial, I)->object_tree_sibling)
PL__Spatial__log_object_tree_recursively(PF_I(spatial, I)->object_tree_sibling, depth);
}
#line 970 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__adopt_object(instance *orphan, instance *foster) {
LOGIF(OBJECT_TREE, "Grafting $O to be child of $O\n", orphan, foster);
if (orphan == NULL) internal_error("orphan is null in adoption");
if (foster == NULL) internal_error("foster is null in adoption");
instance *former_parent = PF_I(spatial, orphan)->object_tree_parent;
if (former_parent)
{
#line 998 "inform7/Chapter 34/Spatial Model.w"
if (PF_I(spatial, former_parent)->object_tree_child == orphan) {
PF_I(spatial, former_parent)->object_tree_child =
PF_I(spatial, orphan)->object_tree_sibling;
} else {
instance *elder = PF_I(spatial, former_parent)->object_tree_child;
while (elder) {
if (PF_I(spatial, elder)->object_tree_sibling == orphan)
PF_I(spatial, elder)->object_tree_sibling =
PF_I(spatial, orphan)->object_tree_sibling;
elder = PF_I(spatial, elder)->object_tree_sibling;
}
}
PF_I(spatial, orphan)->object_tree_parent = NULL;
PF_I(spatial, orphan)->object_tree_sibling = NULL;
}
#line 976 "inform7/Chapter 34/Spatial Model.w"
;
{
#line 1016 "inform7/Chapter 34/Spatial Model.w"
if (PF_I(spatial, foster)->object_tree_child == NULL) {
PF_I(spatial, foster)->object_tree_child = orphan;
} else {
instance *elder = PF_I(spatial, foster)->object_tree_child;
while (PF_I(spatial, elder)->object_tree_sibling)
elder = PF_I(spatial, elder)->object_tree_sibling;
PF_I(spatial, elder)->object_tree_sibling = orphan;
}
PF_I(spatial, orphan)->object_tree_parent = foster;
}
#line 977 "inform7/Chapter 34/Spatial Model.w"
;
}
#line 984 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__part_object(instance *orphan) {
LOGIF(OBJECT_TREE, "Parting $O\n", orphan);
if (orphan == NULL) internal_error("new part is null in parting");
instance *former_parent = PF_I(spatial, orphan)->object_tree_parent;
if (former_parent == NULL) internal_error("new part is without parent");
{
#line 998 "inform7/Chapter 34/Spatial Model.w"
if (PF_I(spatial, former_parent)->object_tree_child == orphan) {
PF_I(spatial, former_parent)->object_tree_child =
PF_I(spatial, orphan)->object_tree_sibling;
} else {
instance *elder = PF_I(spatial, former_parent)->object_tree_child;
while (elder) {
if (PF_I(spatial, elder)->object_tree_sibling == orphan)
PF_I(spatial, elder)->object_tree_sibling =
PF_I(spatial, orphan)->object_tree_sibling;
elder = PF_I(spatial, elder)->object_tree_sibling;
}
}
PF_I(spatial, orphan)->object_tree_parent = NULL;
PF_I(spatial, orphan)->object_tree_sibling = NULL;
}
#line 991 "inform7/Chapter 34/Spatial Model.w"
;
{
#line 1029 "inform7/Chapter 34/Spatial Model.w"
if (PF_I(spatial, former_parent)->incorp_tree_child == NULL) {
PF_I(spatial, former_parent)->incorp_tree_child = orphan;
} else {
instance *existing_part = PF_I(spatial, former_parent)->incorp_tree_child;
while (PF_I(spatial, existing_part)->incorp_tree_sibling)
existing_part = PF_I(spatial, existing_part)->incorp_tree_sibling;
PF_I(spatial, existing_part)->incorp_tree_sibling = orphan;
}
PF_I(spatial, orphan)->incorp_tree_parent = former_parent;
}
#line 992 "inform7/Chapter 34/Spatial Model.w"
;
}
#line 1043 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__encloses(instance *I1, instance *I2) {
while (I1) {
I1 = PL__Spatial__progenitor(I1);
if (I1 == I2) return TRUE;
}
return FALSE;
}
#line 1056 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_stage_III(void) {
int well_founded = TRUE;
{
#line 1073 "inform7/Chapter 34/Spatial Model.w"
instance *I;
int max_loop = NUMBER_CREATED(instance) + 1;
LOOP_OVER_OBJECT_INSTANCES(I) {
instance *I2;
int k;
for (I2 = PL__Spatial__progenitor(I), k=0;
(I2) && (k<max_loop);
I2 = PL__Spatial__progenitor(I2), k++) {
if (I2 == I) {
{
#line 1092 "inform7/Chapter 34/Spatial Model.w"
Problems__quote_object(1, I);
Problems__Issue__handmade_problem(_p_(PM_IllFounded));
Problems__issue_problem_segment("The %1 seems to be containing itself: ");
instance *I3 = I;
while (TRUE) {
wording IW = Instances__get_name(I3, FALSE);
parse_node *creator = Sentences__NPs__new_raw(IW);
Problems__quote_object(2, I3);
Problems__quote_source(3, creator);
Problems__issue_problem_segment("%2 (created by %3) ");
if (PF_I(spatial, I3)->part_flag) Problems__issue_problem_segment("part of ");
else Problems__issue_problem_segment("in ");
I3 = PL__Spatial__progenitor(I3);
if (I3 == I) break;
}
Problems__issue_problem_segment("%1... and so on. This is forbidden.");
Problems__issue_problem_end();
}
#line 1082 "inform7/Chapter 34/Spatial Model.w"
;
PL__Spatial__void_progenitor(I); /* thus cutting the cycle */
well_founded = FALSE;
}
}
}
}
#line 1058 "inform7/Chapter 34/Spatial Model.w"
;
if (well_founded)
{
#line 1128 "inform7/Chapter 34/Spatial Model.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
if (PL__Spatial__progenitor(I))
PL__Spatial__adopt_object(I, PL__Spatial__progenitor(I));
if (PF_I(spatial, I)->part_flag)
PL__Spatial__part_object(I);
}
}
#line 1059 "inform7/Chapter 34/Spatial Model.w"
;
{
#line 1142 "inform7/Chapter 34/Spatial Model.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
int portable = FALSE;
instance *J = I;
if (PF_I(spatial, I)->part_flag == FALSE)
for (J = PL__Spatial__progenitor(I); J; J = PL__Spatial__progenitor(J)) {
if (PF_I(spatial, J)->part_flag) break;
if (Instances__of_kind(J, K_person)) {
portable = TRUE;
break;
}
}
if (portable)
Properties__EitherOr__assert(
P_fixed_in_place, Instances__as_subject(I), FALSE, CERTAIN_CE);
}
}
#line 1060 "inform7/Chapter 34/Spatial Model.w"
;
{
#line 1162 "inform7/Chapter 34/Spatial Model.w"
{
#line 1173 "inform7/Chapter 34/Spatial Model.w"
if (K_room) {
inference *inf;
int desc_seen = FALSE;
POSITIVE_KNOWLEDGE_LOOP(inf, Kinds__Behaviour__as_subject(K_room), PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_description)
desc_seen = TRUE;
if (desc_seen == FALSE) {
text_stream *val = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(val) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for name text");
WRITE_TO(val, "\"\"");
Properties__Valued__assert(P_description, Kinds__Behaviour__as_subject(K_room),
Rvalues__from_unescaped_wording(Feeds__feed_text(STREAM_TEXT(val))), LIKELY_CE);
}
}
}
#line 1162 "inform7/Chapter 34/Spatial Model.w"
;
{
#line 1195 "inform7/Chapter 34/Spatial Model.w"
P_mark_as_room = Properties__EitherOr__new_nameless("mark_as_room");
P_mark_as_thing = Properties__EitherOr__new_nameless("mark_as_thing");
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
if (Instances__of_kind(I, K_room))
Properties__EitherOr__assert(
P_mark_as_room, Instances__as_subject(I), TRUE, CERTAIN_CE);
if (Instances__of_kind(I, K_thing))
Properties__EitherOr__assert(
P_mark_as_thing, Instances__as_subject(I), TRUE, CERTAIN_CE);
}
}
#line 1163 "inform7/Chapter 34/Spatial Model.w"
;
{
#line 1212 "inform7/Chapter 34/Spatial Model.w"
P_component_parent =
Properties__Valued__new_nameless("component_parent", K_object);
P_component_child =
Properties__Valued__new_nameless("component_child", K_object);
P_component_sibling =
Properties__Valued__new_nameless("component_sibling", K_object);
if (K_thing) {
parse_node *nothing_constant = Rvalues__new_nothing_object_constant();
Properties__Valued__assert(P_component_parent, Kinds__Behaviour__as_subject(K_thing),
nothing_constant, CERTAIN_CE);
Properties__Valued__assert(P_component_child, Kinds__Behaviour__as_subject(K_thing),
nothing_constant, CERTAIN_CE);
Properties__Valued__assert(P_component_sibling, Kinds__Behaviour__as_subject(K_thing),
nothing_constant, CERTAIN_CE);
}
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
instance *cp = PF_I(spatial, I)->incorp_tree_parent;
if (cp) Properties__Valued__assert(P_component_parent, Instances__as_subject(I),
Rvalues__from_instance(cp), CERTAIN_CE);
instance *cc = PF_I(spatial, I)->incorp_tree_child;
if (cc) Properties__Valued__assert(P_component_child, Instances__as_subject(I),
Rvalues__from_instance(cc), CERTAIN_CE);
instance *cs = PF_I(spatial, I)->incorp_tree_sibling;
if (cs) Properties__Valued__assert(P_component_sibling, Instances__as_subject(I),
Rvalues__from_instance(cs), CERTAIN_CE);
}
}
#line 1164 "inform7/Chapter 34/Spatial Model.w"
;
}
#line 1061 "inform7/Chapter 34/Spatial Model.w"
;
{
#line 1248 "inform7/Chapter 34/Spatial Model.w"
Properties__ObjectImplementation__begin_sequencing_objects();
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PF_I(spatial, I)->object_tree_parent == NULL)
PL__Spatial__add_to_object_sequence(I, 0);
}
#line 1062 "inform7/Chapter 34/Spatial Model.w"
;
if (Log__aspect_switched_on(OBJECT_TREE_DA)) PL__Spatial__log_object_tree();
return FALSE;
}
#line 1257 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__add_to_object_sequence(instance *I, int depth) {
Properties__ObjectImplementation__place_this_object_next(I);
PF_I(spatial, I)->I6_definition_depth = depth;
if (PF_I(spatial, I)->object_tree_child)
PL__Spatial__add_to_object_sequence(PF_I(spatial, I)->object_tree_child, depth+1);
if (PF_I(spatial, I)->object_tree_sibling)
PL__Spatial__add_to_object_sequence(PF_I(spatial, I)->object_tree_sibling, depth);
}
#line 1271 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__get_definition_depth(instance *I) {
if (Plugins__Manage__plugged_in(spatial_plugin))
return PF_I(spatial, I)->I6_definition_depth;
return 0;
}
#line 1283 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_stage_IV(void) {
if (existing_story_file) {
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PL__Spatial__object_is_a_room(I)) {
Problems__Issue__unlocated_problem(_p_(PM_RoomInIgnoredSource),
"This is supposed to be a source text which only contains "
"release instructions to bind up an existing story file "
"(for instance, one produced using Inform 6). That's because "
"the instruction 'Release along with an existing story file' "
"is present. So the source text must not contain rooms or "
"other game design - these would be ignored.");
break;
}
}
return FALSE;
}
#line 1304 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__index_spatial_relationship(instance *I) {
char *rel = NULL;
instance *P = PL__Spatial__progenitor(I);
if (P) {
/* we could set |rel| to "in" here, but the index omits that for clarity */
if (Instances__of_kind(P, K_supporter)) rel = "on";
if (Instances__of_kind(P, K_person)) rel = "carried";
if (PF_I(spatial, I)->part_flag) rel = "part";
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_worn)
rel = "worn";
}
if (rel) INDEX("<i>%s</i> ", rel);
}
#line 1324 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__no_detail_index(instance *I) {
if (PF_I(spatial, I)->incorp_tree_parent != NULL) return TRUE;
return FALSE;
}
#line 1332 "inform7/Chapter 34/Spatial Model.w"
void PL__Spatial__index_object_further(instance *I, int depth, int details) {
if (depth > NUMBER_CREATED(instance) + 1) return; /* to recover from errors */
if (PF_I(spatial, I)->incorp_tree_child != NULL) {
instance *I2 = PF_I(spatial, I)->incorp_tree_child;
while (I2 != NULL) {
Data__Objects__index(I2, NULL, depth+1, details);
I2 = PF_I(spatial, I2)->incorp_tree_sibling;
}
}
if (PF_I(spatial, I)->object_tree_child)
Data__Objects__index(PF_I(spatial, I)->object_tree_child, NULL, depth+1, details);
if ((PL__Spatial__object_is_a_room(I)) &&
(PL__Map__object_is_a_door(I) == FALSE)) {
instance *I2;
LOOP_OVER_OBJECT_INSTANCES(I2) {
if ((PL__Map__object_is_a_door(I2)) && (PL__Spatial__progenitor(I2) != I)) {
instance *A = NULL, *B = NULL;
PL__Map__get_door_data(I2, &A, &B);
if (A == I) Data__Objects__index(I2, NULL, depth+1, details);
if (B == I) Data__Objects__index(I2, NULL, depth+1, details);
}
}
}
PL__Player__index_object_further(I, depth, details);
PL__Backdrops__index_object_further(I, depth, details, "", "");
if (PF_I(spatial, I)->object_tree_sibling)
Data__Objects__index(PF_I(spatial, I)->object_tree_sibling, NULL, depth, details);
}
#line 1365 "inform7/Chapter 34/Spatial Model.w"
int PL__Spatial__spatial_add_to_World_index(instance *O) {
if ((O) && (Instances__of_kind(O, K_thing))) {
HTML__open_para(ifl, 1, "tight");
instance *P = PL__Spatial__progenitor(O);
if (P) {
INDEX("<i>initial location:</i> ");
char *rel = "in";
if (Instances__of_kind(P, K_supporter)) rel = "on";
if (Instances__of_kind(P, K_person)) rel = "carried by";
if (PF_I(spatial, O)->part_flag) rel = "part of";
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(O), PROPERTY_INF)
if (World__Inferences__get_property(inf) == P_worn)
rel = "worn by";
INDEX("%s ", rel);
Instances__index_name(P);
parse_node *at = PF_I(spatial, O)->progenitor_set_at;
if (at) Index__link(Wordings__first_wn(ParseTree__get_text(at)));
}
INDEX("</p>");
}
return FALSE;
}
#line 33 "inform7/Chapter 34/Spatial Relations.w"
void PL__SpatialRelations__REL_create_initial_stock(void) {
{
#line 50 "inform7/Chapter 34/Spatial Relations.w"
R_containment =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__full_new_term(NULL, NULL, EMPTY_WORDING, Calculus__Schemas__new("ContainerOf(*1)")),
BinaryPredicates__new_term(NULL),
"contains", "is-in",
NULL, Calculus__Schemas__new("MoveObject(*2,*1)"), NULL,
Preform__Nonparsing__wording(relation_names_NTM, CONTAINMENT_RELATION_NAME));
R_containment->loop_parent_optimisation_proviso = "ContainerOf";
R_containment->loop_parent_optimisation_ranger = "TestContainmentRange";
BinaryPredicates__set_index_details(R_containment, "container/room", "thing");
R_support =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__full_new_term(infs_supporter, NULL, EMPTY_WORDING, Calculus__Schemas__new("SupporterOf(*1)")),
BinaryPredicates__new_term(infs_thing),
"supports", "is-on",
NULL, Calculus__Schemas__new("MoveObject(*2,*1)"), NULL,
Preform__Nonparsing__wording(relation_names_NTM, SUPPORT_RELATION_NAME));
R_support->loop_parent_optimisation_proviso = "SupporterOf";
R_incorporation =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__full_new_term(infs_thing, NULL, EMPTY_WORDING, Calculus__Schemas__new("(*1.component_parent)")),
BinaryPredicates__new_term(infs_thing),
"incorporates", "is-part-of",
NULL, Calculus__Schemas__new("MakePart(*2,*1)"), NULL,
Preform__Nonparsing__wording(relation_names_NTM, INCORPORATION_RELATION_NAME));
R_carrying =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__full_new_term(infs_person, NULL, EMPTY_WORDING, Calculus__Schemas__new("CarrierOf(*1)")),
BinaryPredicates__new_term(infs_thing),
"carries", "is-carried-by",
NULL, Calculus__Schemas__new("MoveObject(*2,*1)"), NULL,
Preform__Nonparsing__wording(relation_names_NTM, CARRYING_RELATION_NAME));
R_carrying->loop_parent_optimisation_proviso = "CarrierOf";
R_holding =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__full_new_term(infs_person, NULL, EMPTY_WORDING, Calculus__Schemas__new("HolderOf(*1)")),
BinaryPredicates__new_term(infs_thing),
"holds", "is-held-by",
NULL, Calculus__Schemas__new("MoveObject(*2,*1)"), NULL,
Preform__Nonparsing__wording(relation_names_NTM, HOLDING_RELATION_NAME));
/* can't be optimised, because parts are also held */
R_wearing =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__full_new_term(infs_person, NULL, EMPTY_WORDING, Calculus__Schemas__new("WearerOf(*1)")),
BinaryPredicates__new_term(infs_thing),
"wears", "is-worn-by",
NULL, Calculus__Schemas__new("WearObject(*2,*1)"), NULL,
Preform__Nonparsing__wording(relation_names_NTM, WEARING_RELATION_NAME));
R_wearing->loop_parent_optimisation_proviso = "WearerOf";
a_has_b_predicate =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__full_new_term(NULL, NULL, EMPTY_WORDING, Calculus__Schemas__new("OwnerOf(*1)")),
BinaryPredicates__new_term(NULL),
"has", "is-had-by",
NULL, Calculus__Schemas__new("MoveObject(*2,*1)"), NULL,
Preform__Nonparsing__wording(relation_names_NTM, POSSESSION_RELATION_NAME));
a_has_b_predicate->loop_parent_optimisation_proviso = "OwnerOf";
BinaryPredicates__set_index_details(a_has_b_predicate, "person", "thing");
room_containment_predicate =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__full_new_term(infs_room, NULL, EMPTY_WORDING, Calculus__Schemas__new("LocationOf(*1)")),
BinaryPredicates__new_term(infs_thing),
"is-room-of", "is-in-room",
NULL, Calculus__Schemas__new("MoveObject(*2,*1)"), NULL,
Preform__Nonparsing__wording(relation_names_NTM, ROOM_CONTAINMENT_RELATION_NAME));
room_containment_predicate->loop_parent_optimisation_proviso = "LocationOf";
}
#line 34 "inform7/Chapter 34/Spatial Relations.w"
;
{
#line 121 "inform7/Chapter 34/Spatial Relations.w"
R_visibility =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__new_term(infs_thing),
BinaryPredicates__new_term(infs_thing),
"can-see", "can-be-seen-by",
NULL, NULL, Calculus__Schemas__new("TestVisibility(*1,*2)"),
Preform__Nonparsing__wording(relation_names_NTM, VISIBILITY_RELATION_NAME));
R_touchability =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__new_term(infs_thing),
BinaryPredicates__new_term(infs_thing),
"can-touch", "can-be-touched-by",
NULL, NULL, Calculus__Schemas__new("TestTouchability(*1,*2)"),
Preform__Nonparsing__wording(relation_names_NTM, TOUCHABILITY_RELATION_NAME));
R_concealment =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__new_term(infs_thing),
BinaryPredicates__new_term(infs_thing),
"conceals", "is-concealed-by",
NULL, NULL, Calculus__Schemas__new("TestConcealment(*1,*2)"),
Preform__Nonparsing__wording(relation_names_NTM, CONCEALMENT_RELATION_NAME));
R_enclosure =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__new_term(Kinds__Behaviour__as_subject(K_object)),
BinaryPredicates__new_term(Kinds__Behaviour__as_subject(K_object)),
"encloses", "is-enclosed-by",
NULL, NULL, Calculus__Schemas__new("IndirectlyContains(*1,*2)"),
Preform__Nonparsing__wording(relation_names_NTM, ENCLOSURE_RELATION_NAME));
}
#line 35 "inform7/Chapter 34/Spatial Relations.w"
;
PL__MapDirections__create_relations();
PL__Regions__create_relations();
}
#line 154 "inform7/Chapter 34/Spatial Relations.w"
void PL__SpatialRelations__REL_create_second_stock(void) {
}
#line 161 "inform7/Chapter 34/Spatial Relations.w"
int PL__SpatialRelations__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
return DECLINE_TO_MATCH;
}
#line 173 "inform7/Chapter 34/Spatial Relations.w"
int PL__SpatialRelations__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
instance *I0 = InferenceSubjects__as_object_instance(infs0),
*I1 = InferenceSubjects__as_object_instance(infs1);
if ((I0) && (I1)) {
if (I1 == I0) {
Problems__Issue__sentence_problem(_p_(PM_MiseEnAbyme),
"this asks to put something inside itself",
"like saying 'the bottle is in the bottle'.");
return TRUE;
}
{
#line 206 "inform7/Chapter 34/Spatial Relations.w"
if (PL__Backdrops__assert_relations(bp, I0, I1)) return TRUE;
if (PL__MapDirections__assert_relations(bp, I0, I1)) return TRUE;
if (PL__Regions__assert_relations(bp, I0, I1)) return TRUE;
}
#line 185 "inform7/Chapter 34/Spatial Relations.w"
;
if (BinaryPredicates__can_be_made_true_at_runtime(bp) == FALSE)
{
#line 213 "inform7/Chapter 34/Spatial Relations.w"
Problems__Issue__sentence_problem(_p_(PM_Unassertable),
"the relationship you describe is not exact enough",
"so that I do not know how to make this assertion come true. "
"For instance, saying 'The Study is adjacent to the Hallway.' "
"is not good enough because I need to know in what direction: "
"is it east of the Hallway, perhaps, or west?");
return TRUE;
}
#line 188 "inform7/Chapter 34/Spatial Relations.w"
;
if ((bp == R_incorporation) && (Instances__of_kind(I0, K_room)))
{
#line 224 "inform7/Chapter 34/Spatial Relations.w"
Problems__Issue__sentence_problem(_p_(PM_PartOfRoom),
"this asks to make something a part of a room",
"when only things are allowed to have parts.");
return TRUE;
}
#line 190 "inform7/Chapter 34/Spatial Relations.w"
;
{
#line 232 "inform7/Chapter 34/Spatial Relations.w"
inference_subject *item = Instances__as_subject(I1);
inference_subject *loc = Instances__as_subject(I0);
World__Inferences__draw(PART_OF_INF, item,
(bp == R_incorporation)?CERTAIN_CE:IMPOSSIBLE_CE,
loc, NULL);
if (bp == R_containment)
World__Inferences__draw(CONTAINS_THINGS_INF, loc, CERTAIN_CE, item, NULL);
World__Inferences__draw(PARENTAGE_INF, item, CERTAIN_CE, loc, NULL);
World__Inferences__draw(IS_ROOM_INF, item, IMPOSSIBLE_CE, NULL, NULL);
}
#line 192 "inform7/Chapter 34/Spatial Relations.w"
;
if (bp == R_wearing)
{
#line 248 "inform7/Chapter 34/Spatial Relations.w"
inference_subject *item = Instances__as_subject(I1);
if (P_wearable)
World__Inferences__draw_property(item, P_wearable, NULL);
if (P_worn == NULL) P_worn = Properties__EitherOr__new_nameless("worn");
World__Inferences__draw_property(item, P_worn, NULL);
}
#line 194 "inform7/Chapter 34/Spatial Relations.w"
;
return TRUE;
}
return FALSE;
}
#line 258 "inform7/Chapter 34/Spatial Relations.w"
int PL__SpatialRelations__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) {
return FALSE;
}
#line 265 "inform7/Chapter 34/Spatial Relations.w"
int PL__SpatialRelations__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 35 "inform7/Chapter 34/The Player.w"
void PL__Player__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_VARIABLE_NOTIFY, PL__Player__player_new_quantity_notify);
PLUGIN_REGISTER(PLUGIN_VARIABLE_SET_WARNING, PL__Player__player_variable_set_warning);
PLUGIN_REGISTER(PLUGIN_NEW_INSTANCE_NOTIFY, PL__Player__player_new_instance_notify);
PLUGIN_REGISTER(PLUGIN_IRREGULAR_GENITIVE, PL__Player__player_irregular_genitive);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, PL__Player__player_complete_model);
PLUGIN_REGISTER(PLUGIN_REFINE_IMPLICIT_NOUN, PL__Player__player_refine_implicit_noun);
PLUGIN_REGISTER(PLUGIN_DETECT_BODYSNATCHING, PL__Player__player_detect_bodysnatching);
PLUGIN_REGISTER(PLUGIN_ANNOTATE_IN_WORLD_INDEX, PL__Player__player_annotate_in_World_index);
}
#line 52 "inform7/Chapter 34/The Player.w"
int notable_player_instances_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 54 "inform7/Chapter 34/The Player.w"
#line 58 "inform7/Chapter 34/The Player.w"
int PL__Player__player_new_instance_notify(instance *inst) {
wording IW = Instances__get_name(inst, FALSE);
if (Preform__parse_nt_against_word_range(notable_player_instances_NTM, IW, NULL, NULL)) {
I_yourself = inst; player_character_object = I_yourself;
if (player_VAR)
{
#line 147 "inform7/Chapter 34/The Player.w"
inference_subject *subj = Instances__as_subject(I_yourself);
InferenceSubjects__alias_to_nonlocal_variable(subj, player_VAR);
NonlocalVariables__set_alias(player_VAR, subj);
}
#line 62 "inform7/Chapter 34/The Player.w"
;
}
return FALSE;
}
instance *PL__Player__get_start_room(void) {
return start_room;
}
#line 92 "inform7/Chapter 34/The Player.w"
int notable_player_variables_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 96 "inform7/Chapter 34/The Player.w"
#line 100 "inform7/Chapter 34/The Player.w"
int PL__Player__player_new_quantity_notify(nonlocal_variable *nlv) {
if (Preform__parse_nt_against_word_range(notable_player_variables_NTM, nlv->name, NULL, NULL)) {
switch (most_recent_result) {
case 0:
player_VAR = nlv;
if (I_yourself)
{
#line 147 "inform7/Chapter 34/The Player.w"
inference_subject *subj = Instances__as_subject(I_yourself);
InferenceSubjects__alias_to_nonlocal_variable(subj, player_VAR);
NonlocalVariables__set_alias(player_VAR, subj);
}
#line 105 "inform7/Chapter 34/The Player.w"
;
NonlocalVariables__set_write_schema(nlv, "ChangePlayer(*2)");
break;
case 1:
score_VAR = nlv;
NonlocalVariables__make_initalisable(score_VAR);
break;
case 2:
time_of_day_VAR = nlv;
NonlocalVariables__make_initalisable(time_of_day_VAR);
break;
}
}
return FALSE;
}
#line 159 "inform7/Chapter 34/The Player.w"
int PL__Player__player_variable_set_warning(nonlocal_variable *nlv, parse_node *val) {
if (nlv == player_VAR) {
instance *npc = Rvalues__to_object_instance(val);
if (npc) {
player_character_object = npc;
return TRUE;
}
}
return FALSE;
}
#line 193 "inform7/Chapter 34/The Player.w"
int PL__Player__player_detect_bodysnatching(inference_subject *body, int *snatcher,
inference_subject **counterpart) {
if ((player_character_object == I_yourself) ||
(player_character_object == NULL) || (I_yourself == NULL)) return FALSE;
kind *KP = Instances__to_kind(player_character_object);
kind *KY = Instances__to_kind(I_yourself);
if (Kinds__Compare__lt(KP, KY)) {
if (body == Instances__as_subject(player_character_object)) {
*snatcher = FALSE; *counterpart = Instances__as_subject(I_yourself); return TRUE; }
if (body == Instances__as_subject(I_yourself)) {
*snatcher = TRUE; *counterpart = Instances__as_subject(player_character_object); return TRUE; }
} else {
if (body == Instances__as_subject(player_character_object)) {
*snatcher = TRUE; *counterpart = Instances__as_subject(I_yourself); return TRUE; }
if (body == Instances__as_subject(I_yourself)) {
*snatcher = FALSE; *counterpart = Instances__as_subject(player_character_object); return TRUE; }
}
return FALSE;
}
#line 221 "inform7/Chapter 34/The Player.w"
int PL__Player__player_irregular_genitive(inference_subject *owner, char *genitive, int *propriety) {
if (owner == Instances__as_subject(I_yourself)) {
strcpy(genitive, "your ");
*propriety = TRUE;
return TRUE;
}
if ((player_character_object) && (I_yourself) &&
(player_character_object != I_yourself) &&
(owner == Instances__as_subject(player_character_object))) {
strcpy(genitive, "your ");
*propriety = TRUE;
return TRUE;
}
return FALSE;
}
#line 245 "inform7/Chapter 34/The Player.w"
int implicit_player_relationship_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 249 "inform7/Chapter 34/The Player.w"
#line 253 "inform7/Chapter 34/The Player.w"
int PL__Player__player_refine_implicit_noun(parse_node *p) {
if (Preform__parse_nt_against_word_range(implicit_player_relationship_NTM, ParseTree__get_text(p), NULL, NULL)) {
Assertions__Refiner__noun_from_infs(p, Instances__as_subject(player_character_object));
return TRUE;
}
return FALSE;
}
#line 271 "inform7/Chapter 34/The Player.w"
int PL__Player__player_complete_model(int stage) {
if (stage == 4) {
{
#line 283 "inform7/Chapter 34/The Player.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((PL__Spatial__object_is_a_room(I)) && (start_room == NULL)
&& (Instances__get_creating_file(I) == primary_source_file))
start_room = I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((PL__Spatial__object_is_a_room(I)) && (start_room == NULL))
start_room = I;
start_object = start_room;
}
#line 273 "inform7/Chapter 34/The Player.w"
;
{
#line 296 "inform7/Chapter 34/The Player.w"
if ((start_room == NULL) && (existing_story_file == FALSE)) {
Problems__Issue__unlocated_problem(_p_(PM_NoStartRoom),
"There doesn't seem to be any location in this story, so there's "
"nowhere for the player to begin. This may be because I have "
"misunderstood what was meant to be a room and what wasn't: I "
"only know something is a room if you tell me explicitly ('The "
"Observatory is a room') or if you imply it by giving map "
"directions ('East of the Observatory is the Planetarium').");
return FALSE;
}
}
#line 274 "inform7/Chapter 34/The Player.w"
;
{
#line 313 "inform7/Chapter 34/The Player.w"
if (player_character_object) {
start_object = PL__Spatial__progenitor(player_character_object);
if (start_object) {
start_room = start_object;
while ((start_room) && (PL__Spatial__progenitor(start_room)))
start_room = PL__Spatial__progenitor(start_room);
if ((start_room) && (PL__Spatial__object_is_a_room(start_room) == FALSE)) {
Problems__Issue__object_problem(_p_(PM_StartsOutsideRooms),
start_object,
"seems to be where the player is supposed to begin",
"but (so far as I know) it is not a room, nor is it ultimately "
"contained inside a room.");
}
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf,
Instances__as_subject(player_character_object), PART_OF_INF) {
Problems__Issue__object_problem(_p_(PM_PlayerIsPart),
start_object,
"seems to have the player attached as a component part",
"which is not allowed. The player can be in a room, or "
"inside a container, or on a supporter, but can't be part "
"of something.");
}
}
}
}
#line 275 "inform7/Chapter 34/The Player.w"
;
}
return FALSE;
}
#line 345 "inform7/Chapter 34/The Player.w"
void PL__Player__InitialSituation_array(OUTPUT_STREAM) {
if (Plugins__Manage__plugged_in(player_plugin)) {
WRITE("Array InitialSituation --> ");
NonlocalVariables__compile_initial_value(OUT, player_VAR);
WRITE(" %s", Instances__identifier(start_object));
WRITE(" %s ", Instances__identifier(start_room));
NonlocalVariables__compile_initial_value(OUT, time_of_day_VAR);
WRITE(" 0;\n\n");
}
}
#line 361 "inform7/Chapter 34/The Player.w"
void PL__Player__index_object_further(instance *I, int depth, int details) {
if ((I == start_room) && (I_yourself) &&
(Instances__indexed_yet(I_yourself) == FALSE))
Data__Objects__index(I_yourself, NULL, depth+1, details);
}
int PL__Player__player_annotate_in_World_index(instance *I) {
if (I == PL__Player__get_start_room()) {
INDEX(" - <i>room where play begins</i>");
Index__DocReferences__link("ROOMPLAYBEGINS");
return TRUE;
}
return FALSE;
}
#line 27 "inform7/Chapter 34/Backdrops.w"
void PL__Backdrops__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL__Backdrops__backdrops_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, PL__Backdrops__backdrops_new_property_notify);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, PL__Backdrops__backdrops_complete_model);
PLUGIN_REGISTER(PLUGIN_LOG_INFERENCE_TYPE, PL__Backdrops__backdrops_log_inference_type);
PLUGIN_REGISTER(PLUGIN_ESTIMATE_PROPERTY_USAGE, PL__Backdrops__backdrops_estimate_property_usage);
PLUGIN_REGISTER(PLUGIN_INTERVENE_IN_ASSERTION, PL__Backdrops__backdrops_intervene_in_assertion);
}
#line 42 "inform7/Chapter 34/Backdrops.w"
int notable_backdrops_kinds_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 44 "inform7/Chapter 34/Backdrops.w"
#line 48 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_new_base_kind_notify(kind *new_base, char *name, wording W) {
if (Preform__parse_nt_against_word_range(notable_backdrops_kinds_NTM, W, NULL, NULL)) {
K_backdrop = new_base; return TRUE;
}
return FALSE;
}
#line 58 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__object_is_a_backdrop(instance *I) {
if ((Plugins__Manage__plugged_in(regions_plugin)) && (K_backdrop) && (I) &&
(Instances__of_kind(I, K_backdrop))) return TRUE;
return FALSE;
}
#line 70 "inform7/Chapter 34/Backdrops.w"
int notable_backdrops_properties_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 72 "inform7/Chapter 34/Backdrops.w"
#line 76 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_new_property_notify(property *prn) {
if (Preform__parse_nt_against_word_range(notable_backdrops_properties_NTM, prn->name, NULL, NULL))
P_scenery = prn;
return FALSE;
}
int PL__Backdrops__object_is_scenery(instance *I) {
if (World__Inferences__get_EO_state(Instances__as_subject(I), P_scenery) > 0)
return TRUE;
return FALSE;
}
#line 91 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_estimate_property_usage(kind *k, int *words_used) {
if (Kinds__Compare__eq(k, K_backdrop)) *words_used += 2;
return FALSE;
}
#line 99 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_log_inference_type(int it) {
switch(it) {
case FOUND_IN_INF: LOG("FOUND_IN_INF"); return TRUE;
case FOUND_EVERYWHERE_INF: LOG("FOUND_EVERYWHERE_INF"); return TRUE;
}
return FALSE;
}
#line 117 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__assert_relations(binary_predicate *relation,
instance *I0, instance *I1) {
if ((Instances__of_kind(I1, K_backdrop)) &&
((relation == R_incorporation) ||
(relation == R_containment) ||
(relation == R_regional_containment))) {
inference_subject *bd = Instances__as_subject(I1);
inference_subject *loc = Instances__as_subject(I0);
World__Inferences__draw(PART_OF_INF, bd, IMPOSSIBLE_CE, loc, NULL);
World__Inferences__draw(IS_ROOM_INF, bd, IMPOSSIBLE_CE, NULL, NULL);
World__Inferences__draw(FOUND_IN_INF, bd, CERTAIN_CE, loc, loc);
return TRUE;
}
return FALSE;
}
#line 154 "inform7/Chapter 34/Backdrops.w"
void PL__Backdrops__index_object_further(instance *loc, int depth,
int details, char *bef, char *aft) {
int discoveries = 0;
instance *bd;
inference *inf;
if (loc) {
LOOP_OVER_BACKDROPS_IN(bd, loc, inf) {
if (++discoveries == 1) INDEX("%s", bef);
Data__Objects__index(bd, NULL, depth+1, details);
}
} else {
LOOP_OVER_BACKDROPS_EVERYWHERE(bd, inf) {
if (++discoveries == 1) INDEX("%s", bef);
Data__Objects__index(bd, NULL, depth+1, details);
}
}
if (discoveries > 0) INDEX("%s", aft);
}
#line 178 "inform7/Chapter 34/Backdrops.w"
int notable_backdrops_noun_phrases_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 180 "inform7/Chapter 34/Backdrops.w"
#line 184 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_intervene_in_assertion(parse_node *px, parse_node *py) {
if ((ParseTree__get_type(py) == EVERY_NT) &&
(Preform__parse_nt_against_word_range(notable_backdrops_noun_phrases_NTM, ParseTree__get_text(py), NULL, NULL))) {
inference_subject *left_subject = ParseTree__get_subject(px);
if (left_subject == NULL)
Problems__Issue__assertion_problem(_p_(PM_ValueEverywhere),
"'everywhere' can only be used to place individual backdrops",
"so although 'The mist is a backdrop. The mist is everywhere.' "
"would be fine, 'Corruption is everywhere.' would not.");
else if (InferenceSubjects__domain(left_subject))
Problems__Issue__subject_problem_at_sentence(_p_(PM_KindOfBackdropEverywhere),
left_subject,
"seems to be said to be 'everywhere' in some way",
"which doesn't make sense. An individual backdrop can be 'everywhere', "
"but here we're talking about a whole kind, and it's not allowed "
"to talk about general locations of a whole kind of things at once.");
else Calculus__Propositions__Assert__assert_true_about(
Calculus__Propositions__Abstract__to_put_everywhere(), left_subject, prevailing_mood);
return TRUE;
}
return FALSE;
}
#line 211 "inform7/Chapter 34/Backdrops.w"
void PL__Backdrops__infer_presence_everywhere(instance *I) {
if ((I == NULL) || (Instances__of_kind(I, K_backdrop) == FALSE)) {
Problems__Issue__sentence_problem(_p_(PM_EverywhereNonBackdrop),
"only a backdrop can be everywhere",
"and no other kind of object will do. For instance, 'The sky is "
"a backdrop which is everywhere.' is allowed, but 'The travelator "
"is a vehicle which is everywhere.' is not.");
return;
}
World__Inferences__draw(FOUND_EVERYWHERE_INF,
Instances__as_subject(I), prevailing_mood, NULL, NULL);
}
#line 228 "inform7/Chapter 34/Backdrops.w"
int PL__Backdrops__backdrops_complete_model(int stage) {
if (stage == 2) {
P_absent = Properties__EitherOr__new_nameless("absent");
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
text_stream *FOUNDIN = NULL;
{
#line 252 "inform7/Chapter 34/Backdrops.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), FOUND_EVERYWHERE_INF) {
{
#line 313 "inform7/Chapter 34/Backdrops.w"
if (FOUNDIN == NULL) {
FOUNDIN = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(FOUNDIN) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for found-in text");
}
}
#line 254 "inform7/Chapter 34/Backdrops.w"
;
WRITE_TO(FOUNDIN, "FoundEverywhere");
break;
}
}
#line 234 "inform7/Chapter 34/Backdrops.w"
;
int room_count = 0, region_count = 0;
{
#line 262 "inform7/Chapter 34/Backdrops.w"
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), FOUND_IN_INF) {
instance *loc = World__Inferences__get_reference_as_object(inf);
if ((K_region) && (Instances__of_kind(loc, K_region))) region_count++;
else room_count++;
}
}
#line 236 "inform7/Chapter 34/Backdrops.w"
;
if ((FOUNDIN == NULL) && (room_count > 0) && (room_count < 16) && (region_count == 0))
{
#line 272 "inform7/Chapter 34/Backdrops.w"
{
#line 313 "inform7/Chapter 34/Backdrops.w"
if (FOUNDIN == NULL) {
FOUNDIN = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(FOUNDIN) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for found-in text");
}
}
#line 272 "inform7/Chapter 34/Backdrops.w"
;
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), FOUND_IN_INF)
WRITE_TO(FOUNDIN, "%s ",
Instances__identifier(World__Inferences__get_reference_as_object(inf)));
}
#line 238 "inform7/Chapter 34/Backdrops.w"
;
if ((FOUNDIN == NULL) && (room_count + region_count > 0))
{
#line 281 "inform7/Chapter 34/Backdrops.w"
{
#line 313 "inform7/Chapter 34/Backdrops.w"
if (FOUNDIN == NULL) {
FOUNDIN = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(FOUNDIN) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for found-in text");
}
}
#line 281 "inform7/Chapter 34/Backdrops.w"
;
FOUNDIN = Routines__begin(FOUNDIN, "*");
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), FOUND_IN_INF) {
instance *loc = World__Inferences__get_reference_as_object(inf);
if ((K_region) && (Instances__of_kind(loc, K_region)))
WRITE_TO(FOUNDIN, "if (TestRegionalContainment(location, %s)) rtrue; ",
Instances__identifier(loc));
else
WRITE_TO(FOUNDIN, "if (location == %s) rtrue; ",
Instances__identifier(loc));
}
FOUNDIN = Routines__end(FOUNDIN);
WRITE_TO(FOUNDIN, ",");
}
#line 240 "inform7/Chapter 34/Backdrops.w"
;
if ((FOUNDIN == NULL) && (Instances__of_kind(I, K_backdrop)))
{
#line 302 "inform7/Chapter 34/Backdrops.w"
{
#line 313 "inform7/Chapter 34/Backdrops.w"
if (FOUNDIN == NULL) {
FOUNDIN = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(FOUNDIN) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for found-in text");
}
}
#line 302 "inform7/Chapter 34/Backdrops.w"
;
FOUNDIN = Routines__begin(FOUNDIN, "*");
WRITE_TO(FOUNDIN, "rfalse;");
FOUNDIN = Routines__end(FOUNDIN);
WRITE_TO(FOUNDIN, ",");
Properties__EitherOr__assert(
P_absent, Instances__as_subject(I), TRUE, CERTAIN_CE);
}
#line 242 "inform7/Chapter 34/Backdrops.w"
;
if (FOUNDIN) PL__Map__set_found_in(I, FOUNDIN);
}
}
return FALSE;
}
#line 43 "inform7/Chapter 34/Regions.w"
void PL__Regions__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL__Regions__regions_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_SET_SUBKIND_NOTIFY, PL__Regions__regions_set_subkind_notify);
PLUGIN_REGISTER(PLUGIN_NEW_SUBJECT_NOTIFY, PL__Regions__regions_new_subject_notify);
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, PL__Regions__regions_new_property_notify);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, PL__Regions__regions_complete_model);
PLUGIN_REGISTER(PLUGIN_MORE_SPECIFIC, PL__Regions__regions_more_specific);
PLUGIN_REGISTER(PLUGIN_ESTIMATE_PROPERTY_USAGE, PL__Regions__regions_estimate_property_usage);
PLUGIN_REGISTER(PLUGIN_INTERVENE_IN_ASSERTION, PL__Regions__regions_intervene_in_assertion);
PLUGIN_REGISTER(PLUGIN_NAME_TO_EARLY_INFS, PL__Regions__regions_name_to_early_infs);
PLUGIN_REGISTER(PLUGIN_ADD_TO_WORLD_INDEX, PL__Regions__regions_add_to_World_index);
infs_region = InferenceSubjects__new(global_constants,
FUND_SUB, NULL_GENERAL_POINTER, LIKELY_CE);
}
regions_data *PL__Regions__new_data(inference_subject *subj) {
regions_data *rd = CREATE(regions_data);
rd->in_region = NULL;
rd->in_region_set_at = NULL;
return rd;
}
#line 71 "inform7/Chapter 34/Regions.w"
int notable_regions_kinds_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 73 "inform7/Chapter 34/Regions.w"
#line 77 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_new_base_kind_notify(kind *new_base, char *name, wording W) {
if (Preform__parse_nt_against_word_range(notable_regions_kinds_NTM, W, NULL, NULL)) {
K_region = new_base; return TRUE;
}
return FALSE;
}
int PL__Regions__regions_new_subject_notify(inference_subject *subj) {
CREATE_PF_DATA(regions, subj, PL__Regions__new_data);
return FALSE;
}
#line 92 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_set_subkind_notify(kind *sub, kind *super) {
if ((sub == K_region) && (super != K_object)) {
if (problem_count == 0)
Problems__Issue__sentence_problem(_p_(PM_RegionAdrift),
"'region' is not allowed to be a kind of anything (other than "
"'object')",
"because it's too fundamental to the way Inform maps out the "
"geography of the physical world.");
return TRUE;
}
return FALSE;
}
#line 108 "inform7/Chapter 34/Regions.w"
int PL__Regions__object_is_a_region(instance *I) {
if ((Plugins__Manage__plugged_in(regions_plugin)) && (K_region) && (I) &&
(Instances__of_kind(I, K_region))) return TRUE;
return FALSE;
}
#line 120 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_more_specific(instance *I1, instance *I2) {
int r1 = Instances__of_kind(I1, K_room);
int r2 = Instances__of_kind(I2, K_room);
int reg1 = Instances__of_kind(I1, K_region);
int reg2 = Instances__of_kind(I2, K_region);
if ((r1) && (reg2)) return 1;
if ((reg1) && (r2)) return -1;
if ((reg1) && (reg2)) {
if (PL__Spatial__encloses(I1, I2)) return 1;
if (PL__Spatial__encloses(I2, I1)) return -1;
}
return 0;
}
#line 140 "inform7/Chapter 34/Regions.w"
int notable_regions_properties_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 142 "inform7/Chapter 34/Regions.w"
#line 146 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_new_property_notify(property *prn) {
if (Preform__parse_nt_against_word_range(notable_regions_properties_NTM, prn->name, NULL, NULL))
P_map_region = prn;
return FALSE;
}
#line 155 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_estimate_property_usage(kind *k, int *words_used) {
if (Kinds__Compare__eq(k, K_region)) *words_used += 2;
return FALSE;
}
#line 165 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_intervene_in_assertion(parse_node *px, parse_node *py) {
if ((ParseTree__get_type(px) == PROPER_NOUN_NT) &&
(ParseTree__get_type(py) == COMMON_NOUN_NT)) {
inference_subject *left_subject = ParseTree__get_subject(px);
inference_subject *right_kind = ParseTree__get_subject(py);
if ((InferenceSubjects__is_an_object(left_subject)) &&
(right_kind == Kinds__Behaviour__as_subject(K_region))) {
instance *left_object = InferenceSubjects__as_object_instance(left_subject);
if ((left_object) &&
(current_sentence != Instances__get_creating_sentence(left_object)) &&
(Instances__of_kind(left_object, K_region) == FALSE)) {
Problems__Issue__subject_problem_at_sentence(_p_(PM_ExistingRegion),
left_subject,
"(which I notice in another sentence) seems now to "
"be declared as a new region",
"which is suspect. Perhaps I have misinterpreted what was "
"meant to be a new name for an old one?");
return TRUE;
}
}
}
if ((ParseTree__get_type(px) == RELATIONSHIP_NT) &&
(ParseTree__get_subject(py) == Kinds__Behaviour__as_subject(K_region))) {
Problems__Issue__assertion_problem(_p_(PM_RegionRelated),
"a region cannot be given a specific location",
"since it contains what may be many rooms, which may not be "
"contiguous and could be scattered about all over. (Sometimes "
"this problem arises because an ambiguous sentence like 'East "
"of Eden is a region.' has been used: Inform reads that as "
"saying that a nameless region lies to the east of the room "
"'Eden'. The desired effect can be got using 'called' to stop "
"Inform taking 'East of' literally: for instance, 'The Land of "
"Nod is in a region called East of Eden.'");
return TRUE;
}
return FALSE;
}
#line 206 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_name_to_early_infs(wording W, inference_subject **infs) {
if ((Preform__parse_nt_against_word_range(notable_regions_kinds_NTM, W, NULL, NULL)) && (K_region == NULL)) *infs = infs_region;
return FALSE;
}
#line 214 "inform7/Chapter 34/Regions.w"
void PL__Regions__create_relations(void) {
R_regional_containment =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__new_term(infs_region),
BinaryPredicates__new_term(Kinds__Behaviour__as_subject(K_object)),
"region-contains", "in-region",
NULL, NULL, Calculus__Schemas__new("TestRegionalContainment(*2,*1)"),
Preform__Nonparsing__wording(relation_names_NTM,
REGIONAL_CONTAINMENT_RELATION_NAME));
BinaryPredicates__set_index_details(R_regional_containment, NULL, "room/region");
}
#line 232 "inform7/Chapter 34/Regions.w"
int PL__Regions__assert_relations(binary_predicate *relation,
instance *I0, instance *I1) {
int I0_is_region = FALSE;
if (Instances__of_kind(I0, K_region)) I0_is_region = TRUE;
int I1_is_region = FALSE;
if (Instances__of_kind(I1, K_region)) I1_is_region = TRUE;
if (I0_is_region) {
if ((relation == R_incorporation) ||
(relation == R_containment) ||
(relation == R_regional_containment)) {
{
#line 268 "inform7/Chapter 34/Regions.w"
if ((PF_I(regions, I1)->in_region) &&
(PF_I(regions, I1)->in_region != I0)) {
Problems__Issue__sentence_problem(_p_(PM_RegionInTwoRegions),
"each region can only be declared to be inside a single "
"other region",
"since although regions can be placed inside each other, "
"they are not permitted to overlap.");
return TRUE;
}
PF_I(regions, I1)->in_region = I0;
PF_I(regions, I1)->in_region_set_at = current_sentence;
}
#line 243 "inform7/Chapter 34/Regions.w"
;
if (I1_is_region)
{
#line 283 "inform7/Chapter 34/Regions.w"
inference_subject *inner = Instances__as_subject(I1);
inference_subject *outer = Instances__as_subject(I0);
World__Inferences__draw(PARENTAGE_INF, inner, CERTAIN_CE, outer, NULL);
}
#line 244 "inform7/Chapter 34/Regions.w"
else
{
#line 291 "inform7/Chapter 34/Regions.w"
inference_subject *rm = Instances__as_subject(I1);
parse_node *spec = Rvalues__from_instance(I0);
Calculus__Propositions__Abstract__assert_kind_of_object(I1, K_room);
World__Inferences__draw_property(rm, P_map_region, spec);
}
#line 245 "inform7/Chapter 34/Regions.w"
;
} else {
Problems__Issue__sentence_problem(_p_(PM_RegionRelation),
"regions can only contain rooms",
"and have no other relationships.");
}
return TRUE;
} else if (I1_is_region) {
if ((relation == R_incorporation) ||
(relation == R_containment) ||
(relation == R_regional_containment)) {
Problems__Issue__sentence_problem(_p_(PM_RegionRelation2),
"regions can only be contained in other regions",
"and not for example in rooms.");
}
}
return FALSE;
}
#line 301 "inform7/Chapter 34/Regions.w"
instance *PL__Regions__enclosing(instance *reg) {
instance *P = NULL;
if (PL__Spatial__object_is_a_room(reg)) P = PF_I(regions, reg)->in_region;
if (PL__Regions__object_is_a_region(reg)) P = PL__Spatial__progenitor(reg);
if (PL__Regions__object_is_a_region(P) == FALSE) return NULL;
return P;
}
#line 312 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_complete_model(int stage) {
if (stage == 2)
{
#line 323 "inform7/Chapter 34/Regions.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((Instances__of_kind(I, K_room)) ||
(Instances__of_kind(I, K_region))) {
parse_node *where = NULL;
parse_node *val = World__Inferences__get_prop_state_at(
Instances__as_subject(I), P_map_region, &where);
if (val) {
instance *reg =
Rvalues__to_object_instance(val);
PF_I(regions, I)->in_region = reg;
PF_I(regions, I)->in_region_set_at = where;
}
}
}
#line 313 "inform7/Chapter 34/Regions.w"
;
if (stage == 3)
{
#line 341 "inform7/Chapter 34/Regions.w"
P_regional_found_in = Properties__Valued__new_nameless(
"regional_found_in", K_text);
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (Instances__of_kind(I, K_region)) {
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Can't allocate for regional-found-in text");
PROP = Routines__begin(PROP, "*");
WRITE_TO(PROP,
"if (TestRegionalContainment(location, %s)) rtrue; rfalse;",
Instances__identifier(I));
PROP = Routines__end(PROP);
WRITE_TO(PROP, ",");
Properties__Valued__assert(P_regional_found_in, Instances__as_subject(I),
Rvalues__from_permanent_STREAM(PROP), CERTAIN_CE);
}
}
#line 314 "inform7/Chapter 34/Regions.w"
;
return FALSE;
}
#line 362 "inform7/Chapter 34/Regions.w"
int PL__Regions__regions_add_to_World_index(instance *O) {
if ((O) && (Instances__of_kind(O, K_room))) {
instance *R = PL__Regions__enclosing(O);
if (R) PL__HTMLMap__colour_chip(O, R, PF_I(regions, O)->in_region_set_at);
}
return FALSE;
}
#line 96 "inform7/Chapter 34/The Map.w"
void PL__Map__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL__Map__map_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_NEW_SUBJECT_NOTIFY, PL__Map__map_new_subject_notify);
PLUGIN_REGISTER(PLUGIN_SET_KIND_NOTIFY, PL__Map__map_set_kind_notify);
PLUGIN_REGISTER(PLUGIN_SET_SUBKIND_NOTIFY, PL__Map__map_set_subkind_notify);
PLUGIN_REGISTER(PLUGIN_ACT_ON_SPECIAL_NPS, PL__Map__map_act_on_special_NPs);
PLUGIN_REGISTER(PLUGIN_CHECK_GOING, PL__Map__map_check_going);
PLUGIN_REGISTER(PLUGIN_COMPILE_MODEL_TABLES, PL__Map__map_compile_model_tables);
PLUGIN_REGISTER(PLUGIN_ESTIMATE_PROPERTY_USAGE, PL__Map__map_estimate_property_usage);
PLUGIN_REGISTER(PLUGIN_COMPILE_OBJECT_HEADER, PL__Map__map_compile_object_header);
PLUGIN_REGISTER(PLUGIN_LOG_INFERENCE_TYPE, PL__Map__map_log_inference_type);
PLUGIN_REGISTER(PLUGIN_INFERENCES_CONTRADICT, PL__Map__map_inferences_contradict);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, PL__Map__map_complete_model);
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, PL__Map__map_new_property_notify);
PLUGIN_REGISTER(PLUGIN_PROPERTY_VALUE_NOTIFY, PL__Map__map_property_value_notify);
PLUGIN_REGISTER(PLUGIN_INTERVENE_IN_ASSERTION, PL__Map__map_intervene_in_assertion);
PLUGIN_REGISTER(PLUGIN_ADD_TO_WORLD_INDEX, PL__Map__map_add_to_World_index);
PLUGIN_REGISTER(PLUGIN_ANNOTATE_IN_WORLD_INDEX, PL__Map__map_annotate_in_World_index);
}
#line 119 "inform7/Chapter 34/The Map.w"
map_data *PL__Map__new_data(inference_subject *subj) {
map_data *md = CREATE(map_data);
md->direction_index = -1;
md->direction_relation = NULL;
int i;
for (i=0; i<MAX_DIRECTIONS; i++) {
md->exits_set_at[i] = NULL;
md->exits[i] = NULL;
}
md->map_connection_a = NULL; md->map_connection_b = NULL;
md->map_direction_a = NULL; md->map_direction_b = NULL;
PL__SpatialMap__initialise_mapping_data(md);
return md;
}
#line 139 "inform7/Chapter 34/The Map.w"
int PL__Map__map_log_inference_type(int it) {
switch(it) {
case DIRECTION_INF: LOG("DIRECTION_INF"); return TRUE;
}
return FALSE;
}
#line 152 "inform7/Chapter 34/The Map.w"
int PL__Map__map_inferences_contradict(inference *A, inference *B, int similarity) {
switch (World__Inferences__get_inference_type(A)) {
case DIRECTION_INF:
if (similarity == CI_DIFFER_IN_INFS1) return TRUE;
break;
}
return FALSE;
}
#line 167 "inform7/Chapter 34/The Map.w"
int notable_map_kinds_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 170 "inform7/Chapter 34/The Map.w"
#line 174 "inform7/Chapter 34/The Map.w"
int PL__Map__map_new_base_kind_notify(kind *new_base, char *name, wording W) {
if (Preform__parse_nt_against_word_range(notable_map_kinds_NTM, W, NULL, NULL)) {
switch (most_recent_result) {
case 0: K_direction = new_base; return TRUE;
case 1: K_door = new_base; return TRUE;
}
}
return FALSE;
}
#line 187 "inform7/Chapter 34/The Map.w"
int PL__Map__map_set_subkind_notify(kind *sub, kind *super) {
if ((sub == K_direction) && (super != K_object)) {
if (problem_count == 0)
Problems__Issue__sentence_problem(_p_(PM_DirectionAdrift),
"'direction' is not allowed to be a kind of anything (other than "
"'object')",
"because it's too fundamental to the way Inform maps out the "
"geography of the physical world.");
return TRUE;
}
if (super == K_direction) {
if (problem_count == 0)
Problems__Issue__sentence_problem(_p_(PM_DirectionSubkinded),
"'direction' is not allowed to have more specific kinds",
"because it's too fundamental to the way Inform maps out the "
"geography of the physical world.");
return TRUE;
}
if ((K_backdrop) && (sub == K_door) && (Kinds__Compare__le(super, K_backdrop))) {
Problems__Issue__sentence_problem(_p_(PM_DoorAdrift),
"'door' is not allowed to be a kind of 'backdrop'",
"because it's too fundamental to the way Inform maps out the "
"geography of the physical world.");
return TRUE;
}
if ((K_backdrop) && (sub == K_backdrop) && (Kinds__Compare__le(super, K_door))) {
Problems__Issue__sentence_problem(_p_(PM_BackdropAdrift),
"'backdrop' is not allowed to be a kind of 'door'",
"because it's too fundamental to the way Inform maps out the "
"geography of the physical world.");
return TRUE;
}
return FALSE;
}
#line 225 "inform7/Chapter 34/The Map.w"
int PL__Map__map_new_subject_notify(inference_subject *subj) {
CREATE_PF_DATA(map, subj, PL__Map__new_data);
return FALSE;
}
#line 233 "inform7/Chapter 34/The Map.w"
int PL__Map__object_is_a_direction(instance *I) {
if ((Plugins__Manage__plugged_in(map_plugin)) && (K_direction) && (I) &&
(Instances__of_kind(I, K_direction)))
return TRUE;
return FALSE;
}
#line 243 "inform7/Chapter 34/The Map.w"
int PL__Map__object_is_a_door(instance *I) {
if ((Plugins__Manage__plugged_in(map_plugin)) && (K_door) && (I) &&
(Instances__of_kind(I, K_door)))
return TRUE;
return FALSE;
}
int PL__Map__subject_is_a_door(inference_subject *infs) {
return PL__Map__object_is_a_door(
InferenceSubjects__as_object_instance(infs));
}
#line 263 "inform7/Chapter 34/The Map.w"
int PL__Map__is_a_direction(inference_subject *infs) {
if (K_direction == NULL) return FALSE; /* in particular, if we aren't using the IF model */
return InferenceSubjects__is_within(infs, Kinds__Behaviour__as_subject(K_direction));
}
#line 273 "inform7/Chapter 34/The Map.w"
int registered_directions = 0; /* next direction number to be free */
#line 280 "inform7/Chapter 34/The Map.w"
int notable_map_directions_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 283 "inform7/Chapter 34/The Map.w"
#line 287 "inform7/Chapter 34/The Map.w"
int PL__Map__map_set_kind_notify(instance *I, kind *k) {
kind *kw = Instances__to_kind(I);
if ((!(Kinds__Compare__le(kw, K_direction))) &&
(Kinds__Compare__le(k, K_direction))) {
wording IW = Instances__get_name(I, FALSE);
{
#line 308 "inform7/Chapter 34/The Map.w"
if (Wordings__empty(IW)) {
Problems__Issue__sentence_problem(_p_(PM_NamelessDirection),
"nameless directions are not allowed",
"so writing something like 'There is a direction.' is forbidden.");
return TRUE;
}
if (Wordings__length(IW) > MAX_WORDS_IN_DIRECTION) {
Problems__Issue__sentence_problem(_p_(PM_DirectionTooLong),
"although direction names can be really quite long in today's Inform",
"they can't be as long as that.");
return TRUE;
}
}
#line 292 "inform7/Chapter 34/The Map.w"
;
if (Preform__parse_nt_against_word_range(notable_map_directions_NTM, IW, NULL, NULL)) {
switch (most_recent_result) {
case 0: I_up = I; break;
case 1: I_down = I; break;
}
}
PL__Naming__object_takes_definite_article(Instances__as_subject(I));
{
#line 324 "inform7/Chapter 34/The Map.w"
int dn = registered_directions++;
char i6_identifier_constant[32];
sprintf(i6_identifier_constant, "DirectionObject_%d", dn);
PL__MapDirections__make_mapped_predicate(I, i6_identifier_constant);
}
#line 300 "inform7/Chapter 34/The Map.w"
;
}
return FALSE;
}
#line 335 "inform7/Chapter 34/The Map.w"
int PL__Map__map_compile_object_header(OUTPUT_STREAM, instance *I) {
if (PL__Map__object_is_a_direction(I)) {
WRITE("Object %s \"\" Compass", Instances__identifier(I));
return TRUE;
}
return FALSE;
}
#line 357 "inform7/Chapter 34/The Map.w"
void PL__Map__build_exits_array(void) {
instance *I;
int d = 0;
LOOP_OVER_OBJECT_INSTANCES(I) {
if (Kinds__Compare__le(Instances__to_kind(I), K_direction)) {
PF_I(map, I)->direction_index = d++;
}
}
LOOP_OVER_OBJECT_INSTANCES(I) {
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), DIRECTION_INF) {
inference_subject *infs1, *infs2;
World__Inferences__get_references(inf, &infs1, &infs2);
instance *to = NULL, *dir = NULL;
if (infs1) to = InferenceSubjects__as_object_instance(infs1);
if (infs2) dir = InferenceSubjects__as_object_instance(infs2);
if ((to) && (dir)) {
int dn = PF_I(map, dir)->direction_index;
if ((dn >= 0) && (dn < MAX_DIRECTIONS)) {
MAP_EXIT(I, dn) = to;
PF_I(map, I)->exits_set_at[dn] = World__Inferences__where_inferred(inf);
}
}
}
}
}
#line 388 "inform7/Chapter 34/The Map.w"
int PL__Map__map_compile_model_tables(OUTPUT_STREAM) {
{
#line 397 "inform7/Chapter 34/The Map.w"
WRITE("Constant No_Directions = %d;\n", registered_directions);
WRITE("! Table of direction object alias constants:\n");
instance *I;
LOOP_OVER_INSTANCES(I, K_direction)
WRITE("Constant DirectionObject_%d = %s;\n",
PF_I(map, I)->direction_index, Instances__identifier(I));
}
#line 389 "inform7/Chapter 34/The Map.w"
;
{
#line 411 "inform7/Chapter 34/The Map.w"
WRITE("Array Map_Storage -->\n");
if (existing_story_file) {
WRITE(" 0 0 0 0;\n\n"); /* as there are no rooms then */
} else {
int words_used = 0;
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PL__Spatial__object_is_a_room(I)) {
int i;
for (i=0; i<registered_directions; i++) {
instance *to = MAP_EXIT(I, i);
if (to)
WRITE(" %s", Instances__identifier(to));
else
WRITE(" 0");
}
words_used++;
WRITE(" ! Exits from: %s\n", Instances__identifier(I));
}
WRITE(";\n\n");
VirtualMachines__note_usage("map", EMPTY_WORDING, "map of rooms and doors",
words_used, 0, FALSE);
}
}
#line 390 "inform7/Chapter 34/The Map.w"
;
return FALSE;
}
#line 444 "inform7/Chapter 34/The Map.w"
void PL__Map__get_door_data(instance *door, instance **c1, instance **c2) {
if (c1) *c1 = PF_I(map, door)->map_connection_a;
if (c2) *c2 = PF_I(map, door)->map_connection_b;
}
#line 455 "inform7/Chapter 34/The Map.w"
int notable_map_properties_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 458 "inform7/Chapter 34/The Map.w"
#line 462 "inform7/Chapter 34/The Map.w"
int PL__Map__map_new_property_notify(property *prn) {
if (Preform__parse_nt_against_word_range(notable_map_properties_NTM, prn->name, NULL, NULL)) {
switch (most_recent_result) {
case 0: P_opposite = prn; break;
case 1: P_other_side = prn; break;
}
}
return FALSE;
}
#line 481 "inform7/Chapter 34/The Map.w"
int PL__Map__map_property_value_notify(property *prn, parse_node *val) {
if (prn == P_other_side) {
instance *I = Rvalues__to_object_instance(val);
if (I) {
World__Inferences__draw(IS_ROOM_INF, Instances__as_subject(I), CERTAIN_CE,
NULL, NULL);
}
}
return FALSE;
}
#line 499 "inform7/Chapter 34/The Map.w"
void PL__Map__set_found_in(instance *I, text_stream *S) {
if (P_found_in == NULL)
P_found_in = Properties__Valued__new_nameless("found_in",
K_value);
if (World__Inferences__get_prop_state(
Instances__as_subject(I), P_found_in))
internal_error("rival found_in interpretations");
Properties__Valued__assert(P_found_in, Instances__as_subject(I),
Rvalues__from_permanent_STREAM(S), CERTAIN_CE);
}
#line 516 "inform7/Chapter 34/The Map.w"
instance *PL__Map__get_value_of_opposite_property(instance *I) {
parse_node *val = World__Inferences__get_prop_state(
Instances__as_subject(I), P_opposite);
if (val) return Rvalues__to_object_instance(val);
return NULL;
}
#line 526 "inform7/Chapter 34/The Map.w"
int PL__Map__map_estimate_property_usage(kind *k, int *words_used) {
if (Kinds__Compare__eq(k, K_door)) *words_used += 14;
if (Kinds__Compare__eq(k, K_room)) *words_used += 2;
return FALSE;
}
#line 536 "inform7/Chapter 34/The Map.w"
int notable_map_noun_phrases_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 539 "inform7/Chapter 34/The Map.w"
#line 543 "inform7/Chapter 34/The Map.w"
int PL__Map__map_act_on_special_NPs(parse_node *p) {
if (Preform__parse_nt_against_word_range(notable_map_noun_phrases_NTM, ParseTree__get_text(p), NULL, NULL)) {
switch (most_recent_result) {
case 0:
if (I_down) {
Assertions__Refiner__noun_from_infs(p, Instances__as_subject(I_down));
return TRUE;
}
break;
case 1:
if (I_up) {
Assertions__Refiner__noun_from_infs(p, Instances__as_subject(I_up));
return TRUE;
}
break;
}
}
return FALSE;
}
#line 566 "inform7/Chapter 34/The Map.w"
int PL__Map__map_check_going(parse_node *from, parse_node *to,
parse_node *by, parse_node *through, parse_node *pushing) {
if (PL__Actions__Patterns__check_going(from, "from",
K_room, K_region) == FALSE) return FALSE;
if (PL__Actions__Patterns__check_going(to, "to",
K_room, K_region) == FALSE) return FALSE;
if (PL__Actions__Patterns__check_going(by, "by",
K_thing, NULL) == FALSE) return FALSE;
if (PL__Actions__Patterns__check_going(through, "through",
K_door, NULL) == FALSE) return FALSE;
if (PL__Actions__Patterns__check_going(pushing, "with",
K_thing, NULL) == FALSE) return FALSE;
return TRUE;
}
#line 599 "inform7/Chapter 34/The Map.w"
int PL__Map__map_intervene_in_assertion(parse_node *px, parse_node *py) {
if ((ParseTree__get_type(px) == PROPER_NOUN_NT) &&
(ParseTree__get_type(py) == COMMON_NOUN_NT)) {
inference_subject *left_object = ParseTree__get_subject(px);
inference_subject *right_kind = ParseTree__get_subject(py);
if ((PL__Map__is_a_direction(left_object)) &&
(PL__Map__is_a_direction(right_kind) == FALSE)) {
Assertions__Creator__convert_instance_to_nounphrase(py, NULL);
return FALSE;
}
if (ParseTree__int_annotation(px, nowhere_ANNOT)) {
Problems__Issue__assertion_problem(_p_(PM_NowhereDescribed),
"'nowhere' cannot be made specific",
"and so cannot have specific properties or be of any given kind.");
return TRUE;
}
}
return FALSE;
}
#line 629 "inform7/Chapter 34/The Map.w"
int oneway_map_connections_only = FALSE;
void PL__Map__enter_one_way_mode(void) { oneway_map_connections_only = TRUE; }
void PL__Map__exit_one_way_mode(void) { oneway_map_connections_only = FALSE; }
#line 640 "inform7/Chapter 34/The Map.w"
void PL__Map__connect(inference_subject *i_from, inference_subject *i_to,
inference_subject *i_dir) {
instance *go_from = InferenceSubjects__as_object_instance(i_from);
instance *go_to = InferenceSubjects__as_object_instance(i_to);
instance *forwards_dir = InferenceSubjects__as_object_instance(i_dir);
if (Instances__of_kind(forwards_dir, K_direction) == FALSE)
internal_error("unknown direction");
instance *reverse_dir = PL__Map__get_value_of_opposite_property(forwards_dir);
if (go_from == NULL) {
Problems__quote_source(1, current_sentence);
Problems__quote_object(2, forwards_dir);
Problems__quote_object(3, go_to);
Problems__Issue__handmade_problem(_p_(PM_WayFromUnclear));
Problems__issue_problem_segment(
"On the basis of %1, I'm trying to make a map connection in the "
"%2 direction to %3, but I can't make sense of where it goes from.");
Problems__issue_problem_end();
return;
}
PL__Map__oneway_map_connection(go_from, go_to, forwards_dir, CERTAIN_CE);
if ((reverse_dir) && (go_to) && (oneway_map_connections_only == FALSE)) {
if (Instances__of_kind(reverse_dir, K_direction) == FALSE) {
Problems__quote_object(1, forwards_dir);
Problems__quote_object(2, reverse_dir);
Problems__Issue__handmade_problem(_p_(PM_OppositeNotDirection));
Problems__issue_problem_segment(
"I'm trying to make a map connection in the %1 direction, "
"which means there ought to be map connection back in the "
"opposite direction. But the opposite of %1 seems to be %2, "
"which doesn't make sense since %2 isn't a direction. (Maybe "
"you forgot to say that it was?)");
Problems__issue_problem_end();
} else PL__Map__oneway_map_connection(go_to, go_from, reverse_dir, LIKELY_CE);
}
}
void PL__Map__oneway_map_connection(instance *go_from, instance *go_to,
instance *forwards_dir, int certainty_level) {
binary_predicate *bp = PL__MapDirections__get_mapping_relation(forwards_dir);
if (bp == NULL) internal_error("map connection in non-direction");
int x = prevailing_mood;
prevailing_mood = certainty_level;
Calculus__Propositions__Assert__assert_true_about(
Calculus__Propositions__Abstract__to_set_simple_relation(bp, go_to),
Instances__as_subject(go_from), certainty_level);
prevailing_mood = x;
}
#line 694 "inform7/Chapter 34/The Map.w"
int PL__Map__map_complete_model(int stage) {
switch (stage) {
case 2:
{
#line 723 "inform7/Chapter 34/The Map.w"
P_room_index = Properties__Valued__new_nameless("room_index", K_number);
parse_node *minus_one = Rvalues__from_int(-1, EMPTY_WORDING);
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PL__Spatial__object_is_a_room(I))
Properties__Valued__assert(P_room_index,
Instances__as_subject(I), minus_one, CERTAIN_CE);
}
#line 697 "inform7/Chapter 34/The Map.w"
;
{
#line 736 "inform7/Chapter 34/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I) {
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), DIRECTION_INF) {
inference_subject *infs1;
World__Inferences__get_references(inf, &infs1, NULL);
instance *to = InferenceSubjects__as_object_instance(infs1);
if ((PL__Spatial__object_is_a_room(I)) && (to) &&
(PL__Map__object_is_a_door(to) == FALSE) &&
(PL__Spatial__object_is_a_room(to) == FALSE))
Problems__Issue__contradiction_problem(_p_(PM_BadMapCell),
Instances__get_creating_sentence(to),
World__Inferences__where_inferred(inf), to,
"appears to be something which can be reached via a map "
"connection, but it seems to be neither a room nor a door",
"and these are the only possibilities allowed by Inform.");
if ((PL__Map__object_is_a_door(I)) &&
(PL__Spatial__object_is_a_room(to) == FALSE))
Problems__Issue__object_problem(_p_(PM_DoorToNonRoom),
I,
"seems to be a door opening on something not a room",
"but a door must connect one or two rooms (and in particular is "
"not allowed to connect to another door).");
}
}
}
#line 698 "inform7/Chapter 34/The Map.w"
;
if (problem_count > 0) break;
{
#line 765 "inform7/Chapter 34/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PL__Map__object_is_a_door(I)) {
int connections_in = 0;
inference *inf;
parse_node *where[3];
where[0] = NULL; where[1] = NULL; where[2] = NULL; /* to placate |gcc| */
inference *front_side_inf = NULL, *back_side_inf = NULL;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), DIRECTION_INF) {
inference_subject *infs1, *infs2;
World__Inferences__get_references(inf, &infs1, &infs2);
instance *to = InferenceSubjects__as_object_instance(infs1);
instance *dir = InferenceSubjects__as_object_instance(infs2);
if (to) {
if (connections_in == 0) {
PF_I(map, I)->map_connection_a = to;
PF_I(map, I)->map_direction_a = dir;
where[0] = World__Inferences__where_inferred(inf);
front_side_inf = inf;
}
if (connections_in == 1) {
PF_I(map, I)->map_connection_b = to;
PF_I(map, I)->map_direction_b = dir;
where[1] = World__Inferences__where_inferred(inf);
back_side_inf = inf;
}
if (connections_in == 2) {
where[2] = World__Inferences__where_inferred(inf);
}
connections_in++;
}
}
if ((front_side_inf) && (back_side_inf)) {
if (World__Inferences__get_timestamp(front_side_inf) >
World__Inferences__get_timestamp(back_side_inf)) {
instance *X = PF_I(map, I)->map_connection_a;
PF_I(map, I)->map_connection_a = PF_I(map, I)->map_connection_b;
PF_I(map, I)->map_connection_b = X;
X = PF_I(map, I)->map_direction_a;
PF_I(map, I)->map_direction_a = PF_I(map, I)->map_direction_b;
PF_I(map, I)->map_direction_b = X;
parse_node *PX = where[0]; where[0] = where[1]; where[1] = PX;
}
}
if (connections_in == 0)
{
#line 816 "inform7/Chapter 34/The Map.w"
Problems__Issue__object_problem(_p_(PM_DoorUnconnected),
I,
"seems to be a door with no way in or out",
"so either you didn't mean it to be a door or you haven't specified what's "
"on each side. You could do this by writing something like 'The blue door is "
"east of the Library and west of the Conservatory'.");
}
#line 809 "inform7/Chapter 34/The Map.w"
;
if (connections_in > 2)
{
#line 826 "inform7/Chapter 34/The Map.w"
Problems__quote_object(1, I);
Problems__quote_source(2, where[0]);
Problems__quote_source(3, where[1]);
Problems__quote_source(4, where[2]);
Problems__Issue__handmade_problem(_p_(PM_DoorOverconnected));
Problems__issue_problem_segment(
"%1 seems to be a door with three ways out (specified %2, %3 and %4), but "
"you can only have one or two sides to a door in Inform: a one-sided "
"door means a door which is only touchable and usable from one side, and an "
"example might be a window through which one falls to the ground below. If "
"you really need a three-sided cavity, best to make it a room in its own right.");
Problems__issue_problem_end();
}
#line 810 "inform7/Chapter 34/The Map.w"
;
}
}
#line 700 "inform7/Chapter 34/The Map.w"
;
if (problem_count > 0) break;
{
#line 846 "inform7/Chapter 34/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PL__Spatial__object_is_a_room(I)) {
inference *inf;
POSITIVE_KNOWLEDGE_LOOP(inf, Instances__as_subject(I), DIRECTION_INF) {
inference_subject *infs1;
World__Inferences__get_references(inf, &infs1, NULL);
instance *to = InferenceSubjects__as_object_instance(infs1);
if (PL__Map__object_is_a_door(to)) {
instance *exit1 = PF_I(map, to)->map_connection_a;
instance *exit2 = PF_I(map, to)->map_connection_b;
if ((I != exit1) && (exit2 == NULL)) {
Problems__quote_object(1, I);
Problems__quote_object(2, to);
Problems__quote_object(3, exit1);
Problems__Issue__handmade_problem(_p_(PM_RoomTwistyDoor));
Problems__issue_problem_segment(
"%1, a room, seems to have a map connection which goes "
"through %2, a door: but that doesn't seem physically "
"possible, since %2 seems to connect to %3 in the same "
"direction. Something's twisty here.");
Problems__issue_problem_end();
} else if ((I != exit1) && (I != exit2)) {
Problems__quote_object(1, I);
Problems__quote_object(2, to);
Problems__quote_object(3, exit1);
Problems__quote_object(4, exit2);
Problems__Issue__handmade_problem(_p_(PM_RoomMissingDoor));
Problems__issue_problem_segment(
"%1, a room, seems to have a map connection which goes "
"through %2, a door: but that doesn't seem physically "
"possible, since the rooms on each side of %2 have "
"been established as %3 and %4.");
Problems__issue_problem_end();
}
}
}
}
}
#line 702 "inform7/Chapter 34/The Map.w"
;
if (problem_count > 0) break;
{
#line 888 "inform7/Chapter 34/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((PL__Map__object_is_a_door(I)) &&
(PF_I(map, I)->map_connection_a) &&
(PF_I(map, I)->map_connection_b) &&
(World__Inferences__get_prop_state(
Instances__as_subject(I), P_other_side)))
Problems__Issue__object_problem(_p_(PM_BothWaysDoor),
I, "seems to be a door whose connections have been given in both "
"of the alternative ways at once",
"by directly giving its map connections (the normal way to set up "
"a two-sided door) and also by saying what is through it (the normal "
"way to set up a one-sided door). As a door can't be both one- and "
"two-sided at once, I'm going to object to this.");
}
#line 704 "inform7/Chapter 34/The Map.w"
;
if (problem_count > 0) break;
{
#line 911 "inform7/Chapter 34/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((PL__Map__object_is_a_door(I)) &&
(PL__Spatial__progenitor(I)) &&
(PL__Spatial__progenitor(I) != PF_I(map, I)->map_connection_a) &&
(PL__Spatial__progenitor(I) != PF_I(map, I)->map_connection_b))
Problems__Issue__object_problem(_p_(PM_DoorInThirdRoom),
I, "seems to be a door which is present in a room to which it is not connected",
"but this is not allowed. A door must be in one or both of the rooms it is "
"between, but not in a third place altogether.");
}
#line 706 "inform7/Chapter 34/The Map.w"
;
if (problem_count > 0) break;
{
#line 927 "inform7/Chapter 34/The Map.w"
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if ((PL__Map__object_is_a_door(I)) &&
(PF_I(map, I)->map_connection_b == NULL) &&
(PL__Spatial__progenitor(I) == NULL))
PL__Spatial__set_progenitor(I, PF_I(map, I)->map_connection_a, NULL);
}
#line 708 "inform7/Chapter 34/The Map.w"
;
{
#line 940 "inform7/Chapter 34/The Map.w"
P_door_dir = Properties__Valued__new_nameless("door_dir", K_value);
P_door_to = Properties__Valued__new_nameless("door_to", K_value);
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PL__Map__object_is_a_door(I)) {
instance *R1 = PF_I(map, I)->map_connection_a;
instance *R2 = PF_I(map, I)->map_connection_b;
instance *D1 = PF_I(map, I)->map_direction_a;
instance *D2 = PF_I(map, I)->map_direction_b;
if (R1 && R2) {
{
#line 962 "inform7/Chapter 34/The Map.w"
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for found-in text");
WRITE_TO(PROP, "%s %s",
Instances__identifier(R1), Instances__identifier(R2));
PL__Map__set_found_in(I, PROP);
}
#line 951 "inform7/Chapter 34/The Map.w"
;
{
#line 973 "inform7/Chapter 34/The Map.w"
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for door-dir text");
PROP = Routines__begin(PROP, "*");
LocalVariables__add_internal_local_c("loc", "room of actor");
WRITE_TO(PROP, "loc = location;\n");
WRITE_TO(PROP, "if (loc == thedark) loc = real_location;\n");
WRITE_TO(PROP, "if (loc == %s) return %s; return %s;",
Instances__identifier(R1),
Instances__identifier(
PL__Map__get_value_of_opposite_property(D1)),
Instances__identifier(
PL__Map__get_value_of_opposite_property(D2)));
PROP = Routines__end(PROP);
WRITE_TO(PROP, ",");
Properties__Valued__assert(P_door_dir, Instances__as_subject(I),
Rvalues__from_permanent_STREAM(PROP), CERTAIN_CE);
}
#line 952 "inform7/Chapter 34/The Map.w"
;
{
#line 996 "inform7/Chapter 34/The Map.w"
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for door-to text");
PROP = Routines__begin(PROP, "*");
LocalVariables__add_internal_local_c("loc", "room of actor");
WRITE_TO(PROP, "loc = location;\n");
WRITE_TO(PROP, "if (loc == thedark) loc = real_location;\n");
WRITE_TO(PROP, "if (loc == %s) return %s; return %s;",
Instances__identifier(R1),
Instances__identifier(R2), Instances__identifier(R1));
PROP = Routines__end(PROP);
WRITE_TO(PROP, ",");
Properties__Valued__assert(P_door_to, Instances__as_subject(I),
Rvalues__from_permanent_STREAM(PROP), CERTAIN_CE);
}
#line 953 "inform7/Chapter 34/The Map.w"
;
} else if (R1) {
{
#line 1023 "inform7/Chapter 34/The Map.w"
instance *backwards = PL__Map__get_value_of_opposite_property(D1);
if (backwards) {
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for door-dir text");
WRITE_TO(PROP, "%s", Instances__identifier(backwards));
Properties__Valued__assert(P_door_dir, Instances__as_subject(I),
Rvalues__from_permanent_STREAM(PROP), CERTAIN_CE);
}
}
#line 955 "inform7/Chapter 34/The Map.w"
;
}
}
}
#line 709 "inform7/Chapter 34/The Map.w"
;
break;
case 4: PL__Map__build_exits_array(); break;
}
return FALSE;
}
#line 1036 "inform7/Chapter 34/The Map.w"
int PL__Map__map_add_to_World_index(instance *O) {
if ((O) && (Instances__of_kind(O, K_room))) {
PL__SpatialMap__index_room_connections(O);
}
return FALSE;
}
int PL__Map__map_annotate_in_World_index(instance *O) {
if ((O) && (Instances__of_kind(O, K_door))) {
instance *A = NULL, *B = NULL;
PL__Map__get_door_data(O, &A, &B);
if ((A) && (B)) INDEX(" - <i>door to ");
else INDEX(" - <i>one-sided door to ");
instance *X = A;
if (A == indexing_room) X = B;
if (X == NULL) {
parse_node *S = World__Inferences__get_prop_state(
Instances__as_subject(O), P_other_side);
X = Rvalues__to_object_instance(S);
}
if (X == NULL) INDEX("nowhere");
else Instances__index_name(X);
INDEX("</i>");
return TRUE;
}
return FALSE;
}
#line 25 "inform7/Chapter 34/Map Connection Relations.w"
void PL__MapDirections__create_relations(void) {
R_adjacency =
BinaryPredicates__make_pair(SPATIAL_KBP,
BinaryPredicates__new_term(infs_room),
BinaryPredicates__new_term(infs_room),
"adjacent-to", "adjacent-from",
NULL, NULL, Calculus__Schemas__new("TestAdjacency(*1,*2)"),
Preform__Nonparsing__wording(relation_names_NTM, ADJACENCY_RELATION_NAME));
}
#line 38 "inform7/Chapter 34/Map Connection Relations.w"
int PL__MapDirections__assert_relations(binary_predicate *relation, instance *I0, instance *I1) {
return FALSE;
}
#line 47 "inform7/Chapter 34/Map Connection Relations.w"
void PL__MapDirections__REL_create_initial_stock(void) {
}
#line 58 "inform7/Chapter 34/Map Connection Relations.w"
binary_predicate *PL__MapDirections__create_sketchy_mapping_direction(wording W) {
binary_predicate *bp;
{
#line 110 "inform7/Chapter 34/Map Connection Relations.w"
if (Wordings__length(W) > MAX_WORDS_IN_DIRECTION)
W = Wordings__truncate(W, MAX_WORDS_IN_DIRECTION); /* just truncate for now */
char dln[MAX_WORDS_IN_DIRECTION*MAX_WORD_LENGTH+10]; /* for debugging log, e.g., "north-map" */
Wordings__to_string(dln, W); sprintf(dln + Platform__strlen(dln), "-map");
int i;
for (i=0; dln[i]; i++) if (dln[i] == ' ') dln[i] = '-';
bp_term_details room_term = BinaryPredicates__new_term(NULL);
bp = BinaryPredicates__make_pair(MAP_CONNECTING_KBP,
room_term, room_term, dln, NULL, NULL, NULL, NULL,
Preform__Nonparsing__merge(mapping_relation_construction_NTM, 0,
WordAssemblages__from_wording(W)));
int mpc_form = 0;
if (Preform__parse_nt_against_word_range(notable_directions_NTM, W, NULL, NULL)) mpc_form = 1;
Prepositions__register(
Preform__Nonparsing__merge(mapping_preposition_construction_NTM, mpc_form,
WordAssemblages__from_wording(W)),
FALSE, bp, FALSE, FALSE);
}
#line 60 "inform7/Chapter 34/Map Connection Relations.w"
;
return bp;
}
#line 91 "inform7/Chapter 34/Map Connection Relations.w"
int mapping_relation_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 93 "inform7/Chapter 34/Map Connection Relations.w"
int mapping_preposition_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 97 "inform7/Chapter 34/Map Connection Relations.w"
#line 103 "inform7/Chapter 34/Map Connection Relations.w"
int notable_directions_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 106 "inform7/Chapter 34/Map Connection Relations.w"
#line 142 "inform7/Chapter 34/Map Connection Relations.w"
int mmp_call_counter = 0;
void PL__MapDirections__make_mapped_predicate(instance *I, char *ident) {
wording W = Instances__get_name(I, FALSE);
if ((Wordings__empty(W)) || (Wordings__length(W) > MAX_WORDS_IN_DIRECTION))
internal_error("bad direction name");
binary_predicate *bp = Sentences__Rearrangement__relation_noticed(mmp_call_counter++);
if (bp == NULL) {
LOG("Improper text: $w\n", W);
Problems__Issue__sentence_problem(_p_(PM_ImproperlyMadeDirection),
"directions must be created by only the simplest possible sentences",
"in the form 'North-north-west is a direction' only. Using adjectives, "
"'called', 'which', and so on is not allowed. (In practice this is not "
"too much of a restriction. I won't allow 'Clockwise is a privately-named "
"direction.', but I will allow 'Clockwise is a direction. Clockwise "
"is privately-named.')");
return;
}
bp->term_details[0] = BinaryPredicates__new_term(NULL);
bp->term_details[1] = BinaryPredicates__new_term(NULL);
BinaryPredicates__set_index_details(bp, "room/door", "room/door");
bp->test_function = Calculus__Schemas__new("(MapConnection(*2,%s) == *1)", ident);
bp->make_true_function = Calculus__Schemas__new("AssertMapConnection(*2,%s,*1)", ident);
bp->make_false_function = Calculus__Schemas__new("AssertMapUnconnection(*2,%s,*1)", ident);
PF_I(map, I)->direction_relation = bp;
}
#line 172 "inform7/Chapter 34/Map Connection Relations.w"
void PL__MapDirections__REL_create_second_stock(void) {
}
#line 180 "inform7/Chapter 34/Map Connection Relations.w"
int PL__MapDirections__REL_typecheck(binary_predicate *bp,
kind **kinds_of_terms, kind **kinds_required, tc_problem_kit *tck) {
int t;
for (t=0; t<2; t++)
if ((Kinds__Compare__compatible(kinds_of_terms[t], K_room) == NEVER_MATCH) &&
(Kinds__Compare__compatible(kinds_of_terms[t], K_door) == NEVER_MATCH)) {
LOG("Term %d is $u but should be a room or door\n", t, kinds_of_terms[t]);
Calculus__Propositions__Checker__issue_bp_typecheck_error(bp, kinds_of_terms[0], kinds_of_terms[1], tck);
return NEVER_MATCH;
}
return ALWAYS_MATCH;
}
#line 201 "inform7/Chapter 34/Map Connection Relations.w"
int PL__MapDirections__REL_assert(binary_predicate *bp,
inference_subject *infs0, parse_node *spec0,
inference_subject *infs1, parse_node *spec1) {
instance *o_dir = PL__MapDirections__get_mapping_direction(bp);
inference_subject *infs_from = infs0;
inference_subject *infs_to = infs1;
World__Inferences__draw(IS_ROOM_INF, infs_from, prevailing_mood, NULL, NULL);
if ((prevailing_mood >= 0) && (infs_to))
World__Inferences__draw(IS_ROOM_INF, infs_to, LIKELY_CE, NULL, NULL);
World__Inferences__draw(DIRECTION_INF, infs_from, prevailing_mood,
infs_to, o_dir?(Instances__as_subject(o_dir)):NULL);
return TRUE;
}
#line 221 "inform7/Chapter 34/Map Connection Relations.w"
int PL__MapDirections__REL_compile(int task, binary_predicate *bp, annotated_i6_schema *asch) {
return FALSE;
}
#line 228 "inform7/Chapter 34/Map Connection Relations.w"
int PL__MapDirections__REL_describe_for_problems(OUTPUT_STREAM, binary_predicate *bp) {
return FALSE;
}
#line 236 "inform7/Chapter 34/Map Connection Relations.w"
binary_predicate *PL__MapDirections__get_mapping_relation(instance *dir) {
if (dir == NULL) return NULL;
return PF_I(map, dir)->direction_relation;
}
instance *PL__MapDirections__get_mapping_direction(binary_predicate *bp) {
if (bp == NULL) return NULL;
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PF_I(map, I)->direction_relation == bp)
return I;
return NULL;
}
#line 55 "inform7/Chapter 34/Spatial Geometry.w"
vector Geometry__vec(int x, int y, int z) {
vector R;
R.x = x; R.y = y; R.z = z;
return R;
}
#line 64 "inform7/Chapter 34/Spatial Geometry.w"
int Geometry__vec_eq(vector U, vector V) {
if ((U.x == V.x) && (U.y == V.y) && (U.z == V.z)) return TRUE;
return FALSE;
}
int Geometry__vec_lateral(vector V) {
if ((V.x == 0) && (V.y == 0)) return FALSE;
return TRUE;
}
#line 77 "inform7/Chapter 34/Spatial Geometry.w"
vector Geometry__vec_plus(vector U, vector V) {
vector R;
R.x = U.x + V.x; R.y = U.y + V.y; R.z = U.z + V.z;
return R;
}
vector Geometry__vec_minus(vector U, vector V) {
vector R;
R.x = U.x - V.x; R.y = U.y - V.y; R.z = U.z - V.z;
return R;
}
vector Geometry__vec_negate(vector V) {
vector R;
R.x = -V.x; R.y = -V.y; R.z = -V.z;
return R;
}
vector Geometry__vec_scale(int lambda, vector V) {
vector R;
R.x = lambda*V.x; R.y = lambda*V.y; R.z = lambda*V.z;
return R;
}
#line 104 "inform7/Chapter 34/Spatial Geometry.w"
int Geometry__vec_length_squared(vector V) {
return V.x*V.x + V.y*V.y + V.z*V.z;
}
float Geometry__vec_length(vector V) {
return (float) (sqrt(Geometry__vec_length_squared(V)));
}
#line 121 "inform7/Chapter 34/Spatial Geometry.w"
float Geometry__vec_angular_separation(vector E, vector D) {
float E_distance = Geometry__vec_length(E);
float uex = E.x/E_distance, uey = E.y/E_distance, uez = E.z/E_distance;
float D_distance = Geometry__vec_length(D);
float udx = D.x/D_distance, udy = D.y/D_distance, udz = D.z/D_distance;
return (uex-udx)*(uex-udx) + (uey-udy)*(uey-udy) + (uez-udz)*(uez-udz);
}
#line 134 "inform7/Chapter 34/Spatial Geometry.w"
cuboid Geometry__empty_cuboid(void) {
cuboid C;
C.population = 0;
C.corner0 = Zero_vector; C.corner1 = Zero_vector;
return C;
}
void Geometry__adjust_cuboid(cuboid *C, vector V) {
if (C->population++ == 0) {
C->corner0 = V; C->corner1 = V;
} else {
if (V.x < C->corner0.x) C->corner0.x = V.x;
if (V.x > C->corner1.x) C->corner1.x = V.x;
if (V.y < C->corner0.y) C->corner0.y = V.y;
if (V.y > C->corner1.y) C->corner1.y = V.y;
if (V.z < C->corner0.z) C->corner0.z = V.z;
if (V.z > C->corner1.z) C->corner1.z = V.z;
}
}
#line 157 "inform7/Chapter 34/Spatial Geometry.w"
void Geometry__merge_cuboid(cuboid *C, cuboid X) {
if (X.population > 0) {
if (C->population == 0) {
*C = X;
} else {
Geometry__adjust_cuboid(C, X.corner0);
Geometry__adjust_cuboid(C, X.corner1);
C->population += X.population - 2;
}
}
}
#line 173 "inform7/Chapter 34/Spatial Geometry.w"
void Geometry__cuboid_translate(cuboid *C, vector D) {
if (C->population > 0) {
C->corner0 = Geometry__vec_plus(C->corner0, D);
C->corner1 = Geometry__vec_plus(C->corner1, D);
}
}
#line 183 "inform7/Chapter 34/Spatial Geometry.w"
int Geometry__within_cuboid(vector P, cuboid C) {
if (C.population == 0) return FALSE;
if (P.x < C.corner0.x) return FALSE;
if (P.x > C.corner1.x) return FALSE;
if (P.y < C.corner0.y) return FALSE;
if (P.y > C.corner1.y) return FALSE;
if (P.z < C.corner0.z) return FALSE;
if (P.z > C.corner1.z) return FALSE;
return TRUE;
}
#line 200 "inform7/Chapter 34/Spatial Geometry.w"
int Geometry__cuboid_index(vector P, cuboid C) {
if (Geometry__within_cuboid(P, C) == FALSE) return -1;
vector O = Geometry__vec_minus(P, C.corner0);
int width = C.corner1.x - C.corner0.x + 1;
int height = C.corner1.y - C.corner0.y + 1;
return O.x + O.y*width + O.z*width*height;
}
int Geometry__cuboid_volume(cuboid C) {
if (C.population == 0) return 0;
int width = C.corner1.x - C.corner0.x + 1;
int height = C.corner1.y - C.corner0.y + 1;
int depth = C.corner1.z - C.corner0.z + 1;
return width*height*depth;
}
#line 221 "inform7/Chapter 34/Spatial Geometry.w"
void Geometry__thicken_cuboid(cuboid *C, vector V, vector S) {
if (C->population++ == 0) {
C->corner0 = Geometry__vec_minus(V, S);
C->corner1 = Geometry__vec_plus(V, S);
} else {
if (V.x < C->corner0.x) C->corner0.x = V.x - S.x;
if (V.x > C->corner1.x) C->corner1.x = V.x + S.x;
if (V.y < C->corner0.y) C->corner0.y = V.y - S.y;
if (V.y > C->corner1.y) C->corner1.y = V.y + S.y;
if (V.z < C->corner0.z) C->corner0.z = V.z - S.z;
if (V.z > C->corner1.z) C->corner1.z = V.z + S.z;
}
}
#line 141 "inform7/Chapter 34/Spatial Map.w"
int spatial_coordinates_established = FALSE;
int partitioned_into_components = FALSE;
void PL__SpatialMap__establish_spatial_coordinates(void) {
if (spatial_coordinates_established) return;
if (Log__aspect_switched_on(SPATIAL_MAP_DA)) PL__SpatialMap__log_precis_of_map();
Universe = Geometry__empty_cuboid();
{
#line 506 "inform7/Chapter 34/Spatial Map.w"
instance *R;
LOOP_OVER_ROOMS(R) {
int i;
LOOP_OVER_DIRECTIONS(i)
PF_I(map, R)->spatial_relationship[i] = NULL;
}
LOOP_OVER_ROOMS(R) {
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__room_exit_as_indexed(R, i, NULL);
if (T)
{
#line 534 "inform7/Chapter 34/Spatial Map.w"
int back = PL__SpatialMap__opposite(i);
int cw = PL__SpatialMap__rotate_direction(back, 1); /* clockwise one place */
int cwcw = PL__SpatialMap__rotate_direction(cw, 1); /* clockwise twice */
int ccw = PL__SpatialMap__rotate_direction(back, -1); /* counterclockwise once */
int ccwccw = PL__SpatialMap__rotate_direction(ccw, -1); /* counterclockwise twice */
instance *backstep = PL__SpatialMap__room_exit_as_indexed(T, back, NULL);
{
#line 557 "inform7/Chapter 34/Spatial Map.w"
if ((backstep == R) &&
(cwcw >= 0) &&
(PL__SpatialMap__room_exit_as_indexed(T, cwcw, NULL) == R) &&
(PL__SpatialMap__room_exit_as_indexed(T, cw, NULL) == NULL) &&
(PL__SpatialMap__room_exit_as_indexed(R, PL__SpatialMap__opposite(cwcw), NULL) == T) &&
(PL__SpatialMap__room_exit_as_indexed(T, PL__SpatialMap__opposite(cw), NULL) == NULL)) {
PL__SpatialMap__form_spatial_relationship(R, PL__SpatialMap__opposite(cw), T);
continue;
}
if ((backstep == R) &&
(ccwccw >= 0) &&
(PL__SpatialMap__room_exit_as_indexed(T, ccwccw, NULL) == R) &&
(PL__SpatialMap__room_exit_as_indexed(T, ccw, NULL) == NULL) &&
(PL__SpatialMap__room_exit_as_indexed(R, PL__SpatialMap__opposite(ccwccw), NULL) == T) &&
(PL__SpatialMap__room_exit_as_indexed(T, PL__SpatialMap__opposite(ccw), NULL) == NULL)) {
PL__SpatialMap__form_spatial_relationship(R, PL__SpatialMap__opposite(ccw), T);
continue;
}
}
#line 542 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 579 "inform7/Chapter 34/Spatial Map.w"
if (backstep == R) {
PL__SpatialMap__form_spatial_relationship(R, i, T);
continue;
}
}
#line 543 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 589 "inform7/Chapter 34/Spatial Map.w"
/* a deformed 2-way connection made up of 1-way connections */
if ((cwcw >= 0) &&
(PL__SpatialMap__room_exit_as_indexed(T, cwcw, NULL) == R) &&
(PL__SpatialMap__room_exit_as_indexed(T, cw, NULL) == NULL) &&
(PL__SpatialMap__room_exit_as_indexed(R, PL__SpatialMap__opposite(cwcw), NULL) == T) &&
(PL__SpatialMap__room_exit_as_indexed(T, PL__SpatialMap__opposite(cw), NULL) == NULL)) {
PL__SpatialMap__form_spatial_relationship(R, PL__SpatialMap__opposite(cw), T);
continue;
}
if ((ccwccw >= 0) &&
(PL__SpatialMap__room_exit_as_indexed(T, ccwccw, NULL) == R) &&
(PL__SpatialMap__room_exit_as_indexed(T, ccw, NULL) == NULL) &&
(PL__SpatialMap__room_exit_as_indexed(R, PL__SpatialMap__opposite(ccwccw), NULL) == T) &&
(PL__SpatialMap__room_exit_as_indexed(T, PL__SpatialMap__opposite(ccw), NULL) == NULL)) {
PL__SpatialMap__form_spatial_relationship(R, PL__SpatialMap__opposite(ccw), T);
continue;
}
}
#line 544 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 614 "inform7/Chapter 34/Spatial Map.w"
int j, two_ways = 0;
LOOP_OVER_LATTICE_DIRECTIONS(j)
if ((PL__SpatialMap__room_exit_as_indexed(T, j, NULL) == R) &&
(PL__SpatialMap__room_exit_as_indexed(R, PL__SpatialMap__opposite(j), NULL) == T))
two_ways++;
if ((two_ways == 0) && (backstep == NULL))
PL__SpatialMap__form_spatial_relationship(R, i, T);
}
#line 545 "inform7/Chapter 34/Spatial Map.w"
;
}
#line 516 "inform7/Chapter 34/Spatial Map.w"
;
}
}
}
#line 148 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 890 "inform7/Chapter 34/Spatial Map.w"
PL__SpatialMap__create_map_component_around(benchmark_room);
instance *R;
LOOP_OVER_ROOMS(R)
if (PF_I(map, R)->submap == NULL)
PL__SpatialMap__create_map_component_around(R);
}
#line 149 "inform7/Chapter 34/Spatial Map.w"
;
partitioned_into_components = TRUE;
{
#line 995 "inform7/Chapter 34/Spatial Map.w"
connected_submap *sub;
int total_accuracy = 0;
LOOP_OVER(sub, connected_submap) {
LOGIF(SPATIAL_MAP, "Laying out component %d\n", sub->allocation_id);
PL__SpatialMap__lock_positions_in_submap(sub); /* $O(R)$ running time */
PL__SpatialMap__establish_natural_lengths(sub); /* $O(R)$ running time */
PL__SpatialMap__position_submap(sub);
total_accuracy += sub->heat;
LOGIF(SPATIAL_MAP, "Component %d has final heat %d\n", sub->allocation_id, sub->heat);
}
LOGIF(SPATIAL_MAP, "\nAll components laid out: total heat %d\n\n", total_accuracy);
LOGIF(SPATIAL_MAP, "Cost: cutpoint choosing %d drognas\n", cutpoint_spending);
LOGIF(SPATIAL_MAP, "Cost: dividing %d drognas\n", division_spending);
LOGIF(SPATIAL_MAP, "Cost: sliding %d drognas\n", slide_spending);
LOGIF(SPATIAL_MAP, "Cost: cooling %d drognas\n", cooling_spending);
LOGIF(SPATIAL_MAP, "Cost: quenching %d drognas\n", quenching_spending);
LOGIF(SPATIAL_MAP, "Cost: diffusion %d drognas\n", diffusion_spending);
LOGIF(SPATIAL_MAP, "Cost: radiation %d drognas\n", radiation_spending);
LOGIF(SPATIAL_MAP, "Cost: explosion %d drognas\n\n", explosion_spending);
}
#line 151 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 2380 "inform7/Chapter 34/Spatial Map.w"
int ncom = NUMBER_CREATED(connected_submap);
connected_submap **sorted =
Memory__I7_calloc(ncom, sizeof(connected_submap *), INDEX_SORTING_MREASON);
{
#line 2506 "inform7/Chapter 34/Spatial Map.w"
connected_submap *sub;
LOOP_OVER(sub, connected_submap) sub->positioned = FALSE;
int i = 0;
LOOP_OVER(sub, connected_submap) sorted[i++] = sub;
qsort(sorted, (size_t) ncom, sizeof(connected_submap *), PL__SpatialMap__compare_components);
}
#line 2383 "inform7/Chapter 34/Spatial Map.w"
;
connected_submap *sub, *previous_mc = NULL;
int i, j;
vector Drill_square_O = Zero_vector;
vector Drill_square_At = Zero_vector;
int drill_square_side = 0;
cuboid box = Geometry__empty_cuboid();
for (i=0; i<ncom; i++) {
sub = sorted[i];
if (sub->positioned == FALSE) {
{
#line 2410 "inform7/Chapter 34/Spatial Map.w"
if (previous_mc) {
int x_max = box.corner1.x - sub->bounds.corner0.x + 1;
if ((sub->bounds.population == 1) && (PL__SpatialMap__component_is_isolated(sub)))
{
#line 2442 "inform7/Chapter 34/Spatial Map.w"
LOGIF(SPATIAL_MAP, "Component %d (size %d): drill square strategy\n",
sub->allocation_id, sub->bounds.population);
if (drill_square_side == 0) {
Drill_square_O =
Geometry__vec(box.corner1.x + 1, box.corner0.y, Room_position(benchmark_room).z);
Drill_square_At = Drill_square_O;
connected_submap *sing;
int N = 0;
LOOP_OVER(sing, connected_submap)
if ((sing->bounds.population == 1) && (PL__SpatialMap__component_is_isolated(sing)))
N++;
while (drill_square_side*drill_square_side < N) drill_square_side++;
if (drill_square_side*drill_square_side > N) drill_square_side--;
LOGIF(SPATIAL_MAP, "Drill square: side %d\n", drill_square_side);
}
PL__SpatialMap__move_component(sub, Geometry__vec_minus(Drill_square_At, sub->bounds.corner0));
Drill_square_At = Geometry__vec_plus(Drill_square_At, Geometry__vec(0, 1, 0));
if (Drill_square_At.y - Drill_square_O.y == drill_square_side)
Drill_square_At = Geometry__vec_plus(Drill_square_At,
Geometry__vec(1, -drill_square_side, 0));
}
#line 2413 "inform7/Chapter 34/Spatial Map.w"
else if (PL__SpatialMap__component_is_adjoining(sub))
{
#line 2471 "inform7/Chapter 34/Spatial Map.w"
LOGIF(SPATIAL_MAP, "Component %d (size %d): optimised inset strategy\n",
sub->allocation_id, sub->bounds.population);
instance *outer = NULL, *inner = NULL;
PL__SpatialMap__find_link_to_placed_components(sub, &outer, &inner);
vector Best_offset =
Geometry__vec(x_max, box.corner0.y - sub->bounds.corner0.y,
Room_position(benchmark_room).z - sub->bounds.corner0.z);
if ((outer) && (inner)) {
int dx = 0, dy = 0, dz = 0, min_s = FUSION_POINT;
for (dx = -MAX_OFFSET; dx <= MAX_OFFSET; dx++)
for (dy = -MAX_OFFSET; dy <= MAX_OFFSET; dy++)
for (dz = -MAX_OFFSET; dz <= MAX_OFFSET; dz++) {
if ((dx == 0) && (dy == 0) && (dz == 0)) continue;
vector Offset =
Geometry__vec_plus(
Geometry__vec_minus(Room_position(outer), Room_position(inner)),
Geometry__vec(dx, dy, dz));
{
#line 2496 "inform7/Chapter 34/Spatial Map.w"
PL__SpatialMap__move_component(sub, Offset);
int s = PL__SpatialMap__find_component_placement_heat(sub);
if (s < min_s) {
min_s = s; Best_offset = Offset;
}
PL__SpatialMap__move_component(sub, Geometry__vec_negate(Offset));
}
#line 2488 "inform7/Chapter 34/Spatial Map.w"
;
}
}
PL__SpatialMap__move_component(sub, Best_offset);
}
#line 2415 "inform7/Chapter 34/Spatial Map.w"
else
{
#line 2427 "inform7/Chapter 34/Spatial Map.w"
LOGIF(SPATIAL_MAP, "Component %d (size %d): side by side strategy\n",
sub->allocation_id, sub->bounds.population);
PL__SpatialMap__move_component(sub,
Geometry__vec(x_max, box.corner0.y - sub->bounds.corner0.y,
Room_position(benchmark_room).z - sub->bounds.corner0.z));
}
#line 2417 "inform7/Chapter 34/Spatial Map.w"
;
}
Geometry__merge_cuboid(&box, sub->bounds);
previous_mc = sub;
sub->positioned = TRUE;
}
#line 2394 "inform7/Chapter 34/Spatial Map.w"
;
for (j=ncom-1; j>=0; j--) {
sub = sorted[j];
if ((sub->positioned == FALSE) &&
(PL__SpatialMap__no_links_to_placed_components(sub) == 1)) {
{
#line 2410 "inform7/Chapter 34/Spatial Map.w"
if (previous_mc) {
int x_max = box.corner1.x - sub->bounds.corner0.x + 1;
if ((sub->bounds.population == 1) && (PL__SpatialMap__component_is_isolated(sub)))
{
#line 2442 "inform7/Chapter 34/Spatial Map.w"
LOGIF(SPATIAL_MAP, "Component %d (size %d): drill square strategy\n",
sub->allocation_id, sub->bounds.population);
if (drill_square_side == 0) {
Drill_square_O =
Geometry__vec(box.corner1.x + 1, box.corner0.y, Room_position(benchmark_room).z);
Drill_square_At = Drill_square_O;
connected_submap *sing;
int N = 0;
LOOP_OVER(sing, connected_submap)
if ((sing->bounds.population == 1) && (PL__SpatialMap__component_is_isolated(sing)))
N++;
while (drill_square_side*drill_square_side < N) drill_square_side++;
if (drill_square_side*drill_square_side > N) drill_square_side--;
LOGIF(SPATIAL_MAP, "Drill square: side %d\n", drill_square_side);
}
PL__SpatialMap__move_component(sub, Geometry__vec_minus(Drill_square_At, sub->bounds.corner0));
Drill_square_At = Geometry__vec_plus(Drill_square_At, Geometry__vec(0, 1, 0));
if (Drill_square_At.y - Drill_square_O.y == drill_square_side)
Drill_square_At = Geometry__vec_plus(Drill_square_At,
Geometry__vec(1, -drill_square_side, 0));
}
#line 2413 "inform7/Chapter 34/Spatial Map.w"
else if (PL__SpatialMap__component_is_adjoining(sub))
{
#line 2471 "inform7/Chapter 34/Spatial Map.w"
LOGIF(SPATIAL_MAP, "Component %d (size %d): optimised inset strategy\n",
sub->allocation_id, sub->bounds.population);
instance *outer = NULL, *inner = NULL;
PL__SpatialMap__find_link_to_placed_components(sub, &outer, &inner);
vector Best_offset =
Geometry__vec(x_max, box.corner0.y - sub->bounds.corner0.y,
Room_position(benchmark_room).z - sub->bounds.corner0.z);
if ((outer) && (inner)) {
int dx = 0, dy = 0, dz = 0, min_s = FUSION_POINT;
for (dx = -MAX_OFFSET; dx <= MAX_OFFSET; dx++)
for (dy = -MAX_OFFSET; dy <= MAX_OFFSET; dy++)
for (dz = -MAX_OFFSET; dz <= MAX_OFFSET; dz++) {
if ((dx == 0) && (dy == 0) && (dz == 0)) continue;
vector Offset =
Geometry__vec_plus(
Geometry__vec_minus(Room_position(outer), Room_position(inner)),
Geometry__vec(dx, dy, dz));
{
#line 2496 "inform7/Chapter 34/Spatial Map.w"
PL__SpatialMap__move_component(sub, Offset);
int s = PL__SpatialMap__find_component_placement_heat(sub);
if (s < min_s) {
min_s = s; Best_offset = Offset;
}
PL__SpatialMap__move_component(sub, Geometry__vec_negate(Offset));
}
#line 2488 "inform7/Chapter 34/Spatial Map.w"
;
}
}
PL__SpatialMap__move_component(sub, Best_offset);
}
#line 2415 "inform7/Chapter 34/Spatial Map.w"
else
{
#line 2427 "inform7/Chapter 34/Spatial Map.w"
LOGIF(SPATIAL_MAP, "Component %d (size %d): side by side strategy\n",
sub->allocation_id, sub->bounds.population);
PL__SpatialMap__move_component(sub,
Geometry__vec(x_max, box.corner0.y - sub->bounds.corner0.y,
Room_position(benchmark_room).z - sub->bounds.corner0.z));
}
#line 2417 "inform7/Chapter 34/Spatial Map.w"
;
}
Geometry__merge_cuboid(&box, sub->bounds);
previous_mc = sub;
sub->positioned = TRUE;
}
#line 2399 "inform7/Chapter 34/Spatial Map.w"
;
}
}
}
}
Memory__I7_free(sorted, INDEX_SORTING_MREASON);
}
#line 152 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 2710 "inform7/Chapter 34/Spatial Map.w"
Universe = Geometry__empty_cuboid();
instance *R;
LOOP_OVER_ROOMS(R)
Geometry__adjust_cuboid(&Universe, Room_position(R));
}
#line 153 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 2720 "inform7/Chapter 34/Spatial Map.w"
int safety_count = NUMBER_CREATED(instance);
while (safety_count-- >= 0) {
int blank_z = 0, blank_plane_found = FALSE;
int z;
for (z = Universe.corner1.z - 1; z >= Universe.corner0.z + 1; z--) {
int occupied = FALSE;
instance *R;
LOOP_OVER_ROOMS(R)
if (Room_position(R).z == z) occupied = TRUE;
if (occupied == FALSE) {
blank_z = z;
blank_plane_found = TRUE;
}
}
if (blank_plane_found == FALSE) break;
instance *R;
LOOP_OVER_ROOMS(R)
if (Room_position(R).z > blank_z)
PL__SpatialMap__translate_room(R, D_vector);
}
}
#line 154 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 2710 "inform7/Chapter 34/Spatial Map.w"
Universe = Geometry__empty_cuboid();
instance *R;
LOOP_OVER_ROOMS(R)
Geometry__adjust_cuboid(&Universe, Room_position(R));
}
#line 155 "inform7/Chapter 34/Spatial Map.w"
;
spatial_coordinates_established = TRUE;
}
#line 169 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__initialise_mapping_data(map_data *md) {
md->world_index_colour = NULL;
md->world_index_text_colour = NULL;
md->position = Zero_vector;
md->saved_gridpos = Zero_vector;
md->submap = NULL;
md->next_room_in_submap = NULL;
int i;
for (i=0; i<MAX_DIRECTIONS; i++) md->lock_exits[i] = NULL;
PL__EPSMap__prepare_map_parameter_scope(&(md->local_map_parameters));
}
#line 187 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__set_room_position(instance *R, vector P) {
vector O = Room_position(R);
PF_I(map, R)->position = P;
if (PF_I(map, R)->submap) PL__SpatialMap__move_room_within_submap(PF_I(map, R)->submap, O, P);
}
void PL__SpatialMap__set_room_position_breaking_cache(instance *R, vector P) {
PF_I(map, R)->position = P;
}
#line 201 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__lock_exit_in_place(instance *I, int exit, instance *I2) {
PL__SpatialMap__lock_one_exit(I2, exit, I);
PL__SpatialMap__lock_one_exit(I, PL__SpatialMap__opposite(exit), I2);
}
void PL__SpatialMap__lock_one_exit(instance *F, int exit, instance *T) {
LOGIF(SPATIAL_MAP, "Mapping clue: put $O to the %s of $O\n",
T, PL__SpatialMap__usual_Inform_direction_name(exit), F);
PF_I(map, F)->lock_exits[exit] = T;
}
#line 228 "inform7/Chapter 34/Spatial Map.w"
int story_dir_to_page_dir[MAX_DIRECTIONS];
void PL__SpatialMap__initialise_page_directions(void) {
int i;
for (i=0; i<registered_directions; i++)
story_dir_to_page_dir[i] = i;
}
#line 244 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__map_direction_as_if(instance *I, instance *I2) {
story_dir_to_page_dir[PF_I(map, I)->direction_index] = PF_I(map, I2)->direction_index;
}
instance *PL__SpatialMap__mapped_as_if(instance *I) {
int i = PF_I(map, I)->direction_index;
if (story_dir_to_page_dir[i] == i) return NULL;
instance *D;
LOOP_OVER_INSTANCES(D, K_direction)
if (PF_I(map, D)->direction_index == story_dir_to_page_dir[i])
return D;
return NULL;
}
#line 262 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__direction_is_mappable(int story_direction) {
if ((story_direction < 0) || (story_direction >= MAX_DIRECTIONS)) return FALSE;
int page_direction = story_dir_to_page_dir[story_direction];
if (page_direction >= 12) return FALSE;
return TRUE;
}
#line 275 "inform7/Chapter 34/Spatial Map.w"
vector PL__SpatialMap__direction_as_vector(int story_direction) {
if ((story_direction < 0) || (story_direction >= MAX_DIRECTIONS))
return Zero_vector;
int page_direction = story_dir_to_page_dir[story_direction];
switch(page_direction) {
case 0: return N_vector;
case 1: return NE_vector;
case 2: return NW_vector;
case 3: return S_vector;
case 4: return SE_vector;
case 5: return SW_vector;
case 6: return E_vector;
case 7: return W_vector;
case 8: return U_vector;
case 9: return D_vector;
}
return Zero_vector;
}
#line 297 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__opposite(int story_direction) {
if ((story_direction < 0) || (story_direction >= MAX_DIRECTIONS)) return 0;
int page_direction = story_dir_to_page_dir[story_direction];
switch(page_direction) {
case 0: return 3; /* N -- S */
case 1: return 5; /* NE -- SW */
case 2: return 4; /* NW -- SE */
case 3: return 0; /* S -- N */
case 4: return 2; /* SE -- NW */
case 5: return 1; /* SW -- NE */
case 6: return 7; /* E -- W */
case 7: return 6; /* W -- E */
case 8: return 9; /* UP -- DOWN */
case 9: return 8; /* DOWN -- UP */
case 10: return 11; /* IN -- OUT */
case 11: return 10; /* OUT -- IN */
}
return 0;
}
#line 321 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__rotate_direction(int story_direction, int way) {
if ((story_direction < 0) || (story_direction >= MAX_DIRECTIONS)) return 0;
int page_direction = story_dir_to_page_dir[story_direction];
int i, N = 1; if (way < 0) N = 7;
for (i=1; i<=N; i++) {
switch(page_direction) {
case 0: page_direction = 1; break; /* N -- NE */
case 1: page_direction = 6; break; /* NE -- E */
case 2: page_direction = 0; break; /* NW -- N */
case 3: page_direction = 5; break; /* S -- SW */
case 4: page_direction = 3; break; /* SE -- S */
case 5: page_direction = 7; break; /* SW -- W */
case 6: page_direction = 4; break; /* E -- SE */
case 7: page_direction = 2; break; /* W -- NW */
default: page_direction = -1; break;
}
}
return page_direction;
}
#line 345 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__direction_is_lateral(int story_direction) {
return Geometry__vec_lateral(
PL__SpatialMap__direction_as_vector(story_direction));
}
#line 355 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__direction_is_along_lattice(int story_direction) {
vector D = PL__SpatialMap__direction_as_vector(story_direction);
if (Geometry__vec_eq(D, Zero_vector)) return FALSE;
return TRUE;
}
#line 383 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__cell_position_for_direction(int story_direction, int *mx, int *my) {
*mx = 0; *my = 0;
if ((story_direction < 0) || (story_direction >= MAX_DIRECTIONS)) return;
int page_direction = story_dir_to_page_dir[story_direction];
switch(page_direction) {
case 0: *mx = 2; *my = 0; break;
case 1: *mx = 4; *my = 0; break;
case 2: *mx = 0; *my = 0; break;
case 3: *mx = 2; *my = 4; break;
case 4: *mx = 4; *my = 4; break;
case 5: *mx = 0; *my = 4; break;
case 6: *mx = 4; *my = 2; break;
case 7: *mx = 0; *my = 2; break;
case 8: *mx = 1; *my = 0; break;
case 9: *mx = 3; *my = 4; break;
case 10: *mx = 4; *my = 3; break;
case 11: *mx = 0; *my = 1; break;
}
}
#line 406 "inform7/Chapter 34/Spatial Map.w"
char *PL__SpatialMap__find_icon_label(int story_direction) {
if ((story_direction < 0) || (story_direction >= MAX_DIRECTIONS)) return NULL;
int page_direction = story_dir_to_page_dir[story_direction];
switch(page_direction) {
case 0: return "n";
case 1: return "ne";
case 2: return "nw";
case 3: return "s";
case 4: return "se";
case 5: return "sw";
case 6: return "e";
case 7: return "w";
case 8: return "u";
case 9: return "d";
case 10: return "in";
case 11: return "out";
}
return NULL;
}
char *PL__SpatialMap__usual_Inform_direction_name(int story_direction) {
if ((story_direction < 0) || (story_direction >= MAX_DIRECTIONS)) return "<none>";
int page_direction = story_dir_to_page_dir[story_direction];
switch(page_direction) {
case 0: return "north";
case 1: return "northeast";
case 2: return "northwest";
case 3: return "south";
case 4: return "southeast";
case 5: return "southwest";
case 6: return "east";
case 7: return "west";
case 8: return "up";
case 9: return "down";
case 10: return "inside";
case 11: return "outside";
}
return "<none>";
}
#line 449 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__establish_benchmark_room(void) {
if (benchmark_room == NULL) {
benchmark_room = PL__Player__get_start_room();
if (benchmark_room == NULL) {
instance *R;
LOOP_OVER_ROOMS(R) { benchmark_room = R; return; }
internal_error("no room exists in mapping");
}
}
}
#line 466 "inform7/Chapter 34/Spatial Map.w"
instance *PL__SpatialMap__room_exit(instance *origin, int dir_num, instance **via) {
if (via) *via = NULL;
if ((origin == NULL) || (PL__Spatial__object_is_a_room(origin) == FALSE) ||
(dir_num < 0) || (dir_num >= MAX_DIRECTIONS)) return NULL;
instance *ultimate_destination = NULL;
instance *immediate_destination = MAP_EXIT(origin, dir_num);
if (immediate_destination) {
if (PL__Spatial__object_is_a_room(immediate_destination))
ultimate_destination = immediate_destination;
if (PL__Map__object_is_a_door(immediate_destination)) {
if (via) *via = immediate_destination;
instance *A = NULL, *B = NULL;
PL__Map__get_door_data(immediate_destination, &A, &B);
if (A == origin) ultimate_destination = B;
if (B == origin) ultimate_destination = A;
}
}
return ultimate_destination;
}
instance *PL__SpatialMap__room_exit_as_indexed(instance *origin, int dir_num, instance **via) {
int j;
for (j=0; j<MAX_DIRECTIONS; j++) {
if (story_dir_to_page_dir[j] == dir_num) {
instance *I = PL__SpatialMap__room_exit(origin, j, via);
if (I) return I;
}
}
return NULL;
}
#line 626 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__form_spatial_relationship(instance *R, int dir, instance *T) {
PF_I(map, R)->spatial_relationship[dir] = T;
PF_I(map, T)->spatial_relationship[PL__SpatialMap__opposite(dir)] = R;
}
#line 642 "inform7/Chapter 34/Spatial Map.w"
instance *PL__SpatialMap__read_smap(instance *from, int dir) {
if (from == NULL) internal_error("tried to read smap at null room");
drognas_spent++;
instance *to = PF_I(map, from)->spatial_relationship[dir];
if ((partitioned_into_components) && (to) &&
(PF_I(map, from)->submap != PF_I(map, to)->submap))
to = NULL;
return to;
}
instance *PL__SpatialMap__read_smap_cross(instance *from, int dir) {
if (from == NULL) internal_error("tried to read smap at null room");
drognas_spent++;
instance *to = PL__SpatialMap__room_exit(from, dir, NULL);
return to;
}
#line 662 "inform7/Chapter 34/Spatial Map.w"
instance *PL__SpatialMap__read_slock(instance *from, int dir) {
if (from == NULL) internal_error("tried to read slock at null room");
drognas_spent++;
return PF_I(map, from)->lock_exits[dir];
}
#line 672 "inform7/Chapter 34/Spatial Map.w"
connected_submap *PL__SpatialMap__new_submap(void) {
connected_submap *sub = CREATE(connected_submap);
sub->bounds = Geometry__empty_cuboid();
sub->first_room_in_submap = NULL;
sub->last_room_in_submap = NULL;
sub->incidence_cache = NULL;
sub->incidence_cache_bounds = Geometry__empty_cuboid();
sub->superpositions = 0;
return sub;
}
#line 695 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__add_room_to_submap(instance *R, connected_submap *sub) {
if (sub->last_room_in_submap == NULL) {
sub->last_room_in_submap = R;
sub->first_room_in_submap = R;
} else {
PF_I(map, sub->last_room_in_submap)->next_room_in_submap = R;
sub->last_room_in_submap = R;
}
PF_I(map, R)->submap = sub;
PF_I(map, R)->next_room_in_submap = NULL;
PL__SpatialMap__add_room_to_cache(sub, Room_position(R), 1);
}
#line 721 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__occupied_in_submap(connected_submap *sub, vector P) {
int i = Geometry__cuboid_index(P, sub->incidence_cache_bounds);
if (i < 0) return 0;
return sub->incidence_cache[i];
}
#line 731 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__move_room_within_submap(connected_submap *sub, vector O, vector P) {
PL__SpatialMap__add_room_to_cache(sub, O, -1);
PL__SpatialMap__add_room_to_cache(sub, P, 1);
}
#line 740 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__add_room_to_cache(connected_submap *sub, vector P, int m) {
if (Geometry__within_cuboid(P, sub->incidence_cache_bounds) == FALSE)
{
#line 766 "inform7/Chapter 34/Spatial Map.w"
cuboid old_cuboid = sub->incidence_cache_bounds;
cuboid new_cuboid = old_cuboid;
Geometry__thicken_cuboid(&new_cuboid, P, Geometry__vec(20, 20, 3));
int *new_cache =
Memory__I7_calloc(Geometry__cuboid_volume(new_cuboid),
sizeof(int), MAP_INDEX_MREASON);
int x, y, z;
for (x = new_cuboid.corner0.x; x <= new_cuboid.corner1.x; x++)
for (y = new_cuboid.corner0.y; y <= new_cuboid.corner1.y; y++)
for (z = new_cuboid.corner0.z; z <= new_cuboid.corner1.z; z++) {
int i = Geometry__cuboid_index(Geometry__vec(x,y,z), new_cuboid);
new_cache[i] = 0;
}
int *old_cache = sub->incidence_cache;
if (old_cache)
for (x = old_cuboid.corner0.x; x <= old_cuboid.corner1.x; x++)
for (y = old_cuboid.corner0.y; y <= old_cuboid.corner1.y; y++)
for (z = old_cuboid.corner0.z; z <= old_cuboid.corner1.z; z++) {
int i = Geometry__cuboid_index(Geometry__vec(x,y,z), old_cuboid);
int t = old_cache[i];
if (t > 0) {
int j = Geometry__cuboid_index(Geometry__vec(x,y,z), new_cuboid);
new_cache[j] = t;
}
}
PL__SpatialMap__free_incidence_cache(sub);
sub->incidence_cache = new_cache;
sub->incidence_cache_bounds = new_cuboid;
}
#line 742 "inform7/Chapter 34/Spatial Map.w"
;
int i = Geometry__cuboid_index(P, sub->incidence_cache_bounds);
int t = sub->incidence_cache[i];
if (t+m < 0) t = -m;
sub->incidence_cache[i] = t+m;
if (m == 1) sub->superpositions += 2*t;
if (m == -1) sub->superpositions -= 2*(t-1);
}
#line 799 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__free_incidence_cache(connected_submap *sub) {
if (sub->incidence_cache == NULL) return;
Memory__I7_free(sub->incidence_cache, MAP_INDEX_MREASON);
sub->incidence_cache_bounds = Geometry__empty_cuboid();
sub->incidence_cache = NULL;
}
#line 809 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__empty_submap(connected_submap *sub) {
sub->first_room_in_submap = NULL;
sub->last_room_in_submap = NULL;
PL__SpatialMap__free_incidence_cache(sub);
sub->superpositions = 0;
}
#line 819 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__destroy_submap(connected_submap *sub) {
PL__SpatialMap__free_incidence_cache(sub);
DESTROY(sub, connected_submap);
}
#line 829 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__move_component(connected_submap *sub, vector D) {
instance *R;
LOOP_OVER_SUBMAP(R, sub)
PL__SpatialMap__set_room_position_breaking_cache(R, Geometry__vec_plus(Room_position(R), D));
Geometry__cuboid_translate(&(sub->bounds), D);
Geometry__cuboid_translate(&(sub->incidence_cache_bounds), D);
}
#line 848 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__create_submaps_from_zones(connected_submap *sub,
int Z1_number, connected_submap *Zone1, int Z2_number, connected_submap *Zone2) {
instance *R;
LOOP_OVER_ROOMS(R) {
if (PF_I(map, R)->zone == Z1_number)
PL__SpatialMap__add_room_to_submap(R, Zone1);
else if (PF_I(map, R)->zone == Z2_number)
PL__SpatialMap__add_room_to_submap(R, Zone2);
PF_I(map, R)->zone = 0;
}
PL__SpatialMap__empty_submap(sub);
}
#line 865 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__create_zones_from_submaps(connected_submap *sub,
int Z1_number, connected_submap *Zone1, int Z2_number, connected_submap *Zone2) {
instance *R;
LOOP_OVER_ROOMS(R) {
if (PF_I(map, R)->submap == Zone1) {
PL__SpatialMap__add_room_to_submap(R, sub);
PF_I(map, R)->zone = Z1_number;
}
if (PF_I(map, R)->submap == Zone2) {
PL__SpatialMap__add_room_to_submap(R, sub);
PF_I(map, R)->zone = Z2_number;
}
}
}
#line 905 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__create_map_component_around(instance *at) {
if (PF_I(map, at)->submap == NULL) PL__SpatialMap__add_room_to_submap(at, PL__SpatialMap__new_submap());
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *locked_to = PL__SpatialMap__read_slock(at, i);
if ((locked_to) && (PF_I(map, locked_to)->submap != PF_I(map, at)->submap)) {
PL__SpatialMap__add_room_to_submap(locked_to, PF_I(map, at)->submap);
PL__SpatialMap__create_map_component_around(locked_to);
}
instance *dest = PL__SpatialMap__read_smap(at, i);
if ((dest) && (PF_I(map, dest)->submap != PF_I(map, at)->submap)) {
PL__SpatialMap__add_room_to_submap(dest, PF_I(map, at)->submap);
PL__SpatialMap__create_map_component_around(dest);
}
}
}
#line 927 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__translate_room(instance *R, vector D) {
PL__SpatialMap__set_room_position(R, Geometry__vec_plus(Room_position(R), D));
}
void PL__SpatialMap__move_room_to(instance *R, vector P) {
PL__SpatialMap__set_room_position(R, P);
PL__SpatialMap__move_anything_locked_to(R);
}
#line 947 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__move_anything_locked_to(instance *R) {
connected_submap *sub = PF_I(map, R)->submap;
instance *R2;
LOOP_OVER_SUBMAP(R2, sub)
PF_I(map, R2)->shifted = FALSE;
PL__SpatialMap__move_anything_locked_to_r(R);
}
void PL__SpatialMap__move_anything_locked_to_r(instance *R) {
if (PF_I(map, R)->shifted) return;
PF_I(map, R)->shifted = TRUE;
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *F = PL__SpatialMap__read_slock(R, i);
if (F) {
vector D = PL__SpatialMap__direction_as_vector(i);
PL__SpatialMap__set_room_position(F, Geometry__vec_plus(Room_position(R), D));
PL__SpatialMap__move_anything_locked_to_r(F);
}
}
}
#line 974 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__lock_positions_in_submap(connected_submap *sub) {
instance *R;
LOOP_OVER_SUBMAP(R, sub)
PF_I(map, R)->shifted = FALSE;
LOOP_OVER_SUBMAP(R, sub)
PL__SpatialMap__move_anything_locked_to_r(R);
}
#line 1022 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__establish_natural_lengths(connected_submap *sub) {
instance *R;
LOOP_OVER_SUBMAP(R, sub) {
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
if (PL__SpatialMap__read_smap(R, i))
PF_I(map, R)->exit_lengths[i] = 1;
else
PF_I(map, R)->exit_lengths[i] = -1;
}
}
}
#line 1060 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__heat_sum(int h1, int h2) {
int h = h1+h2;
if (h > FUSION_POINT) return FUSION_POINT;
return h;
}
#line 1072 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_submap_heat(connected_submap *sub) {
int heat = 0;
sub->bounds = Geometry__empty_cuboid();
instance *R;
LOOP_OVER_SUBMAP(R, sub) {
heat = PL__SpatialMap__heat_sum(heat, PL__SpatialMap__find_room_heat(R));
Geometry__adjust_cuboid(&(sub->bounds), Room_position(R));
}
int collisions = sub->superpositions;
while (collisions >= 1000) {
heat = PL__SpatialMap__heat_sum(heat, 1000*COLLISION_HEAT);
collisions -= 1000;
}
heat = PL__SpatialMap__heat_sum(heat, collisions*COLLISION_HEAT);
if (heat == FUSION_POINT) heat = FUSION_POINT + sub->superpositions;
sub->heat = heat;
return heat;
}
#line 1096 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_room_heat(instance *R) {
int i, h = 0;
LOOP_OVER_LATTICE_DIRECTIONS(i) h += PL__SpatialMap__find_exit_heat(R, i);
return h;
}
#line 1123 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_exit_heat(instance *from, int exit) {
drognas_spent++;
instance *to = PL__SpatialMap__read_smap(from, exit);
if (to == NULL) return 0; /* if there's no exit this way, there's no heat */
if (from == to) return 0; /* an exit from a room to itself doesn't show on the map */
if (PL__SpatialMap__direction_is_along_lattice(exit) == FALSE) return 0; /* IN, OUT generate no heat */
vector D = Geometry__vec_minus(Room_position(to), Room_position(from));
if (Geometry__vec_eq(D, Zero_vector)) return COLLISION_HEAT; /* the two rooms have collided! */
vector E = PL__SpatialMap__direction_as_vector(exit);
int distance_distortion = Geometry__vec_length_squared(Geometry__vec_minus(E, D));
if (distance_distortion == 0) return 0; /* perfect placement */
int angular_distortion = (int) (ANGULAR_MULTIPLIER*Geometry__vec_angular_separation(E, D));
int overlying_penalty = 0;
if ((angular_distortion == 0) && (Geometry__vec_eq(E, Zero_vector) == FALSE)) {
vector P = Room_position(from);
int n = 1;
P = Geometry__vec_plus(P, E);
while ((n++ < 20) && (Geometry__vec_eq(P, Room_position(to)) == FALSE)) {
if (PL__SpatialMap__occupied_in_submap(PF_I(map, from)->submap, P) > 0)
overlying_penalty += OVERLYING_HEAT;
P = Geometry__vec_plus(P, E);
}
}
return angular_distortion + distance_distortion + overlying_penalty;
}
#line 1160 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__exit_aligned(instance *from, int exit) {
drognas_spent++;
instance *to = PL__SpatialMap__read_smap(from, exit);
if (to == NULL) return TRUE; /* at any rate, not misaligned */
if (from == to) return TRUE; /* ditto */
if (PL__SpatialMap__direction_is_along_lattice(exit) == FALSE) return TRUE; /* IN, OUT are always aligned */
vector D = Geometry__vec_minus(Room_position(to), Room_position(from));
if (Geometry__vec_eq(D, Zero_vector)) return TRUE; /* bad, but not for alignment reasons */
vector E = PL__SpatialMap__direction_as_vector(exit);
int angular_distortion = (int) (ANGULAR_MULTIPLIER*Geometry__vec_angular_separation(E, D));
if (angular_distortion == 0) return TRUE;
return FALSE;
}
#line 1189 "inform7/Chapter 34/Spatial Map.w"
int unique_Z_number = 1;
void PL__SpatialMap__position_submap(connected_submap *sub) {
int initial_heat = PL__SpatialMap__find_submap_heat(sub), initial_spending = drognas_spent;
LOGIF(SPATIAL_MAP, "\nPOSITIONING submap %d: initial heat %d",
sub->allocation_id, sub->heat);
if (sub->heat == 0) LOGIF(SPATIAL_MAP, ": nothing to do");
if (Log__aspect_switched_on(SPATIAL_MAP_DA)) {
instance *R; int n = 0;
LOOP_OVER_SUBMAP(R, sub) {
if ((n++) % 8 == 0) LOG("\n ");
LOG(" $O", R);
}
LOG("\n");
}
if (sub->heat > 0) {
PL__SpatialMap__cool_submap(sub);
PL__SpatialMap__find_submap_heat(sub);
if (sub->heat > 0) {
{
#line 1228 "inform7/Chapter 34/Spatial Map.w"
int Z1_number = unique_Z_number++, Z2_number = unique_Z_number++;
instance *div_F1 = NULL, *div_T1 = NULL; int div_dir1 = -1;
instance *div_F2 = NULL, *div_T2 = NULL; int div_dir2 = -1;
int initial_spending = drognas_spent;
int found = PL__SpatialMap__work_out_optimal_cutpoint(sub, &div_F1, &div_T1, &div_dir1,
&div_F2, &div_T2, &div_dir2);
cutpoint_spending += drognas_spent - initial_spending;
if (found) {
{
#line 1267 "inform7/Chapter 34/Spatial Map.w"
int Z1_count = 0, Z2_count = 0;
if (div_F2) {
int predivision_spending = drognas_spent;
PL__SpatialMap__divide_into_zones_twocut(div_F1, div_T1, div_F2, div_T2, Z1_number, Z2_number);
instance *R;
LOOP_OVER_SUBMAP(R, sub) {
if (PF_I(map, R)->zone == Z1_number) Z1_count++;
if (PF_I(map, R)->zone == Z2_number) Z2_count++;
}
LOGIF(SPATIAL_MAP, "Making a double cut: $O %s to $O and $O %s to $O at cost %d\n",
div_F1, PL__SpatialMap__usual_Inform_direction_name(div_dir1), div_T1,
div_F2, PL__SpatialMap__usual_Inform_direction_name(div_dir2), div_T2,
drognas_spent - predivision_spending);
division_spending += drognas_spent - predivision_spending;
} else {
int predivision_spending = drognas_spent;
PL__SpatialMap__divide_into_zones_onecut(sub, div_F1, div_T1,
&Z1_count, &Z2_count, Z1_number, Z2_number);
LOGIF(SPATIAL_MAP, "Making a single cut: $O %s to $O at cost %d\n",
div_F1, PL__SpatialMap__usual_Inform_direction_name(div_dir1), div_T1,
drognas_spent - predivision_spending);
division_spending += drognas_spent - predivision_spending;
}
LOGIF(SPATIAL_MAP, "This produces two zones of sizes %d and %d\n",
Z1_count, Z2_count);
}
#line 1236 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 1296 "inform7/Chapter 34/Spatial Map.w"
connected_submap *Zone1 = PL__SpatialMap__new_submap();
connected_submap *Zone2 = PL__SpatialMap__new_submap();
PL__SpatialMap__create_submaps_from_zones(sub, Z1_number, Zone1, Z2_number, Zone2);
LOGIF(SPATIAL_MAP, "Zone 1 becomes submap %d; zone 2 becomes submap %d\n",
Zone1->allocation_id, Zone2->allocation_id);
LOG_INDENT;
PL__SpatialMap__position_submap(Zone1);
PL__SpatialMap__position_submap(Zone2);
LOG_OUTDENT;
PL__SpatialMap__create_zones_from_submaps(sub, Z1_number, Zone1, Z2_number, Zone2);
LOGIF(SPATIAL_MAP, "Destroying submaps %d and %d\n",
Zone1->allocation_id, Zone2->allocation_id);
PL__SpatialMap__destroy_submap(Zone1);
PL__SpatialMap__destroy_submap(Zone2);
}
#line 1237 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 1337 "inform7/Chapter 34/Spatial Map.w"
int preslide_spending = drognas_spent;
vector Axis = PL__SpatialMap__direction_as_vector(div_dir1);
int worst_case_length = 0;
instance *R;
LOOP_OVER_SUBMAP(R, sub) worst_case_length++;
worst_case_length--;
int L, coolest_L = 1, coolest_temperature = -1;
for (L = 1; L <= worst_case_length; L++) {
PL__SpatialMap__save_component_positions(sub);
{
#line 1373 "inform7/Chapter 34/Spatial Map.w"
PF_I(map, div_F1)->exit_lengths[div_dir1] = L;
vector D = Geometry__vec_plus(
Geometry__vec_scale(L, Axis),
Geometry__vec_minus(Room_position(div_F1), Room_position(div_T1)));
instance *Z2;
LOOP_OVER_SUBMAP(Z2, sub)
if (PF_I(map, Z2)->zone == Z2_number)
PL__SpatialMap__translate_room(Z2, D);
}
#line 1348 "inform7/Chapter 34/Spatial Map.w"
;
int h = PL__SpatialMap__find_submap_heat(sub);
if ((h < coolest_temperature) || (coolest_temperature == -1)) {
coolest_temperature = h;
coolest_L = L;
}
PL__SpatialMap__restore_component_positions(sub);
if ((coolest_temperature >= 0) && (coolest_temperature < COLLISION_HEAT) &&
(L == CAP_ON_SLIDE_LENGTHS))
break;
}
LOGIF(SPATIAL_MAP, "Optimal axis length for cut-exit is %d (heat %d), found at cost %d.\n",
coolest_L, coolest_temperature, drognas_spent - preslide_spending);
slide_spending += drognas_spent - preslide_spending;
L = coolest_L;
{
#line 1373 "inform7/Chapter 34/Spatial Map.w"
PF_I(map, div_F1)->exit_lengths[div_dir1] = L;
vector D = Geometry__vec_plus(
Geometry__vec_scale(L, Axis),
Geometry__vec_minus(Room_position(div_F1), Room_position(div_T1)));
instance *Z2;
LOOP_OVER_SUBMAP(Z2, sub)
if (PF_I(map, Z2)->zone == Z2_number)
PL__SpatialMap__translate_room(Z2, D);
}
#line 1363 "inform7/Chapter 34/Spatial Map.w"
;
}
#line 1238 "inform7/Chapter 34/Spatial Map.w"
;
if (PL__SpatialMap__find_submap_heat(sub) > 0) PL__SpatialMap__radiate_submap(sub);
} else
{
#line 1247 "inform7/Chapter 34/Spatial Map.w"
if (PL__SpatialMap__find_submap_heat(sub) > 0) {
PL__SpatialMap__quench_submap(sub, NULL, NULL);
if (PL__SpatialMap__find_submap_heat(sub) > 0) {
PL__SpatialMap__diffuse_submap(sub);
if (PL__SpatialMap__find_submap_heat(sub) > 0) {
PL__SpatialMap__quench_submap(sub, NULL, NULL);
if (PL__SpatialMap__find_submap_heat(sub) > 0) {
PL__SpatialMap__radiate_submap(sub);
if (PL__SpatialMap__find_submap_heat(sub) >= COLLISION_HEAT)
PL__SpatialMap__explode_submap(sub);
}
}
}
}
}
#line 1241 "inform7/Chapter 34/Spatial Map.w"
;
}
#line 1208 "inform7/Chapter 34/Spatial Map.w"
;
PL__SpatialMap__find_submap_heat(sub);
}
LOGIF(SPATIAL_MAP, "\nPOSITIONING submap %d done: cooled by %d to %d "
"at cost of %d drognas\n\n",
sub->allocation_id, initial_heat - sub->heat, sub->heat,
drognas_spent - initial_spending);
}
}
#line 1428 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__work_out_optimal_cutpoint(connected_submap *sub,
instance **from, instance **to, int *way,
instance **from2, instance **to2, int *way2) {
instance *first = NULL; int size = 0;
{
#line 1459 "inform7/Chapter 34/Spatial Map.w"
instance *R;
LOOP_OVER_SUBMAP(R, sub) {
PF_I(map, R)->zone = 0; /* i.e., not yet given a generation */
size++;
if (first == NULL) first = R;
}
if (size == 0) return FALSE;
}
#line 1433 "inform7/Chapter 34/Spatial Map.w"
;
PF_I(map, first)->zone = 1;
int best_spread[EXPLORATION_RECORDS];
instance *best_from1[EXPLORATION_RECORDS], *best_to1[EXPLORATION_RECORDS];
int best_dir1[EXPLORATION_RECORDS];
instance *best_from2[EXPLORATION_RECORDS], *best_to2[EXPLORATION_RECORDS];
int best_dir2[EXPLORATION_RECORDS];
int outer_contact_generation[CLIPBOARD_SIZE], outer_contact_dir[CLIPBOARD_SIZE];
instance *outer_contact_from[CLIPBOARD_SIZE], *outer_contact_to[CLIPBOARD_SIZE];
{
#line 1470 "inform7/Chapter 34/Spatial Map.w"
int i;
for (i = 0; i < CLIPBOARD_SIZE; i++) {
outer_contact_generation[i] = -1;
outer_contact_from[i] = NULL; outer_contact_to[i] = NULL; outer_contact_dir[i] = -1;
}
for (i = 0; i < EXPLORATION_RECORDS; i++) {
best_spread[i] = size+1; /* an impossibly high value */
best_from1[i] = NULL; best_to1[i] = NULL; best_dir1[i] = -1;
best_from2[i] = NULL; best_to2[i] = NULL; best_dir2[i] = -1;
}
}
#line 1444 "inform7/Chapter 34/Spatial Map.w"
;
PL__SpatialMap__assign_generation_count(first, NULL, size,
best_spread,
best_from1, best_to1, best_dir1,
best_from2, best_to2, best_dir2,
outer_contact_generation, outer_contact_from, outer_contact_to, outer_contact_dir);
{
#line 1491 "inform7/Chapter 34/Spatial Map.w"
if ((size - best_spread[BEST_ONECUT_ER])/2 >= MIN_ONECUT_ZONE_SIZE) {
*from = best_from1[BEST_ONECUT_ER];
*to = best_to1[BEST_ONECUT_ER];
*way = best_dir1[BEST_ONECUT_ER];
return TRUE;
}
if ((size - best_spread[BEST_PARALLEL_TWOCUT_ER])/2 >= MIN_TWOCUT_ZONE_SIZE) {
*from = best_from1[BEST_PARALLEL_TWOCUT_ER];
*to = best_to1[BEST_PARALLEL_TWOCUT_ER];
*way = best_dir1[BEST_PARALLEL_TWOCUT_ER];
*from2 = best_from2[BEST_PARALLEL_TWOCUT_ER];
*to2 = best_to2[BEST_PARALLEL_TWOCUT_ER];
*way2 = best_dir2[BEST_PARALLEL_TWOCUT_ER];
return TRUE;
}
if ((size - best_spread[BEST_TWOCUT_ER])/2 >= MIN_TWOCUT_ZONE_SIZE) {
*from = best_from1[BEST_TWOCUT_ER];
*to = best_to1[BEST_TWOCUT_ER];
*way = best_dir1[BEST_TWOCUT_ER];
*from2 = best_from2[BEST_TWOCUT_ER];
*to2 = best_to2[BEST_TWOCUT_ER];
*way2 = best_dir2[BEST_TWOCUT_ER];
return TRUE;
}
}
#line 1452 "inform7/Chapter 34/Spatial Map.w"
;
return FALSE;
}
#line 1524 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__assign_generation_count(instance *at, instance *from, int size,
int *best_spread,
instance **best_from1, instance **best_to1, int *best_dir1,
instance **best_from2, instance **best_to2, int *best_dir2,
int *contact_generation,
instance **contact_from, instance **contact_to, int *contact_dir) {
int rooms_visited = 0;
int generation = PF_I(map, at)->zone, i;
LOG_INDENT;
int locking_to_neighbours = TRUE;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_slock(at, i);
if (T) {
{
#line 1564 "inform7/Chapter 34/Spatial Map.w"
if ((T == at) || (T == from)) continue;
int T_generation = PF_I(map, T)->zone;
if (T_generation >= generation) continue;
if ((T_generation > 0) && (T_generation < generation)) {
int observed_generation = T_generation;
instance *observed_from = at;
instance *observed_to = T;
int observed_dir = i;
{
#line 1708 "inform7/Chapter 34/Spatial Map.w"
int k;
for (k = 0; k < CLIPBOARD_SIZE; k++)
if ((contact_generation[k] == -1) ||
(observed_generation <= contact_generation[k])) {
int l;
for (l = CLIPBOARD_SIZE-1; l > k; l--) {
contact_generation[l] = contact_generation[l-1];
contact_from[l] = contact_from[l-1]; contact_to[l] = contact_to[l-1];
contact_dir[l] = contact_dir[l-1];
}
contact_generation[k] = observed_generation;
contact_from[k] = observed_from; contact_to[k] = observed_to;
contact_dir[k] = observed_dir;
break;
}
}
#line 1572 "inform7/Chapter 34/Spatial Map.w"
;
continue;
}
}
#line 1537 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 1600 "inform7/Chapter 34/Spatial Map.w"
int inner_contact_generation[CLIPBOARD_SIZE], inner_contact_dir[CLIPBOARD_SIZE];
instance *inner_contact_from[CLIPBOARD_SIZE], *inner_contact_to[CLIPBOARD_SIZE];
{
#line 1622 "inform7/Chapter 34/Spatial Map.w"
int j;
for (j = 0; j < CLIPBOARD_SIZE; j++) {
inner_contact_generation[j] = -1;
inner_contact_from[j] = NULL; inner_contact_to[j] = NULL; inner_contact_dir[j] = -1;
}
}
#line 1602 "inform7/Chapter 34/Spatial Map.w"
;
PF_I(map, T)->zone = generation + 1;
int rooms_explored_in_the_beyond = PL__SpatialMap__assign_generation_count(T, at, size,
best_spread,
best_from1, best_to1, best_dir1,
best_from2, best_to2, best_dir2,
inner_contact_generation, inner_contact_from, inner_contact_to, inner_contact_dir);
rooms_visited += rooms_explored_in_the_beyond;
{
#line 1635 "inform7/Chapter 34/Spatial Map.w"
int j;
for (j = 0; j < CLIPBOARD_SIZE; j++) {
int observed_generation = inner_contact_generation[j];
if ((observed_generation > 0) && (observed_generation < generation)) {
instance *observed_from = inner_contact_from[j];
instance *observed_to = inner_contact_to[j];
int observed_dir = inner_contact_dir[j];
{
#line 1708 "inform7/Chapter 34/Spatial Map.w"
int k;
for (k = 0; k < CLIPBOARD_SIZE; k++)
if ((contact_generation[k] == -1) ||
(observed_generation <= contact_generation[k])) {
int l;
for (l = CLIPBOARD_SIZE-1; l > k; l--) {
contact_generation[l] = contact_generation[l-1];
contact_from[l] = contact_from[l-1]; contact_to[l] = contact_to[l-1];
contact_dir[l] = contact_dir[l-1];
}
contact_generation[k] = observed_generation;
contact_from[k] = observed_from; contact_to[k] = observed_to;
contact_dir[k] = observed_dir;
break;
}
}
#line 1642 "inform7/Chapter 34/Spatial Map.w"
;
}
}
}
#line 1612 "inform7/Chapter 34/Spatial Map.w"
;
if (locking_to_neighbours == FALSE)
{
#line 1651 "inform7/Chapter 34/Spatial Map.w"
int no_contacts_found = 0;
int j;
for (j = 0; j < CLIPBOARD_SIZE; j++)
if (inner_contact_generation[j] > 0)
no_contacts_found++;
if (no_contacts_found < CLIPBOARD_SIZE) {
int spread = size - 2*rooms_explored_in_the_beyond;
if (spread < 0) spread = -spread;
if (no_contacts_found == 0)
{
#line 1670 "inform7/Chapter 34/Spatial Map.w"
if (spread < best_spread[BEST_ONECUT_ER]) {
best_spread[BEST_ONECUT_ER] = spread;
best_from1[BEST_ONECUT_ER] = at;
best_to1[BEST_ONECUT_ER] = T;
best_dir1[BEST_ONECUT_ER] = i;
}
}
#line 1661 "inform7/Chapter 34/Spatial Map.w"
else if (no_contacts_found == 1)
{
#line 1689 "inform7/Chapter 34/Spatial Map.w"
if (PL__SpatialMap__read_slock(inner_contact_from[0], inner_contact_dir[0]) == inner_contact_to[0]) break;
int r = BEST_TWOCUT_ER;
if ((inner_contact_dir[0] == i) || (inner_contact_dir[0] == PL__SpatialMap__opposite(i)))
r = BEST_PARALLEL_TWOCUT_ER;
if (spread < best_spread[r]) {
best_spread[r] = spread;
best_from1[r] = at; best_to1[r] = T; best_dir1[r] = i;
best_from2[r] = inner_contact_from[0];
best_to2[r] = inner_contact_to[0];
best_dir2[r] = inner_contact_dir[0];
}
}
#line 1663 "inform7/Chapter 34/Spatial Map.w"
;
}
}
#line 1614 "inform7/Chapter 34/Spatial Map.w"
;
}
#line 1538 "inform7/Chapter 34/Spatial Map.w"
;
}
}
locking_to_neighbours = FALSE;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_smap(at, i);
if (T) {
{
#line 1564 "inform7/Chapter 34/Spatial Map.w"
if ((T == at) || (T == from)) continue;
int T_generation = PF_I(map, T)->zone;
if (T_generation >= generation) continue;
if ((T_generation > 0) && (T_generation < generation)) {
int observed_generation = T_generation;
instance *observed_from = at;
instance *observed_to = T;
int observed_dir = i;
{
#line 1708 "inform7/Chapter 34/Spatial Map.w"
int k;
for (k = 0; k < CLIPBOARD_SIZE; k++)
if ((contact_generation[k] == -1) ||
(observed_generation <= contact_generation[k])) {
int l;
for (l = CLIPBOARD_SIZE-1; l > k; l--) {
contact_generation[l] = contact_generation[l-1];
contact_from[l] = contact_from[l-1]; contact_to[l] = contact_to[l-1];
contact_dir[l] = contact_dir[l-1];
}
contact_generation[k] = observed_generation;
contact_from[k] = observed_from; contact_to[k] = observed_to;
contact_dir[k] = observed_dir;
break;
}
}
#line 1572 "inform7/Chapter 34/Spatial Map.w"
;
continue;
}
}
#line 1545 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 1600 "inform7/Chapter 34/Spatial Map.w"
int inner_contact_generation[CLIPBOARD_SIZE], inner_contact_dir[CLIPBOARD_SIZE];
instance *inner_contact_from[CLIPBOARD_SIZE], *inner_contact_to[CLIPBOARD_SIZE];
{
#line 1622 "inform7/Chapter 34/Spatial Map.w"
int j;
for (j = 0; j < CLIPBOARD_SIZE; j++) {
inner_contact_generation[j] = -1;
inner_contact_from[j] = NULL; inner_contact_to[j] = NULL; inner_contact_dir[j] = -1;
}
}
#line 1602 "inform7/Chapter 34/Spatial Map.w"
;
PF_I(map, T)->zone = generation + 1;
int rooms_explored_in_the_beyond = PL__SpatialMap__assign_generation_count(T, at, size,
best_spread,
best_from1, best_to1, best_dir1,
best_from2, best_to2, best_dir2,
inner_contact_generation, inner_contact_from, inner_contact_to, inner_contact_dir);
rooms_visited += rooms_explored_in_the_beyond;
{
#line 1635 "inform7/Chapter 34/Spatial Map.w"
int j;
for (j = 0; j < CLIPBOARD_SIZE; j++) {
int observed_generation = inner_contact_generation[j];
if ((observed_generation > 0) && (observed_generation < generation)) {
instance *observed_from = inner_contact_from[j];
instance *observed_to = inner_contact_to[j];
int observed_dir = inner_contact_dir[j];
{
#line 1708 "inform7/Chapter 34/Spatial Map.w"
int k;
for (k = 0; k < CLIPBOARD_SIZE; k++)
if ((contact_generation[k] == -1) ||
(observed_generation <= contact_generation[k])) {
int l;
for (l = CLIPBOARD_SIZE-1; l > k; l--) {
contact_generation[l] = contact_generation[l-1];
contact_from[l] = contact_from[l-1]; contact_to[l] = contact_to[l-1];
contact_dir[l] = contact_dir[l-1];
}
contact_generation[k] = observed_generation;
contact_from[k] = observed_from; contact_to[k] = observed_to;
contact_dir[k] = observed_dir;
break;
}
}
#line 1642 "inform7/Chapter 34/Spatial Map.w"
;
}
}
}
#line 1612 "inform7/Chapter 34/Spatial Map.w"
;
if (locking_to_neighbours == FALSE)
{
#line 1651 "inform7/Chapter 34/Spatial Map.w"
int no_contacts_found = 0;
int j;
for (j = 0; j < CLIPBOARD_SIZE; j++)
if (inner_contact_generation[j] > 0)
no_contacts_found++;
if (no_contacts_found < CLIPBOARD_SIZE) {
int spread = size - 2*rooms_explored_in_the_beyond;
if (spread < 0) spread = -spread;
if (no_contacts_found == 0)
{
#line 1670 "inform7/Chapter 34/Spatial Map.w"
if (spread < best_spread[BEST_ONECUT_ER]) {
best_spread[BEST_ONECUT_ER] = spread;
best_from1[BEST_ONECUT_ER] = at;
best_to1[BEST_ONECUT_ER] = T;
best_dir1[BEST_ONECUT_ER] = i;
}
}
#line 1661 "inform7/Chapter 34/Spatial Map.w"
else if (no_contacts_found == 1)
{
#line 1689 "inform7/Chapter 34/Spatial Map.w"
if (PL__SpatialMap__read_slock(inner_contact_from[0], inner_contact_dir[0]) == inner_contact_to[0]) break;
int r = BEST_TWOCUT_ER;
if ((inner_contact_dir[0] == i) || (inner_contact_dir[0] == PL__SpatialMap__opposite(i)))
r = BEST_PARALLEL_TWOCUT_ER;
if (spread < best_spread[r]) {
best_spread[r] = spread;
best_from1[r] = at; best_to1[r] = T; best_dir1[r] = i;
best_from2[r] = inner_contact_from[0];
best_to2[r] = inner_contact_to[0];
best_dir2[r] = inner_contact_dir[0];
}
}
#line 1663 "inform7/Chapter 34/Spatial Map.w"
;
}
}
#line 1614 "inform7/Chapter 34/Spatial Map.w"
;
}
#line 1546 "inform7/Chapter 34/Spatial Map.w"
;
}
}
LOG_OUTDENT;
return rooms_visited + 1;
}
#line 1739 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__divide_into_zones_onecut(connected_submap *sub, instance *R1, instance *R2,
int *Z1_count, int *Z2_count, int Z1, int Z2) {
if (R1 == R2) internal_error("can't divide");
instance *R;
LOOP_OVER_SUBMAP(R, sub) PF_I(map, R)->zone = 0;
PF_I(map, R1)->zone = Z1; PF_I(map, R2)->zone = Z2;
*Z1_count = 0; *Z2_count = 0;
int contacts = 0;
*Z1_count = PL__SpatialMap__divide_into_zones_onecut_r(R1, NULL, R1, R2, &contacts);
if (contacts > 0) return FALSE;
*Z2_count = PL__SpatialMap__divide_into_zones_onecut_r(R2, NULL, R2, R1, &contacts);
LOOP_OVER_SUBMAP(R, sub)
if (PF_I(map, R)->zone == 0)
PF_I(map, R)->zone = Z1;
if ((PF_I(map, R1)->zone == Z1) && (PF_I(map, R2)->zone == Z2) &&
((*Z1_count) > 1) && ((*Z2_count) > 1)) return TRUE;
return FALSE;
}
#line 1768 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__divide_into_zones_onecut_r(instance *at, instance *from,
instance *our_capital, instance *foreign_capital, int *borders) {
int rooms_visited = 0;
int our_zone = PF_I(map, at)->zone, i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_slock(at, i);
if (T)
{
#line 1786 "inform7/Chapter 34/Spatial Map.w"
int T_zone = PF_I(map, T)->zone, foreign_zone = PF_I(map, foreign_capital)->zone;
if (T_zone == our_zone) continue;
if ((at == our_capital) && (T == foreign_capital)) continue;
if ((at == foreign_capital) && (T == our_capital)) continue;
if (T_zone == foreign_zone) { (*borders)++; continue; }
PF_I(map, T)->zone = our_zone;
rooms_visited +=
PL__SpatialMap__divide_into_zones_onecut_r(T, at, our_capital, foreign_capital, borders);
}
#line 1774 "inform7/Chapter 34/Spatial Map.w"
;
}
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_smap(at, i);
if (T)
{
#line 1786 "inform7/Chapter 34/Spatial Map.w"
int T_zone = PF_I(map, T)->zone, foreign_zone = PF_I(map, foreign_capital)->zone;
if (T_zone == our_zone) continue;
if ((at == our_capital) && (T == foreign_capital)) continue;
if ((at == foreign_capital) && (T == our_capital)) continue;
if (T_zone == foreign_zone) { (*borders)++; continue; }
PF_I(map, T)->zone = our_zone;
rooms_visited +=
PL__SpatialMap__divide_into_zones_onecut_r(T, at, our_capital, foreign_capital, borders);
}
#line 1778 "inform7/Chapter 34/Spatial Map.w"
;
}
return rooms_visited + 1;
}
#line 1800 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__divide_into_zones_twocut(instance *div_F1, instance *div_T1,
instance *other_F, instance *div_T2, int Z1, int Z2) {
connected_submap *sub = PF_I(map, div_F1)->submap;
instance *R;
LOOP_OVER_SUBMAP(R, sub) PF_I(map, R)->zone = 0;
PF_I(map, div_F1)->zone = Z1; PF_I(map, div_T1)->zone = Z2;
PL__SpatialMap__divide_into_zones_twocut_r(div_F1, div_F1, div_T1, other_F, div_T2);
PL__SpatialMap__divide_into_zones_twocut_r(div_T1, div_F1, div_T1, other_F, div_T2);
}
#line 1813 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__divide_into_zones_twocut_r(instance *at, instance *not_X1, instance *not_Y1,
instance *not_X2, instance *not_Y2) {
int Z = PF_I(map, at)->zone, i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_slock(at, i);
if (T)
{
#line 1829 "inform7/Chapter 34/Spatial Map.w"
if ((T != at) && (PF_I(map, T)->zone == 0)) {
if (((at == not_X1) && (T == not_Y1)) || ((at == not_Y1) && (T == not_X1)))
continue;
if (((at == not_X2) && (T == not_Y2)) || ((at == not_Y2) && (T == not_X2)))
continue;
PF_I(map, T)->zone = Z;
PL__SpatialMap__divide_into_zones_twocut_r(T, not_X1, not_Y1, not_X2, not_Y2);
}
}
#line 1818 "inform7/Chapter 34/Spatial Map.w"
;
}
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_smap(at, i);
if (T)
{
#line 1829 "inform7/Chapter 34/Spatial Map.w"
if ((T != at) && (PF_I(map, T)->zone == 0)) {
if (((at == not_X1) && (T == not_Y1)) || ((at == not_Y1) && (T == not_X1)))
continue;
if (((at == not_X2) && (T == not_Y2)) || ((at == not_Y2) && (T == not_X2)))
continue;
PF_I(map, T)->zone = Z;
PL__SpatialMap__divide_into_zones_twocut_r(T, not_X1, not_Y1, not_X2, not_Y2);
}
}
#line 1822 "inform7/Chapter 34/Spatial Map.w"
;
}
}
#line 1853 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__save_component_positions(connected_submap *sub) {
instance *R;
LOOP_OVER_SUBMAP(R, sub)
PF_I(map, R)->saved_gridpos = Room_position(R);
}
void PL__SpatialMap__restore_component_positions(connected_submap *sub) {
instance *R;
LOOP_OVER_SUBMAP(R, sub)
PL__SpatialMap__set_room_position(R, PF_I(map, R)->saved_gridpos);
}
#line 1891 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__cool_submap(connected_submap *sub) {
int initial_heat = PL__SpatialMap__find_submap_heat(sub), initial_spending = drognas_spent;
LOGIF(SPATIAL_MAP, "\nTACTIC: Cooling submap %d: initial heat %d\n",
sub->allocation_id, sub->heat);
int heat_before_round = initial_heat;
int rounds = 0;
while (TRUE) {
LOGIF(SPATIAL_MAP, "Cooling round %d.\n", ++rounds);
instance *R;
LOOP_OVER_SUBMAP(R, sub) PF_I(map, R)->cooled = FALSE;
PL__SpatialMap__save_component_positions(sub);
LOOP_OVER_SUBMAP(R, sub) PL__SpatialMap__cool_component_from(sub, R);
PL__SpatialMap__find_submap_heat(sub);
if (sub->heat == 0) break;
if (sub->heat >= heat_before_round) {
PL__SpatialMap__restore_component_positions(sub);
PL__SpatialMap__find_submap_heat(sub);
LOGIF(SPATIAL_MAP, "Cooling round %d raised heat, so undone.\n", rounds);
break;
} else {
LOGIF(SPATIAL_MAP, "Cooling round %d leaves penalty %d.\n", rounds, sub->heat);
}
heat_before_round = sub->heat;
}
LOGIF(SPATIAL_MAP,
"Cooling submap %d done (%d round(s)): cooled by %d at cost of %d drognas\n\n",
sub->allocation_id, rounds,
initial_heat - sub->heat, drognas_spent - initial_spending);
cooling_spending += drognas_spent - initial_spending;
}
#line 1929 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__cool_component_from(connected_submap *sub, instance *R) {
if (PF_I(map, R)->cooled) return;
PF_I(map, R)->cooled = TRUE;
int exit_heats[MAX_DIRECTIONS];
instance *exit_rooms[MAX_DIRECTIONS];
{
#line 1942 "inform7/Chapter 34/Spatial Map.w"
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
exit_heats[i] = PL__SpatialMap__find_exit_heat(R, i);
exit_rooms[i] = PL__SpatialMap__read_smap(R, i);
}
}
#line 1935 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 1979 "inform7/Chapter 34/Spatial Map.w"
while (TRUE) {
int i, exits_cooled = 0;
LOOP_OVER_LATTICE_DIRECTIONS(i)
if (exit_heats[i] > 0) {
int j;
LOOP_OVER_LATTICE_DIRECTIONS(j)
if ((exit_heats[j] == 0) && (exit_rooms[i] == exit_rooms[j])) {
exit_heats[i] = 0; exits_cooled++;
}
if (exit_heats[i] > 0) {
PL__SpatialMap__cool_exit(R, i);
exit_heats[i] = 0; exits_cooled++;
PL__SpatialMap__cool_component_from(sub, exit_rooms[i]);
LOOP_OVER_LATTICE_DIRECTIONS(j)
if ((exit_heats[j] > 0) && (exit_rooms[i] == exit_rooms[j])) {
exit_heats[j] = 0; exits_cooled++;
}
}
}
if (exits_cooled == 0) break;
}
}
#line 1936 "inform7/Chapter 34/Spatial Map.w"
;
}
#line 2009 "inform7/Chapter 34/Spatial Map.w"
instance *saved_to; vector Saved_position;
void PL__SpatialMap__undo_cool_exit(void) {
PL__SpatialMap__move_room_to(saved_to, Saved_position);
LOGIF(SPATIAL_MAP_WORKINGS, "Undoing move of $O\n", saved_to);
}
void PL__SpatialMap__cool_exit(instance *R, int exit) {
instance *to = PL__SpatialMap__read_smap(R, exit);
saved_to = to; Saved_position = Room_position(to);
vector D = PL__SpatialMap__direction_as_vector(exit);
int length = PF_I(map, R)->exit_lengths[exit];
vector N = Geometry__vec_plus(Room_position(R), Geometry__vec_scale(length, D));
if (Geometry__vec_eq(Room_position(to), N)) return;
PL__SpatialMap__move_room_to(saved_to, N);
LOGIF(SPATIAL_MAP_WORKINGS, "Moving $O %s from $O: now at (%d,%d,%d)\n",
to, PL__SpatialMap__find_icon_label(exit), R, N.x, N.y, N.z);
}
#line 2045 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__quench_submap(connected_submap *sub, instance *avoid1, instance *avoid2) {
int initial_heat = PL__SpatialMap__find_submap_heat(sub), initial_spending = drognas_spent;
LOGIF(SPATIAL_MAP, "\nTACTIC: Quenching submap %d: initial heat %d\n",
sub->allocation_id, sub->heat);
instance *R;
int heat = sub->heat, last_heat = sub->heat + 1, rounds = 0;
while (heat < last_heat) {
LOGIF(SPATIAL_MAP, "Quenching round %d begins with heat at %d.\n", ++rounds, heat);
LOG_INDENT;
last_heat = heat;
int successes = 0;
LOOP_OVER_SUBMAP(R, sub) {
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i)
if (PL__SpatialMap__find_exit_heat(R, i) > 0)
{
#line 2073 "inform7/Chapter 34/Spatial Map.w"
instance *T = PL__SpatialMap__read_smap(R, i);
if ((T == avoid1) && (R == avoid2)) continue;
if ((T == avoid2) && (R == avoid1)) continue;
LOGIF(SPATIAL_MAP_WORKINGS, "Quenching $O %s to $O.\n",
R, PL__SpatialMap__find_icon_label(i), T);
PL__SpatialMap__cool_exit(R, i);
int h = PL__SpatialMap__find_submap_heat(sub);
if (h >= heat) {
PL__SpatialMap__undo_cool_exit();
LOGIF(SPATIAL_MAP_WORKINGS, "Undoing: would have resulted in heat %d\n", h);
} else {
heat = h;
LOGIF(SPATIAL_MAP_WORKINGS, "Accepting: reduces heat to %d\n", h);
successes++;
}
}
#line 2060 "inform7/Chapter 34/Spatial Map.w"
;
}
LOG_OUTDENT;
LOGIF(SPATIAL_MAP, "Quenching round %d had %d success(es).\n", rounds, successes);
}
LOGIF(SPATIAL_MAP, "Quenching submap %d done: cooled by %d at cost of %d drognas\n",
sub->allocation_id, initial_heat - sub->heat, drognas_spent - initial_spending);
quenching_spending += drognas_spent - initial_spending;
}
#line 2100 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__diffuse_submap(connected_submap *sub) {
int initial_heat = PL__SpatialMap__find_submap_heat(sub), initial_spending = drognas_spent;
LOGIF(SPATIAL_MAP, "\nTACTIC: Diffusing submap %d: initial heat %d\n",
sub->allocation_id, sub->heat);
instance *R;
int heat = sub->heat, last_heat = sub->heat + 1, rounds = 0;
while (heat < last_heat) {
LOGIF(SPATIAL_MAP, "Diffusion round %d with heat at %d.\n", ++rounds, heat);
LOG_INDENT;
last_heat = heat;
LOOP_OVER_SUBMAP(R, sub) {
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_smap(R, i);
if (T)
{
#line 2134 "inform7/Chapter 34/Spatial Map.w"
int L = PF_I(map, R)->exit_lengths[i];
if (L > -1) {
LOGIF(SPATIAL_MAP_WORKINGS, "Lengthening $O %s to $O to %d.\n",
R, PL__SpatialMap__find_icon_label(i), T, L+1);
LOG_INDENT;
PL__SpatialMap__save_component_positions(sub);
vector O = Room_position(R);
PF_I(map, R)->exit_lengths[i] = L+1;
PL__SpatialMap__cool_exit(R, i);
vector D = Geometry__vec_minus(Room_position(R), O);
instance *S;
LOOP_OVER_SUBMAP(S, sub) PF_I(map, S)->zone = 1;
PL__SpatialMap__diffuse_across(R, T);
LOOP_OVER_SUBMAP(S, sub)
if ((PF_I(map, S)->zone == 2) && (S != R))
PL__SpatialMap__translate_room(S, D);
PL__SpatialMap__find_submap_heat(sub);
if (sub->heat >= heat) {
PL__SpatialMap__restore_component_positions(sub);
PF_I(map, R)->exit_lengths[i] = L;
PL__SpatialMap__find_submap_heat(sub);
LOGIF(SPATIAL_MAP_WORKINGS, "Lengthening left heat undecreased at %d.\n", sub->heat);
LOG_OUTDENT;
} else {
LOGIF(SPATIAL_MAP_WORKINGS, "Lengthening reduced heat to %d.\n", sub->heat);
heat = sub->heat;
LOG_OUTDENT;
break;
}
}
}
#line 2115 "inform7/Chapter 34/Spatial Map.w"
;
}
}
LOG_OUTDENT;
}
LOGIF(SPATIAL_MAP, "Diffusing submap %d done after %d round(s): "
"cooled by %d at cost of %d drognas\n",
sub->allocation_id, rounds,
initial_heat - sub->heat, drognas_spent - initial_spending);
diffusion_spending += drognas_spent - initial_spending;
}
#line 2172 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__diffuse_across(instance *at, instance *avoiding) {
PF_I(map, at)->zone = 2;
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_slock(at, i);
if ((T) && (PF_I(map, T)->zone == 1)) PL__SpatialMap__diffuse_across(T, avoiding);
}
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_smap(at, i);
if ((T) && (PF_I(map, T)->zone == 1) && (T != avoiding) &&
(PL__SpatialMap__find_exit_heat(at, i) == 0))
PL__SpatialMap__diffuse_across(T, avoiding);
}
}
#line 2203 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__radiate_submap(connected_submap *sub) {
int initial_heat = PL__SpatialMap__find_submap_heat(sub), initial_spending = drognas_spent;
LOGIF(SPATIAL_MAP, "\nTACTIC: Radiating submap %d: initial heat %d\n",
sub->allocation_id, sub->heat);
instance *R;
int heat = sub->heat, last_heat = sub->heat + 1, rounds = 0;
while (heat < last_heat) {
LOGIF(SPATIAL_MAP, "Radiation round %d with heat at %d.\n", ++rounds, heat);
LOG_INDENT;
last_heat = heat;
LOOP_OVER_SUBMAP(R, sub) {
int i;
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_smap(R, i);
if (T) {
if (PL__SpatialMap__exit_aligned(R, i) == FALSE)
{
#line 2242 "inform7/Chapter 34/Spatial Map.w"
LOGIF(SPATIAL_MAP_WORKINGS, "Map misaligned on $O %s to $O.\n",
R, PL__SpatialMap__find_icon_label(i), T);
LOG_INDENT;
int j;
vector O = Room_position(R);
LOOP_OVER_LATTICE_DIRECTIONS(j) {
vector E = PL__SpatialMap__direction_as_vector(j);
int L;
for (L = 1; L <= MAX_RADIATION_DISTANCE; L++) {
vector D = Geometry__vec_scale(L, E);
PL__SpatialMap__set_room_position(R, Geometry__vec_plus(O, D));
if (PL__SpatialMap__exit_aligned(R, i))
{
#line 2264 "inform7/Chapter 34/Spatial Map.w"
LOGIF(SPATIAL_MAP_WORKINGS, "Aligned at offset %d, %d, %d\n", D.x, D.y, D.z);
PL__SpatialMap__save_component_positions(sub);
instance *S;
LOOP_OVER_SUBMAP(S, sub) PF_I(map, S)->zone = 1;
PL__SpatialMap__radiate_across(R, T, j);
LOOP_OVER_SUBMAP(S, sub)
if ((PF_I(map, S)->zone == 2) && (S != R)) {
LOGIF(SPATIAL_MAP_WORKINGS, "Comoving $O\n", S);
PL__SpatialMap__translate_room(S, D);
}
PL__SpatialMap__find_submap_heat(sub);
if (sub->heat >= heat) {
PL__SpatialMap__restore_component_positions(sub);
LOGIF(SPATIAL_MAP_WORKINGS,
"Radiating left heat undecreased at %d.\n", sub->heat);
} else {
LOGIF(SPATIAL_MAP_WORKINGS,
"Radiating reduced heat to %d.\n", sub->heat);
heat = sub->heat;
goto Escape;
}
}
#line 2254 "inform7/Chapter 34/Spatial Map.w"
;
}
PL__SpatialMap__set_room_position(R, O);
}
Escape: ;
LOG_OUTDENT;
}
#line 2219 "inform7/Chapter 34/Spatial Map.w"
;
}
}
}
LOG_OUTDENT;
}
PL__SpatialMap__find_submap_heat(sub);
LOGIF(SPATIAL_MAP, "Radiating submap %d done after %d round(s): "
"cooled by %d at cost of %d drognas\n",
sub->allocation_id, rounds,
initial_heat - sub->heat, drognas_spent - initial_spending);
radiation_spending += drognas_spent - initial_spending;
}
#line 2300 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__radiate_across(instance *at, instance *avoiding, int not_this_way) {
PF_I(map, at)->zone = 2;
int i, not_this_way_either = PL__SpatialMap__opposite(not_this_way);
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_slock(at, i);
if ((T) && (PF_I(map, T)->zone == 1))
PL__SpatialMap__radiate_across(T, avoiding, not_this_way);
}
LOOP_OVER_LATTICE_DIRECTIONS(i) {
instance *T = PL__SpatialMap__read_smap(at, i);
if ((T) && (PF_I(map, T)->zone == 1) && (T != avoiding) &&
(i != not_this_way) && (i != not_this_way_either))
PL__SpatialMap__radiate_across(T, avoiding, not_this_way);
}
}
#line 2327 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__explode_submap(connected_submap *sub) {
int initial_heat = PL__SpatialMap__find_submap_heat(sub), initial_spending = drognas_spent;
LOGIF(SPATIAL_MAP, "\nTACTIC: Exploding submap %d: initial heat %d\n",
sub->allocation_id, sub->heat);
int keep_trying = TRUE, moves = 0;
while (keep_trying) {
keep_trying = FALSE;
instance *R;
LOOP_OVER_SUBMAP(R, sub) {
vector At = Room_position(R);
if (PL__SpatialMap__occupied_in_submap(sub, At) >= 2) {
LOGIF(SPATIAL_MAP, "Collision: pushing $O away\n", R);
int x, y, coldest = FUSION_POINT;
vector Coldest = Geometry__vec(MAX_EXPLOSION_DISTANCE + 1, 0, 0);
for (x = -MAX_EXPLOSION_DISTANCE; x<=MAX_EXPLOSION_DISTANCE; x++)
for (y = -MAX_EXPLOSION_DISTANCE; y<=MAX_EXPLOSION_DISTANCE; y++)
if ((x != 0) || (y != 0)) {
vector V = Geometry__vec_plus(At, Geometry__vec(x, y, 0));
if (PL__SpatialMap__occupied_in_submap(sub, V) == 0) {
PL__SpatialMap__move_room_to(R, V);
int h = PL__SpatialMap__find_submap_heat(sub);
if (h < coldest) { Coldest = V; coldest = h; }
}
}
PL__SpatialMap__move_room_to(R, Geometry__vec_plus(At, Coldest));
LOGIF(SPATIAL_MAP, "Moving $O to blank offset (%d,%d,%d) for heat %d\n",
R, Coldest.x, Coldest.y, Coldest.z, coldest);
keep_trying = TRUE;
moves++;
break;
}
}
}
PL__SpatialMap__find_submap_heat(sub);
LOGIF(SPATIAL_MAP, "Exploding submap %d done after %d move(s): "
"cooled by %d at cost of %d drognas\n",
sub->allocation_id, moves,
initial_heat - sub->heat, drognas_spent - initial_spending);
explosion_spending += drognas_spent - initial_spending;
}
#line 2519 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__compare_components(const void *ent1, const void *ent2) {
const connected_submap *mc1 = *((const connected_submap **) ent1);
const connected_submap *mc2 = *((const connected_submap **) ent2);
int d = mc2->bounds.population - mc1->bounds.population;
if (d != 0) return d;
if (mc1->bounds.population == 1) {
instance *R1 = mc1->first_room_in_submap;
instance *R2 = mc2->first_room_in_submap;
if ((R1) && (R2)) { /* which should always happen, but just in case of an error */
instance *reg1 = PL__Regions__enclosing(R1);
instance *reg2 = PL__Regions__enclosing(R2);
if ((reg1) && (reg2 == NULL)) return -1;
if ((reg1 == NULL) && (reg2)) return 1;
if (reg1) {
d = reg1->allocation_id - reg2->allocation_id;
if (d != 0) return d;
}
d = R1->allocation_id - R2->allocation_id;
if (d != 0) return d;
}
}
return mc1->allocation_id - mc2->allocation_id;
}
#line 2548 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__component_is_adjoining(connected_submap *sub) {
if (PL__SpatialMap__no_links_to_placed_components(sub) > 0) return TRUE;
return FALSE;
}
int PL__SpatialMap__component_is_isolated(connected_submap *sub) {
if (PL__SpatialMap__no_links_to_other_components(sub) == 0) return TRUE;
return FALSE;
}
#line 2562 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_component_placement_heat(connected_submap *sub) {
connected_submap *other;
LOOP_OVER(other, connected_submap)
if (other->positioned) {
instance *R;
LOOP_OVER_SUBMAP(R, sub)
if (PL__SpatialMap__occupied_in_submap(other, Room_position(R)))
return FUSION_POINT;
}
int heat = PL__SpatialMap__find_cross_component_heat(sub);
if (heat >= FUSION_POINT) heat = FUSION_POINT - 1;
return heat;
}
#line 2579 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_cross_component_heat(connected_submap *sub) {
int heat = 0;
PL__SpatialMap__cross_component_links(sub, NULL, NULL, &heat, TRUE);
return heat;
}
void PL__SpatialMap__find_link_to_placed_components(connected_submap *sub,
instance **outer, instance **inner) {
PL__SpatialMap__cross_component_links(sub, outer, inner, NULL, TRUE);
}
int PL__SpatialMap__no_links_to_placed_components(connected_submap *sub) {
return PL__SpatialMap__cross_component_links(sub, NULL, NULL, NULL, TRUE);
}
int PL__SpatialMap__no_links_to_other_components(connected_submap *sub) {
return PL__SpatialMap__cross_component_links(sub, NULL, NULL, NULL, FALSE);
}
#line 2607 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__cross_component_links(connected_submap *sub, instance **outer, instance **inner,
int *heat, int posnd) {
int no_links = 0;
if (heat) *heat = 0;
instance *R;
LOOP_OVER_SUBMAP(R, sub) {
int d;
LOOP_OVER_NONLATTICE_DIRECTIONS(d) {
instance *R2 = PL__SpatialMap__read_smap_cross(R, d);
if ((R2) && (PF_I(map, R2)->submap != sub)) {
if ((posnd == FALSE) || (PF_I(map, R2)->submap->positioned)) {
no_links++;
if (inner) *inner = R; if (outer) *outer = R2;
if (heat) *heat = PL__SpatialMap__heat_sum(*heat, PL__SpatialMap__find_cross_link_heat(R, R2, d));
}
}
}
instance *S;
LOOP_OVER_ROOMS(S) {
if (PF_I(map, S)->submap == sub) continue;
if ((posnd) && (PF_I(map, S)->submap->positioned == FALSE)) continue;
int d;
LOOP_OVER_NONLATTICE_DIRECTIONS(d) {
instance *R2 = PL__SpatialMap__read_smap_cross(S, d);
if ((R2) && (PF_I(map, R2)->submap == sub)) {
no_links++;
if (outer) *outer = S; if (inner) *inner = R2;
if (heat) *heat = PL__SpatialMap__heat_sum(*heat, PL__SpatialMap__find_cross_link_heat(S, R2, d));
}
}
}
}
if (no_links == 0)
{
#line 2649 "inform7/Chapter 34/Spatial Map.w"
if (sub->bounds.population == 1) {
instance *R = sub->first_room_in_submap;
if (R) { /* which should always happen, but just in case of an error */
instance *reg = PL__Regions__enclosing(R);
if (reg) {
instance *S, *closest_S = NULL;
int closest = 0;
LOOP_OVER_ROOMS(S)
if ((S != R) && (PL__Regions__enclosing(S) == reg))
if ((posnd == FALSE) || (PF_I(map, S)->submap->positioned)) {
int diff = 2*(R->allocation_id - S->allocation_id);
if (diff < 0) diff = 1-diff;
if ((closest_S == NULL) || (diff < closest)) {
closest = diff; closest_S = S;
}
}
if (closest_S) {
LOGIF(SPATIAL_MAP, "vdW force between $O and $O\n", R, closest_S);
no_links++;
if (outer) *outer = closest_S; if (inner) *inner = R;
if (heat) *heat = PL__SpatialMap__heat_sum(*heat, PL__SpatialMap__find_cross_link_heat(closest_S, R, 3));
}
}
}
}
}
#line 2639 "inform7/Chapter 34/Spatial Map.w"
;
return no_links;
}
#line 2682 "inform7/Chapter 34/Spatial Map.w"
int PL__SpatialMap__find_cross_link_heat(instance *R, instance *S, int dir) {
if ((R == NULL) || (S == NULL)) internal_error("bad room distance");
return PL__SpatialMap__component_metric(Room_position(R), Room_position(S), dir);
}
int PL__SpatialMap__component_metric(vector P1, vector P2, int dir) {
vector D = Geometry__vec_minus(P1, P2);
int b = 0;
if ((dir == 10) || (dir == 11)) { /* IN and OUT respectively */
if (D.x > 0) b++;
if (D.x < 0) b--;
if (D.y > 0) b--;
if (D.y < 0) b++;
if (dir == 11) b = -b;
b += 2;
}
if (dir == 3) { /* SOUTH, the notional direction for van der Waals forces */
if (D.y > 0) b++;
if (D.y < 0) b--;
b += 2;
}
return 2*b + D.x*D.x + D.y*D.y + 100*D.z*D.z;
}
#line 2748 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__log_precis_of_map(void) {
LOG("[Precis of source text giving map layout follows.]\n\n");
instance *R;
LOOP_OVER_INSTANCES(R, K_object) PF_I(map, R)->zone = 1;
LOOP_OVER_INSTANCES(R, K_object) {
{
#line 2765 "inform7/Chapter 34/Spatial Map.w"
if ((Instances__of_kind(R, K_direction)) &&
(PF_I(map, R)->direction_index >= 12)) {
wording W = Instances__get_name(R, FALSE);
wording OW = Instances__get_name(PL__Map__get_value_of_opposite_property(R), FALSE);
LOG("$c is a direction. The opposite of $c is $c.\n", W, W, OW);
}
if (Instances__of_kind(R, K_region)) {
wording W = Instances__get_name(R, FALSE);
LOG("$c is a region.\n", W);
}
if (Instances__of_kind(R, K_door)) {
wording W = Instances__get_name(R, FALSE);
LOG("$c is a door.\n", W);
parse_node *S = World__Inferences__get_prop_state(
Instances__as_subject(R), P_other_side);
instance *X = Rvalues__to_object_instance(S);
if (X) {
wording XW = Instances__get_name(X, FALSE);
LOG("The other side of $c is $c.\n", W, XW);
}
}
}
#line 2753 "inform7/Chapter 34/Spatial Map.w"
;
{
#line 2790 "inform7/Chapter 34/Spatial Map.w"
if (Instances__of_kind(R, K_room)) {
wording RW = Instances__get_name(R, FALSE);
LOG("$c is a room.\n", RW);
instance *reg = PL__Regions__enclosing(R);
if (reg) {
wording RGW = Instances__get_name(reg, FALSE);
if (PF_I(map, reg)->zone == 1) {
LOG("$c is a region.\n", RGW);
PF_I(map, reg)->zone = 0;
}
LOG("$c is in $c.\n", RW, RGW);
}
instance *start = PL__Player__get_start_room();
if (R == start) {
LOG("The player is in $c.\n", RW);
}
}
}
#line 2754 "inform7/Chapter 34/Spatial Map.w"
;
PF_I(map, R)->zone = 0;
}
{
#line 2811 "inform7/Chapter 34/Spatial Map.w"
instance *R;
LOOP_OVER_ROOMS(R) {
wording RW = Instances__get_name(R, FALSE);
int i;
LOOP_OVER_STORY_DIRECTIONS(i) {
instance *D = NULL;
instance *S = PL__SpatialMap__room_exit(R, i, &D);
if ((S) || (D)) {
wording OW = EMPTY_WORDING;
if (D) OW = Instances__get_name(D, FALSE);
else OW = Instances__get_name(S, FALSE);
if (i < 12) {
char *n = PL__SpatialMap__usual_Inform_direction_name(i);
int opp = PL__SpatialMap__opposite(i);
LOG("$c is %s of $c.\n", OW, n, RW);
if ((S) && (PL__SpatialMap__room_exit(S, opp, NULL) == NULL))
LOG("%s of $c is nowhere.\n",
PL__SpatialMap__usual_Inform_direction_name(opp), OW);
} else {
instance *dir;
LOOP_OVER_INSTANCES(dir, K_direction)
if (PF_I(map, dir)->direction_index == i) {
wording DW = Instances__get_name(dir, FALSE);
LOG("$c is $w of $c.\n", OW, DW, RW);
instance *opp = PL__Map__get_value_of_opposite_property(dir);
int od = PF_I(map, opp)->direction_index;
if ((S) && (PL__SpatialMap__room_exit(S, od, NULL) == NULL)) {
wording OPW = Instances__get_name(dir, FALSE);
LOG("$w of $c is nowhere.\n", OPW, OW);
}
}
}
}
}
}
}
#line 2757 "inform7/Chapter 34/Spatial Map.w"
;
ParseTree__traverse(PL__SpatialMap__visit_to_transcribe);
LOG("\n[Precis complete.]\n\n");
}
#line 2850 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__visit_to_transcribe(parse_node *p) {
if ((ParseTree__get_type(p) == SENTENCE_NT)
&& (p->down)
&& (ParseTree__int_annotation(p->down, verb_id_ANNOT) == MAP_PARAMETER_VB)
&& (p->down->next) && (p->down->next))
LOG("\nIndex map with $c.\n", ParseTree__get_text(p->down->next));
}
#line 2861 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__index_room_connections(instance *R) {
wording RW = Instances__get_name(R, FALSE); /* name of the origin room */
instance *dir;
LOOP_OVER_INSTANCES(dir, K_direction) {
int i = PF_I(map, dir)->direction_index;
instance *opp = PL__Map__get_value_of_opposite_property(dir);
int od = opp?(PF_I(map, opp)->direction_index):(-1);
instance *D = NULL;
instance *S = PL__SpatialMap__room_exit(R, i, &D);
if ((S) || (D)) {
HTML__open_para(ifl, 1, "tight");
char *icon = "e_arrow";
if ((S) && (D)) icon = "e_arrow_door";
else if (D) icon = "e_arrow_door_blocked";
INDEX("<img border=0 src=inform:/map_icons/%s.png>&nbsp;", icon);
Instances__index_name(dir);
INDEX(" to ");
if (S) {
Instances__index_name(S);
if (D) {
INDEX(" via ");
Instances__index_name(D);
}
} else {
Instances__index_name(D);
INDEX(" (a door)");
}
if (S) {
instance *B = opp?(PL__SpatialMap__room_exit(S, od, NULL)):NULL;
if (B == NULL) {
INDEX(" (but ");
Instances__index_name(opp);
INDEX(" from ");
Instances__index_name(S);
INDEX(" is nowhere)");
} else if (B != R) {
INDEX(" (but ");
Instances__index_name(opp);
INDEX(" from ");
Instances__index_name(S);
INDEX(" is ");
Instances__index_name(B);
INDEX(")");
}
}
parse_node *at = PF_I(map, R)->exits_set_at[i];
if (at) Index__link(Wordings__first_wn(ParseTree__get_text(at)));
INDEX("</p>");
}
}
int k = 0;
LOOP_OVER_INSTANCES(dir, K_direction) {
int i = PF_I(map, dir)->direction_index;
if (PL__SpatialMap__room_exit(R, i, NULL)) continue;
wording DW = Instances__get_name(dir, FALSE); /* name of the direction */
k++;
if (k == 1) {
HTML__open_para(ifl, 1, "hanging");
INDEX("<i>add:</i> ");
} else {
INDEX("; ");
}
TEMPORARY_STREAM;
char *p = Lexer__word_raw_text(Wordings__first_wn(DW));
int j;
for (j=0; p[j]; j++) {
if (j==0) WRITE_TO(TEMP, "%c", Platform__toupper(p[j]));
else WRITE_TO(TEMP, "%c", p[j]);
}
if (Wordings__length(DW) > 1) {
WRITE_TO(TEMP, " ");
Wordings__to_stream_raw(TEMP, Wordings__trim_first_word(DW));
}
WRITE_TO(TEMP, " from ");
if (Wordings__nonempty(RW)) Wordings__to_stream_raw(TEMP, RW);
else WRITE_TO(TEMP, "here");
WRITE_TO(TEMP, " is .[=0x000A=]");
HTML__Javascript__paste(ifl, STREAM_TEXT(TEMP));
CLOSE_TEMPORARY_STREAM;
INDEX("&nbsp;");
Wordings__index_raw(DW);
}
if (k>0) INDEX("</p>");
}
#line 2951 "inform7/Chapter 34/Spatial Map.w"
void PL__SpatialMap__log_spatial_layout(void) {
PL__SpatialMap__establish_benchmark_room();
PL__EPSMap__traverse_for_map_parameters(1);
PL__SpatialMap__establish_spatial_coordinates();
connected_submap *sub;
LOOP_OVER(sub, connected_submap) {
LOG("\nMap component %d: "
"extent (%d...%d, %d...%d, %d...%d): population %d\n",
sub->allocation_id,
sub->bounds.corner0.x, sub->bounds.corner1.x,
sub->bounds.corner0.y, sub->bounds.corner1.y,
sub->bounds.corner0.z, sub->bounds.corner1.z,
sub->bounds.population);
instance *R;
LOOP_OVER_SUBMAP(R, sub) {
wording W = Instances__get_name(R, FALSE);
if (R == benchmark_room) LOG("Benchmark: ");
LOG("$w: %d, %d, %d\n", W,
Room_position(R).x,
Room_position(R).y,
Room_position(R).z);
}
}
}
#line 29 "inform7/Chapter 34/HTML Map.w"
instance **room_grid = NULL;
int *icon_grid = NULL, *exit_grid = NULL;
void PL__HTMLMap__calculate_map_grid(void) {
{
#line 42 "inform7/Chapter 34/HTML Map.w"
int size_needed = Geometry__cuboid_volume(Universe), x;
room_grid = (instance **)
(Memory__I7_calloc(size_needed, sizeof(instance *), MAP_INDEX_MREASON));
for (x=0; x<size_needed; x++) room_grid[x] = NULL;
icon_grid = (int *)
(Memory__I7_calloc(25*size_needed, sizeof(int), MAP_INDEX_MREASON));
exit_grid = (int *)
(Memory__I7_calloc(25*size_needed, sizeof(int), MAP_INDEX_MREASON));
for (x=0; x<25*size_needed; x++) {
icon_grid[x] = 0;
exit_grid[x] = -1;
}
}
#line 33 "inform7/Chapter 34/HTML Map.w"
;
{
#line 60 "inform7/Chapter 34/HTML Map.w"
instance *R;
LOOP_OVER_ROOMS(R)
room_grid[ROOM_GRID_POS(Room_position(R))] = R;
}
#line 34 "inform7/Chapter 34/HTML Map.w"
;
{
#line 67 "inform7/Chapter 34/HTML Map.w"
instance *R;
LOOP_OVER_ROOMS(R) {
int exit;
LOOP_OVER_STORY_DIRECTIONS(exit)
if (PL__SpatialMap__direction_is_mappable(exit)) {
instance *D = NULL; /* door which the exit passes through, if it does */
instance *T = PL__SpatialMap__room_exit(R, exit, &D); /* target at the other end */
if ((T) || (D))
{
#line 114 "inform7/Chapter 34/HTML Map.w"
int i1, i2;
PL__SpatialMap__cell_position_for_direction(exit, &i1, &i2);
int bitmap = 0;
if (D) {
if (T) bitmap |= DOOR2_MAPBIT;
else bitmap |= DOOR1_MAPBIT;
}
if (T) {
bitmap |= EXIT_MAPBIT;
vector E = PL__SpatialMap__direction_as_vector(exit);
if ((Geometry__vec_eq(E, Zero_vector) == FALSE) &&
(PL__SpatialMap__direction_is_lateral(exit))) {
{
#line 139 "inform7/Chapter 34/HTML Map.w"
vector V = Geometry__vec_minus(Room_position(T), Room_position(R));
int lambda;
for (lambda=1; lambda<10; lambda++)
if (Geometry__vec_eq(V, Geometry__vec_scale(lambda, E))) {
if (lambda == 1) bitmap |= ADJACENT_MAPBIT;
else bitmap |= ALIGNED_MAPBIT;
}
}
#line 126 "inform7/Chapter 34/HTML Map.w"
;
{
#line 157 "inform7/Chapter 34/HTML Map.w"
vector Farend = Geometry__vec_plus(Room_position(R), E);
instance *R;
LOOP_OVER_ROOMS(R)
if ((R != T) && (Geometry__vec_eq(Room_position(R), Farend)))
bitmap |= FADING_MAPBIT;
}
#line 127 "inform7/Chapter 34/HTML Map.w"
;
}
}
icon_grid[ICON_GRID_POS(Room_position(R), i1, i2)] = bitmap;
exit_grid[ICON_GRID_POS(Room_position(R), i1, i2)] = exit;
}
#line 75 "inform7/Chapter 34/HTML Map.w"
;
}
}
}
#line 35 "inform7/Chapter 34/HTML Map.w"
;
{
#line 166 "inform7/Chapter 34/HTML Map.w"
instance *R;
LOOP_OVER_ROOMS(R)
icon_grid[ICON_GRID_POS(Room_position(R), 2, 2)] = OCCUPIED_MAPBIT;
LOOP_OVER_ROOMS(R) {
vector P = Room_position(R);
PL__HTMLMap__correct_pair(P, SW_vector, 0, 4, 4, 0);
PL__HTMLMap__correct_pair(P, W_vector, 0, 2, 4, 2);
PL__HTMLMap__correct_pair(P, NW_vector, 0, 0, 4, 4);
PL__HTMLMap__correct_pair(P, S_vector, 2, 4, 2, 0);
PL__HTMLMap__correct_pair(P, N_vector, 2, 0, 2, 4);
PL__HTMLMap__correct_pair(P, SE_vector, 4, 4, 0, 0);
PL__HTMLMap__correct_pair(P, E_vector, 4, 2, 0, 2);
PL__HTMLMap__correct_pair(P, NE_vector, 4, 0, 0, 4);
}
}
#line 36 "inform7/Chapter 34/HTML Map.w"
;
}
#line 197 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__correct_pair(vector P, vector D, int from_i1, int from_i2, int to_i1, int to_i2) {
vector Q = Geometry__vec_plus(P, D);
if (Geometry__within_cuboid(P, Universe) == FALSE) return; /* should never happen */
if (Geometry__within_cuboid(Q, Universe) == FALSE) return; /* neighbouring cell outside map */
int from = icon_grid[ICON_GRID_POS(P, from_i1, from_i2)];
int to = icon_grid[ICON_GRID_POS(Q, to_i1, to_i2)];
if ((D.x == 0) || (D.y == 0))
{
#line 249 "inform7/Chapter 34/HTML Map.w"
if ((from == to) && (from & ADJACENT_MAPBIT) && (from & DOOR2_MAPBIT)) {
icon_grid[ICON_GRID_POS(P, from_i1, from_i2)] |= MEET_MAPBIT;
icon_grid[ICON_GRID_POS(Q, to_i1, to_i2)] |= MEET_MAPBIT;
}
}
#line 206 "inform7/Chapter 34/HTML Map.w"
else
{
#line 262 "inform7/Chapter 34/HTML Map.w"
vector N = P;
if (D.x < 0) N.x--;
if (D.y < 0) N.y--;
PL__HTMLMap__correct_diagonal(N, TRUE);
PL__HTMLMap__correct_diagonal(N, FALSE);
}
#line 207 "inform7/Chapter 34/HTML Map.w"
;
if (from & ALIGNED_MAPBIT)
{
#line 221 "inform7/Chapter 34/HTML Map.w"
while (TRUE) {
P = Geometry__vec_plus(P, D);
if (icon_grid[ICON_GRID_POS(P, 2, 2)] & OCCUPIED_MAPBIT) break;
if ((Geometry__vec_eq(D, E_vector)) || (Geometry__vec_eq(D, W_vector))) {
icon_grid[ICON_GRID_POS(P, 0, 2)] = EXIT_MAPBIT;
icon_grid[ICON_GRID_POS(P, 2, 2)] |= LONGEW_MAPBIT;
icon_grid[ICON_GRID_POS(P, 4, 2)] = EXIT_MAPBIT;
} else if ((Geometry__vec_eq(D, N_vector)) || (Geometry__vec_eq(D, S_vector))) {
icon_grid[ICON_GRID_POS(P, 2, 0)] = EXIT_MAPBIT;
icon_grid[ICON_GRID_POS(P, 2, 2)] |= LONGNS_MAPBIT;
icon_grid[ICON_GRID_POS(P, 2, 4)] = EXIT_MAPBIT;
} else if ((Geometry__vec_eq(D, SW_vector)) || (Geometry__vec_eq(D, NE_vector))) {
icon_grid[ICON_GRID_POS(P, 0, 4)] = EXIT_MAPBIT;
icon_grid[ICON_GRID_POS(P, 2, 2)] |= LONGSWNE_MAPBIT;
icon_grid[ICON_GRID_POS(P, 4, 0)] = EXIT_MAPBIT;
} else if ((Geometry__vec_eq(D, NW_vector)) || (Geometry__vec_eq(D, SE_vector))) {
icon_grid[ICON_GRID_POS(P, 0, 0)] = EXIT_MAPBIT;
icon_grid[ICON_GRID_POS(P, 2, 2)] |= LONGNWSE_MAPBIT;
icon_grid[ICON_GRID_POS(P, 4, 4)] = EXIT_MAPBIT;
}
}
}
#line 209 "inform7/Chapter 34/HTML Map.w"
;
}
#line 274 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__correct_diagonal(vector BL, int SW_to_NE) {
int pos_00, /* corner icon position of lower cell used by the map connection */
pos_01, /* corner icon position of lower cell not used by the map connection */
pos_10, /* corner icon position of upper cell not used by the map connection */
pos_11; /* corner icon position of upper cell used by the map connection */
if (SW_to_NE) {
pos_00 = ICON_GRID_POS(BL, 4, 0);
pos_01 = ICON_GRID_POS(Geometry__vec_plus(BL, N_vector), 4, 4);
pos_10 = ICON_GRID_POS(Geometry__vec_plus(BL, E_vector), 0, 0);
pos_11 = ICON_GRID_POS(Geometry__vec_plus(BL, NE_vector), 0, 4);
} else {
pos_00 = ICON_GRID_POS(Geometry__vec_plus(BL, E_vector), 0, 0);
pos_01 = ICON_GRID_POS(Geometry__vec_plus(BL, NE_vector), 0, 4);
pos_10 = ICON_GRID_POS(BL, 4, 0);
pos_11 = ICON_GRID_POS(Geometry__vec_plus(BL, N_vector), 4, 4);
}
{
#line 297 "inform7/Chapter 34/HTML Map.w"
int from = icon_grid[pos_00], to = icon_grid[pos_11];
if (from == to) {
if ((from & ADJACENT_MAPBIT) && (from & DOOR2_MAPBIT) && ((from & MEET_MAPBIT) == 0)) {
if ((icon_grid[pos_01] == 0) && (icon_grid[pos_10] == 0))
{
#line 312 "inform7/Chapter 34/HTML Map.w"
icon_grid[pos_00] |= MEET_MAPBIT;
icon_grid[pos_11] |= MEET_MAPBIT;
icon_grid[pos_01] = CROSSDOOR_MAPBIT;
icon_grid[pos_10] = CROSSDOOR_MAPBIT;
}
#line 301 "inform7/Chapter 34/HTML Map.w"
else
{
#line 322 "inform7/Chapter 34/HTML Map.w"
icon_grid[pos_00] = DOOR2_MAPBIT; /* mark the door on the BL half of the exit */
icon_grid[pos_11] = EXIT_MAPBIT; /* with no door on the other half of the exit */
}
#line 303 "inform7/Chapter 34/HTML Map.w"
;
}
}
}
#line 290 "inform7/Chapter 34/HTML Map.w"
;
{
#line 330 "inform7/Chapter 34/HTML Map.w"
int from = icon_grid[pos_00], to = icon_grid[pos_11];
if ((from == to) && (from & CONNECTIVE_BITMAP) &&
(icon_grid[pos_01] == 0) && (icon_grid[pos_10] == 0)) {
icon_grid[pos_01] = CROSSDOT_MAPBIT;
icon_grid[pos_10] = CROSSDOT_MAPBIT;
}
}
#line 291 "inform7/Chapter 34/HTML Map.w"
;
}
#line 346 "inform7/Chapter 34/HTML Map.w"
int map_tables_begun = 2;
void PL__HTMLMap__begin_variable_width_table(void) {
{
#line 378 "inform7/Chapter 34/HTML Map.w"
int i;
INDEX("\n");
for (i=0; i<map_tables_begun; i++) INDEX(" ");
}
#line 348 "inform7/Chapter 34/HTML Map.w"
;
map_tables_begun++;
HTML__begin_html_table(ifl, NULL, FALSE, 0, 0, 0, 0, 0);
}
void PL__HTMLMap__begin_map_table(int width, int height) {
{
#line 378 "inform7/Chapter 34/HTML Map.w"
int i;
INDEX("\n");
for (i=0; i<map_tables_begun; i++) INDEX(" ");
}
#line 354 "inform7/Chapter 34/HTML Map.w"
;
map_tables_begun++;
HTML__begin_html_table(ifl, NULL, FALSE, 0, 0, 0, height, width);
}
void PL__HTMLMap__begin_variable_width_table_with_background(char *bg_image) {
{
#line 378 "inform7/Chapter 34/HTML Map.w"
int i;
INDEX("\n");
for (i=0; i<map_tables_begun; i++) INDEX(" ");
}
#line 360 "inform7/Chapter 34/HTML Map.w"
;
map_tables_begun++;
HTML__begin_html_table_bg(ifl, NULL, FALSE, 0, 0, 0, 0, 0, bg_image);
}
#line 368 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__end_map_table(void) {
map_tables_begun--;
{
#line 378 "inform7/Chapter 34/HTML Map.w"
int i;
INDEX("\n");
for (i=0; i<map_tables_begun; i++) INDEX(" ");
}
#line 370 "inform7/Chapter 34/HTML Map.w"
;
HTML__end_html_table(ifl);
INDEX("\n");
}
#line 388 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__plot_map_icon(char *icon_name) {
INDEX("<img border=0 src=inform:/map_icons/%s.png>", icon_name);
}
void PL__HTMLMap__plot_map_icon_with_tip(char *icon_name, char *tool_tip) {
INDEX("<img border=0 src=inform:/map_icons/%s.png %s>", icon_name, tool_tip);
}
#line 403 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__render_map_as_HTML(void) {
PL__HTMLMap__calculate_map_grid();
{
#line 425 "inform7/Chapter 34/HTML Map.w"
char *some_map_colours[NO_REGION_COLOURS] = {
"Pale Green", "Light Blue", "Plum",
"Light Sea Green", "Light Slate Blue", "Navajo White",
"Violet Red", "Light Cyan", "Light Coral", "Light Pink",
"Medium Aquamarine", "Medium Blue", "Medium Orchid",
"Medium Purple", "Medium Sea Green", "Medium Slate Blue",
"Medium Spring Green", "Medium Turquoise", "Medium Violet Red",
"Light Golden Rod Yellow" };
instance *RG;
int regc = 0;
LOOP_OVER_INSTANCES(RG, K_region)
if (PF_I(map, RG)->world_index_colour == NULL)
PF_I(map, RG)->world_index_colour =
HTML__translate_colour_name(
some_map_colours[(regc++) % NO_REGION_COLOURS]);
}
#line 406 "inform7/Chapter 34/HTML Map.w"
;
{
#line 445 "inform7/Chapter 34/HTML Map.w"
char *default_room_col = HTML__translate_colour_name("Light Grey");
instance *R;
LOOP_OVER_ROOMS(R)
if (PF_I(map, R)->world_index_colour == NULL) {
instance *reg = PL__Regions__enclosing(R);
if (reg)
PF_I(map, R)->world_index_colour = PF_I(map, reg)->world_index_colour;
else
PF_I(map, R)->world_index_colour = default_room_col;
}
}
#line 407 "inform7/Chapter 34/HTML Map.w"
;
if (Instances__count(K_room) >= 2) {
INDEX("\n\n<!--WORLD INDEX MAP BEGINS-->\n<p>\n");
{
#line 459 "inform7/Chapter 34/HTML Map.w"
PL__HTMLMap__begin_variable_width_table();
int z;
for (z=Universe.corner1.z; z>=Universe.corner0.z; z--) {
{
#line 472 "inform7/Chapter 34/HTML Map.w"
char *level_rubric = "Map"; int par = 0;
PL__HTMLMap__devise_level_rubric(z, &level_rubric, &par);
INDEX("<tr><td>");
int rounding = 0;
if (z == Universe.corner1.z) rounding = ROUND_BOX_TOP;
HTML__open_coloured_box(ifl, "e0e0e0", rounding);
INDEX("<i>"); INDEX(level_rubric, par); INDEX("</i>");
HTML__close_coloured_box(ifl, "e0e0e0", rounding);
INDEX("</td></tr>");
}
#line 462 "inform7/Chapter 34/HTML Map.w"
;
{
#line 485 "inform7/Chapter 34/HTML Map.w"
int y_max = -1000000000, y_min = 1000000000; /* assuming there are fewer than 1 billion rooms */
instance *R;
LOOP_OVER_ROOMS(R)
if (Room_position(R).z == z) {
if (Room_position(R).y < y_min) y_min = Room_position(R).y;
if (Room_position(R).y > y_max) y_max = Room_position(R).y;
}
if (y_max < y_min) continue;
LOGIF(SPATIAL_MAP, "Level %d has rooms with %d <= y <= %d\n", z, y_min, y_max);
INDEX("<tr><td>");
PL__HTMLMap__plot_map_level(Universe.corner0.x, Universe.corner1.x, y_min, y_max, z, 1);
INDEX("</td></tr>\n");
}
#line 463 "inform7/Chapter 34/HTML Map.w"
;
}
{
#line 503 "inform7/Chapter 34/HTML Map.w"
INDEX("<tr><td>");
HTML__open_coloured_box(ifl, "e0e0e0", ROUND_BOX_BOTTOM);
HTML__close_coloured_box(ifl, "e0e0e0", ROUND_BOX_BOTTOM);
INDEX("</td></tr>");
}
#line 465 "inform7/Chapter 34/HTML Map.w"
;
PL__HTMLMap__end_map_table();
{
#line 511 "inform7/Chapter 34/HTML Map.w"
instance *D; int k = 0;
LOOP_OVER_INSTANCES(D, K_direction) {
instance *A = PL__SpatialMap__mapped_as_if(D);
if (A) {
k++;
if (k == 1) {
INDEX("<p><i>Mapping ");
} else INDEX("; ");
wording DW = Instances__get_name(D, FALSE); /* name of the direction */
wording AW = Instances__get_name(A, FALSE); /* name of the as-direction */
Wordings__index_raw(DW);
INDEX(" as ");
Wordings__index_raw(AW);
}
}
if (k > 0) INDEX("</i></p>");
}
#line 467 "inform7/Chapter 34/HTML Map.w"
;
}
#line 411 "inform7/Chapter 34/HTML Map.w"
;
INDEX("</p>\n<!--WORLD INDEX MAP ENDS-->\n");
}
}
#line 531 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__devise_level_rubric(int z, char **level_rubric, int *par) {
*level_rubric = "Map"; *par = 0;
switch(Universe.corner1.z - Universe.corner0.z) {
case 0:
break;
case 1: if (z == Universe.corner0.z) *level_rubric = "Lower";
if (z == Universe.corner1.z) *level_rubric = "Upper";
break;
default: {
int z_offset = z-Room_position(benchmark_room).z;
switch(z_offset) {
case 0: *level_rubric = "Starting level"; break;
case 1: *level_rubric = "First level up"; break;
case -1: *level_rubric = "First level down"; break;
case 2: *level_rubric = "Second level up"; break;
case -2: *level_rubric = "Second level down"; break;
case 3: *level_rubric = "Third level up"; break;
case -3: *level_rubric = "Third level down"; break;
default:
if (z_offset > 0) {
*par = z_offset; *level_rubric = "Level %d up";
}
if (z_offset < 0) {
*par = -z_offset; *level_rubric = "Level %d down";
}
break;
}
break;
}
}
}
#line 572 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__render_single_room_as_HTML(instance *R) {
INDEX("\n\n");
nametag *nt = Instances__get_nametag(R);
Index__anchor(Nametags__identifier(nt));
INDEX("<a name=wo_%d>", R->allocation_id);
HTML__begin_plain_html_table(ifl);
HTML__first_html_column(ifl, 0);
vector P = Room_position(R);
PL__HTMLMap__plot_map_level(P.x, P.x, P.y, P.y, P.z, 2);
HTML__next_html_column(ifl, 0);
INDEX("&nbsp;");
HTML__next_html_column(ifl, 0);
Data__Objects__index(R, NULL, 1, FALSE);
HTML__end_html_row(ifl);
HTML__end_html_table(ifl);
INDEX("<p>");
}
#line 597 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__plot_map_level(int x0, int x1, int y0, int y1, int z, int pass) {
if (pass == 1)
LOGIF(SPATIAL_MAP, "Plot: [%d, %d] x [%d, %d] x {%d}\n", x0, x1, y0, y1, z);
int with_numbering = FALSE;
if ((pass == 1) && (Universe.corner1.z != Universe.corner0.z)) with_numbering = TRUE;
INDEX("\n\n");
PL__HTMLMap__begin_variable_width_table_with_background("grid.png");
int y, just_dislocated = FALSE;
for (y=y1; y>=y0; y--) {
int x, c = 0;
for (x=x0; x<=x1; x++)
if (room_grid[ROOM_GRID_POS(Geometry__vec(x, y, z))])
c++;
if (c == 0) {
if (just_dislocated == FALSE) {
just_dislocated = TRUE;
{
#line 654 "inform7/Chapter 34/HTML Map.w"
PL__HTMLMap__end_map_table();
PL__HTMLMap__begin_variable_width_table_with_background("dislocation.png");
INDEX("<tr>");
int i, cells = x1-x0+1;
if (with_numbering) cells += 2;
for (i=0; i<cells; i++) {
INDEX("<td>\n");
PL__HTMLMap__begin_map_table(MAP_CELL_SIZE, MAP_DISLOCATION_HEIGHT);
INDEX("<tr>");
INDEX("<td>");
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("\n</td>");
}
INDEX("</tr>");
PL__HTMLMap__end_map_table();
PL__HTMLMap__begin_variable_width_table_with_background("grid.png");
}
#line 615 "inform7/Chapter 34/HTML Map.w"
;
}
continue;
}
just_dislocated = FALSE;
{
#line 676 "inform7/Chapter 34/HTML Map.w"
{
#line 683 "inform7/Chapter 34/HTML Map.w"
INDEX("<tr>");
if (with_numbering)
{
#line 829 "inform7/Chapter 34/HTML Map.w"
INDEX("<td>");
PL__HTMLMap__begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
}
#line 684 "inform7/Chapter 34/HTML Map.w"
;
for (x=x0; x<=x1; x++)
{
#line 710 "inform7/Chapter 34/HTML Map.w"
vector P = Geometry__vec(x, y, z);
INDEX("<td>");
PL__HTMLMap__begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
PL__HTMLMap__plot_map_cell(pass, P, 0, 0, 2);
if (icon_grid[ICON_GRID_POS(P, 0, 0)] & CONNECTIVE_BITMAP)
PL__HTMLMap__plot_map_icon("s_dot"); else PL__HTMLMap__plot_map_icon("ns_spacer");
PL__HTMLMap__plot_map_cell(pass, P, 1, 0, 8);
PL__HTMLMap__plot_map_cell(pass, P, 2, 0, 0);
PL__HTMLMap__plot_map_cell(pass, P, 3, 0, -1);
if (icon_grid[ICON_GRID_POS(P, 4, 0)] & CONNECTIVE_BITMAP)
PL__HTMLMap__plot_map_icon("s_dot"); else PL__HTMLMap__plot_map_icon("ns_spacer");
PL__HTMLMap__plot_map_cell(pass, P, 4, 0, 1);
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
}
#line 685 "inform7/Chapter 34/HTML Map.w"
;
if (with_numbering)
{
#line 829 "inform7/Chapter 34/HTML Map.w"
INDEX("<td>");
PL__HTMLMap__begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
}
#line 686 "inform7/Chapter 34/HTML Map.w"
INDEX("</tr>");
}
#line 676 "inform7/Chapter 34/HTML Map.w"
;
{
#line 692 "inform7/Chapter 34/HTML Map.w"
INDEX("<tr>");
if (with_numbering)
{
#line 846 "inform7/Chapter 34/HTML Map.w"
INDEX("<td>");
PL__HTMLMap__begin_map_table(MAP_CELL_SIZE, MAP_CELL_INNER_SIZE);
INDEX("<tr>");
INDEX("<td>");
INDEX("<font color=\"#%s\">", NUMBERING_TEXT_COLOUR);
#ifdef HTML_MAP_FONT_SIZE
INDEX("<font style=\"font-size:%dpx;\">", HTML_MAP_FONT_SIZE);
#endif
INDEX("<center><i>%d</i></center>", y-Universe.corner0.y+1);
#ifdef HTML_MAP_FONT_SIZE
INDEX("</font>");
#endif
INDEX("</font>");
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
}
#line 693 "inform7/Chapter 34/HTML Map.w"
;
for (x=x0; x<=x1; x++)
{
#line 732 "inform7/Chapter 34/HTML Map.w"
vector P = Geometry__vec(x, y, z);
INDEX("<td>");
PL__HTMLMap__begin_map_table(MAP_CELL_SIZE, MAP_CELL_INNER_SIZE);
INDEX("<tr>");
INDEX("<td>");
PL__HTMLMap__begin_variable_width_table();
INDEX("<tr>");
INDEX("<td>");
if (icon_grid[ICON_GRID_POS(P, 0, 0)] & CONNECTIVE_BITMAP)
PL__HTMLMap__plot_map_icon("e_dot"); else PL__HTMLMap__plot_map_icon("ew_spacer");
INDEX("<br>");
PL__HTMLMap__plot_map_cell(pass, P, 0, 1, 11);
INDEX("<br>");
PL__HTMLMap__plot_map_cell(pass, P, 0, 2, 7);
INDEX("<br>");
PL__HTMLMap__plot_map_cell(pass, P, 0, 3, -1);
INDEX("<br>");
if (icon_grid[ICON_GRID_POS(P, 0, 4)] & CONNECTIVE_BITMAP)
PL__HTMLMap__plot_map_icon("e_dot"); else PL__HTMLMap__plot_map_icon("ew_spacer");
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
{
#line 786 "inform7/Chapter 34/HTML Map.w"
INDEX("<td>");
int bits = (icon_grid[ICON_GRID_POS(P, 2, 2)]) & LONGS_BITMAP;
if (bits == 0)
PL__HTMLMap__index_room_square(room_grid[ROOM_GRID_POS(P)], pass);
else {
char icon_name[32];
sprintf(icon_name, "long");
if (bits & LONGEW_MAPBIT) strcat(icon_name, "_ew");
if (bits & LONGNS_MAPBIT) strcat(icon_name, "_ns");
if (bits & LONGSWNE_MAPBIT) strcat(icon_name, "_swne");
if (bits & LONGNWSE_MAPBIT) strcat(icon_name, "_nwse");
PL__HTMLMap__plot_map_icon(icon_name);
}
INDEX("</td>");
}
#line 756 "inform7/Chapter 34/HTML Map.w"
;
INDEX("<td>");
PL__HTMLMap__begin_map_table(MAP_CELL_OUTER_SIZE, MAP_CELL_INNER_SIZE);
INDEX("<tr>");
INDEX("<td>");
if (icon_grid[ICON_GRID_POS(P, 4, 0)] & CONNECTIVE_BITMAP)
PL__HTMLMap__plot_map_icon("w_dot"); else PL__HTMLMap__plot_map_icon("ew_spacer");
INDEX("<br>");
PL__HTMLMap__plot_map_cell(pass, P, 4, 1, -1);
INDEX("<br>");
PL__HTMLMap__plot_map_cell(pass, P, 4, 2, 6);
INDEX("<br>");
PL__HTMLMap__plot_map_cell(pass, P, 4, 3, 10);
INDEX("<br>");
if (icon_grid[ICON_GRID_POS(P, 4, 4)] & CONNECTIVE_BITMAP)
PL__HTMLMap__plot_map_icon("w_dot"); else PL__HTMLMap__plot_map_icon("ew_spacer");
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
}
#line 694 "inform7/Chapter 34/HTML Map.w"
;
if (with_numbering)
{
#line 846 "inform7/Chapter 34/HTML Map.w"
INDEX("<td>");
PL__HTMLMap__begin_map_table(MAP_CELL_SIZE, MAP_CELL_INNER_SIZE);
INDEX("<tr>");
INDEX("<td>");
INDEX("<font color=\"#%s\">", NUMBERING_TEXT_COLOUR);
#ifdef HTML_MAP_FONT_SIZE
INDEX("<font style=\"font-size:%dpx;\">", HTML_MAP_FONT_SIZE);
#endif
INDEX("<center><i>%d</i></center>", y-Universe.corner0.y+1);
#ifdef HTML_MAP_FONT_SIZE
INDEX("</font>");
#endif
INDEX("</font>");
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
}
#line 695 "inform7/Chapter 34/HTML Map.w"
;
INDEX("</tr>");
}
#line 677 "inform7/Chapter 34/HTML Map.w"
;
{
#line 701 "inform7/Chapter 34/HTML Map.w"
INDEX("<tr>");
if (with_numbering)
{
#line 829 "inform7/Chapter 34/HTML Map.w"
INDEX("<td>");
PL__HTMLMap__begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
}
#line 702 "inform7/Chapter 34/HTML Map.w"
for (x=x0; x<=x1; x++)
{
#line 804 "inform7/Chapter 34/HTML Map.w"
vector P = Geometry__vec(x, y, z);
INDEX("<td>");
PL__HTMLMap__begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
PL__HTMLMap__plot_map_cell(pass, P, 0, 4, 5);
if (icon_grid[ICON_GRID_POS(P, 0, 4)] & CONNECTIVE_BITMAP)
PL__HTMLMap__plot_map_icon("n_dot"); else PL__HTMLMap__plot_map_icon("ns_spacer");
PL__HTMLMap__plot_map_cell(pass, P, 1, 4, -1);
PL__HTMLMap__plot_map_cell(pass, P, 2, 4, 3);
PL__HTMLMap__plot_map_cell(pass, P, 3, 4, 9);
if (icon_grid[ICON_GRID_POS(P, 4, 4)] & CONNECTIVE_BITMAP)
PL__HTMLMap__plot_map_icon("n_dot"); else PL__HTMLMap__plot_map_icon("ns_spacer");
PL__HTMLMap__plot_map_cell(pass, P, 4, 4, 4);
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
}
#line 703 "inform7/Chapter 34/HTML Map.w"
;
if (with_numbering)
{
#line 829 "inform7/Chapter 34/HTML Map.w"
INDEX("<td>");
PL__HTMLMap__begin_map_table(MAP_CELL_SIZE, MAP_CELL_OUTER_SIZE);
INDEX("<tr>");
INDEX("<td>");
INDEX("</td>");
INDEX("</tr>");
PL__HTMLMap__end_map_table();
INDEX("</td>");
}
#line 704 "inform7/Chapter 34/HTML Map.w"
INDEX("</tr>");
}
#line 678 "inform7/Chapter 34/HTML Map.w"
;
}
#line 620 "inform7/Chapter 34/HTML Map.w"
;
}
PL__HTMLMap__end_map_table();
}
#line 869 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__plot_map_cell(int pass, vector P, int i1, int i2, int faux_exit) {
int bitmap = icon_grid[ICON_GRID_POS(P, i1, i2)];
if (pass == 2) bitmap &= CONNECTIVE_BITMAP;
if (bitmap == 0)
{
#line 879 "inform7/Chapter 34/HTML Map.w"
if ((i1 == 1) || (i1 == 3)) PL__HTMLMap__plot_map_icon("blank_ns");
else {
if ((i2 == 1) || (i2 == 3)) PL__HTMLMap__plot_map_icon("blank_ew");
else PL__HTMLMap__plot_map_icon("blank_square");
}
}
#line 872 "inform7/Chapter 34/HTML Map.w"
else
{
#line 888 "inform7/Chapter 34/HTML Map.w"
char icon_name[32];
char *addendum = "";
if (bitmap & DOOR2_MAPBIT) {
addendum = "_door";
if (bitmap & MEET_MAPBIT) addendum = "_door_meet";
}
if (bitmap & DOOR1_MAPBIT) addendum = "_door_blocked";
if (bitmap & CROSSDOOR_MAPBIT) addendum = "_corner_door";
if (bitmap & CROSSDOT_MAPBIT) addendum = "_dot";
if ((addendum[0] == 0) && (bitmap & FADING_MAPBIT)) addendum = "_fading";
int exit = exit_grid[ICON_GRID_POS(P, i1, i2)];
char *clue = PL__SpatialMap__find_icon_label(exit);
if (clue == NULL) clue = PL__SpatialMap__find_icon_label(faux_exit);
if (clue == NULL) clue = ""; /* should never happen */
sprintf(icon_name, "%s_arrow%s", clue, addendum);
TEMPORARY_STREAM;
char *tool_tip = NULL;
{
#line 914 "inform7/Chapter 34/HTML Map.w"
instance *D = NULL;
instance *I3 = PL__SpatialMap__room_exit(room_grid[ROOM_GRID_POS(P)], exit, &D);
if ((I3) || (D)) {
WRITE_TO(TEMP, "title=\"");
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
if (PL__Counting__instance_count(I, K_direction) == exit) {
Instances__write_name_for_index(TEMP, I);
break;
}
if (D) {
if (I3 == NULL) WRITE_TO(TEMP, " exit blocked by ");
else WRITE_TO(TEMP, " through ");
Instances__write_name_for_index(TEMP, D);
}
if (I3) {
WRITE_TO(TEMP, " to ");
Instances__write_name_for_index(TEMP, I3);
}
WRITE_TO(TEMP, "\"");
tool_tip = STREAM_TEXT(TEMP);
}
}
#line 906 "inform7/Chapter 34/HTML Map.w"
;
if (tool_tip) PL__HTMLMap__plot_map_icon_with_tip(icon_name, tool_tip);
else PL__HTMLMap__plot_map_icon(icon_name);
CLOSE_TEMPORARY_STREAM;
}
#line 873 "inform7/Chapter 34/HTML Map.w"
;
}
#line 948 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__index_room_square(instance *I, int pass) {
if (I) {
int b = ROOM_BORDER_SIZE;
if ((I == benchmark_room) && (pass == 1)) b = B_ROOM_BORDER_SIZE;
INDEX("<table border=\"%d\" cellpadding=\"0\" cellspacing=\"0\" ", b);
INDEX("bordercolor=\"#%s\" width=\"%d\" height=\"%d\"",
ROOM_BORDER_COLOUR, MAP_CELL_INNER_SIZE, MAP_CELL_INNER_SIZE);
INDEX(" title=\"");
Instances__write_name_for_index(ifl, I);
INDEX("\"><tr>");
INDEX("<td valign=\"middle\" align=\"center\" bgcolor=\"#%s\">",
PF_I(map, I)->world_index_colour);
char *col = ROOM_TEXT_COLOUR;
if (PF_I(map, I)->world_index_text_colour)
col = PF_I(map, I)->world_index_text_colour;
INDEX("<font size=2 color=\"#%s\">", col);
{
#line 974 "inform7/Chapter 34/HTML Map.w"
if (pass == 1)
INDEX("<a href=#wo_%d STYLE=\"text-decoration: none\"><font color=\"#%s\">",
I->allocation_id, col);
if ((pass == 1) && (I == benchmark_room)) INDEX("<b>");
char abbrev[ABBREV_ROOMS_TO+1];
{
#line 1005 "inform7/Chapter 34/HTML Map.w"
for (int i=0; i<ABBREV_ROOMS_TO+1; i++) abbrev[i] = 0;
wording W = Instances__get_name(I, FALSE);
if (Wordings__nonempty(W)) {
int c = 0;
LOOP_THROUGH_WORDING(i, W) {
if ((i > Wordings__first_wn(W)) && (i < Wordings__last_wn(W)) &&
(Preform__parse_nt_against_word_range(map_name_abbreviation_omission_words_NTM, Wordings__one_word(i), NULL, NULL))) continue;
char *p = Lexer__word_raw_text(i);
if (c < ABBREV_ROOMS_TO) abbrev[c++] = Platform__toupper(p[0]);
}
LOOP_THROUGH_WORDING(i, W) {
if ((i > Wordings__first_wn(W)) && (i < Wordings__last_wn(W)) &&
(Preform__parse_nt_against_word_range(map_name_abbreviation_omission_words_NTM, Wordings__one_word(i), NULL, NULL))) continue;
char *p = Lexer__word_raw_text(i);
int j;
for (j=1; p[j]; j++)
if ((p[j] != 'a') && (p[j] != 'e') && (p[j] != 'i') &&
(p[j] != 'o') && (p[j] != 'u'))
if (c < ABBREV_ROOMS_TO)
abbrev[c++] = p[j];
if ((c < ABBREV_ROOMS_TO) && (p[1])) abbrev[c++] = p[1];
}
}
}
#line 979 "inform7/Chapter 34/HTML Map.w"
;
#ifdef HTML_MAP_FONT_SIZE
INDEX("<font style=\"font-size:%dpx;\">", HTML_MAP_FONT_SIZE);
#endif
int i;
for (i=0; abbrev[i]; i++) HTML__html_char_out(ifl, abbrev[i]);
#ifdef HTML_MAP_FONT_SIZE
INDEX("</font>");
#endif
if ((pass == 1) && (I == benchmark_room)) INDEX("</b>");
if (pass == 1) INDEX("</font></a>");
}
#line 964 "inform7/Chapter 34/HTML Map.w"
;
INDEX("</font></td></tr></table>\n");
}
}
#line 997 "inform7/Chapter 34/HTML Map.w"
int map_name_abbreviation_omission_words_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 1001 "inform7/Chapter 34/HTML Map.w"
#line 1035 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__colour_chip(instance *I, instance *Reg, parse_node *at) {
INDEX("<table border=\"%d\" cellpadding=\"0\" cellspacing=\"0\" ", ROOM_BORDER_SIZE);
INDEX("bordercolor=\"#%s\" height=\"%d\">", ROOM_BORDER_COLOUR, MAP_CELL_INNER_SIZE);
INDEX("<tr><td valign=\"middle\" align=\"center\" bgcolor=\"#%s\"><font size=2>&nbsp;",
PF_I(map, Reg)->world_index_colour);
Instances__index_name(Reg); INDEX(" region");
if (at) Index__link(Wordings__first_wn(ParseTree__get_text(at)));
INDEX("&nbsp;</font></td></tr></table>\n");
}
#line 1050 "inform7/Chapter 34/HTML Map.w"
void PL__HTMLMap__add_region_key(void) {
instance *reg; int count = 0;
LOOP_OVER_INSTANCES(reg, K_region)
count += PL__HTMLMap__add_key_for(reg);
if (count > 0) count += PL__HTMLMap__add_key_for(NULL);
if (count > 0) INDEX("<hr>");
}
int PL__HTMLMap__add_key_for(instance *reg) {
int count = 0;
instance *R;
LOOP_OVER_ROOMS(R) {
if (PL__Regions__enclosing(R) == reg) {
if (count++ == 0) {
{
#line 1079 "inform7/Chapter 34/HTML Map.w"
INDEX("<p>");
HTML__begin_plain_html_table(ifl);
INDEX("<tr><td width=\"40\" valign=\"middle\" align=\"left\">");
PL__HTMLMap__index_room_square(R, 1);
INDEX("</td><td valign=\"middle\" align=\"left\">");
INDEX("<font %s>", DEFAULT_HTML_FONT);
INDEX("<b>");
wording W = Instances__get_name(reg, FALSE);
if (reg) Wordings__index_raw(W);
else INDEX("<i>Not in any region</i>");
INDEX("</b>: ");
}
#line 1064 "inform7/Chapter 34/HTML Map.w"
;
} else {
INDEX(", ");
}
wording W = Instances__get_name(R, FALSE);
Wordings__index_raw(W);
}
}
if (count > 0)
{
#line 1094 "inform7/Chapter 34/HTML Map.w"
HTML__end_html_row(ifl);
HTML__end_html_table(ifl);
INDEX("</p>");
}
#line 1072 "inform7/Chapter 34/HTML Map.w"
;
return count;
}
#line 158 "inform7/Chapter 34/EPS Map.w"
int PL__EPSMap__get_map_variable_index(char *name) {
int s = PL__EPSMap__get_map_variable_index_forgivingly(name);
if (s < 0) {
LOG("Tried to look up <%s>\n", name);
internal_error("looked up non-existent map variable");
s = 0;
}
return s;
}
int PL__EPSMap__get_map_variable_index_forgivingly(char *name) {
int s;
for (s=0; s<NO_MAP_PARAMETERS; s++)
if ((global_map_scope.values[s].name) &&
(strcmp(name, global_map_scope.values[s].name) == 0))
return s;
return -1;
}
#line 181 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__prepare_map_parameter_scope(map_parameter_scope *scope) {
int s;
scope->wider_scope = &global_map_scope;
for (s=0; s<NO_MAP_PARAMETERS; s++) {
scope->values[s].specified = FALSE;
scope->values[s].name = NULL;
scope->values[s].string_value = NULL;
scope->values[s].numeric_value = 0;
}
}
#line 199 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__put_mp(char *name, map_parameter_scope *scope, instance *scope_I,
kind *scope_k, char *put_string, int put_integer) {
if (scope_I) {
if (PL__Spatial__object_is_a_room(scope_I))
scope = PL__EPSMap__scope_for_single_room(scope_I);
else if (PL__Regions__object_is_a_region(scope_I)) {
instance *rm;
LOOP_OVER_INSTANCES(rm, K_room)
if (PL__EPSMap__obj_in_region(rm, scope_I))
PL__EPSMap__put_mp(name, NULL, rm, NULL, put_string, put_integer);
return;
} else return;
}
if (scope_k) {
instance *I;
LOOP_OVER_INSTANCES(I, scope_k)
PL__EPSMap__put_mp(name, NULL, I, NULL, put_string, put_integer);
return;
}
if (scope == NULL) scope = &global_map_scope;
if (strcmp(name, "room-colour") == 0) {
if (scope == &global_map_scope) changed_global_room_colour = TRUE;
if (scope_I) PF_I(map, scope_I)->world_index_colour = put_string;
}
if (strcmp(name, "room-name-colour") == 0)
if (scope_I) PF_I(map, scope_I)->world_index_text_colour = put_string;
if (put_string) PL__EPSMap__put_string_mp(name, scope, put_string);
else PL__EPSMap__put_int_mp(name, scope, put_integer);
}
map_parameter_scope *PL__EPSMap__scope_for_single_room(instance *rm) {
return &(PF_I(map, rm)->local_map_parameters);
}
int PL__EPSMap__obj_in_region(instance *I, instance *reg) {
if ((I == NULL) || (reg == NULL)) return FALSE;
if (PL__Regions__enclosing(I) == reg) return TRUE;
return PL__EPSMap__obj_in_region(PL__Regions__enclosing(I), reg);
}
#line 242 "inform7/Chapter 34/EPS Map.w"
char *PL__EPSMap__get_string_mp(char *name, map_parameter_scope *scope) {
int s = PL__EPSMap__get_map_variable_index(name);
char *p;
if (scope == NULL) scope = &global_map_scope;
while (scope->values[s].specified == FALSE) {
scope = scope->wider_scope;
if (scope == NULL) internal_error("scope exhausted in looking up map parameter");
}
p = scope->values[s].string_value;
if (strcmp(p, "<font>") == 0) return PL__EPSMap__get_string_mp("font", NULL);
return p;
}
void PL__EPSMap__put_string_mp(char *name, map_parameter_scope *scope, char *val) {
int s = PL__EPSMap__get_map_variable_index(name);
if (scope == NULL) scope = &global_map_scope;
scope->values[s].specified = TRUE;
scope->values[s].string_value = val;
}
#line 265 "inform7/Chapter 34/EPS Map.w"
int PL__EPSMap__get_int_mp(char *name, map_parameter_scope *scope) {
int s = PL__EPSMap__get_map_variable_index(name);
if (scope == NULL) scope = &global_map_scope;
while (scope->values[s].specified == FALSE) {
scope = scope->wider_scope;
if (scope == NULL) internal_error("scope exhausted in looking up map parameter");
}
return scope->values[s].numeric_value;
}
void PL__EPSMap__put_int_mp(char *name, map_parameter_scope *scope, int val) {
int s = PL__EPSMap__get_map_variable_index(name);
if (scope == NULL) scope = &global_map_scope;
scope->values[s].specified = TRUE;
scope->values[s].numeric_value = val;
}
#line 286 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__traverse_for_map_parameters(int pass) {
if (pass == 1) PL__SpatialMap__initialise_page_directions();
ParseTree__traverse_int(PL__EPSMap__look_for_map_parameters, &pass);
}
void PL__EPSMap__look_for_map_parameters(parse_node *p, int *pass) {
if ((ParseTree__get_type(p) == SENTENCE_NT)
&& (p->down)
&& (ParseTree__int_annotation(p->down, verb_id_ANNOT) == MAP_PARAMETER_VB)
&& (p->down->next)) {
PL__EPSMap__new_map_hint_sentence(*pass, p->down->next);
}
}
#line 304 "inform7/Chapter 34/EPS Map.w"
int direction_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1]; if (Instances__of_kind(RP[1], K_direction) == FALSE) return FALSE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 306 "inform7/Chapter 34/EPS Map.w"
#line 316 "inform7/Chapter 34/EPS Map.w"
int index_map_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = EPSFILE_IMW;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = MAPPED_AS_IMW; instance_x_NTMV = RP[1]; instance_y_NTMV = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 336 "inform7/Chapter 34/EPS Map.w"
*X = NO_IMW;
if (index_map_with_pass == 1) {
Problems__Issue__map_problem(_p_(PM_MapDirectionClue),
index_map_with_p, "You can only say 'Index map with D mapped as E.' "
"when D and E are directions.");
}
}
#line 319 "inform7/Chapter 34/EPS Map.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = MAPPED_IMW; instance_x_NTMV = RP[1]; instance_y_NTMV = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 346 "inform7/Chapter 34/EPS Map.w"
*X = NO_IMW;
if (index_map_with_pass == 1) {
Problems__Issue__map_problem(_p_(PM_MapPlacement),
index_map_with_p, "The map placement hint should either have the form 'Index map with X "
"mapped east of Y' or 'Index map with X mapped above/below Y'.");
}
}
#line 321 "inform7/Chapter 34/EPS Map.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = SETTING_IMW; scoping_NTMV = R[1]; if (R[1] == NO_IMW) *X = NO_IMW; msvtype_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 356 "inform7/Chapter 34/EPS Map.w"
*X = NO_IMW;
if (index_map_with_pass == 1) {
Problems__Issue__map_problem(_p_(PM_MapSettingTooLong),
index_map_with_p, "The value supplied has to be a single item, a number, a word "
"or some text in double-quotes: this looks too long to be right.");
}
}
#line 323 "inform7/Chapter 34/EPS Map.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7:
{
#line 366 "inform7/Chapter 34/EPS Map.w"
*X = NO_IMW;
{
#line 701 "inform7/Chapter 34/EPS Map.w"
if (index_map_with_pass == 1) {
Problems__Issue__map_problem(_p_(PM_MapSettingOfUnknown),
index_map_with_p, "The parameter has to be 'of' either 'the first room' "
"or a specific named room (beware ambiguities!) or "
"a level such as 'level 0' (the first room is by "
"definition on level 0), or a region, or a kind of room.");
}
}
#line 367 "inform7/Chapter 34/EPS Map.w"
;
}
#line 324 "inform7/Chapter 34/EPS Map.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = RUBRIC_IMW;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9:
{
#line 372 "inform7/Chapter 34/EPS Map.w"
*X = NO_IMW;
if (index_map_with_pass == 2) {
Problems__Issue__map_problem(_p_(PM_MapHintUnknown),
index_map_with_p, "The general form for this is 'Index map with ...' and then a "
"list of clues, such as 'the Ballroom mapped east of the Terrace', "
"or 'room-size of the Ballroom set to 100'.");
}
}
#line 326 "inform7/Chapter 34/EPS Map.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 327 "inform7/Chapter 34/EPS Map.w"
int map_positioning_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; instance_dir_NTMV = RP[1]; *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE; instance_dir_NTMV = I_up; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; instance_dir_NTMV = I_down; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 332 "inform7/Chapter 34/EPS Map.w"
#line 388 "inform7/Chapter 34/EPS Map.w"
int map_setting_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[2]; char_partext_NTMV = RP[1]; parindex_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = ENTIRE_MAP_SCOPE; char_partext_NTMV = RP[1]; parindex_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 426 "inform7/Chapter 34/EPS Map.w"
*X = NO_IMW;
if (index_map_with_pass == 1) {
Problems__Issue__map_problem(_p_(PM_MapSettingUnknown),
index_map_with_p, "The parameter has to be one of the fixed named set given in "
"the documentation, like 'room-name'. All parameters are one "
"word, but many are hyphenated. (Also, note that 'colour' has the "
"Canadian/English spelling, not the American one 'color'.)");
}
}
#line 391 "inform7/Chapter 34/EPS Map.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 392 "inform7/Chapter 34/EPS Map.w"
int map_setting_scope_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 396 "inform7/Chapter 34/EPS Map.w"
int map_setting_scope_unarticled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FIRST_ROOM_MAP_SCOPE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = LEVEL_MAP_SCOPE; level_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = KIND_MAP_SCOPE; kind_kscope_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = INSTANCE_MAP_SCOPE; instance_iscope_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 402 "inform7/Chapter 34/EPS Map.w"
#line 411 "inform7/Chapter 34/EPS Map.w"
int map_parameter_NTMR(wording W, int *X, void **XP) {
#line 412 "inform7/Chapter 34/EPS Map.w"
int i;
char *parameter_name = Lexer__word_text(Wordings__first_wn(W));
if ((Wordings__length(W) == 1) &&
((i = PL__EPSMap__get_map_variable_index_forgivingly(parameter_name))>=0)) {
*X = i;
*XP = parameter_name;
return TRUE;
}
return FALSE;
}
#line 440 "inform7/Chapter 34/EPS Map.w"
int map_setting_value_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = INT_MDT; msvalue_NTMV = R[1]; msword_NTMV = Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TEXT_MDT; msvalue_NTMV = R[1]; msword_NTMV = Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = BOOL_MDT; msvalue_NTMV = R[1]; msword_NTMV = Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = OFF_MDT; msvalue_NTMV = R[1]; msword_NTMV = Wordings__first_wn(W); if (R[1] == ERRONEOUS_OFFSET_VALUE) return FALSE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = -1; msword_NTMV = Wordings__first_wn(W); /* leads to a problem message later */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 446 "inform7/Chapter 34/EPS Map.w"
int map_setting_boolean_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 450 "inform7/Chapter 34/EPS Map.w"
#line 457 "inform7/Chapter 34/EPS Map.w"
int map_offset_NTMR(wording W, int *X, void **XP) {
#line 458 "inform7/Chapter 34/EPS Map.w"
*X = PL__EPSMap__parse_eps_map_offset(Lexer__word_text(Wordings__first_wn(W)));
return TRUE;
}
#line 467 "inform7/Chapter 34/EPS Map.w"
int map_rubric_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = RUBRIC_SIZE; rsize_NTMV = R[1]; edge_NTMV = Wordings__first_wn(map_rubric_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = RUBRIC_FONT; rfont_NTMV = R[1]; edge_NTMV = Wordings__first_wn(map_rubric_NTM->range_result[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = RUBRIC_COLOUR; rcol_NTMV = R[1]; edge_NTMV = Wordings__first_wn(map_rubric_NTM->range_result[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = RUBRIC_OFFSET; roff_NTMV = R[1]; edge_NTMV = Wordings__first_wn(map_rubric_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = RUBRIC_POSITION; roff_NTMV = R[1]; edge_NTMV = Wordings__first_wn(map_rubric_NTM->range_result[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 473 "inform7/Chapter 34/EPS Map.w"
#line 495 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__new_map_hint_sentence(int pass, parse_node *p) {
if (ParseTree__get_type(p) == AND_NT) {
PL__EPSMap__new_map_hint_sentence(pass, p->down);
PL__EPSMap__new_map_hint_sentence(pass, p->down->next);
return;
}
current_sentence = p;
index_map_with_pass = pass;
index_map_with_p = p;
/* the following take effect on pass 1 */
Preform__parse_nt_against_word_range(index_map_sentence_subject_NTM, ParseTree__get_text(p), NULL, NULL);
switch (most_recent_result) {
case EPSFILE_IMW: if (pass == 1) write_EPS_format_map = TRUE;
break;
case MAPPED_AS_IMW:
{
#line 526 "inform7/Chapter 34/EPS Map.w"
if (pass == 1)
PL__SpatialMap__map_direction_as_if(instance_x_NTMV, instance_y_NTMV);
}
#line 510 "inform7/Chapter 34/EPS Map.w"
;
break;
case MAPPED_IMW:
{
#line 532 "inform7/Chapter 34/EPS Map.w"
if (Instances__of_kind(instance_dir_NTMV, K_direction) == FALSE) {
if (pass == 1) Problems__Issue__map_problem(_p_(PM_MapPlacementDirection),
p, "The direction given as a hint for map placement wasn't "
"one that I know of.");
return;
}
instance *I = instance_x_NTMV;
instance *I2 = instance_y_NTMV;
int exit = PF_I(map, instance_dir_NTMV)->direction_index;
if ((I == NULL) || (PL__Spatial__object_is_a_room(I) == FALSE)) {
if (pass == 1) Problems__Issue__map_problem(_p_(PM_MapFromNonRoom),
p, "The first-named thing must be a room (beware ambiguities!).");
return;
}
if ((I2 == NULL) || (PL__Spatial__object_is_a_room(I2) == FALSE)) {
if (pass == 1) Problems__Issue__map_problem(_p_(PM_MapToNonRoom),
p, "The second-named thing must be a room (beware ambiguities!).");
return;
}
if (PL__SpatialMap__direction_is_lateral(exit) == FALSE) {
if (pass == 1) Problems__Issue__map_problem(_p_(PM_MapNonLateral),
p, "The direction given as a hint for map placement must be "
"a lateral direction (not up, down, above, below, inside "
"or outside).");
return;
}
if (pass == 1) PL__SpatialMap__lock_exit_in_place(I, exit, I2);
}
#line 512 "inform7/Chapter 34/EPS Map.w"
;
break;
case SETTING_IMW:
{
#line 636 "inform7/Chapter 34/EPS Map.w"
int allow_on_pass_2 = FALSE;
map_parameter_scope *scope = NULL;
instance *scope_I = NULL;
kind *scope_k = NULL;
{
#line 649 "inform7/Chapter 34/EPS Map.w"
int bad_scope = FALSE;
switch (scoping_NTMV) {
case FIRST_ROOM_MAP_SCOPE:
if (benchmark_room) scope_I = benchmark_room;
break;
case LEVEL_MAP_SCOPE:
if (pass == 1) return; /* we'll pick this up on pass 2 when levels exist */
allow_on_pass_2 = TRUE;
int ln = level_NTMV;
EPS_map_level *eml;
LOOP_OVER(eml, EPS_map_level)
if ((eml->contains_rooms)
&& (eml->map_level - Room_position(benchmark_room).z == ln))
scope = &(eml->map_parameters);
if (scope == NULL) {
Problems__Issue__map_problem(_p_(PM_MapLevelMisnamed),
p, "Layers of the map must be called 'level N', where "
"N is a number, and level 0 is the one which contains "
"the first room.");
return;
}
break;
case KIND_MAP_SCOPE:
scope_k = kind_kscope_NTMV;
if (Kinds__Compare__lt(scope_k, K_object) == FALSE) scope_k = NULL;
if ((scope_k) &&
((Kinds__Compare__le(scope_k, K_room)) ||
(Kinds__Compare__le(scope_k, K_region)))) {
LOGIF(SPATIAL_MAP, "Setting for kind $u\n", scope_k);
} else bad_scope = TRUE;
break;
case INSTANCE_MAP_SCOPE:
if ((PL__Spatial__object_is_a_room(instance_iscope_NTMV)) ||
(PL__Regions__object_is_a_region(instance_iscope_NTMV)))
scope_I = instance_iscope_NTMV;
if (scope_I) {
LOGIF(SPATIAL_MAP, "Setting for object $O\n", scope_I);
} else bad_scope = TRUE;
break;
case ENTIRE_MAP_SCOPE:
scope_k = K_room;
break;
}
if (bad_scope) {
{
#line 701 "inform7/Chapter 34/EPS Map.w"
if (index_map_with_pass == 1) {
Problems__Issue__map_problem(_p_(PM_MapSettingOfUnknown),
index_map_with_p, "The parameter has to be 'of' either 'the first room' "
"or a specific named room (beware ambiguities!) or "
"a level such as 'level 0' (the first room is by "
"definition on level 0), or a region, or a kind of room.");
}
}
#line 694 "inform7/Chapter 34/EPS Map.w"
;
return;
}
}
#line 640 "inform7/Chapter 34/EPS Map.w"
;
if ((allow_on_pass_2 == FALSE) && (pass == 2)) return;
char *parameter_name = char_partext_NTMV;
int index_of_parameter = parindex_NTMV;
{
#line 712 "inform7/Chapter 34/EPS Map.w"
int type_wanted = global_map_scope.values[index_of_parameter].parameter_data_type;
int type_found = msvtype_NTMV;
char *i_wanted_a = "";
int wn = msword_NTMV;
switch(type_wanted) {
case INT_MDT: i_wanted_a = "an integer";
if (type_found == INT_MDT) {
PL__EPSMap__put_mp(parameter_name, scope, scope_I, scope_k, NULL, msvalue_NTMV);
return;
}
break;
case OFF_MDT: i_wanted_a = "an offset in the form 34&-450";
if (type_found == OFF_MDT) {
PL__EPSMap__put_mp(parameter_name, scope, scope_I, scope_k, NULL, msvalue_NTMV);
return;
}
break;
case BOOL_MDT: i_wanted_a = "'on' or 'off'";
if (type_found == BOOL_MDT) {
PL__EPSMap__put_mp(parameter_name, scope, scope_I, scope_k, NULL, msvalue_NTMV);
return;
}
break;
case TEXT_MDT: i_wanted_a = "some text in double-quotes";
if (type_found == TEXT_MDT) {
Text__dequote_word(wn);
PL__EPSMap__put_mp(parameter_name, scope, scope_I, scope_k, Lexer__word_text(wn), 0);
return;
}
break;
case FONT_MDT: i_wanted_a = "a font name in double-quotes";
if (type_found == TEXT_MDT) {
Text__dequote_word(wn);
PL__EPSMap__put_mp(parameter_name, scope, scope_I, scope_k, Lexer__word_text(wn), 0);
return;
}
break;
case COL_MDT: i_wanted_a = "a colour name in double-quotes";
if (type_found == TEXT_MDT) {
Text__dequote_word(wn);
char *col = HTML__translate_colour_name(Lexer__word_text(wn));
if (col) {
PL__EPSMap__put_mp(parameter_name, scope, scope_I, scope_k, col, 0);
return;
}
}
break;
default: internal_error("Unexpected map parameter data type");
}
if (pass == 1) Problems__Issue__map_problem_wanted_but(_p_(PM_MapSettingTypeFailed),
p, i_wanted_a, wn);
}
#line 644 "inform7/Chapter 34/EPS Map.w"
;
}
#line 514 "inform7/Chapter 34/EPS Map.w"
;
break;
case RUBRIC_IMW:
if (pass == 2)
{
#line 565 "inform7/Chapter 34/EPS Map.w"
wording RW = GET_RW(index_map_sentence_subject_NTM, 1);
wording RESTW = GET_RW(index_map_sentence_subject_NTM, 2);
Text__dequote_word(Wordings__first_wn(RW));
rubric_holder *rh = CREATE(rubric_holder);
rh->annotation = Lexer__word_text(Wordings__first_wn(RW));
rh->point_size = 12; /* 12-point type */
rh->font = "<font>"; /* meaning the default font */
rh->colour = "000000"; /* black */
rh->at_offset = 10001; /* the offset $(1, 1)$ */
rh->offset_from = NULL;
int i = Wordings__first_wn(RESTW);
while (i <= Wordings__last_wn(RESTW)) {
if (Preform__parse_nt_against_word_range(map_rubric_NTM, Wordings__from(RESTW, i), NULL, NULL)) {
i = edge_NTMV;
switch (most_recent_result) {
case RUBRIC_SIZE:
rh->point_size = rsize_NTMV;
break;
case RUBRIC_FONT:
Text__dequote_word(rfont_NTMV);
rh->font = Lexer__word_text(rfont_NTMV);
break;
case RUBRIC_COLOUR:
{
#line 604 "inform7/Chapter 34/EPS Map.w"
char *thec;
Text__dequote_word(rcol_NTMV);
thec = HTML__translate_colour_name(Lexer__word_text(rcol_NTMV));
if (thec == NULL) {
Problems__Issue__map_problem(_p_(PM_MapUnknownColour), p, "There's no such map colour.");
return;
}
rh->colour = thec;
}
#line 588 "inform7/Chapter 34/EPS Map.w"
; break;
case RUBRIC_OFFSET:
case RUBRIC_POSITION:
{
#line 616 "inform7/Chapter 34/EPS Map.w"
if (roff_NTMV == ERRONEOUS_OFFSET_VALUE) {
Problems__Issue__map_problem(_p_(PM_MapUnknownOffset), p, "There's no such offset.");
return;
}
rh->at_offset = roff_NTMV;
if (most_recent_result == RUBRIC_OFFSET) {
instance *I = Instances__parse_object(Wordings__from(ParseTree__get_text(p), i));
i = Wordings__last_wn(RESTW) + 1;
if (I == NULL) {
Problems__Issue__map_problem(_p_(PM_MapUnknownOffsetBase),
p, "There's no such room to be offset from.");
return;
}
rh->offset_from = I;
}
}
#line 591 "inform7/Chapter 34/EPS Map.w"
; break;
}
} else {
Problems__Issue__map_problem(_p_(PM_MapBadRubric),
p, "Unfortunately the details of that rubric seem to be "
"in error (a lame message, but an accurate one).");
break;
}
}
}
#line 518 "inform7/Chapter 34/EPS Map.w"
;
break;
}
}
#line 773 "inform7/Chapter 34/EPS Map.w"
int PL__EPSMap__parse_eps_map_offset(char *original) {
char offs[32];
if (Platform__strlen(original) >= 30) return ERRONEOUS_OFFSET_VALUE;
strcpy(offs, original);
int j, k=-1, start = TRUE;
for (j=0; offs[j]; j++) {
if (isdigit(offs[j])) { start = FALSE; continue; }
if ((offs[j] == '&') && (start == FALSE) && (k<0)) {
start = TRUE; offs[j] = 0; k=j+1; continue;
}
if ((offs[j] == '-') && (start)) { start = FALSE; continue; }
return ERRONEOUS_OFFSET_VALUE;
}
if (k<0) return ERRONEOUS_OFFSET_VALUE;
char *xstr = offs, *ystr = offs+k;
int xsign = 1, ysign = 1;
if (xstr[0] == '-') { xsign = -1; xstr++; }
if (ystr[0] == '-') { ysign = -1; ystr++; }
int xl = Platform__strlen(xstr), yl = Platform__strlen(ystr);
if ((xl == 0) || (xl > 4) || (yl == 0) || (yl > 4)) return ERRONEOUS_OFFSET_VALUE;
int xbit = atoi(offs), ybit = atoi(offs+k);
return xsign*xbit + ysign*ybit*10000;
}
#line 800 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__render_map_as_EPS(void) {
{
#line 816 "inform7/Chapter 34/EPS Map.w"
EPS_map_level *main_eml = CREATE(EPS_map_level);
main_eml->width = PL__EPSMap__get_int_mp("minimum-map-width", NULL);
main_eml->actual_height = 0;
main_eml->titling_point_size = PL__EPSMap__get_int_mp("title-size", NULL);
strcpy(main_eml->titling, "Map");
main_eml->contains_titling = TRUE;
main_eml->contains_rooms = FALSE;
PL__EPSMap__prepare_map_parameter_scope(&(main_eml->map_parameters));
PL__EPSMap__put_string_mp("title", &(main_eml->map_parameters), main_eml->titling);
}
#line 801 "inform7/Chapter 34/EPS Map.w"
;
int z;
for (z=Universe.corner1.z; z>=Universe.corner0.z; z--)
{
#line 829 "inform7/Chapter 34/EPS Map.w"
EPS_map_level *eml = CREATE(EPS_map_level);
eml->contains_rooms = TRUE;
eml->map_level = z;
eml->y_max = -100000, eml->y_min = 100000;
instance *R;
LOOP_OVER_ROOMS(R)
if (Room_position(R).z == z) {
if (Room_position(R).y < eml->y_min) eml->y_min = Room_position(R).y;
if (Room_position(R).y > eml->y_max) eml->y_max = Room_position(R).y;
}
strcpy(eml->titling, "");
char *level_rubric = "Map"; int par = 0;
PL__HTMLMap__devise_level_rubric(z, &level_rubric, &par);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-nonliteral"
sprintf(eml->titling, level_rubric, par);
#pragma clang diagnostic pop
if (strcmp(eml->titling, "") == 0) eml->contains_titling = FALSE;
else eml->contains_titling = TRUE;
PL__EPSMap__prepare_map_parameter_scope(&(eml->map_parameters));
PL__EPSMap__put_string_mp("subtitle", &(eml->map_parameters), eml->titling);
LOOP_OVER_ROOMS(R)
if (Room_position(R).z == z) {
PF_I(map, R)->local_map_parameters.wider_scope = &(eml->map_parameters);
}
}
#line 804 "inform7/Chapter 34/EPS Map.w"
;
PL__EPSMap__traverse_for_map_parameters(2);
if (changed_global_room_colour == FALSE)
{
#line 863 "inform7/Chapter 34/EPS Map.w"
instance *R;
LOOP_OVER_ROOMS(R)
PL__EPSMap__put_string_mp("room-colour", &(PF_I(map, R)->local_map_parameters),
PF_I(map, R)->world_index_colour);
}
#line 808 "inform7/Chapter 34/EPS Map.w"
;
if (write_EPS_format_map)
{
#line 871 "inform7/Chapter 34/EPS Map.w"
text_stream EPS_struct; text_stream *EPS = &EPS_struct;
if (STREAM_OPEN_TO_FILE(EPS, filename_of_epsfile, ISO_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open EPS map file", filename_of_epsfile);
PL__EPSMap__EPS_compile_map(EPS);
STREAM_CLOSE(EPS);
}
#line 810 "inform7/Chapter 34/EPS Map.w"
;
}
#line 880 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_map(OUTPUT_STREAM) {
int blh, /* total height of the EPS map area (not counting border) */
blw, /* total width of the EPS map area (not counting border) */
border = PL__EPSMap__get_int_mp("border-size", NULL),
vskip = PL__EPSMap__get_int_mp("vertical-spacing", NULL);
{
#line 923 "inform7/Chapter 34/EPS Map.w"
int total_chunk_height = 0, max_chunk_width = 0;
EPS_map_level *eml;
LOOP_BACKWARDS_OVER(eml, EPS_map_level) {
map_parameter_scope *level_scope = &(eml->map_parameters);
int mapunit = PL__EPSMap__get_int_mp("grid-size", level_scope);
int p = PL__EPSMap__get_int_mp("title-size", level_scope);
if (eml->contains_rooms) p = PL__EPSMap__get_int_mp("subtitle-size", level_scope);
eml->titling_point_size = p;
eml->width = (Universe.corner1.x-Universe.corner0.x+2)*mapunit;
if (eml->allocation_id == 0) eml->actual_height = 0;
else eml->actual_height = (eml->y_max-eml->y_min+1)*mapunit;
eml->eps_origin = total_chunk_height + border;
eml->height = eml->actual_height + vskip;
if (eml->contains_rooms) eml->height += vskip;
if (eml->contains_titling) eml->height += eml->titling_point_size+vskip;
total_chunk_height += eml->height;
if (max_chunk_width < eml->width) max_chunk_width = eml->width;
}
blh = total_chunk_height;
blw = max_chunk_width;
}
#line 885 "inform7/Chapter 34/EPS Map.w"
;
int bounding_box_width = blw+2*border, bounding_box_height = blh+2*border;
PL__EPSMap__EPS_compile_header(OUT, bounding_box_width, bounding_box_height,
PL__EPSMap__get_string_mp("title-font", NULL), PL__EPSMap__get_int_mp("title-size", NULL));
if (PL__EPSMap__get_int_mp("map-outline", NULL))
{
#line 948 "inform7/Chapter 34/EPS Map.w"
WRITE("newpath %% Ruled outline outer box of map\n");
PL__EPSMap__EPS_compile_rectangular_path(OUT, border, border, border+blw, border+blh);
WRITE("stroke\n");
}
#line 892 "inform7/Chapter 34/EPS Map.w"
;
EPS_map_level *eml;
LOOP_OVER(eml, EPS_map_level) {
map_parameter_scope *level_scope = &(eml->map_parameters);
int mapunit = PL__EPSMap__get_int_mp("grid-size", level_scope);
if (eml->contains_rooms == FALSE)
if (PL__EPSMap__get_int_mp("map-outline", NULL))
{
#line 956 "inform7/Chapter 34/EPS Map.w"
WRITE("newpath %% Ruled horizontal line\n");
PL__EPSMap__EPS_compile_horizontal_line_path(OUT, border, blw+border, eml->eps_origin);
WRITE("stroke\n");
}
#line 900 "inform7/Chapter 34/EPS Map.w"
;
if (eml->contains_titling)
{
#line 963 "inform7/Chapter 34/EPS Map.w"
int y = eml->eps_origin + vskip + eml->actual_height;
if (eml->contains_rooms) {
if (PL__EPSMap__get_int_mp("monochrome", level_scope)) PL__EPSMap__EPS_compile_set_greyscale(OUT, 0);
else PL__EPSMap__EPS_compile_set_colour(OUT, PL__EPSMap__get_string_mp("subtitle-colour", level_scope));
PL__EPSMap__plot_text_at(OUT,
PL__EPSMap__get_string_mp("subtitle", level_scope),
NULL, 128,
PL__EPSMap__get_string_mp("subtitle-font", level_scope),
border*2, y+vskip,
PL__EPSMap__get_int_mp("subtitle-size", level_scope),
FALSE, FALSE);
} else {
if (PL__EPSMap__get_int_mp("monochrome", level_scope)) PL__EPSMap__EPS_compile_set_greyscale(OUT, 0);
else PL__EPSMap__EPS_compile_set_colour(OUT, PL__EPSMap__get_string_mp("title-colour", level_scope));
PL__EPSMap__plot_text_at(OUT,
PL__EPSMap__get_string_mp("title", NULL),
NULL, 128,
PL__EPSMap__get_string_mp("title-font", level_scope),
border*2, y+2*vskip,
PL__EPSMap__get_int_mp("title-size", level_scope),
FALSE, TRUE);
}
}
#line 902 "inform7/Chapter 34/EPS Map.w"
;
if (eml->contains_rooms) {
instance *R;
LOOP_OVER_ROOMS(R)
if (Room_position(R).z == eml->map_level)
{
#line 989 "inform7/Chapter 34/EPS Map.w"
map_parameter_scope *room_scope = &(PF_I(map, R)->local_map_parameters);
int bx = Room_position(R).x-Universe.corner0.x;
int by = Room_position(R).y-eml->y_min;
int offs = PL__EPSMap__get_int_mp("room-offset", room_scope);
int xpart = offs%10000, ypart = offs/10000;
while (xpart > 5000) xpart-=10000;
while (xpart < -5000) xpart+=10000;
bx = (bx)*mapunit + border + mapunit/2;
by = (by)*mapunit + eml->eps_origin + vskip + mapunit/2;
bx += xpart*mapunit/100;
by += ypart*mapunit/100;
PF_I(map, R)->eps_x = bx;
PF_I(map, R)->eps_y = by;
}
#line 907 "inform7/Chapter 34/EPS Map.w"
;
LOOP_OVER_ROOMS(R)
if (Room_position(R).z == eml->map_level)
{
#line 1009 "inform7/Chapter 34/EPS Map.w"
map_parameter_scope *room_scope = &(PF_I(map, R)->local_map_parameters);
PL__EPSMap__EPS_compile_line_width_setting(OUT, PL__EPSMap__get_int_mp("route-thickness", room_scope));
int bx = PF_I(map, R)->eps_x;
int by = PF_I(map, R)->eps_y;
int boxsize = PL__EPSMap__get_int_mp("room-size", room_scope)/2;
int R_stiffness = PL__EPSMap__get_int_mp("route-stiffness", room_scope);
int dir;
LOOP_OVER_STORY_DIRECTIONS(dir) {
instance *T = PL__SpatialMap__room_exit(R, dir, NULL);
int exit = story_dir_to_page_dir[dir];
if (PL__Spatial__object_is_a_room(T))
{
#line 1028 "inform7/Chapter 34/EPS Map.w"
int T_stiffness = PL__EPSMap__get_int_mp("route-stiffness", &(PF_I(map, T)->local_map_parameters));
if (PL__EPSMap__get_int_mp("monochrome", level_scope)) PL__EPSMap__EPS_compile_set_greyscale(OUT, 0);
else PL__EPSMap__EPS_compile_set_colour(OUT, PL__EPSMap__get_string_mp("route-colour", level_scope));
if ((Room_position(T).z == Room_position(R).z) &&
(PL__SpatialMap__room_exit(T, PL__SpatialMap__opposite(dir), FALSE) == R))
{
#line 1041 "inform7/Chapter 34/EPS Map.w"
if (R->allocation_id <= T->allocation_id)
PL__EPSMap__EPS_compile_Bezier_curve(OUT,
R_stiffness*mapunit, T_stiffness*mapunit,
bx, by, exit,
PF_I(map, T)->eps_x, PF_I(map, T)->eps_y, PL__SpatialMap__opposite(exit));
}
#line 1033 "inform7/Chapter 34/EPS Map.w"
else
{
#line 1051 "inform7/Chapter 34/EPS Map.w"
int scaled = 1;
vector E = PL__SpatialMap__direction_as_vector(exit);
switch(exit) {
case 8: E = U_vector_EPS; scaled = 2; break;
case 9: E = D_vector_EPS; scaled = 2; break;
case 10: E = IN_vector_EPS; scaled = 2; break;
case 11: E = OUT_vector_EPS; scaled = 2; break;
}
PL__EPSMap__EPS_compile_dashed_arrow(OUT, boxsize/scaled, E, bx, by);
PL__EPSMap__plot_text_at(OUT, NULL, T,
PL__EPSMap__get_int_mp("annotation-length", NULL),
PL__EPSMap__get_string_mp("annotation-font", NULL),
bx+E.x*boxsize*6/scaled/5, by+E.y*boxsize*6/scaled/5,
PL__EPSMap__get_int_mp("annotation-size", NULL),
TRUE, TRUE);
}
#line 1035 "inform7/Chapter 34/EPS Map.w"
;
}
#line 1021 "inform7/Chapter 34/EPS Map.w"
;
}
PL__EPSMap__EPS_compile_line_width_unsetting(OUT);
}
#line 910 "inform7/Chapter 34/EPS Map.w"
;
LOOP_OVER_ROOMS(R)
if (Room_position(R).z == eml->map_level)
{
#line 1070 "inform7/Chapter 34/EPS Map.w"
map_parameter_scope *room_scope = &(PF_I(map, R)->local_map_parameters);
int bx = PF_I(map, R)->eps_x;
int by = PF_I(map, R)->eps_y;
int boxsize = PL__EPSMap__get_int_mp("room-size", room_scope)/2;
{
#line 1081 "inform7/Chapter 34/EPS Map.w"
WRITE("newpath %% Room interior\n");
if (PL__EPSMap__get_int_mp("monochrome", room_scope)) PL__EPSMap__EPS_compile_set_greyscale(OUT, 75);
else PL__EPSMap__EPS_compile_set_colour(OUT, PL__EPSMap__get_string_mp("room-colour", room_scope));
PL__EPSMap__EPS_compile_room_boundary_path(OUT, bx, by, boxsize, PL__EPSMap__get_string_mp("room-shape", room_scope));
WRITE("fill\n\n");
}
#line 1074 "inform7/Chapter 34/EPS Map.w"
;
{
#line 1090 "inform7/Chapter 34/EPS Map.w"
if (PL__EPSMap__get_int_mp("room-outline", room_scope)) {
PL__EPSMap__EPS_compile_line_width_setting(OUT, PL__EPSMap__get_int_mp("room-outline-thickness", room_scope));
WRITE("newpath %% Room outline\n");
if (PL__EPSMap__get_int_mp("monochrome", level_scope)) PL__EPSMap__EPS_compile_set_greyscale(OUT, 0);
else PL__EPSMap__EPS_compile_set_colour(OUT, PL__EPSMap__get_string_mp("room-outline-colour", room_scope));
PL__EPSMap__EPS_compile_room_boundary_path(OUT, bx, by, boxsize, PL__EPSMap__get_string_mp("room-shape", room_scope));
WRITE("stroke\n");
PL__EPSMap__EPS_compile_line_width_unsetting(OUT);
}
}
#line 1075 "inform7/Chapter 34/EPS Map.w"
;
{
#line 1103 "inform7/Chapter 34/EPS Map.w"
int offs = PL__EPSMap__get_int_mp("room-name-offset", room_scope);
int xpart = offs%10000, ypart = offs/10000;
while (xpart > 5000) xpart-=10000;
while (xpart < -5000) xpart+=10000;
bx += xpart*mapunit/100;
by += ypart*mapunit/100;
if (PL__EPSMap__get_int_mp("monochrome", level_scope)) PL__EPSMap__EPS_compile_set_greyscale(OUT, 0);
else PL__EPSMap__EPS_compile_set_colour(OUT, PL__EPSMap__get_string_mp("room-name-colour", room_scope));
char *legend = PL__EPSMap__get_string_mp("room-name", room_scope);
instance *room_to_name = NULL;
if (strcmp(legend, "") == 0) { room_to_name = R; legend = NULL; }
PL__EPSMap__plot_text_at(OUT, legend, room_to_name,
PL__EPSMap__get_int_mp("room-name-length", room_scope),
PL__EPSMap__get_string_mp("room-name-font", room_scope),
bx, by, PL__EPSMap__get_int_mp("room-name-size", room_scope),
TRUE, TRUE);
}
#line 1076 "inform7/Chapter 34/EPS Map.w"
;
}
#line 913 "inform7/Chapter 34/EPS Map.w"
;
}
}
{
#line 1124 "inform7/Chapter 34/EPS Map.w"
rubric_holder *rh;
LOOP_OVER(rh, rubric_holder) {
int bx = 0, by = 0;
int xpart = rh->at_offset%10000, ypart = rh->at_offset/10000;
int mapunit = PL__EPSMap__get_int_mp("grid-size", NULL);
while (xpart > 5000) xpart-=10000;
while (xpart < -5000) xpart+=10000;
if (PL__EPSMap__get_int_mp("monochrome", NULL)) PL__EPSMap__EPS_compile_set_greyscale(OUT, 0);
else PL__EPSMap__EPS_compile_set_colour(OUT, rh->colour);
if (rh->offset_from) {
bx = PF_I(map, rh->offset_from)->eps_x;
by = PF_I(map, rh->offset_from)->eps_y;
}
bx += xpart*mapunit/100; by += ypart*mapunit/100;
PL__EPSMap__plot_text_at(OUT, rh->annotation, NULL, 128, rh->font, bx, by, rh->point_size,
TRUE, TRUE); /* centred both horizontally and vertically */
}
}
#line 917 "inform7/Chapter 34/EPS Map.w"
;
}
#line 1150 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__plot_text_at(OUTPUT_STREAM, char *text_to_plot, instance *I, int abbrev_to,
char *font, int x, int y, int pointsize, int centre_h, int centre_v) {
char txt[MAX_EPS_TEXT_LENGTH];
if (text_to_plot) {
Extensions__IDs__truncated_strcpy(txt, text_to_plot, MAX_EPS_TEXT_LENGTH);
} else if (I) {
txt[0] = 0;
{
#line 1167 "inform7/Chapter 34/EPS Map.w"
if (P_printed_name) {
parse_node *V = World__Inferences__get_prop_state_at(
Instances__as_subject(I), P_printed_name, NULL);
if ((Rvalues__is_CONSTANT_of_kind(V, K_text)) &&
(Wordings__nonempty(ParseTree__get_text(V)))) {
int wn = Wordings__first_wn(ParseTree__get_text(V));
Extensions__IDs__truncated_strcpy(txt,
Lexer__word_raw_text(wn)+1, MAX_EPS_TEXT_LENGTH);
if ((txt[0]) && (txt[Platform__strlen(txt)-1] == '\"'))
txt[Platform__strlen(txt)-1] = 0;
}
}
}
#line 1157 "inform7/Chapter 34/EPS Map.w"
;
{
#line 1183 "inform7/Chapter 34/EPS Map.w"
if (txt[0] == 0) {
wording W = Instances__get_name(I, FALSE);
if (Wordings__empty(W)) return;
Wordings__to_string_raw_truncated(txt, MAX_EPS_TEXT_LENGTH, W);
}
}
#line 1158 "inform7/Chapter 34/EPS Map.w"
;
} else return;
{
#line 1196 "inform7/Chapter 34/EPS Map.w"
if (abbrev_to > MAX_EPS_ABBREVIATED_LENGTH) abbrev_to = MAX_EPS_ABBREVIATED_LENGTH;
while (Platform__strlen(txt) > abbrev_to) {
int j;
for (j=Platform__strlen(txt)-1; j>=0; j--)
if ((txt[j] == 'a') || (txt[j] == 'e') || (txt[j] == 'i') ||
(txt[j] == 'o') || (txt[j] == 'u')) goto RemoveOne;
for (j=Platform__strlen(txt)-1; j>=0; j--)
if (txt[j] == ' ') goto RemoveOne;
for (j=Platform__strlen(txt)-1; j>=0; j--)
if (islower(txt[j])) goto RemoveOne;
for (j=Platform__strlen(txt)-1; j>=0; j--)
if (isupper(txt[j]) == FALSE) goto RemoveOne;
txt[abbrev_to] = 0;
break;
RemoveOne: ;
for (; txt[j]; j++) txt[j] = txt[j+1];
}
}
#line 1160 "inform7/Chapter 34/EPS Map.w"
;
PL__EPSMap__EPS_compile_text(OUT, txt, x, y, font, pointsize, centre_h, centre_v);
}
#line 1218 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_header(OUTPUT_STREAM, int bounding_box_width, int bounding_box_height,
char *default_font, int default_point_size) {
WRITE("%%!PS-Adobe EPSF-3.0\n");
WRITE("%%%%BoundingBox: 0 0 %d %d\n", bounding_box_width, bounding_box_height);
WRITE("%%%%IncludeFont: %s\n", default_font);
WRITE("/%s findfont %d scalefont setfont\n", default_font, default_point_size);
}
#line 1232 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_circular_path(OUTPUT_STREAM, int x0, int y0, int radius) {
WRITE("%d %d moveto %% rightmost point\n", x0+radius, y0);
WRITE("%d %d %d %d %d arc %% full circle traced anticlockwise\n",
x0, y0, radius, 0, 360);
WRITE("closepath\n");
}
void PL__EPSMap__EPS_compile_rectangular_path(OUTPUT_STREAM, int x0, int y0, int x1, int y1) {
WRITE("%d %d moveto %% bottom left corner\n", x0, y0);
WRITE("%d %d lineto %% bottom side\n", x1, y0);
WRITE("%d %d lineto %% right side\n", x1, y1);
WRITE("%d %d lineto %% top side\n", x0, y1);
WRITE("closepath\n");
}
#line 1250 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_room_boundary_path(OUTPUT_STREAM, int bx, int by, int boxsize, char *shape) {
if (strcmp(shape, "square") == 0)
PL__EPSMap__EPS_compile_rectangular_path(OUT, bx-boxsize, by-boxsize, bx+boxsize, by+boxsize);
else if (strcmp(shape, "rectangle") == 0)
PL__EPSMap__EPS_compile_rectangular_path(OUT, bx-2*boxsize, by-boxsize, bx+2*boxsize, by+boxsize);
else if (strcmp(shape, "circle") == 0)
PL__EPSMap__EPS_compile_circular_path(OUT, bx, by, boxsize);
else
PL__EPSMap__EPS_compile_rectangular_path(OUT, bx-boxsize, by-boxsize, bx+boxsize, by+boxsize);
}
#line 1264 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_horizontal_line_path(OUTPUT_STREAM, int x0, int x1, int y) {
WRITE("%d %d moveto %% LHS\n", x0, y);
WRITE("%d %d lineto %% RHS\n", x1, y);
WRITE("closepath\n");
}
#line 1273 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_dashed_arrow(OUTPUT_STREAM, int length, vector Dir, int x0, int y0) {
WRITE("[2 1] 0 setdash %% dashed line for arrow\n");
WRITE("%d %d moveto %% room centre\n", x0, y0);
WRITE("%d %d rlineto %% arrow out\n", Dir.x*length, Dir.y*length);
WRITE("stroke\n");
WRITE("[] 0 setdash %% back to normal solid lines\n");
}
#line 1287 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_Bezier_curve(OUTPUT_STREAM, int stiffness0, int stiffness1,
int x0, int y0, int exit0, int x1, int y1, int exit1) {
int cx1, cy1, cx2, cy2;
vector E = PL__SpatialMap__direction_as_vector(exit0);
cx1 = x0+E.x*stiffness0/100; cy1 = y0+E.y*stiffness0/100;
E = PL__SpatialMap__direction_as_vector(exit1);
cx2 = x1+E.x*stiffness1/100; cy2 = y1+E.y*stiffness1/100;
WRITE("%d %d moveto %% start of Bezier curve\n", x0, y0);
WRITE("%d %d %d %d %d %d curveto %% control points 1, 2 and end\n",
cx1, cy1, cx2, cy2, x1, y1);
WRITE("stroke\n");
}
#line 1305 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_line_width_setting(OUTPUT_STREAM, int new) {
WRITE("currentlinewidth %% Push old line width onto stack\n");
WRITE("%d setlinewidth\n", new);
}
void PL__EPSMap__EPS_compile_line_width_unsetting(OUTPUT_STREAM) {
WRITE("setlinewidth %% Pull old line width from stack\n");
}
#line 1318 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_text(OUTPUT_STREAM, char *text, int x, int y, char *font, int pointsize,
int centre_h, int centre_v) {
WRITE("/%s findfont %d scalefont setfont\n", font, pointsize);
WRITE("newpath (%s)\n", text);
if (centre_h) WRITE("dup stringwidth add 2 div %d exch sub %% = X centre-offset\n", x);
else WRITE("%d %% = X\n", x);
if (centre_v) WRITE("%d %d 2 div sub %% = Y centre-offset\n", y, pointsize);
else WRITE("%d %% = Y\n", y);
WRITE("moveto show\n");
}
#line 1337 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_set_colour(OUTPUT_STREAM, char *htmlcolour) {
if (Platform__strlen(htmlcolour) != 6) internal_error("Improper HTML colour");
PL__EPSMap__choose_colour_beam(OUT, htmlcolour[0], htmlcolour[1]);
PL__EPSMap__choose_colour_beam(OUT, htmlcolour[2], htmlcolour[3]);
PL__EPSMap__choose_colour_beam(OUT, htmlcolour[4], htmlcolour[5]);
WRITE("setrgbcolor %% From HTML colour %s\n", htmlcolour);
}
void PL__EPSMap__choose_colour_beam(OUTPUT_STREAM, char hex1, char hex2) {
int k = PL__EPSMap__hex_to_int(hex1)*16 + PL__EPSMap__hex_to_int(hex2);
WRITE("%.6g ", (double) (((float) k)/255.0));
}
int PL__EPSMap__hex_to_int(char hex) {
switch(hex) {
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
case 'a': case 'A': return 10;
case 'b': case 'B': return 11;
case 'c': case 'C': return 12;
case 'd': case 'D': return 13;
case 'e': case 'E': return 14;
case 'f': case 'F': return 15;
default: internal_error("Improper character in HTML colour");
}
return 0;
}
#line 1376 "inform7/Chapter 34/EPS Map.w"
void PL__EPSMap__EPS_compile_set_greyscale(OUTPUT_STREAM, int N) {
WRITE("%0.02f setgray %% greyscale %d/100ths of white\n", (float) N/100, N);
}
#line 16 "inform7/Chapter 34/Showme Command.w"
void PL__Showme__start(void) {
}
#line 31 "inform7/Chapter 34/Showme Command.w"
void PL__Showme__compile_SHOWME_details(OUTPUT_STREAM) {
if (Plugins__Manage__plugged_in(showme_plugin) == FALSE) return;
PL__Showme__compile_SHOWME_type(OUT, FALSE);
PL__Showme__compile_SHOWME_type(OUT, TRUE);
}
void PL__Showme__compile_SHOWME_type(OUTPUT_STREAM, int val) {
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__le(K, K_object))
PL__Showme__compile_SHOWME_type_subj(OUT, val, Kinds__Behaviour__as_subject(K));
instance *I;
LOOP_OVER_OBJECT_INSTANCES(I)
PL__Showme__compile_SHOWME_type_subj(OUT, val, Instances__as_subject(I));
}
void PL__Showme__compile_SHOWME_type_subj(OUTPUT_STREAM, int val, inference_subject *subj) {
{
#line 63 "inform7/Chapter 34/Showme Command.w"
int todo = FALSE;
property *prn;
LOOP_OVER(prn, property)
if (Properties__is_value_property(prn) == val)
if (PL__Showme__is_property_worth_SHOWME(OUT, subj, prn))
todo = TRUE;
if (todo == FALSE) return;
}
#line 48 "inform7/Chapter 34/Showme Command.w"
;
WRITE("if (");
char cond[1024]; cond[0] = 0;
InferenceSubjects__write_element_of_condition(subj, cond);
if (cond[0] != 0) WRITE("%s", cond); else WRITE("true");
WRITE(") {");
INDENT;
{
#line 83 "inform7/Chapter 34/Showme Command.w"
char *divider = "; ";
if (val) divider = "^";
WRITE("if (na > 0) { na = 0; print \"%s\"; }\n", divider);
}
#line 55 "inform7/Chapter 34/Showme Command.w"
;
{
#line 90 "inform7/Chapter 34/Showme Command.w"
property *prn;
LOOP_OVER(prn, property)
if (Properties__is_value_property(prn) == val)
PL__Showme__compile_property_SHOWME(OUT, subj, prn);
}
#line 56 "inform7/Chapter 34/Showme Command.w"
;
OUTDENT; WRITE("}\n");
}
#line 98 "inform7/Chapter 34/Showme Command.w"
int PL__Showme__is_property_worth_SHOWME(OUTPUT_STREAM, inference_subject *subj, property *prn) {
return PL__Showme__SHOWME_primitive(OUT, subj, prn, FALSE);
}
void PL__Showme__compile_property_SHOWME(OUTPUT_STREAM, inference_subject *subj, property *prn) {
PL__Showme__SHOWME_primitive(OUT, subj, prn, TRUE);
}
#line 109 "inform7/Chapter 34/Showme Command.w"
int PL__Showme__SHOWME_primitive(OUTPUT_STREAM, inference_subject *subj, property *prn, int comp) {
if (Properties__is_shown_in_index(prn) == FALSE) return FALSE;
if (Properties__can_be_compiled(prn) == FALSE) return FALSE;
inference_subject *parent = InferenceSubjects__narrowest_broader_subject(subj);
if ((World__Permissions__find(subj, prn, FALSE)) &&
(World__Permissions__find(parent, prn, TRUE) == FALSE)) {
if (comp) {
if (Properties__is_value_property(prn))
{
#line 148 "inform7/Chapter 34/Showme Command.w"
kind *K = Properties__Valued__kind(prn);
if (K) {
char *P = Properties__get_translation(prn);
char *R = Kinds__Behaviour__get_name_of_printing_rule(K);
int require_nonzero = FALSE;
if ((Properties__Valued__is_used_for_non_typesafe_relation(prn)) ||
(Kinds__Compare__le(K, K_object)))
require_nonzero = TRUE;
if (require_nonzero) WRITE("if (GProperty(OBJECT_TY, t_0, %s)) { ", P);
{
#line 164 "inform7/Chapter 34/Showme Command.w"
WRITE("print \"");
Wordings__to_stream_raw(OUT, prn->name);
WRITE(": \"; ");
if (Kinds__Compare__eq(K, K_text)) {
WRITE("if (TEXT_TY_Compare(GProperty(OBJECT_TY, t_0, %s), EMPTY_TEXT_VALUE) == 0) ", P);
WRITE("print \"none^\"; else ");
WRITE("print \"~\", (%s) GProperty(OBJECT_TY, t_0, %s), \"~\"", R, P);
} else {
WRITE("print (%s) GProperty(OBJECT_TY, t_0, %s)", R, P);
}
WRITE(", \"^\";\n");
}
#line 157 "inform7/Chapter 34/Showme Command.w"
;
if (require_nonzero) WRITE("}\n");
}
}
#line 119 "inform7/Chapter 34/Showme Command.w"
else
{
#line 182 "inform7/Chapter 34/Showme Command.w"
property *allow = prn;
if (Properties__EitherOr__stored_in_negation(prn))
allow = Properties__EitherOr__get_negation(prn);
WRITE("if ((AllowInShowme(%s)) && (t_0 ", Properties__get_translation(allow));
Properties__ObjectImplementation__compile_has_property(OUT, prn);
WRITE(")) { if (na++ > 0) print \", \"; print \"");
Wordings__to_stream_raw(OUT, prn->name);
WRITE("\"; }\n");
}
#line 121 "inform7/Chapter 34/Showme Command.w"
;
}
return TRUE;
}
return FALSE;
}
#line 97 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_PROPERTY_NOTIFY, PL__Scenes__scenes_new_property_notify);
PLUGIN_REGISTER(PLUGIN_NEW_INSTANCE_NOTIFY, PL__Scenes__scenes_new_named_instance_notify);
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL__Scenes__scenes_new_base_kind_notify);
}
#line 106 "inform7/Chapter 34/Scenes.w"
int PL__Scenes__scenes_new_base_kind_notify(kind *new_base, char *name, wording W) {
if ((name) && (strcmp(name, "SCENE_TY") == 0)) {
K_scene = new_base; return TRUE;
}
return FALSE;
}
#line 118 "inform7/Chapter 34/Scenes.w"
int notable_scene_properties_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 120 "inform7/Chapter 34/Scenes.w"
#line 124 "inform7/Chapter 34/Scenes.w"
int PL__Scenes__scenes_new_property_notify(property *prn) {
if (Preform__parse_nt_against_word_range(notable_scene_properties_NTM, prn->name, NULL, NULL)) {
switch (most_recent_result) {
case 0: P_recurring = prn; break;
}
}
return FALSE;
}
#line 137 "inform7/Chapter 34/Scenes.w"
int PL__Scenes__scenes_new_named_instance_notify(instance *I) {
if ((K_scene) && (Kinds__Compare__eq(Instances__to_kind(I), K_scene))) {
PL__Scenes__new_scene(I);
return TRUE;
}
return FALSE;
}
#line 150 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__new_scene(instance *I) {
scene *sc = CREATE(scene);
{
#line 182 "inform7/Chapter 34/Scenes.w"
sc->as_instance = I;
Instances__set_connection(I, STORE_POINTER_scene(sc));
wording W = Instances__get_name(I, FALSE);
if (Preform__parse_nt_against_word_range(notable_scenes_NTM, W, NULL, NULL)) SC_entire_game = sc;
}
#line 152 "inform7/Chapter 34/Scenes.w"
;
{
#line 159 "inform7/Chapter 34/Scenes.w"
sc->once_only = TRUE;
sc->indexed = FALSE;
sc->no_ends = 2;
sc->start_of_play = FALSE;
sc->scene_declared_at = current_sentence;
int end;
for (end=0; end<sc->no_ends; end++) {
sc->anchor_condition[end] = NULL;
sc->anchor_scene[end] = NULL;
PL__Scenes__new_scene_rulebook(sc, end);
}
}
#line 153 "inform7/Chapter 34/Scenes.w"
;
}
#line 176 "inform7/Chapter 34/Scenes.w"
int notable_scenes_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 178 "inform7/Chapter 34/Scenes.w"
#line 190 "inform7/Chapter 34/Scenes.w"
scene *PL__Scenes__from_named_constant(instance *I) {
if (K_scene == NULL) return NULL;
kind *K = Instances__to_kind(I);
if (Kinds__Compare__eq(K, K_scene))
return RETRIEVE_POINTER_scene(Instances__get_connection(I));
return NULL;
}
wording PL__Scenes__get_name(scene *sc) {
return Instances__get_name(sc->as_instance, FALSE);
}
#line 205 "inform7/Chapter 34/Scenes.w"
int PL__Scenes__parse_scene_end_name(scene *sc, wording EW, int create) {
int i;
for (i=2; i<sc->no_ends; i++)
if (Wordings__match(EW, sc->end_names[i]))
return i;
if (create) {
int end = sc->no_ends++;
int max = 31;
if (VirtualMachines__is_16_bit()) max = 15;
if (end >= max)
{
#line 227 "inform7/Chapter 34/Scenes.w"
Problems__Issue__sentence_problem(_p_(PM_ScenesWithTooManyEnds),
"this scene now has too many different ways to end",
"and will need to be simplified. (We can have up to 15 ends to a scene "
"if the project format is for the Z-machine, and 31 for Glulx: see the "
"project's Settings panel. Note that the ordinary 'begins' and 'ends' "
"count as two of those, so you can only name up to 13 or 29 more specific "
"ways for the scene to end.)");
}
#line 214 "inform7/Chapter 34/Scenes.w"
else {
sc->end_names[end] = EW;
PL__Scenes__new_scene_rulebook(sc, end);
return end;
}
}
return -1;
}
#line 238 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__new_scene_rulebook(scene *sc, int end) {
wording RW = EMPTY_WORDING, AW = EMPTY_WORDING;
{
#line 255 "inform7/Chapter 34/Scenes.w"
wording NW = Instances__get_name(sc->as_instance, FALSE);
feed_t id = Feeds__begin();
Feeds__feed_text_expanding_strings("when");
Feeds__feed_wording(NW);
Feeds__feed_text_expanding_strings((end==0)?"begins":"ends");
if (end >= 2) Feeds__feed_wording(sc->end_names[end]);
RW = Feeds__end(id);
id = Feeds__begin();
Feeds__feed_text_expanding_strings("when the");
NW = Instances__get_name(sc->as_instance, FALSE);
Feeds__feed_wording(NW);
Feeds__feed_text_expanding_strings((end==0)?"begins":"ends");
if (end >= 2) Feeds__feed_wording(sc->end_names[end]);
AW = Feeds__end(id);
}
#line 240 "inform7/Chapter 34/Scenes.w"
;
rulebook *rb = Rulebooks__new_automatic(RW, K_action_name,
NO_OUTCOME, FALSE, FALSE, FALSE);
Rulebooks__set_alt_name(rb, AW);
sc->end_rulebook[end] = rb;
if (end >= 2)
{
#line 275 "inform7/Chapter 34/Scenes.w"
wording NW = Instances__get_name(sc->as_instance, FALSE);
char i6_code[128];
feed_t id = Feeds__begin();
Feeds__feed_text_expanding_strings("To decide if (S - ");
Feeds__feed_wording(NW);
Feeds__feed_text_expanding_strings(") ended ");
Feeds__feed_wording(sc->end_names[end]);
Sentences__make_node(Feeds__end(id), ':');
id = Feeds__begin();
sprintf(i6_code, " (- (scene_latest_ending-->%d == %d) -) ",
sc->allocation_id, end);
Feeds__feed_text_expanding_strings(i6_code);
Sentences__make_node(Feeds__end(id), '.');
id = Feeds__begin();
Feeds__feed_text_expanding_strings("To decide if (S - ");
Feeds__feed_wording(NW);
Feeds__feed_text_expanding_strings(") did not end ");
Feeds__feed_wording(sc->end_names[end]);
Sentences__make_node(Feeds__end(id), ':');
id = Feeds__begin();
sprintf(i6_code, " (- (scene_latest_ending-->%d ~= 0 or %d) -) ",
sc->allocation_id, end);
Feeds__feed_text_expanding_strings(i6_code);
Sentences__make_node(Feeds__end(id), '.');
Sentences__RuleSubtrees__register_recently_lexed_phrases();
}
#line 247 "inform7/Chapter 34/Scenes.w"
;
}
#line 310 "inform7/Chapter 34/Scenes.w"
sentence_handler BEGINS_WHEN_SH_handler =
{ SENTENCE_NT, BEGINS_WHEN_VB, 0, PL__Scenes__begins_or_ends_when };
sentence_handler ENDS_WHEN_SH_handler =
{ SENTENCE_NT, ENDS_WHEN_VB, 0, PL__Scenes__begins_or_ends_when };
void PL__Scenes__begins_or_ends_when(parse_node *p) {
PL__Scenes__new_scene_anchor(p, traverse);
}
scene *scene_end_of_which_parsed = NULL;
#line 335 "inform7/Chapter 34/Scenes.w"
int scene_ends_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 342 "inform7/Chapter 34/Scenes.w"
*X = FALSE;
Problems__Issue__sentence_problem(_p_(PM_ScenesOnly),
"'begins when' and 'ends when' can only be applied to scenes",
"which have already been defined with a sentence like 'The final "
"confrontation is a scene.'");
}
#line 337 "inform7/Chapter 34/Scenes.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 338 "inform7/Chapter 34/Scenes.w"
#line 352 "inform7/Chapter 34/Scenes.w"
int scene_ends_sentence_adverb_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 354 "inform7/Chapter 34/Scenes.w"
#line 360 "inform7/Chapter 34/Scenes.w"
int scene_ends_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 373 "inform7/Chapter 34/Scenes.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_ScenesDisallowCalled),
"'(called ...)' is not allowed within conditions for a scene to begin or end",
"since calling gives only a temporary name to something, for the purpose "
"of further instructions which immediately follow in. Here there is no room "
"for such further instructions, so a calling would have no effect. Anyway - "
"not allowed!");
}
#line 361 "inform7/Chapter 34/Scenes.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = -1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 384 "inform7/Chapter 34/Scenes.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_ScenesNotPlay),
"'play' is not really a scene",
"so although you can write '... when play begins' you cannot write '... "
"when play ends'. But there's no need to do so, anyway. When play ends, "
"all scenes end.");
}
#line 363 "inform7/Chapter 34/Scenes.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; scene_named_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 1; scene_named_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = R[2]; scene_named_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 394 "inform7/Chapter 34/Scenes.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_ScenesUnknownEnd),
"that's not one of the known ends for that scene",
"which must be declared with something like 'Confrontation ends happily "
"when...' or 'Confrontation ends tragically when...'.");
}
#line 367 "inform7/Chapter 34/Scenes.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = -2; parse_node_cond_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 369 "inform7/Chapter 34/Scenes.w"
#line 404 "inform7/Chapter 34/Scenes.w"
int scene_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[2]; *XP = RP[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 407 "inform7/Chapter 34/Scenes.w"
int scene_name_unarticled_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 414 "inform7/Chapter 34/Scenes.w"
instance *I = most_recent_result_p;
if (Instances__of_kind(I, K_scene) == FALSE) return FALSE;
*XP = PL__Scenes__from_named_constant(I);
scene_end_of_which_parsed = *XP;
}
#line 409 "inform7/Chapter 34/Scenes.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 410 "inform7/Chapter 34/Scenes.w"
#line 424 "inform7/Chapter 34/Scenes.w"
int scene_end_name_NTMR(wording W, int *X, void **XP) {
#line 425 "inform7/Chapter 34/Scenes.w"
int end = PL__Scenes__parse_scene_end_name(scene_end_of_which_parsed, W, FALSE);
if (end < 0) return FALSE;
*X = end; return TRUE;
}
int scene_end_name_creating_NTMR(wording W, int *X, void **XP) {
#line 431 "inform7/Chapter 34/Scenes.w"
*X = PL__Scenes__parse_scene_end_name(scene_end_of_which_parsed, W, TRUE);
return TRUE;
}
#line 443 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__new_scene_anchor(parse_node *p, int phase) {
scene *this_scene = NULL; /* scene whose end is being caused: must be set */
int end = -1; /* end which is being anchored: must be set */
scene *other_scene = NULL; /* Either: another scene whose end it connects to */
int other_end = -1; /* and which end it is... */
parse_node *external_condition = NULL; /* Or: an absolute condition... */
int when_play_begins = FALSE; /* Or: anchor to the start of play */
wording SW = ParseTree__get_text(p->down->next); /* scene name */
wording EW = EMPTY_WORDING; /* end name, if any */
wording CW = EMPTY_WORDING; /* condition for end to occur */
if (p->down->next->next->next) {
EW = ParseTree__get_text(p->down->next->next);
CW = ParseTree__get_text(p->down->next->next->next);
} else {
CW = ParseTree__get_text(p->down->next->next);
}
{
#line 514 "inform7/Chapter 34/Scenes.w"
Preform__parse_nt_against_word_range(scene_ends_sentence_subject_NTM, SW, NULL, NULL);
if (most_recent_result == FALSE) return;
this_scene = most_recent_result_p;
scene_end_of_which_parsed = this_scene;
if (Wordings__nonempty(EW)) {
Preform__parse_nt_against_word_range(scene_ends_sentence_adverb_NTM, EW, NULL, NULL);
end = most_recent_result;
} else if (ParseTree__int_annotation(p->down, verb_id_ANNOT) == ENDS_WHEN_VB)
end = 1;
else
end = 0;
if (end < 0) return; /* to recover from any parsing Problems */
}
#line 462 "inform7/Chapter 34/Scenes.w"
;
if ((this_scene == NULL) || (end < 0)) internal_error("scene misparsed");
if (phase == 2) {
{
#line 531 "inform7/Chapter 34/Scenes.w"
if (Preform__parse_nt_against_word_range(scene_ends_sentence_object_NTM, CW, NULL, NULL)) {
int end = most_recent_result;
switch (end) {
case -2: external_condition = parse_node_cond_NTMV; break;
case -1: when_play_begins = TRUE; break;
default: other_end = end; other_scene = scene_named_NTMV; break;
}
} else external_condition = Specifications__new_UNKNOWN(CW);
}
#line 466 "inform7/Chapter 34/Scenes.w"
;
if ((this_scene == SC_entire_game) && (external_condition == NULL)) {
Problems__Issue__sentence_problem(_p_(PM_EntireGameHardwired),
"the special 'Entire Game' scene cannot have its start or end modified",
"because it is a built-in scene designed to be going on whenever there "
"is play going on in the story.");
} else if (when_play_begins)
{
#line 485 "inform7/Chapter 34/Scenes.w"
this_scene->start_of_play = TRUE;
}
#line 473 "inform7/Chapter 34/Scenes.w"
else if (other_scene)
{
#line 504 "inform7/Chapter 34/Scenes.w"
scene_connector *scon = CREATE(scene_connector);
scon->connect_to = other_scene;
scon->end = other_end;
scon->where_said = current_sentence;
scon->next = this_scene->anchor_scene[end];
this_scene->anchor_scene[end] = scon;
}
#line 475 "inform7/Chapter 34/Scenes.w"
else if (external_condition)
{
#line 490 "inform7/Chapter 34/Scenes.w"
if (this_scene->anchor_condition[end])
Problems__Issue__sentence_problem(_p_(PM_ScenesOversetEnd),
"you have already told me a condition for when that happens",
"and although a scene can be linked to the beginning or ending "
"of any number of other scenes, it can only have a single "
"condition such as 'when the player is in the Dining Car' "
"to trigger it from outside the scene machinery.");
this_scene->anchor_condition[end] = external_condition;
this_scene->anchor_condition_set[end] = current_sentence;
}
#line 477 "inform7/Chapter 34/Scenes.w"
else internal_error("failed to obtain an anchor condition");
}
}
#line 558 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__DetectSceneChange_routine(OUTPUT_STREAM) {
OUT = Routines__begin(OUT, "DetectSceneChange");
LocalVariables__add_internal_local_c("chs", "count of changes made");
LocalVariables__add_internal_local_c("ch", "flag: change made");
scene *sc;
LOOP_OVER(sc, scene)
{
#line 580 "inform7/Chapter 34/Scenes.w"
int ix = sc->allocation_id;
WRITE("if (scene_status-->%d == 1) {\n", ix); INDENT;
int end;
for (end=sc->no_ends-1; end>=1; end--) PL__Scenes__test_scene_end(OUT, sc, end);
OUTDENT; WRITE("}\n");
WRITE("if (scene_status-->%d == 0) {\n", ix); INDENT;
PL__Scenes__test_scene_end(OUT, sc, 0);
OUTDENT; WRITE("}\n");
}
#line 564 "inform7/Chapter 34/Scenes.w"
;
WRITE(".CScene;\n");
WRITE("if (chs>%d) \">--> The scene change machinery is stuck.\";\n\n",
MAX_SCENE_CHANGE_ITERATION);
WRITE("if (ch>0) DetectSceneChange(++chs);\n\n");
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
}
#line 596 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__test_scene_end(OUTPUT_STREAM, scene *sc, int end) {
if ((end == 0) && (sc->start_of_play)) {
WRITE("if (((scene_endings-->%d) & 1) == 0) {\n", sc->allocation_id); INDENT;
PL__Scenes__compile_scene_end(OUT, sc, 0);
OUTDENT; WRITE("}\n");
}
parse_node *S = sc->anchor_condition[end];
if (S) {
{
#line 612 "inform7/Chapter 34/Scenes.w"
current_sentence = sc->anchor_condition_set[end];
if (ParseTree__is(S, UNKNOWN_VNT)) {
if (Preform__parse_nt_against_word_range(s_condition_NTM, ParseTree__get_text(S), NULL, NULL)) S = most_recent_result_p;
sc->anchor_condition[end] = S;
}
if (ParseTree__is(S, UNKNOWN_VNT)) {
LOG("Condition: $P\n", S);
Problems__Issue__sentence_problem(_p_(PM_ScenesBadCondition),
"'begins when' and 'ends when' must be followed by a condition",
"which this does not seem to be, or else 'when play begins', "
"'when play ends', 'when S begins', or 'when S ends', where "
"S is the name of any scene.");
return;
}
if (Dash__check_condition(S) == FALSE) return;
}
#line 604 "inform7/Chapter 34/Scenes.w"
;
{
#line 634 "inform7/Chapter 34/Scenes.w"
WRITE("if (");
current_sentence = sc->anchor_condition_set[end];
Specifications__Compiler__compile(OUT, S);
WRITE(") {\n"); INDENT;
WRITE("ch = true;\n");
PL__Scenes__compile_scene_end(OUT, sc, end);
WRITE("jump CScene;\n");
OUTDENT; WRITE("}\n");
}
#line 605 "inform7/Chapter 34/Scenes.w"
;
}
}
#line 653 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__compile_scene_end(OUTPUT_STREAM, scene *sc, int end) {
scene *sc2;
LOOP_OVER(sc2, scene) sc2->marker = 0;
PL__Scenes__compile_scene_end_dash(OUT, sc, end);
}
#line 668 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__compile_scene_end_dash(OUTPUT_STREAM, scene *sc, int end) {
int ix = sc->allocation_id;
sc->marker++;
if (end >= 2) {
int e = end; end = 1;
{
#line 725 "inform7/Chapter 34/Scenes.w"
WRITE("if (debug_scenes) print \"[Scene '");
if (sc->as_instance) {
wording NW = Instances__get_name(sc->as_instance, FALSE);
Wordings__to_stream_raw(OUT, NW);
}
WRITE("' ");
if (end == 0) WRITE("begins");
if (end >= 1) WRITE("ends");
if (end >= 2) {
WRITE(" ");
Wordings__to_stream_raw(OUT, sc->end_names[end]);
}
WRITE("]^\";\n");
}
#line 674 "inform7/Chapter 34/Scenes.w"
;
{
#line 698 "inform7/Chapter 34/Scenes.w"
if (end == 0)
WRITE("scene_status-->%d = 1; ", ix);
else {
WRITE("if (GProperty(%d, %d, %s)) scene_status-->%d = 0; ",
Kinds__RunTime__weak_id(K_scene), ix+1,
Properties__get_translation(P_recurring), ix);
WRITE("else scene_status-->%d = 2; ", ix);
}
}
#line 675 "inform7/Chapter 34/Scenes.w"
;
{
#line 717 "inform7/Chapter 34/Scenes.w"
if (end == 0) WRITE("scene_started-->%d = the_time;\n", ix);
else WRITE("scene_ended-->%d = the_time;\n", ix);
WRITE("scene_endings-->%d = (scene_endings-->%d)|%d;\n", ix, ix, 1 << end);
WRITE("scene_latest_ending-->%d = %d;\n", ix, end);
}
#line 676 "inform7/Chapter 34/Scenes.w"
;
end = e;
}
{
#line 725 "inform7/Chapter 34/Scenes.w"
WRITE("if (debug_scenes) print \"[Scene '");
if (sc->as_instance) {
wording NW = Instances__get_name(sc->as_instance, FALSE);
Wordings__to_stream_raw(OUT, NW);
}
WRITE("' ");
if (end == 0) WRITE("begins");
if (end >= 1) WRITE("ends");
if (end >= 2) {
WRITE(" ");
Wordings__to_stream_raw(OUT, sc->end_names[end]);
}
WRITE("]^\";\n");
}
#line 679 "inform7/Chapter 34/Scenes.w"
;
{
#line 698 "inform7/Chapter 34/Scenes.w"
if (end == 0)
WRITE("scene_status-->%d = 1; ", ix);
else {
WRITE("if (GProperty(%d, %d, %s)) scene_status-->%d = 0; ",
Kinds__RunTime__weak_id(K_scene), ix+1,
Properties__get_translation(P_recurring), ix);
WRITE("else scene_status-->%d = 2; ", ix);
}
}
#line 680 "inform7/Chapter 34/Scenes.w"
;
{
#line 710 "inform7/Chapter 34/Scenes.w"
if (end == 0) WRITE("FollowRulebook(WHEN_SCENE_BEGINS_RB, %d);\n", ix + 1);
WRITE("FollowRulebook(%d);\n", sc->end_rulebook[end]->allocation_id);
if (end == 1) WRITE("FollowRulebook(WHEN_SCENE_ENDS_RB, %d);\n", ix + 1);
}
#line 681 "inform7/Chapter 34/Scenes.w"
{
#line 717 "inform7/Chapter 34/Scenes.w"
if (end == 0) WRITE("scene_started-->%d = the_time;\n", ix);
else WRITE("scene_ended-->%d = the_time;\n", ix);
WRITE("scene_endings-->%d = (scene_endings-->%d)|%d;\n", ix, ix, 1 << end);
WRITE("scene_latest_ending-->%d = %d;\n", ix, end);
}
#line 682 "inform7/Chapter 34/Scenes.w"
;
{
#line 751 "inform7/Chapter 34/Scenes.w"
scene *other_scene;
LOOP_OVER(other_scene, scene) {
int tolerance = 1;
if (sc == other_scene) tolerance = sc->no_ends;
if (other_scene->marker < tolerance) {
int other_end;
for (other_end = 0; other_end < other_scene->no_ends; other_end++) {
scene_connector *scon;
for (scon = other_scene->anchor_scene[other_end]; scon; scon = scon->next)
if ((scon->connect_to == sc) && (scon->end == end)) {
if (other_end >= 1)
WRITE("if (scene_status-->%d == 1) {\n", other_scene->allocation_id);
else
WRITE("if (scene_status-->%d == 0) {\n", other_scene->allocation_id);
INDENT;
PL__Scenes__compile_scene_end_dash(OUT, other_scene, other_end);
OUTDENT; WRITE("}\n");
}
}
}
}
}
#line 683 "inform7/Chapter 34/Scenes.w"
;
if (end >= 2) {
int e = end; end = 1;
{
#line 710 "inform7/Chapter 34/Scenes.w"
if (end == 0) WRITE("FollowRulebook(WHEN_SCENE_BEGINS_RB, %d);\n", ix + 1);
WRITE("FollowRulebook(%d);\n", sc->end_rulebook[end]->allocation_id);
if (end == 1) WRITE("FollowRulebook(WHEN_SCENE_ENDS_RB, %d);\n", ix + 1);
}
#line 687 "inform7/Chapter 34/Scenes.w"
;
{
#line 751 "inform7/Chapter 34/Scenes.w"
scene *other_scene;
LOOP_OVER(other_scene, scene) {
int tolerance = 1;
if (sc == other_scene) tolerance = sc->no_ends;
if (other_scene->marker < tolerance) {
int other_end;
for (other_end = 0; other_end < other_scene->no_ends; other_end++) {
scene_connector *scon;
for (scon = other_scene->anchor_scene[other_end]; scon; scon = scon->next)
if ((scon->connect_to == sc) && (scon->end == end)) {
if (other_end >= 1)
WRITE("if (scene_status-->%d == 1) {\n", other_scene->allocation_id);
else
WRITE("if (scene_status-->%d == 0) {\n", other_scene->allocation_id);
INDENT;
PL__Scenes__compile_scene_end_dash(OUT, other_scene, other_end);
OUTDENT; WRITE("}\n");
}
}
}
}
}
#line 688 "inform7/Chapter 34/Scenes.w"
;
end = e;
}
}
#line 780 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__ShowSceneStatus_routine(OUTPUT_STREAM) {
OUT = Routines__begin(OUT, "ShowSceneStatus");
LocalVariables__add_internal_local("chs");
LocalVariables__add_internal_local("sc");
LocalVariables__add_internal_local("ch");
scene *sc;
LOOP_OVER(sc, scene) {
int ix = sc->allocation_id;
wording NW = Instances__get_name(sc->as_instance, FALSE);
WRITE("if (scene_status-->%d == 1) {\n", ix); INDENT;
WRITE("print \"Scene '");
Wordings__to_stream_raw(OUT, NW);
WRITE("' playing (for \", the_time-(scene_started-->%d), \" mins now)^\";\n", ix);
OUTDENT; WRITE("} else {\n"); INDENT;
WRITE("if (scene_latest_ending-->%d > 0) {\n", ix); INDENT;
WRITE("print \"Scene '");
Wordings__to_stream_raw(OUT, NW);
WRITE("' ended\";\n");
if (sc->no_ends > 2) {
WRITE("switch(scene_latest_ending-->%d) {\n", ix); INDENT;
for (int end=2; end<sc->no_ends; end++) {
WRITE("%d: print \" ", end);
Wordings__to_stream_raw(OUT, sc->end_names[end]);
WRITE("\";\n");
}
OUTDENT; WRITE("}\n");
}
WRITE("print \"^\";\n");
OUTDENT; WRITE("}\n");
OUTDENT; WRITE("}\n");
}
OUT = Routines__end(OUT);
}
#line 824 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__PrintSceneName_routine(OUTPUT_STREAM) {
OUT = Routines__begin(OUT, "PrintSceneName");
LocalVariables__add_named_call("sc");
WRITE("switch (sc) {\n"); INDENT;
scene *sc;
LOOP_OVER(sc, scene) {
int ix = sc->allocation_id;
WRITE("%d: print \"", ix+1);
wording NW = Instances__get_name(sc->as_instance, FALSE);
Wordings__to_stream_raw(OUT, NW);
WRITE("\";\n");
}
WRITE("default: print \"<no-such-scene>\";\n");
OUTDENT; WRITE("}\n");
OUT = Routines__end(OUT);
}
#line 850 "inform7/Chapter 34/Scenes.w"
int s_scene_description_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 856 "inform7/Chapter 34/Scenes.w"
if (K_scene == NULL) return FALSE;
parse_node *spec = RP[1];
instance *I = Rvalues__to_instance(spec);
if (((I) && (Instances__of_kind(I, K_scene))) ||
((Specifications__is_description(spec)) &&
(Kinds__Compare__eq(Specifications__to_kind(spec), K_scene)))) {
*XP = spec;
} else return FALSE;
}
#line 851 "inform7/Chapter 34/Scenes.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 852 "inform7/Chapter 34/Scenes.w"
#line 869 "inform7/Chapter 34/Scenes.w"
void PL__Scenes__test_during_clause(OUTPUT_STREAM, parse_node *spec) {
int stuck = TRUE;
if (K_scene == NULL) { WRITE("if (true) {\n"); return; }
if (ParseTree__is_rvalue(spec)) {
Dash__check_value(spec, K_scene);
instance *I = Rvalues__to_instance(spec);
if (Instances__of_kind(I, K_scene)) {
scene *sc = PL__Scenes__from_named_constant(I);
WRITE("if (scene_status-->%d == 1) { ! Runs only during scene\n",
sc->allocation_id);
stuck = FALSE;
}
} else {
if (Dash__check_value(spec, Kinds__unary_construction(CON_description, K_scene)) == ALWAYS_MATCH) {
parse_node *desc = Descriptions__to_rvalue(spec);
if (desc) {
WRITE("if (DuringSceneMatching(");
Specifications__Compiler__compile(OUT, desc);
WRITE(")) { ! Runs only during scene\n");
stuck = FALSE;
}
}
}
if (stuck) {
WRITE("if (true) {\n");
Problems__Issue__sentence_problem(_p_(PM_ScenesBadDuring),
"'during' must be followed by the name of a scene or of a "
"description which applies to a single scene",
"such as 'during Station Arrival' or 'during a recurring scene'.");
return;
}
}
#line 20 "inform7/Chapter 34/Temporal Map.w"
void PL__Scenes__Index__index(void) {
int nr = NUMBER_CREATED(scene);
scene **sorted = Memory__I7_calloc(nr, sizeof(scene *), INDEX_SORTING_MREASON);
{
#line 40 "inform7/Chapter 34/Temporal Map.w"
int i = 0;
scene *sc;
LOOP_OVER(sc, scene) sorted[i++] = sc;
qsort(sorted, (size_t) nr, sizeof(scene *), PL__Scenes__Index__compare_scenes);
}
#line 23 "inform7/Chapter 34/Temporal Map.w"
;
{
#line 54 "inform7/Chapter 34/Temporal Map.w"
int i;
for (i=0; i<nr; i++) {
scene *sc = sorted[i];
if ((sc->start_of_play) || (sc == SC_entire_game))
PL__Scenes__Index__index_from_scene(sc, 0, START_OF_PLAY_END, NULL, sorted, nr);
}
for (i=0; i<nr; i++) {
scene *sc = sorted[i];
if ((sc->anchor_condition[0]) && (sc != SC_entire_game))
PL__Scenes__Index__index_from_scene(sc, 0, START_OF_PLAY_END, NULL, sorted, nr);
}
for (i=0; i<nr; i++) {
scene *sc = sorted[i];
if (sc->indexed == FALSE)
PL__Scenes__Index__index_from_scene(sc, 0, NEVER_HAPPENS_END, NULL, sorted, nr);
}
}
#line 25 "inform7/Chapter 34/Temporal Map.w"
;
{
#line 75 "inform7/Chapter 34/Temporal Map.w"
INDEX("<p>Legend: ");
PL__Scenes__Index__scene_icon_legend("WPB", "Begins when play begins");
INDEX("; ");
PL__Scenes__Index__scene_icon_legend("WhenC", "can begin whenever some condition holds");
INDEX("; ");
PL__Scenes__Index__scene_icon_legend("Segue", "follows when a previous scene ends");
INDEX("; ");
PL__Scenes__Index__scene_icon_legend("Simul", "begins simultaneously");
INDEX("; ");
PL__Scenes__Index__scene_icon_legend("WNever", "never begins");
INDEX("; ");
PL__Scenes__Index__scene_icon_legend("ENever", "never ends");
INDEX("; ");
PL__Scenes__Index__scene_icon_legend("Recurring", "recurring (can happen more than once)");
INDEX(". <i>Scene names are italicised when and if they appear for a second "
"or subsequent time because the scene can begin in more than one way</i>.</p>");
}
#line 26 "inform7/Chapter 34/Temporal Map.w"
;
{
#line 106 "inform7/Chapter 34/Temporal Map.w"
Index__anchor("SDETAILS");
int i;
for (i=0; i<nr; i++) {
INDEX("<hr>");
scene *sc = sorted[i];
{
#line 119 "inform7/Chapter 34/Temporal Map.w"
{
#line 135 "inform7/Chapter 34/Temporal Map.w"
HTML__open_para(ifl, 1, "hanging");
Index__anchor_numbered(sc->allocation_id);
INDEX("<b>The <i>");
wording NW = PL__Scenes__get_name(sc);
Wordings__index_raw(NW);
INDEX("</i> scene</b>");
Index__link(Wordings__first_wn(ParseTree__get_text(sc->scene_declared_at)));
if (World__Inferences__get_EO_state(
Instances__as_subject(sc->as_instance), P_recurring) > 0)
INDEX("&nbsp;&nbsp;<i>recurring</i>");
INDEX("</p>");
}
#line 119 "inform7/Chapter 34/Temporal Map.w"
;
if (sc == SC_entire_game)
{
#line 150 "inform7/Chapter 34/Temporal Map.w"
HTML__open_para(ifl, 1, "tight");
INDEX("The Entire Game scene is built-in. It is going on whenever play is "
"going on. (It is recurring so that if the story ends, but then resumes, "
"it too will end but then begin again.)</p>");
}
#line 120 "inform7/Chapter 34/Temporal Map.w"
;
int end;
for (end=0; end<sc->no_ends; end++) {
if ((end == 1) && (sc->no_ends > 2) &&
(sc->anchor_condition[1]==NULL) && (sc->anchor_scene[1]==NULL))
continue;
{
#line 178 "inform7/Chapter 34/Temporal Map.w"
HTML__open_para(ifl, 1, "hanging");
INDEX("<i>%s ", (end==0)?"Begins":"Ends");
if (end >= 2) {
Wordings__index_raw(sc->end_names[end]);
INDEX(" ");
}
INDEX("when:</i> ");
int count = 0;
{
#line 195 "inform7/Chapter 34/Temporal Map.w"
if ((end==0) && (sc->start_of_play)) {
if (count > 0) INDEX("<br><i>or when:</i> ");
INDEX("<b>play begins</b>");
count++;
}
}
#line 186 "inform7/Chapter 34/Temporal Map.w"
;
{
#line 204 "inform7/Chapter 34/Temporal Map.w"
if (sc->anchor_condition[end]) {
if (count > 0) INDEX("<br><i>or when:</i> ");
Wordings__index_raw(ParseTree__get_text(sc->anchor_condition[end]));
Index__link(Wordings__first_wn(ParseTree__get_text(sc->anchor_condition_set[end])));
count++;
}
}
#line 187 "inform7/Chapter 34/Temporal Map.w"
;
{
#line 214 "inform7/Chapter 34/Temporal Map.w"
scene_connector *scon;
for (scon = sc->anchor_scene[end]; scon; scon=scon->next) {
if (count > 0) INDEX("<br><i>or when:</i> ");
INDEX("<b>");
wording NW = Instances__get_name(scon->connect_to->as_instance, FALSE);
Wordings__index_raw(NW);
INDEX("</b> <i>%s</i>", (scon->end==0)?"begins":"ends");
if (scon->end >= 2) {
INDEX(" ");
Wordings__index_raw(scon->connect_to->end_names[scon->end]);
}
Index__link(Wordings__first_wn(ParseTree__get_text(scon->where_said)));
count++;
}
}
#line 188 "inform7/Chapter 34/Temporal Map.w"
;
if (count == 0) INDEX("<b>never</b>");
INDEX("</p>");
}
#line 127 "inform7/Chapter 34/Temporal Map.w"
;
{
#line 232 "inform7/Chapter 34/Temporal Map.w"
if (Rulebooks__is_empty(sc->end_rulebook[end], NULL) == FALSE) {
HTML__open_para(ifl, 1, "hanging");
INDEX("<i>What happens:</i></p>");
int ignore_me = 0;
Rulebooks__index(sc->end_rulebook[end], "", NULL, NULL, &ignore_me);
}
}
#line 128 "inform7/Chapter 34/Temporal Map.w"
;
if (end == 0)
{
#line 158 "inform7/Chapter 34/Temporal Map.w"
int rbc = 0;
rulebook *rb;
LOOP_OVER(rb, rulebook) {
if (Rulebooks__is_empty(rb, sc) == FALSE) {
if (rbc++ == 0) {
HTML__open_para(ifl, 1, "hanging");
INDEX("<i>During this scene:</i></p>");
}
HTML__open_para(ifl, 2, "hanging");
INDEX("<i>");
Wordings__index_raw(rb->primary_name);
INDEX("</i></p>");
int ignore_me = 0;
Rulebooks__index(rb, "", sc, NULL, &ignore_me);
}
}
}
#line 129 "inform7/Chapter 34/Temporal Map.w"
;
}
}
#line 111 "inform7/Chapter 34/Temporal Map.w"
;
}
}
#line 27 "inform7/Chapter 34/Temporal Map.w"
;
Memory__I7_free(sorted, INDEX_SORTING_MREASON);
}
void PL__Scenes__Index__index_rules(void) {
Rulebooks__index_scene(); /* rules in generic scene-ending rulebooks */
{
#line 95 "inform7/Chapter 34/Temporal Map.w"
INDEX("<p>");
Index__anchor("SRULES");
INDEX("<b>General rules applying to scene changes</b><p>");
Rulebooks__index_rules_box("When a scene begins", EMPTY_WORDING, NULL,
built_in_rulebooks[WHEN_SCENE_BEGINS_RB], NULL, NULL, 1, FALSE);
Rulebooks__index_rules_box("When a scene ends", EMPTY_WORDING, NULL,
built_in_rulebooks[WHEN_SCENE_ENDS_RB], NULL, NULL, 1, FALSE);
}
#line 34 "inform7/Chapter 34/Temporal Map.w"
;
}
#line 255 "inform7/Chapter 34/Temporal Map.w"
void PL__Scenes__Index__index_from_scene(scene *sc, int depth, int end, scene *sc_from, scene **sorted, int nr) {
HTML__open_para(ifl, depth+1, "tight");
{
#line 272 "inform7/Chapter 34/Temporal Map.w"
switch(end) {
case 0: PL__Scenes__Index__scene_icon("Simul"); break;
case 1: PL__Scenes__Index__scene_icon("Segue"); break;
case START_OF_PLAY_END: break;
case NEVER_HAPPENS_END: PL__Scenes__Index__scene_icon("WNever"); break;
default:
PL__Scenes__Index__scene_icon("Segue");
INDEX("[ends ");
Wordings__index_raw(sc_from->end_names[end]);
INDEX("]&nbsp;"); break;
}
if ((sc->indexed == FALSE) || (depth == 0)) {
if (sc == SC_entire_game) PL__Scenes__Index__scene_icon("WPB");
else if (sc->anchor_condition[0]) PL__Scenes__Index__scene_icon("WhenC");
if (sc->start_of_play) PL__Scenes__Index__scene_icon("WPB");
}
}
#line 257 "inform7/Chapter 34/Temporal Map.w"
;
{
#line 292 "inform7/Chapter 34/Temporal Map.w"
if (sc->indexed) INDEX("<i>");
wording NW = Instances__get_name(sc->as_instance, FALSE);
Wordings__index_raw(NW);
if (sc->indexed) INDEX("</i>");
else Index__below_link_numbered(sc->allocation_id);
}
#line 258 "inform7/Chapter 34/Temporal Map.w"
;
if (sc->indexed == FALSE) {
{
#line 301 "inform7/Chapter 34/Temporal Map.w"
int ways_to_end = 0, e;
for (e=1; e<sc->no_ends; e++) {
if (sc->anchor_scene[e]) ways_to_end++;
if (sc->anchor_condition[e]) ways_to_end++;
}
if (ways_to_end == 0) PL__Scenes__Index__scene_icon_append("ENever");
}
#line 260 "inform7/Chapter 34/Temporal Map.w"
;
{
#line 311 "inform7/Chapter 34/Temporal Map.w"
inference_subject *subj = Instances__as_subject(sc->as_instance);
if (World__Inferences__get_EO_state(subj, P_recurring) > UNKNOWN_CE)
PL__Scenes__Index__scene_icon_append("Recurring");
}
#line 261 "inform7/Chapter 34/Temporal Map.w"
;
}
INDEX("</p>");
if (sc->indexed) return;
sc->indexed = TRUE;
{
#line 321 "inform7/Chapter 34/Temporal Map.w"
int i;
for (i=0; i<nr; i++) {
scene *sc2 = sorted[i];
scene_connector *scon;
for (scon = sc2->anchor_scene[0]; scon; scon=scon->next)
if ((scon->connect_to == sc) && (scon->end >= 1))
PL__Scenes__Index__index_from_scene(sc2, depth + 1, scon->end, sc, sorted, nr);
}
for (i=0; i<nr; i++) {
scene *sc2 = sorted[i];
scene_connector *scon;
for (scon = sc2->anchor_scene[0]; scon; scon=scon->next)
if ((scon->connect_to == sc) && (scon->end == 0))
PL__Scenes__Index__index_from_scene(sc2, depth, scon->end, sc, sorted, nr);
}
}
#line 266 "inform7/Chapter 34/Temporal Map.w"
;
}
#line 340 "inform7/Chapter 34/Temporal Map.w"
void PL__Scenes__Index__scene_icon(char *si) {
PL__Scenes__Index__scene_icon_unspaced(si); INDEX("&nbsp;&nbsp;");
}
void PL__Scenes__Index__scene_icon_append(char *si) {
INDEX("&nbsp;&nbsp;"); PL__Scenes__Index__scene_icon_unspaced(si);
}
void PL__Scenes__Index__scene_icon_legend(char *si, char *gloss) {
PL__Scenes__Index__scene_icon_unspaced(si); INDEX("&nbsp;<i>%s</i>", gloss);
}
void PL__Scenes__Index__scene_icon_unspaced(char *si) {
INDEX("<img border=0 src=inform:/scene_icons/%s.png>", si);
}
#line 361 "inform7/Chapter 34/Temporal Map.w"
int PL__Scenes__Index__compare_scenes(const void *ent1, const void *ent2) {
const scene *sc1 = *((const scene **) ent1);
const scene *sc2 = *((const scene **) ent2);
if ((sc1 == SC_entire_game) && (sc2 != SC_entire_game)) return -1;
if ((sc1 != SC_entire_game) && (sc2 == SC_entire_game)) return 1;
wording SW1 = Instances__get_name(sc1->as_instance, FALSE);
wording SW2 = Instances__get_name(sc2->as_instance, FALSE);
return Wordings__strcmp(SW1, SW2);
}
#line 106 "inform7/Chapter 35/Actions.w"
void PL__Actions__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL__Actions__actions_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_COMPILE_CONSTANT, PL__Actions__actions_compile_constant);
PLUGIN_REGISTER(PLUGIN_OFFERED_PROPERTY, PL__Actions__actions_offered_property);
PLUGIN_REGISTER(PLUGIN_OFFERED_SPECIFICATION, PL__Actions__actions_offered_specification);
PLUGIN_REGISTER(PLUGIN_TYPECHECK_EQUALITY, PL__Actions__actions_typecheck_equality);
PLUGIN_REGISTER(PLUGIN_FORBID_SETTING, PL__Actions__actions_forbid_setting);
Vocabulary__set_flags(Vocabulary__entry_for_text("doing"), ACTION_PARTICIPLE_MC);
Vocabulary__set_flags(Vocabulary__entry_for_text("asking"), ACTION_PARTICIPLE_MC);
}
#line 121 "inform7/Chapter 35/Actions.w"
int PL__Actions__actions_new_base_kind_notify(kind *new_base, char *name, wording W) {
if ((name) && (strcmp(name, "ACTION_NAME_TY") == 0)) {
K_action_name = new_base; return TRUE;
}
if ((name) && (strcmp(name, "DESCRIPTION_OF_ACTION_TY") == 0)) {
K_description_of_action = new_base; return TRUE;
}
if ((name) && (strcmp(name, "STORED_ACTION_TY") == 0)) {
K_stored_action = new_base; return TRUE;
}
return FALSE;
}
#line 137 "inform7/Chapter 35/Actions.w"
int PL__Actions__actions_compile_constant(OUTPUT_STREAM, kind *K, parse_node *spec) {
if (Plugins__Manage__plugged_in(actions_plugin) == FALSE)
internal_error("actions plugin inactive");
if (Kinds__Compare__eq(K, K_action_name)) {
action_name *an = Rvalues__to_action_name(spec);
WRITE("##%s", PL__Actions__identifier(an));
return TRUE;
}
if (Kinds__Compare__eq(K, K_description_of_action)) {
action_pattern *ap = ParseTree__get_constant_action_pattern(spec);
PL__Actions__Patterns__compile_pattern_match(OUT, *ap, FALSE);
return TRUE;
}
if (Kinds__Compare__eq(K, K_stored_action)) {
action_pattern *ap = ParseTree__get_constant_action_pattern(spec);
if (TEST_COMPILATION_MODE(CONSTANT_CMODE))
PL__Actions__Patterns__as_stored_action(OUT, ap);
else
PL__Actions__Patterns__compile_try(OUT, ap, TRUE);
return TRUE;
}
return FALSE;
}
int PL__Actions__actions_offered_property(kind *K, parse_node *owner, parse_node *what) {
if (Kinds__Compare__eq(K, K_action_name)) {
action_name *an = Rvalues__to_action_name(owner);
if (an == NULL) internal_error("failed to extract action-name structure");
if (traverse == 1) PL__Actions__an_add_variable(an, what);
return TRUE;
}
return FALSE;
}
int PL__Actions__actions_offered_specification(parse_node *owner, wording W) {
if (Rvalues__is_CONSTANT_of_kind(owner, K_action_name)) {
PL__Actions__actions_set_specification_text(Rvalues__to_action_name(owner), Wordings__first_wn(W));
return TRUE;
}
return FALSE;
}
#line 184 "inform7/Chapter 35/Actions.w"
int PL__Actions__actions_typecheck_equality(kind *K1, kind *K2) {
if ((Kinds__Compare__eq(K1, K_stored_action)) &&
(Kinds__Compare__eq(K2, K_description_of_action)))
return TRUE;
return FALSE;
}
#line 198 "inform7/Chapter 35/Actions.w"
int PL__Actions__actions_forbid_setting(kind *K) {
return FALSE;
}
#line 213 "inform7/Chapter 35/Actions.w"
int notable_actions_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 215 "inform7/Chapter 35/Actions.w"
#line 220 "inform7/Chapter 35/Actions.w"
int action_name_construction_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 222 "inform7/Chapter 35/Actions.w"
#line 226 "inform7/Chapter 35/Actions.w"
action_name *PL__Actions__act_new(wording W, int implemented_by_I7) {
action_name *an = CREATE(action_name);
if ((Preform__parse_nt_against_word_range(notable_actions_NTM, W, NULL, NULL)) && (going_action == NULL)) going_action = an;
an->present_name = W;
an->past_name = Inflections__make_past_of_participle(an->present_name);
an->it_optional = TRUE;
an->abbreviable = FALSE;
an->an_I6_identifier[0] = 0;
an->use_verb_routine_in_I6_library = TRUE;
an->check_rules = NULL;
an->carry_out_rules = NULL;
an->report_rules = NULL;
an->requires_light = FALSE;
an->noun_access = IMPOSSIBLE_ACCESS;
an->second_access = IMPOSSIBLE_ACCESS;
an->min_parameters = 0;
an->max_parameters = 0;
an->noun_kind = K_object;
an->second_kind = K_object;
an->designers_specification = NULL;
an->list_with_action = NULL;
an->out_of_world = FALSE;
an->an_specification_text_word = -1;
Semantics__Nouns__ExcerptMeanings__register_noun_from_assemblage(
MISCELLANEOUS_MC,
Preform__Nonparsing__merge(action_name_construction_NTM, 0,
WordAssemblages__from_wording(W)),
Rvalues__from_action_name(an));
Vocabulary__set_flags(Lexer__word(Wordings__first_wn(W)), ACTION_PARTICIPLE_MC);
Kinds__Behaviour__new_enumerated_value(K_action_name);
LOGIF(ACTION_CREATIONS, "Created action: $w\n", W);
if (implemented_by_I7) {
an->use_verb_routine_in_I6_library = FALSE;
feed_t id = Feeds__begin();
Feeds__feed_text_expanding_strings("check");
Feeds__feed_wording(an->present_name);
wording W = Feeds__end(id);
an->check_rules =
Rulebooks__new_automatic(W, K_action_name,
NO_OUTCOME, TRUE, FALSE, FALSE);
Rulebooks__fragment_by_actions(an->check_rules, 1);
id = Feeds__begin();
Feeds__feed_text_expanding_strings("carry out");
Feeds__feed_wording(an->present_name);
W = Feeds__end(id);
an->carry_out_rules =
Rulebooks__new_automatic(W, K_action_name,
NO_OUTCOME, TRUE, FALSE, FALSE);
Rulebooks__fragment_by_actions(an->carry_out_rules, 2);
id = Feeds__begin();
Feeds__feed_text_expanding_strings("report");
Feeds__feed_wording(an->present_name);
W = Feeds__end(id);
an->report_rules =
Rulebooks__new_automatic(W, K_action_name,
NO_OUTCOME, TRUE, FALSE, FALSE);
Rulebooks__fragment_by_actions(an->report_rules, 1);
an->owned_by_an = StackedVariables__new_owner(20000+an->allocation_id);
} else {
an->owned_by_an = NULL;
}
action_name *an2;
LOOP_OVER(an2, action_name)
if (an != an2)
if (PL__Actions__action_names_overlap(an, an2)) {
an->it_optional = FALSE;
an2->it_optional = FALSE;
}
return an;
}
/* pointing at, pointing it at */
#line 326 "inform7/Chapter 35/Actions.w"
int action_pronoun_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 328 "inform7/Chapter 35/Actions.w"
#line 332 "inform7/Chapter 35/Actions.w"
int PL__Actions__action_names_overlap(action_name *an1, action_name *an2) {
wording W = an1->present_name;
wording XW = an2->present_name;
for (int i = Wordings__first_wn(W), j = Wordings__first_wn(XW);
(i <= Wordings__last_wn(W)) && (j <= Wordings__last_wn(XW));
i++, j++) {
if ((Preform__parse_nt_against_word_range(action_pronoun_NTM, Wordings__one_word(i), NULL, NULL)) && (compare_words(i+1, j))) return TRUE;
if ((Preform__parse_nt_against_word_range(action_pronoun_NTM, Wordings__one_word(j), NULL, NULL)) && (compare_words(j+1, i))) return TRUE;
if (compare_words(i, j) == FALSE) return FALSE;
}
return FALSE;
}
void PL__Actions__log(action_name *an) {
if (an == NULL) LOG("<null-action-name>");
else LOG("$w", an->present_name);
}
#line 355 "inform7/Chapter 35/Actions.w"
int action_name_NTMR(wording W, int *X, void **XP) {
#line 356 "inform7/Chapter 35/Actions.w"
action_name *an;
LOOP_OVER(an, action_name)
if (Wordings__match(W, an->present_name)) {
*XP = an;
return TRUE;
}
LOOP_OVER(an, action_name)
if (Preform__parse_nt_against_word_range(action_optional_trailing_prepositions_NTM, an->present_name, NULL, NULL)) {
wording SHW = GET_RW(action_optional_trailing_prepositions_NTM, 1);
if (Wordings__match(W, SHW)) {
*XP = an;
return TRUE;
}
}
return FALSE;
}
#line 382 "inform7/Chapter 35/Actions.w"
int action_optional_trailing_prepositions_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 384 "inform7/Chapter 35/Actions.w"
#line 388 "inform7/Chapter 35/Actions.w"
action_name *PL__Actions__longest_null(wording W, int tense, int *excess) {
action_name *an;
LOOP_OVER(an, action_name)
if (an->max_parameters == 0) {
wording AW = (tense == IS_TENSE) ? (an->present_name) : (an->past_name);
if (Wordings__starts_with(W, AW)) {
*excess = Wordings__first_wn(W) + Wordings__length(AW);
return an;
}
}
return NULL;
}
int PL__Actions__it_optional(action_name *an) {
return an->it_optional;
}
int PL__Actions__abbreviable(action_name *an) {
return an->abbreviable;
}
char *PL__Actions__identifier(action_name *an) {
return an->an_I6_identifier;
}
rulebook *PL__Actions__get_fragmented_rulebook(action_name *an, rulebook *rb) {
if (rb == built_in_rulebooks[CHECK_RB]) return an->check_rules;
if (rb == built_in_rulebooks[CARRY_OUT_RB]) return an->carry_out_rules;
if (rb == built_in_rulebooks[REPORT_RB]) return an->report_rules;
internal_error("asked for peculiar fragmented rulebook"); return NULL;
}
rulebook *PL__Actions__switch_fragmented_rulebook(action_name *new_an, rulebook *orig) {
action_name *an;
if (new_an == NULL) return orig;
LOOP_OVER(an, action_name) {
if (orig == an->check_rules) return new_an->check_rules;
if (orig == an->carry_out_rules) return new_an->carry_out_rules;
if (orig == an->report_rules) return new_an->report_rules;
}
return orig;
}
void PL__Actions__actions_set_specification_text(action_name *an, int wn) {
an->an_specification_text_word = wn;
}
int PL__Actions__an_get_specification_text(action_name *an) {
return an->an_specification_text_word;
}
#line 443 "inform7/Chapter 35/Actions.w"
void PL__Actions__name_all(void) {
action_name *an;
LOOP_OVER(an, action_name)
if (an->an_I6_identifier[0] == 0)
Identifiers__compose(an->an_I6_identifier,
'A', an->allocation_id, an->present_name);
}
void PL__Actions__translates(wording W, parse_node *p2) {
action_name *an = NULL;
if (Preform__parse_nt_against_word_range(action_name_NTM, W, NULL, NULL)) an = most_recent_result_p;
else {
LOG("Tried action name $w\n", W);
Problems__Issue__sentence_problem(_p_(PM_TranslatesNonAction),
"this does not appear to be the name of an action",
"so cannot be translated into I6 at all.");
return;
}
if (an->an_I6_identifier[0]) {
LOG("Tried action name $w = %s\n", W, an->an_I6_identifier);
Problems__Issue__sentence_problem(_p_(PM_TranslatesActionAlready),
"this action has already been translated",
"so there must be some duplication somewhere.");
return;
}
strcpy(an->an_I6_identifier, Lexer__word_text(Wordings__first_wn(ParseTree__get_text(p2))));
LOGIF(ACTION_CREATIONS, "Translated action: $l as %s\n",
an, Lexer__word_text(Wordings__first_wn(ParseTree__get_text(p2))));
}
int PL__Actions__get_stem_length(action_name *an) {
if (Wordings__empty(an->present_name)) return 0; /* should never happen */
int s = 0;
LOOP_THROUGH_WORDING(k, an->present_name)
if (!(Preform__parse_nt_against_word_range(action_pronoun_NTM, Wordings__one_word(k), NULL, NULL)))
s++;
return s;
}
#line 491 "inform7/Chapter 35/Actions.w"
int action_variable_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 506 "inform7/Chapter 35/Actions.w"
*X = NOT_APPLICABLE;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_BadMatchingSyntax));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for an action - a value associated "
"with a action and which has a name. The request seems to "
"say in parentheses that the name in question is '%2', but "
"I only recognise the form '(matched as \"some text\")' here.");
Problems__issue_problem_end();
}
#line 493 "inform7/Chapter 35/Actions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 495 "inform7/Chapter 35/Actions.w"
#line 499 "inform7/Chapter 35/Actions.w"
int action_variable_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 521 "inform7/Chapter 35/Actions.w"
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_ActionVarAnd));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for an action - a value associated "
"with a action and which has a name. The request seems to "
"say that the name in question is '%2', but I'd prefer to "
"avoid 'and', 'or', 'with', or 'having' in such names, please.");
Problems__issue_problem_end();
}
#line 500 "inform7/Chapter 35/Actions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 502 "inform7/Chapter 35/Actions.w"
#line 535 "inform7/Chapter 35/Actions.w"
void PL__Actions__an_add_variable(action_name *an, parse_node *cnode) {
wording MW = EMPTY_WORDING, NW = EMPTY_WORDING;
stacked_variable *stv = NULL;
if (ParseTree__get_type(cnode) != PROPERTYCALLED_NT) {
Problems__quote_source(1, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_ActionVarUncalled));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for an action - a value associated "
"with a action and which has a name. But since you only give "
"a kind, not a name, I'm stuck. ('The taking action has a "
"number called tenacity' is right, 'The taking action has a "
"number' is too vague.)");
Problems__issue_problem_end();
return;
}
if (an->owned_by_an == NULL) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down->next));
Problems__Issue__handmade_problem(_p_(Untestable)); /* since we no longer define such actions */
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for an action - a value associated "
"with a action and which has a name. But this is a low-level "
"action implemented internally by the Inform 6 library, and "
"I am unable to give it any variables. Sorry.");
Problems__issue_problem_end();
return;
}
NW = ParseTree__get_text(cnode->down->next);
if (Preform__parse_nt_against_word_range(action_variable_NTM, ParseTree__get_text(cnode->down->next), NULL, NULL)) {
if (most_recent_result == NOT_APPLICABLE) return;
NW = GET_RW(action_variable_name_NTM, 1);
if (most_recent_result) {
MW = GET_RW(action_variable_NTM, 1);
int wn = Wordings__first_wn(MW);
Text__dequote_word(wn);
MW = Feeds__feed_text(Lexer__word_text(wn));
if (Wordings__length(MW) > 1) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, MW);
Problems__Issue__handmade_problem(_p_(PM_MatchedAsTooLong));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for an action - a value associated "
"with a action and which has a name. You say that it should "
"be '(matched as \"%2\")', but I can only recognise such "
"matches when a single keyword is used to introduce the "
"clause, and this is more than one word.");
Problems__issue_problem_end();
return;
}
}
}
kind *K = NULL;
if (Preform__parse_nt_against_word_range(k_kind_NTM, ParseTree__get_text(cnode->down), NULL, NULL)) K = most_recent_result_p;
else {
parse_node *spec = NULL;
if (Preform__parse_nt_against_word_range(s_type_expression_NTM, ParseTree__get_text(cnode->down), NULL, NULL)) spec = most_recent_result_p;
if (Specifications__is_description(spec)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down));
Problems__Issue__handmade_problem(_p_(PM_ActionVarOverspecific));
Problems__issue_problem_segment(
"You wrote %1, which I am reading as a request to make "
"a new named variable for an action - a value associated "
"with a action and which has a name. The request seems to "
"say that the value in question is '%2', but this is too "
"specific a description. (Instead, a kind of value "
"(such as 'number') or a kind of object (such as 'room' "
"or 'thing') should be given. To get a property whose "
"contents can be any kind of object, use 'object'.)");
Problems__issue_problem_end();
} else {
LOG("Offending SP: $T", spec);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down));
Problems__Issue__handmade_problem(_p_(PM_ActionVarUnknownKOV));
Problems__issue_problem_segment(
"You wrote %1, but '%2' is not the name of a kind of "
"value which I know (such as 'number' or 'text').");
Problems__issue_problem_end();
}
return;
}
if (Kinds__Compare__eq(K, K_value)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(cnode->down));
Problems__Issue__handmade_problem(_p_(PM_ActionVarValue));
Problems__issue_problem_segment(
"You wrote %1, but saying that a variable is a 'value' "
"does not give me a clear enough idea what it will hold. "
"You need to say what kind of value: for instance, 'A door "
"has a number called street address.' is allowed because "
"'number' is specific about the kind of value.");
Problems__issue_problem_end();
return;
}
if (StackedVariables__owner_empty(an->owned_by_an)) {
all_nonempty_stacked_action_vars =
StackedVariables__add_owner_to_list(all_nonempty_stacked_action_vars, an->owned_by_an);
}
stv = StackedVariables__add_empty(an->owned_by_an, NW, K);
LOGIF(ACTION_CREATIONS, "Created action variable for $l: $w ($u)\n",
an, ParseTree__get_text(cnode->down->next), K);
if (Wordings__nonempty(MW)) {
StackedVariables__set_matching_text(stv, MW);
LOGIF(ACTION_CREATIONS, "Match with text: $w + SP\n", MW);
}
}
stacked_variable *PL__Actions__parse_match_clause(action_name *an, wording W) {
return StackedVariables__parse_match_clause(an->owned_by_an, W);
}
void PL__Actions__compile_action_name_var_creators(OUTPUT_STREAM) {
action_name *an;
LOOP_OVER(an, action_name) {
if ((an->owned_by_an) &&
(StackedVariables__owner_empty(an->owned_by_an) == FALSE))
StackedVariables__compile_frame_creator(OUT, an->owned_by_an,
"ANSTVC_%d", an->allocation_id);
}
}
#line 673 "inform7/Chapter 35/Actions.w"
sentence_handler NEW_ACTION_SH_handler =
{ SENTENCE_NT, NEW_ACTION_VB, 1, PL__Actions__act_parse_definition };
#line 685 "inform7/Chapter 35/Actions.w"
action_name *an_being_parsed = NULL;
#line 697 "inform7/Chapter 35/Actions.w"
int action_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 704 "inform7/Chapter 35/Actions.w"
*XP = NULL;
Problems__Issue__sentence_problem(_p_(PM_ActionAlreadyExists),
"that seems to be an action already existing",
"so it cannot be redefined now. If you would like to reconfigure "
"an action in the standard set - for instance if you prefer "
"'unlocking' to apply to only one thing, not two - create a new "
"action for what you need ('keyless unlocking', perhaps) and then "
"change the grammar to use the new action rather than the old "
"('Understand \"unlock [something]\" as keyless unlocking.').");
}
#line 698 "inform7/Chapter 35/Actions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = PL__Actions__act_new(W, TRUE);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 700 "inform7/Chapter 35/Actions.w"
#line 725 "inform7/Chapter 35/Actions.w"
int action_clause_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = OOW_ACT_CLAUSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = ABBREV_ACT_CLAUSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = PP_ACT_CLAUSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = APPLYING_ACT_CLAUSE; num_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = LIGHT_ACT_CLAUSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 731 "inform7/Chapter 35/Actions.w"
int action_applications_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2; kind_op1_NTMV = RP[1]; ac1_NTMV = R[1]; kind_op2_NTMV = RP[2]; ac2_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 2; kind_op1_NTMV = RP[1]; ac1_NTMV = R[1]; kind_op2_NTMV = RP[2]; ac2_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 2; kind_op1_NTMV = RP[1]; ac1_NTMV = R[1]; kind_op2_NTMV = RP[2]; ac2_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 2; kind_op1_NTMV = RP[1]; ac1_NTMV = R[1]; kind_op2_NTMV = RP[2]; ac2_NTMV = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = -1; kind_op1_NTMV = RP[1]; ac1_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = 1; kind_op1_NTMV = RP[1]; ac1_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = 2; kind_op1_NTMV = RP[1]; ac1_NTMV = R[1]; kind_op2_NTMV = RP[1]; ac2_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = 1; kind_op1_NTMV = RP[1]; ac1_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9:
{
#line 831 "inform7/Chapter 35/Actions.w"
*X = REQUIRES_ACCESS; *XP = K_thing;
Problems__Issue__sentence_problem(_p_(PM_ActionMisapplied),
"an action can only apply to things or to kinds of value",
"for instance: 'photographing is an action applying to "
"one visible thing'.");
}
#line 742 "inform7/Chapter 35/Actions.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 743 "inform7/Chapter 35/Actions.w"
int act_req_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; *XP = RP[2];
{
#line 819 "inform7/Chapter 35/Actions.w"
if (Kinds__Compare__eq(*XP, K_thing)) {
if (*X == UNRESTRICTED_ACCESS) *X = REQUIRES_ACCESS;
*XP = K_object;
} else if (Kinds__Compare__lt(*XP, K_object)) {
{
#line 831 "inform7/Chapter 35/Actions.w"
*X = REQUIRES_ACCESS; *XP = K_thing;
Problems__Issue__sentence_problem(_p_(PM_ActionMisapplied),
"an action can only apply to things or to kinds of value",
"for instance: 'photographing is an action applying to "
"one visible thing'.");
}
#line 823 "inform7/Chapter 35/Actions.w"
;
} else {
if (*X != UNRESTRICTED_ACCESS)
{
#line 831 "inform7/Chapter 35/Actions.w"
*X = REQUIRES_ACCESS; *XP = K_thing;
Problems__Issue__sentence_problem(_p_(PM_ActionMisapplied),
"an action can only apply to things or to kinds of value",
"for instance: 'photographing is an action applying to "
"one visible thing'.");
}
#line 825 "inform7/Chapter 35/Actions.w"
;
}
}
#line 745 "inform7/Chapter 35/Actions.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = UNRESTRICTED_ACCESS; *XP = RP[1];
{
#line 819 "inform7/Chapter 35/Actions.w"
if (Kinds__Compare__eq(*XP, K_thing)) {
if (*X == UNRESTRICTED_ACCESS) *X = REQUIRES_ACCESS;
*XP = K_object;
} else if (Kinds__Compare__lt(*XP, K_object)) {
{
#line 831 "inform7/Chapter 35/Actions.w"
*X = REQUIRES_ACCESS; *XP = K_thing;
Problems__Issue__sentence_problem(_p_(PM_ActionMisapplied),
"an action can only apply to things or to kinds of value",
"for instance: 'photographing is an action applying to "
"one visible thing'.");
}
#line 823 "inform7/Chapter 35/Actions.w"
;
} else {
if (*X != UNRESTRICTED_ACCESS)
{
#line 831 "inform7/Chapter 35/Actions.w"
*X = REQUIRES_ACCESS; *XP = K_thing;
Problems__Issue__sentence_problem(_p_(PM_ActionMisapplied),
"an action can only apply to things or to kinds of value",
"for instance: 'photographing is an action applying to "
"one visible thing'.");
}
#line 825 "inform7/Chapter 35/Actions.w"
;
}
}
#line 746 "inform7/Chapter 35/Actions.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 747 "inform7/Chapter 35/Actions.w"
int action_access_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = DOESNT_REQUIRE_ACCESS;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = REQUIRES_ACCESS;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = REQUIRES_POSSESSION;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 752 "inform7/Chapter 35/Actions.w"
#line 756 "inform7/Chapter 35/Actions.w"
int action_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 774 "inform7/Chapter 35/Actions.w"
Problems__Issue__sentence_problem(_p_(PM_ActionClauseUnknown),
"the action definition contained text I couldn't follow",
"and may be too complicated.");
}
#line 758 "inform7/Chapter 35/Actions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 759 "inform7/Chapter 35/Actions.w"
int action_clauses_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return preform_lookahead_mode; /* match only on lookahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[2];
{
#line 781 "inform7/Chapter 35/Actions.w"
switch (*X) {
case OOW_ACT_CLAUSE:
an_being_parsed->out_of_world = TRUE; break;
case PP_ACT_CLAUSE: {
wording C = GET_RW(action_clause_NTM, 1);
if (Wordings__length(C) != 1)
Problems__Issue__sentence_problem(_p_(PM_MultiwordPastParticiple),
"a past participle must be given as a single word",
"even if the action name itself is longer than that. "
"(For instance, the action name 'hanging around until' "
"should have past participle given just as 'hung'; I "
"can already deduce the rest.)");
an_being_parsed->past_name =
Inflections__set_past_participle(an_being_parsed->past_name,
Wordings__last_wn(C));
break;
}
case APPLYING_ACT_CLAUSE:
an_being_parsed->noun_access = ac1_NTMV; an_being_parsed->second_access = ac2_NTMV;
an_being_parsed->noun_kind = kind_op1_NTMV; an_being_parsed->second_kind = kind_op2_NTMV;
an_being_parsed->min_parameters = num_NTMV;
an_being_parsed->max_parameters = an_being_parsed->min_parameters;
if (an_being_parsed->min_parameters == -1) {
an_being_parsed->min_parameters = 0;
an_being_parsed->max_parameters = 1;
}
break;
case LIGHT_ACT_CLAUSE:
an_being_parsed->requires_light = TRUE;
break;
case ABBREV_ACT_CLAUSE:
an_being_parsed->abbreviable = TRUE;
break;
}
}
#line 762 "inform7/Chapter 35/Actions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1];
{
#line 781 "inform7/Chapter 35/Actions.w"
switch (*X) {
case OOW_ACT_CLAUSE:
an_being_parsed->out_of_world = TRUE; break;
case PP_ACT_CLAUSE: {
wording C = GET_RW(action_clause_NTM, 1);
if (Wordings__length(C) != 1)
Problems__Issue__sentence_problem(_p_(PM_MultiwordPastParticiple),
"a past participle must be given as a single word",
"even if the action name itself is longer than that. "
"(For instance, the action name 'hanging around until' "
"should have past participle given just as 'hung'; I "
"can already deduce the rest.)");
an_being_parsed->past_name =
Inflections__set_past_participle(an_being_parsed->past_name,
Wordings__last_wn(C));
break;
}
case APPLYING_ACT_CLAUSE:
an_being_parsed->noun_access = ac1_NTMV; an_being_parsed->second_access = ac2_NTMV;
an_being_parsed->noun_kind = kind_op1_NTMV; an_being_parsed->second_kind = kind_op2_NTMV;
an_being_parsed->min_parameters = num_NTMV;
an_being_parsed->max_parameters = an_being_parsed->min_parameters;
if (an_being_parsed->min_parameters == -1) {
an_being_parsed->min_parameters = 0;
an_being_parsed->max_parameters = 1;
}
break;
case LIGHT_ACT_CLAUSE:
an_being_parsed->requires_light = TRUE;
break;
case ABBREV_ACT_CLAUSE:
an_being_parsed->abbreviable = TRUE;
break;
}
}
#line 763 "inform7/Chapter 35/Actions.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 764 "inform7/Chapter 35/Actions.w"
int action_clause_terminated_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 770 "inform7/Chapter 35/Actions.w"
#line 840 "inform7/Chapter 35/Actions.w"
void PL__Actions__act_parse_definition(parse_node *p) {
Preform__parse_nt_against_word_range(action_sentence_subject_NTM, ParseTree__get_text(p->down->next), NULL, NULL);
action_name *an = most_recent_result_p;
if (an == NULL) return;
if (p->down->next->next) {
an->designers_specification = p->down->next->next;
an_being_parsed = an;
ac1_NTMV = IMPOSSIBLE_ACCESS;
ac2_NTMV = IMPOSSIBLE_ACCESS;
kind_op1_NTMV = K_object;
kind_op2_NTMV = K_object;
num_NTMV = 0;
Preform__parse_nt_against_word_range(action_sentence_object_NTM, ParseTree__get_text(p->down->next->next), NULL, NULL);
}
if (an->max_parameters >= 2) {
if ((Kinds__Compare__le(an->noun_kind, K_object) == FALSE) &&
(Kinds__Compare__le(an->second_kind, K_object) == FALSE)) {
Problems__Issue__sentence_problem(_p_(PM_ActionBothValues),
"this action definition asks to have a single action apply "
"to two different things which are not objects",
"and unfortunately a fundamental restriction is that an "
"action can apply to two objects, or one object and one "
"value, but not to two values. Sorry about that.");
return;
}
}
}
int PL__Actions__is_out_of_world(action_name *an) {
if (an->out_of_world) return TRUE;
return FALSE;
}
kind *PL__Actions__get_data_type_of_noun(action_name *an) {
return an->noun_kind;
}
kind *PL__Actions__get_data_type_of_second_noun(action_name *an) {
return an->second_kind;
}
wording PL__Actions__set_text_to_name_tensed(action_name *an, int tense) {
if (tense == HASBEEN_TENSE) return an->past_name;
return an->present_name;
}
int PL__Actions__can_have_parameters(action_name *an) {
if (an->max_parameters > 0) return TRUE;
return FALSE;
}
int PL__Actions__get_max_parameters(action_name *an) {
return an->max_parameters;
}
int PL__Actions__get_min_parameters(action_name *an) {
return an->min_parameters;
}
#line 911 "inform7/Chapter 35/Actions.w"
int PL__Actions__can_be_compiled_in_past_tense(action_name *an) {
if (an->min_parameters > 1) return FALSE;
if (an->max_parameters > 1) return FALSE;
if ((an->max_parameters == 1) &&
(Kinds__Compare__le(an->noun_kind, K_object) == FALSE))
return FALSE;
return TRUE;
}
void PL__Actions__compile_action_bitmap_property(OUTPUT_STREAM) {
int i;
for (i=0; i<=((NUMBER_CREATED(action_name))/16); i++) WRITE("0 ");
}
void PL__Actions__ActionHappened_array(OUTPUT_STREAM) {
int i = 0;
WRITE("Array ActionHappened -->");
for (i=0; i<=((NUMBER_CREATED(action_name))/16); i++) {
WRITE(" 0");
}
WRITE(";\n\n");
}
#line 937 "inform7/Chapter 35/Actions.w"
void PL__Actions__add_gl(action_name *an, grammar_line *gl) {
if (an->list_with_action == NULL) an->list_with_action = gl;
else PL__Parsing__Lines__list_with_action_add(an->list_with_action, gl);
}
void PL__Actions__remove_gl(action_name *an) {
an->list_with_action = NULL;
}
#line 949 "inform7/Chapter 35/Actions.w"
void PL__Actions__check_types_for_grammar(action_name *an, int tok_values,
kind **tok_value_kinds) {
int required = 0; char *failed_on = "<internal error>";
if (an->noun_access != IMPOSSIBLE_ACCESS)
required++;
if (an->second_access != IMPOSSIBLE_ACCESS)
required++;
if (required < tok_values) {
switch(required) {
case 0:
failed_on =
"this action applies to nothing, but you have provided "
"material in square brackets which expands to something";
break;
case 1:
failed_on =
"this action applies to just one thing, but you have "
"put more than one thing in square brackets";
break;
default:
failed_on =
"this action applies to two things, the maximum possible, "
"but you have put more than two in square brackets";
break;
}
goto Unmatched;
}
if (tok_values >= 1) {
switch(an->noun_access) {
case UNRESTRICTED_ACCESS: {
kind *supplied_data_type = tok_value_kinds[0];
kind *desired_data_type = an->noun_kind;
if (Kinds__Compare__compatible(supplied_data_type, desired_data_type)
!= ALWAYS_MATCH) {
failed_on =
"the thing you suggest this action should act on "
"has the wrong kind of value";
goto Unmatched;
}
break;
}
case REQUIRES_ACCESS:
case REQUIRES_POSSESSION:
case DOESNT_REQUIRE_ACCESS:
if (Kinds__Compare__le(tok_value_kinds[0], K_object) == FALSE) {
failed_on =
"the thing you suggest this action should act on "
"is not an object at all";
goto Unmatched;
}
break;
}
}
if (tok_values == 2) {
switch(an->second_access) {
case UNRESTRICTED_ACCESS: {
kind *supplied_data_type = tok_value_kinds[1];
kind *desired_data_type = an->second_kind;
if (Kinds__Compare__compatible(supplied_data_type, desired_data_type)
!= ALWAYS_MATCH) {
failed_on =
"the second thing you suggest this action should act on "
"has the wrong kind of value";
goto Unmatched;
}
break;
}
case REQUIRES_ACCESS:
case REQUIRES_POSSESSION:
case DOESNT_REQUIRE_ACCESS:
if (Kinds__Compare__le(tok_value_kinds[1], K_object) == FALSE) {
failed_on =
"the second thing you suggest this action should act on "
"is not an object at all";
goto Unmatched;
}
break;
}
}
return;
Unmatched:
LOG("%d token values supplied\n", tok_values);
{ int i;
for (i=0; i<tok_values; i++)
LOG("Token value %d: $u\n", i, tok_value_kinds[i]);
LOG("Expected noun K: $u\n", an->noun_kind);
LOG("Expected second K: $u\n", an->second_kind);
LOG("Noun access level: %d\n", an->noun_access);
LOG("Second access level: %d\n", an->second_access);
}
Problems__quote_source(1, current_sentence);
if (an->designers_specification == NULL)
Problems__quote_text(2, "<none given>");
else
Problems__quote_wording(2, ParseTree__get_text(an->designers_specification));
Problems__quote_wording(3, an->present_name);
Problems__quote_text(4, failed_on);
Problems__Issue__handmade_problem(_p_(PM_GrammarMismatchesAction));
Problems__issue_problem_segment("The grammar you give in %1 is not compatible "
"with the %3 action (defined as '%2') - %4.");
Problems__issue_problem_end();
}
#line 1061 "inform7/Chapter 35/Actions.w"
void PL__Actions__compile_action_routines(OUTPUT_STREAM) {
action_name *an;
LOOP_OVER(an, action_name) {
if (an->use_verb_routine_in_I6_library) continue;
char vname[32];
sprintf(vname, "%sSub", an->an_I6_identifier);
OUT = Routines__begin(OUT, vname);
WRITE("return GenericVerbSub(%d,%d,%d);\n",
an->check_rules->allocation_id,
an->carry_out_rules->allocation_id,
an->report_rules->allocation_id);
OUT = Routines__end(OUT);
}
}
#line 1080 "inform7/Chapter 35/Actions.w"
void PL__Actions__ActionData_array(OUTPUT_STREAM) {
action_name *an;
int mn, ms, ml, mnp, msp, hn, hs, record_count = 0;
WRITE("Array ActionData table\n");
LOOP_OVER(an, action_name) {
if (an->use_verb_routine_in_I6_library) continue;
mn = 0; ms = 0; ml = 0; mnp = 1; msp = 1; hn = 0; hs = 0;
if (an->requires_light) ml = 1;
if (an->noun_access == REQUIRES_ACCESS) mn = 1;
if (an->second_access == REQUIRES_ACCESS) ms = 1;
if (an->noun_access == REQUIRES_POSSESSION) { mn = 1; hn = 1; }
if (an->second_access == REQUIRES_POSSESSION) { ms = 1; hs = 1; }
if (an->noun_access == IMPOSSIBLE_ACCESS) mnp = 0;
if (an->second_access == IMPOSSIBLE_ACCESS) msp = 0;
record_count++;
WRITE(" ##%-32s $$%d%d%d%d%d%d%d%d ",
an->an_I6_identifier,
hs, hn,
(an->out_of_world)?1:0, msp, mnp, ml, ms, mn);
Kinds__RunTime__compile_strong_id(OUT, an->noun_kind); WRITE(" ");
Kinds__RunTime__compile_strong_id(OUT, an->second_kind); WRITE(" ");
if ((an->owned_by_an) &&
(StackedVariables__owner_empty(an->owned_by_an) == FALSE))
WRITE(" ANSTVC_%d", an->allocation_id);
else WRITE(" 0");
WRITE(" %d", 20000+an->allocation_id);
WRITE("\n");
}
WRITE(";\n");
WRITE("Constant AD_RECORDS = %d;\n", record_count);
PL__Actions__compile_action_name_var_creators(OUT);
VirtualMachines__note_usage("action", EMPTY_WORDING, NULL, 12, 0, TRUE);
OUT = Routines__begin(OUT, "DB_Action_Details");
LocalVariables__add_named_call("act");
LocalVariables__add_named_call("n");
LocalVariables__add_named_call("s");
LocalVariables__add_named_call("for_say");
PL__Actions__DB_Action_Details(OUT);
OUT = Routines__end(OUT);
}
void PL__Actions__DB_Action_Details(OUTPUT_STREAM) {
action_name *an;
WRITE("switch (act) {\n"); INDENT;
LOOP_OVER(an, action_name) {
if (an->use_verb_routine_in_I6_library) continue;
WRITE("##%s: ", an->an_I6_identifier);
int j = Wordings__first_wn(an->present_name), j0 = -1, somethings = 0, clc = 0;
while (j <= Wordings__last_wn(an->present_name)) {
if (Preform__parse_nt_against_word_range(action_pronoun_NTM, Wordings__one_word(j), NULL, NULL)) {
if (j0 >= 0) {
{
#line 1165 "inform7/Chapter 35/Actions.w"
if (clc++ > 0) WRITE("print \" \"; ");
}
#line 1131 "inform7/Chapter 35/Actions.w"
;
WRITE("print \"");
PL__Actions__print_action_text_to(Wordings__new(j0, j-1), Wordings__first_wn(an->present_name), OUT);
WRITE("\"; ");
j0 = -1;
}
{
#line 1165 "inform7/Chapter 35/Actions.w"
if (clc++ > 0) WRITE("print \" \"; ");
}
#line 1137 "inform7/Chapter 35/Actions.w"
;
WRITE("if (for_say == 2) print \"it\"; else ");
PL__Actions__cat_something2(OUT, an, somethings++);
} else {
if (j0<0) j0 = j;
}
j++;
}
if (j0 >= 0) {
{
#line 1165 "inform7/Chapter 35/Actions.w"
if (clc++ > 0) WRITE("print \" \"; ");
}
#line 1146 "inform7/Chapter 35/Actions.w"
;
WRITE("print \"");
PL__Actions__print_action_text_to(Wordings__new(j0, j-1), Wordings__first_wn(an->present_name), OUT);
WRITE("\"; ");
}
if (somethings < an->max_parameters) {
WRITE("if (for_say ~= 2) { ");
{
#line 1165 "inform7/Chapter 35/Actions.w"
if (clc++ > 0) WRITE("print \" \"; ");
}
#line 1153 "inform7/Chapter 35/Actions.w"
;
PL__Actions__cat_something2(OUT, an, somethings++);
WRITE("}");
}
WRITE("\n");
}
OUTDENT; WRITE("}\n");
}
#line 1170 "inform7/Chapter 35/Actions.w"
void PL__Actions__cat_something2(OUTPUT_STREAM, action_name *an, int n) {
kind *K = an->noun_kind;
char *var = "n";
if (n > 0) {
K = an->second_kind; var = "s";
}
if (Kinds__Compare__eq(K, K_understanding)) var = "100*consult_from + consult_words";
else if (Kinds__Compare__le(K, K_object) == FALSE) var = "parsed_number";
WRITE("%s(%s); ", Kinds__Behaviour__get_name_of_printing_rule_ACTIONS(K), var);
}
void PL__Actions__print_action_text_to(wording W, int start, OUTPUT_STREAM) {
if (Wordings__first_wn(W) == start) {
Wordings__to_stream(OUT, Wordings__first_word(W));
W = Wordings__trim_first_word(W);
if (Wordings__empty(W)) return;
WRITE(" ");
}
Wordings__to_stream_raw(OUT, W);
}
void PL__Actions__ActionCoding_array(OUTPUT_STREAM) {
int i = 0;
action_name *an;
WRITE("Array ActionCoding -->");
LOOP_OVER(an, action_name) {
if ((i++)%8 == 0) WRITE("\n ");
if ((an->an_I6_identifier)[0] == '_')
WRITE(" 0");
else WRITE(" ##%s", an->an_I6_identifier);
}
WRITE(";\n\n");
}
#line 1207 "inform7/Chapter 35/Actions.w"
int PL__Actions__index(action_name *an, int pass,
extension_file **ext, heading **current_area, int f, int *new_par, int bold,
int on_details_page) {
if (an->use_verb_routine_in_I6_library) return f;
heading *definition_area = Wordings__heading_of(an->present_name);
*new_par = FALSE;
if (pass == 1) {
extension_file *this_extension =
Sentences__Headings__get_extension_containing(definition_area);
if (*ext != this_extension) {
*ext = this_extension;
if (*ext == NULL) {
INDEX("<p><b>New actions defined in the source</b><br>");
} else
if (*ext != standard_rules_extension) {
INDEX("<p><b>Actions defined by the extension ");
Extensions__Files__write_name_to_file(*ext, ifl);
INDEX(" by ");
Extensions__Files__write_author_to_file(*ext, ifl);
INDEX("</b><br>");
}
f = FALSE;
*new_par = TRUE;
}
if ((definition_area != *current_area) && (*ext == standard_rules_extension)) {
if (f) INDEX("<p>");
wording W = Sentences__Headings__get_text(definition_area);
if (Wordings__nonempty(W)) {
Phrases__Index__index_definition_area(W, TRUE);
f = FALSE;
*new_par = TRUE;
} else {
if (*ext == NULL) {
INDEX("<b>");
INDEX("New actions");
INDEX("</b><br>");
f = FALSE;
*new_par = TRUE;
}
}
}
}
if ((pass == 1) && (f)) INDEX(", ");
f = TRUE;
*current_area = definition_area;
if (pass == 2) INDEX("<b>");
if (an->out_of_world) INDEX("<font color=\"#800000\">");
if (pass == 1) {
if (bold) INDEX("<b>");
Wordings__index_raw(an->present_name);
if (bold) INDEX("</b>");
} else {
int j = Wordings__first_wn(an->present_name);
int somethings = 0;
while (j <= Wordings__last_wn(an->present_name)) {
if (Preform__parse_nt_against_word_range(action_pronoun_NTM, Wordings__one_word(j), NULL, NULL)) {
PL__Actions__act_index_something(an, somethings++);
} else {
Wordings__index_raw(Wordings__one_word(j));
INDEX(" ");
}
j++;
}
if (somethings < an->max_parameters)
PL__Actions__act_index_something(an, somethings++);
}
if (an->out_of_world) INDEX("</font>");
if (pass == 2) {
int swn = PL__Actions__an_get_specification_text(an);
INDEX("</b>");
Index__link(Wordings__first_wn(ParseTree__get_text(an->designers_specification)));
Index__anchor(an->an_I6_identifier);
if (an->requires_light) INDEX(" (requires light)");
INDEX(" (<i>past tense</i> ");
Wordings__index_raw(an->past_name);
INDEX(")<br>\n");
INDEX("<p>");
if (swn >= 0) {
Wordings__index(Wordings__one_word(swn));
INDEX("<p>");
}
INDEX("<hr>");
INDEX("<p><b>Typed commands leading to this action</b><p>\n");
if (PL__Parsing__Lines__index_list_with_action(an->list_with_action) == FALSE)
INDEX("<i>None</i>");
if (StackedVariables__owner_empty(an->owned_by_an) == FALSE) {
INDEX("<p><b>Named values belonging to this action</b></p>\n");
StackedVariables__index_owner(an->owned_by_an);
}
INDEX("<p><b>Rules controlling this action</b></p><p>\n");
int resp_count = 0;
if (an->out_of_world == FALSE) {
Rulebooks__index_action_rules(an, NULL, PERSUASION_RB, "persuasion", &resp_count);
Rulebooks__index_action_rules(an, NULL, UNSUCCESSFUL_ATTEMPT_BY_RB, "unsuccessful attempt", &resp_count);
Rulebooks__index_action_rules(an, NULL, SETTING_ACTION_VARIABLES_RB, "set action variables for", &resp_count);
Rulebooks__index_action_rules(an, NULL, BEFORE_RB, "before", &resp_count);
Rulebooks__index_action_rules(an, NULL, INSTEAD_RB, "instead of", &resp_count);
}
Rulebooks__index_action_rules(an, an->check_rules, CHECK_RB, "check", &resp_count);
Rulebooks__index_action_rules(an, an->carry_out_rules, CARRY_OUT_RB, "carry out", &resp_count);
if (an->out_of_world == FALSE) {
Rulebooks__index_action_rules(an, NULL, AFTER_RB, "after", &resp_count);
}
Rulebooks__index_action_rules(an, an->report_rules, REPORT_RB, "report", &resp_count);
if (resp_count > 1) {
INDEX("Click on the speech-bubble icons to see the responses, "
"or here to see all of them:");
INDEX("&nbsp;");
Index__extra_link_with(2000000, "responses");
INDEX("%d", resp_count);
INDEX("</p>");
}
} else {
Index__link(Wordings__first_wn(ParseTree__get_text(an->designers_specification)));
Index__detail_link("A", an->allocation_id, (on_details_page)?FALSE:TRUE);
}
return f;
}
void PL__Actions__act_index_something(action_name *an, int argc) {
kind *K = NULL; /* redundant assignment to appease |gcc -O2| */
INDEX("<font color=\"#000080\">");
if (argc == 0) K = an->noun_kind;
if (argc == 1) K = an->second_kind;
if (Kinds__Compare__le(K, K_object)) INDEX("something");
else if (Kinds__Compare__eq(K, K_understanding)) INDEX("some text");
else Kinds__Textual__write(ifl, K);
INDEX("</font> ");
}
#line 38 "inform7/Chapter 35/Action Name Lists.w"
action_name_list *PL__Actions__Lists__anl_new(void) {
action_name_list *new_anl = CREATE(action_name_list);
new_anl->action_listed = NULL;
new_anl->nap_listed = NULL;
new_anl->parc = 0;
new_anl->word_position = -1;
new_anl->parity = 1;
new_anl->negate_pattern = FALSE;
new_anl->in_clause = EMPTY_WORDING;
new_anl->abbreviation_level = 0;
new_anl->anyone_specified = FALSE;
new_anl->delete_this_link = FALSE;
return new_anl;
}
void PL__Actions__Lists__log(action_name_list *anl) {
int i, c;
for (c=0; anl; anl = anl->next, c++) {
LOG("ANL entry %s(%d@%d): %s ",
(anl->delete_this_link)?"(to be deleted) ":"",
c, anl->word_position,
(anl->parity==1)?"+":"-");
if (anl->action_listed)
LOG("$w", anl->action_listed->present_name);
if (anl->nap_listed)
LOG("$w", anl->nap_listed->text_of_declaration);
else LOG("NULL");
for (i=0; i<anl->parc; i++)
LOG(" [%d: $w]", i, anl->parameter[i]);
LOG(" [in: $w]\n", anl->in_clause);
}
}
void PL__Actions__Lists__log_briefly(action_name_list *anl) {
if (anl == NULL) LOG("<null-anl>");
else {
if (anl->negate_pattern) LOG("NOT[ ");
action_name_list *a;
for (a = anl; a; a = a->next) {
if (a->nap_listed) {
if (a->parity == -1) LOG("not-");
LOG("$w / ", a->nap_listed->text_of_declaration);
} else if (a->action_listed == NULL)
LOG("ANY / ");
else {
if (a->parity == -1) LOG("not-");
LOG("$w / ", a->action_listed->present_name);
}
}
if (anl->negate_pattern) LOG(" ]");
}
}
action_name *PL__Actions__Lists__get_singleton_action(action_name_list *anl) {
action_name *an;
if (anl == NULL) internal_error("Supposed singleton ANL is empty");
an = anl->action_listed;
if (an == NULL) internal_error("Singleton ANL points to null AN");
return an;
}
action_name_list *anl_being_parsed = NULL;
#line 111 "inform7/Chapter 35/Action Name Lists.w"
int action_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 131 "inform7/Chapter 35/Action Name Lists.w"
*X = TRUE;
action_name_list *new_anl = PL__Actions__Lists__anl_new();
new_anl->word_position = Wordings__first_wn(W);
*XP = new_anl;
}
#line 115 "inform7/Chapter 35/Action Name Lists.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = TRUE; *XP = NULL; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = TRUE; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 118 "inform7/Chapter 35/Action Name Lists.w"
int anl_excluded_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 245 "inform7/Chapter 35/Action Name Lists.w"
action_name_list *anl = PL__Actions__Lists__flip_anl_parity(RP[1], TRUE);
if ((anl == NULL) ||
(PL__Actions__can_have_parameters(anl->action_listed) == FALSE))
return FALSE;
anl->parameter[anl->parc] = GET_RW(anl_excluded_NTM, 1);
anl->parc++;
*XP = anl;
}
#line 120 "inform7/Chapter 35/Action Name Lists.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE; *XP = PL__Actions__Lists__flip_anl_parity(RP[1], FALSE);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 122 "inform7/Chapter 35/Action Name Lists.w"
int anl_minimal_common_operand_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE; return FAIL_NONTERMINAL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 127 "inform7/Chapter 35/Action Name Lists.w"
#line 148 "inform7/Chapter 35/Action Name Lists.w"
int anl_to_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 163 "inform7/Chapter 35/Action Name Lists.w"
action_name_list *anl = RP[1];
anl->in_clause = GET_RW(anl_in_tail_NTM, 1);
}
#line 149 "inform7/Chapter 35/Action Name Lists.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 151 "inform7/Chapter 35/Action Name Lists.w"
int anl_operand_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 169 "inform7/Chapter 35/Action Name Lists.w"
*X = TRUE;
action_name_list *new_anl;
if ((!preform_lookahead_mode) && (anl_being_parsed)) new_anl = anl_being_parsed;
else {
new_anl = PL__Actions__Lists__anl_new();
new_anl->word_position = Wordings__first_wn(W);
}
new_anl->parameter[new_anl->parc] = W;
new_anl->parc++;
*XP = new_anl;
}
#line 153 "inform7/Chapter 35/Action Name Lists.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 154 "inform7/Chapter 35/Action Name Lists.w"
int anl_in_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE; return FAIL_NONTERMINAL + Wordings__first_wn(anl_in_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE; return FAIL_NONTERMINAL + Wordings__first_wn(anl_in_tail_NTM->range_result[1]) - Wordings__first_wn(W);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 159 "inform7/Chapter 35/Action Name Lists.w"
#line 183 "inform7/Chapter 35/Action Name Lists.w"
int anl_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 256 "inform7/Chapter 35/Action Name Lists.w"
action_name_list *left_atom = RP[1];
action_name_list *right_tail = RP[2];
if (left_atom == NULL) { *XP = right_tail; }
else if (right_tail == NULL) { *XP = left_atom; }
else {
action_name_list *new_anl = right_tail;
while (new_anl->next != NULL) new_anl = new_anl->next;
new_anl->next = left_atom;
*XP = right_tail;
}
}
#line 184 "inform7/Chapter 35/Action Name Lists.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 186 "inform7/Chapter 35/Action Name Lists.w"
int anl_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 190 "inform7/Chapter 35/Action Name Lists.w"
#line 202 "inform7/Chapter 35/Action Name Lists.w"
int anl_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 226 "inform7/Chapter 35/Action Name Lists.w"
*X = 0;
action_name_list *new_anl = PL__Actions__Lists__anl_new();
new_anl->word_position = Wordings__first_wn(W);
new_anl->nap_listed = RP[1];
*XP = new_anl;
}
#line 203 "inform7/Chapter 35/Action Name Lists.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 235 "inform7/Chapter 35/Action Name Lists.w"
*X = 0;
action_name_list *new_anl = PL__Actions__Lists__anl_new();
new_anl->word_position = Wordings__first_wn(W);
new_anl->nap_listed = RP[1];
new_anl->in_clause = GET_RW(anl_in_tail_NTM, 1);
*XP = new_anl;
}
#line 204 "inform7/Chapter 35/Action Name Lists.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 206 "inform7/Chapter 35/Action Name Lists.w"
int named_action_pattern_NTMR(wording W, int *X, void **XP) {
#line 208 "inform7/Chapter 35/Action Name Lists.w"
named_action_pattern *nap = PL__Actions__Patterns__Named__by_name(W);
if (nap) {
*XP = nap; return TRUE;
}
return FALSE;
}
int anl_entry_with_action_NTMR(wording W, int *X, void **XP) {
#line 216 "inform7/Chapter 35/Action Name Lists.w"
action_name_list *anl = PL__Actions__Lists__anl_parse_internal(W);
if (anl) {
*XP = anl; return TRUE;
}
return FALSE;
}
#line 271 "inform7/Chapter 35/Action Name Lists.w"
action_name_list *PL__Actions__Lists__flip_anl_parity(action_name_list *anl, int flip_all) {
if (flip_all) {
action_name_list *L;
for (L = anl; L; L = L->next) {
L->parity = (L->parity == 1)?(-1):1;
}
} else {
anl->negate_pattern = (anl->negate_pattern)?FALSE:TRUE;
}
return anl;
}
#line 286 "inform7/Chapter 35/Action Name Lists.w"
int anl_parsing_tense = IS_TENSE;
action_name_list *PL__Actions__Lists__parse(wording W, int tense) {
if (Wordings__mismatched_brackets(W)) return NULL;
int t = anl_parsing_tense;
anl_parsing_tense = tense;
int r = Preform__parse_nt_against_word_range(action_list_NTM, W, NULL, NULL);
anl_parsing_tense = t;
if (r) return most_recent_result_p;
return NULL;
}
#line 300 "inform7/Chapter 35/Action Name Lists.w"
action_name_list *PL__Actions__Lists__anl_parse_internal(wording W) {
LOGIF(ACTION_PATTERN_PARSING, "Parsing ANL from $w (tense %d)\n", W, anl_parsing_tense);
int tense = anl_parsing_tense;
action_name_list *anl_list = NULL, *new_anl = NULL;
action_name *an;
new_anl = PL__Actions__Lists__anl_new();
anl_list = NULL;
LOOP_OVER(an, action_name) {
int x_ended = FALSE;
int fc = 0;
int it_optional = PL__Actions__it_optional(an);
int abbreviable = PL__Actions__abbreviable(an);
wording XW = PL__Actions__set_text_to_name_tensed(an, tense);
new_anl->action_listed = an;
new_anl->parc = 0;
new_anl->word_position = Wordings__first_wn(W);
new_anl->parity = 1;
new_anl->in_clause = EMPTY_WORDING;
int w_m = Wordings__first_wn(W), x_m = Wordings__first_wn(XW);
while ((w_m <= Wordings__last_wn(W)) && (x_m <= Wordings__last_wn(XW))) {
if (Lexer__word(x_m++) != Lexer__word(w_m++)) {
fc=1; goto DontInclude;
}
if (x_m > Wordings__last_wn(XW)) { x_ended = TRUE; break; }
if (Preform__parse_nt_against_word_range(action_pronoun_NTM, Wordings__one_word(x_m), NULL, NULL)) {
if (w_m > Wordings__last_wn(W)) x_ended = TRUE; else {
int j = -1, k;
for (k=(it_optional)?(w_m):(w_m+1); k<=Wordings__last_wn(W); k++)
if (Lexer__word(k) == Lexer__word(x_m+1)) { j = k; break; }
if (j<0) { fc=2; goto DontInclude; }
if (j-1 >= w_m) {
new_anl->parameter[new_anl->parc] = Wordings__new(w_m, j-1);
new_anl->parc++;
} else {
new_anl->parameter[new_anl->parc] = EMPTY_WORDING;
new_anl->parc++;
}
w_m = j; x_m++;
}
}
if (x_ended) break;
}
if ((w_m > Wordings__last_wn(W)) && (x_ended == FALSE)) {
if (abbreviable) x_ended = TRUE;
else { fc=3; goto DontInclude; }
}
if (x_m <= Wordings__last_wn(XW)) new_anl->abbreviation_level = Wordings__last_wn(XW)-x_m+1;
int inc = FALSE;
if (w_m > Wordings__last_wn(W)) inc = TRUE;
else if (Preform__parse_nt_against_word_range(anl_in_tail_NTM, Wordings__from(W, w_m), NULL, NULL)) {
new_anl->in_clause = GET_RW(anl_in_tail_NTM, 1);
inc = TRUE;
} else if (PL__Actions__can_have_parameters(an)) {
anl_being_parsed = new_anl;
if (Preform__parse_nt_against_word_range(anl_to_tail_NTM, Wordings__from(W, w_m), NULL, NULL)) {
inc = TRUE;
}
anl_being_parsed = NULL;
}
new_anl->next = NULL;
if (inc) {
if (anl_list == NULL) anl_list = new_anl;
else {
action_name_list *pos = anl_list, *prev = NULL;
while ((pos) && (pos->abbreviation_level < new_anl->abbreviation_level))
prev = pos, pos = pos->next;
if (prev) prev->next = new_anl; else anl_list = new_anl;
new_anl->next = pos;
}
}
new_anl = PL__Actions__Lists__anl_new();
DontInclude: ;
}
LOGIF(ACTION_PATTERN_PARSING, "Parsing ANL from $w resulted in:\n$L\n", W, anl_list);
return anl_list;
}
int scanning_anl_only_mode = FALSE;
action_name_list *PL__Actions__Lists__extract_actions_only(wording W) {
action_name_list *anl = NULL;
int s = scanning_anl_only_mode;
scanning_anl_only_mode = TRUE;
int s2 = permit_trying_omission;
permit_trying_omission = TRUE;
if (Preform__parse_nt_against_word_range(action_pattern_NTM, W, NULL, NULL)) {
anl = PL__Actions__Patterns__list(most_recent_result_p);
if (anl) {
anl->anyone_specified = FALSE;
if (most_recent_result == ACTOR_EXPLICITLY_UNIVERSAL) anl->anyone_specified = TRUE;
}
}
scanning_anl_only_mode = s;
permit_trying_omission = s2;
return anl;
}
action_name *PL__Actions__Lists__get_single_action(action_name_list *anl) {
int posn = -1, matchl = -1;
action_name *anf = NULL;
LOGIF(RULE_ATTACHMENTS, "Getting single action from:\n$L\n", anl);
while (anl) {
if (anl->parity == -1) return NULL;
if (anl->negate_pattern) return NULL;
if (anl->action_listed) {
int k = PL__Actions__get_stem_length(anl->action_listed) - anl->abbreviation_level;
if (anl->word_position != posn) {
if (posn >= 0) return NULL;
posn = anl->word_position;
anf = anl->action_listed;
matchl = k;
} else {
if (k > matchl) {
matchl = k;
anf = anl->action_listed;
}
}
}
anl = anl->next;
}
LOGIF(RULE_ATTACHMENTS, "Posn %d AN $l\n", posn, anf);
return anf;
}
int PL__Actions__Lists__get_explicit_anyone_flag(action_name_list *anl) {
if (anl == NULL) return FALSE;
return anl->anyone_specified;
}
int PL__Actions__Lists__negated(action_name_list *anl) {
if (anl == NULL) return FALSE;
return anl->negate_pattern;
}
void PL__Actions__Lists__compile(OUTPUT_STREAM, action_name_list *anl) {
if (anl == NULL) return;
LOGIF(ACTION_PATTERN_COMPILATION, "CANL: $L", anl);
WRITE("(");
int optimise = TRUE;
for (action_name_list *L = anl; L; L = L->next)
if (L->nap_listed)
optimise = FALSE;
if (optimise) {
WRITE("action %s", (anl->parity==1)?"==":"~=");
for (action_name_list *L = anl; L; L = L->next) {
WRITE("##%s", PL__Actions__identifier(L->action_listed));
if (L->next) WRITE(" or ");
}
} else {
for (action_name_list *L = anl; L; L = L->next) {
if (L->parity == -1) WRITE("(~~");
if (L->nap_listed)
WRITE("(%s())", PL__Actions__Patterns__Named__identifier(L->nap_listed));
else
WRITE("action == ##%s", PL__Actions__identifier(L->action_listed));
if (L->parity == -1) WRITE(")");
if (L->next) WRITE(" || ");
}
}
WRITE(")");
}
#line 477 "inform7/Chapter 35/Action Name Lists.w"
int PL__Actions__Lists__compare_specificity(action_name_list *anl1, action_name_list *anl2) {
int count1, count2;
count1 = PL__Actions__Lists__count_actions_covered(anl1);
count2 = PL__Actions__Lists__count_actions_covered(anl2);
if (count1 < count2) return 1;
if (count1 > count2) return -1;
return 0;
}
#line 489 "inform7/Chapter 35/Action Name Lists.w"
int PL__Actions__Lists__count_actions_covered(action_name_list *anl) {
int k, parity = TRUE, infinity = NUMBER_CREATED(action_name);
if (anl == NULL) return infinity;
if (anl->negate_pattern) parity = FALSE;
for (k=0; anl; anl = anl->next) {
if (anl->nap_listed) continue;
if (anl->parity == -1) parity = FALSE;
if ((anl->action_listed) && (k < infinity)) k++;
else k = infinity;
}
if (parity == FALSE) k = infinity-k;
return k;
}
#line 126 "inform7/Chapter 35/Action Patterns.w"
action_pattern PL__Actions__Patterns__new(void) {
action_pattern ap;
ap.text_of_pattern = EMPTY_WORDING;
ap.action = NULL;
ap.test_anl = TRUE;
ap.actor_spec = NULL;
ap.noun_spec = NULL; ap.second_spec = NULL; ap.room_spec = NULL;
ap.noun_any = FALSE; ap.second_any = FALSE; ap.room_any = FALSE;
ap.parameter_spec = NULL;
ap.parameter_kind = K_object;
ap.valid = FALSE;
ap.next = NULL;
ap.when = NULL;
ap.presence_spec = NULL;
ap.from_spec = NULL;
ap.to_spec = NULL;
ap.by_spec = NULL;
ap.through_spec = NULL;
ap.pushing_spec = NULL;
ap.nowhere_flag = FALSE;
ap.request = FALSE;
ap.applies_to_any_actor = FALSE;
ap.duration = TimePeriods__new();
ap.optional_clauses = NULL;
ap.chief_action_owner_id = 0;
ap.entered_into_NAP_here = NULL;
return ap;
}
ap_optional_clause *PL__Actions__Patterns__apoc_new(stacked_variable *stv, parse_node *spec) {
ap_optional_clause *apoc = CREATE(ap_optional_clause);
apoc->stv_to_match = stv;
apoc->clause_spec = spec;
apoc->next = NULL;
apoc->allow_region_as_room = FALSE;
return apoc;
}
void PL__Actions__Patterns__ap_add_optional_clause(action_pattern *ap, ap_optional_clause *apoc) {
int oid = StackedVariables__get_owner_id(apoc->stv_to_match);
int off = StackedVariables__get_offset(apoc->stv_to_match);
if (ap->optional_clauses == NULL) {
ap->optional_clauses = apoc;
apoc->next = NULL;
} else {
ap_optional_clause *oapoc = ap->optional_clauses, *papoc = NULL;
while (oapoc) {
int ooff = StackedVariables__get_offset(oapoc->stv_to_match);
if (off < ooff) {
if (oapoc == ap->optional_clauses) {
apoc->next = ap->optional_clauses;
ap->optional_clauses = apoc;
papoc = NULL;
} else {
apoc->next = papoc->next;
papoc->next = apoc;
papoc = NULL;
}
break;
}
papoc = oapoc;
oapoc = oapoc->next;
}
if (papoc) {
apoc->next = NULL;
papoc->next = apoc;
}
}
if (oid == 20007 /* i.e., going */ ) {
switch (off) {
case 0: ap->from_spec = apoc->clause_spec; apoc->allow_region_as_room = TRUE; break;
case 1: ap->to_spec = apoc->clause_spec; apoc->allow_region_as_room = TRUE; break;
case 2: ap->through_spec = apoc->clause_spec; break;
case 3: ap->by_spec = apoc->clause_spec; break;
case 4: ap->pushing_spec = apoc->clause_spec; break;
}
}
ap->chief_action_owner_id = oid;
}
int PL__Actions__Patterns__ap_count_optional_clauses(action_pattern *ap) {
int n = 0;
ap_optional_clause *apoc;
for (apoc = ap->optional_clauses; apoc; apoc = apoc->next) {
if ((ap->chief_action_owner_id != 20007) ||
(StackedVariables__get_offset(apoc->stv_to_match) >= 5))
n++;
}
return n;
}
int PL__Actions__Patterns__compare_specificity_of_apoc_list(action_pattern *ap1, action_pattern *ap2) {
int rct1 = PL__Actions__Patterns__ap_count_optional_clauses(ap1);
int rct2 = PL__Actions__Patterns__ap_count_optional_clauses(ap2);
if (rct1 > rct2) return 1;
if (rct1 < rct2) return -1;
if (rct1 == 0) return 0;
if (ap1->chief_action_owner_id != ap2->chief_action_owner_id) return 0;
ap_optional_clause *apoc1 = ap1->optional_clauses, *apoc2 = ap2->optional_clauses;
while ((apoc1) && (apoc2)) {
int off1 = StackedVariables__get_offset(apoc1->stv_to_match);
int off2 = StackedVariables__get_offset(apoc2->stv_to_match);
if (off1 == off2) {
int rv = Specifications__compare_specificity(apoc1->clause_spec, apoc2->clause_spec, NULL);
if (rv != 0) return rv;
apoc1 = apoc1->next;
apoc2 = apoc2->next;
}
if (off1 < off2) apoc1 = apoc1->next;
if (off1 > off2) apoc2 = apoc2->next;
}
return 0;
}
void PL__Actions__Patterns__log(action_pattern *ap) {
if (ap == NULL) LOG(" [Null]");
else {
if (ap->valid != TRUE) LOG(" [Invalid]");
else LOG(" [Valid]");
LOG(" Action: ");
if (ap->action == NULL) LOG("unspecified");
else PL__Actions__Lists__log_briefly(ap->action);
if (ap->noun_spec) LOG(" Noun: $P", ap->noun_spec);
if (ap->second_spec) LOG(" Second: $P", ap->second_spec);
if (ap->from_spec) LOG(" From: $P", ap->from_spec);
if (ap->to_spec) LOG(" To: $P", ap->to_spec);
if (ap->by_spec) LOG(" By: $P", ap->by_spec);
if (ap->through_spec) LOG(" Through: $P", ap->through_spec);
if (ap->pushing_spec) LOG(" Pushing: $P", ap->pushing_spec);
if (ap->room_spec) LOG(" Room: $P", ap->room_spec);
if (ap->parameter_spec) LOG(" Parameter: $P", ap->parameter_spec);
if (ap->presence_spec) LOG(" Presence: $P", ap->presence_spec);
if (ap->nowhere_flag) LOG(" Nowhere ");
if (ap->when)
LOG(" When: $P ", ap->when);
if (TimePeriods__is_valid(&(ap->duration)))
LOG(" Duration: $t ", &(ap->duration));
}
LOG("\n");
}
action_pattern *PL__Actions__Patterns__ap_store(action_pattern ap) {
action_pattern *sap = CREATE(action_pattern);
*sap = ap;
return sap;
}
int PL__Actions__Patterns__is_named(action_pattern *ap) {
if (ap == NULL) return FALSE;
if (ap->action == NULL) return FALSE;
if (ap->action->nap_listed == NULL) return FALSE;
return TRUE;
}
int PL__Actions__Patterns__is_valid(action_pattern *ap) {
if (ap == NULL) return FALSE;
return ap->valid;
}
int PL__Actions__Patterns__is_request(action_pattern *ap) {
if (ap == NULL) return FALSE;
return ap->request;
}
int PL__Actions__Patterns__within_action_context(action_pattern *ap, action_name *an) {
action_name_list *anl;
if (ap == NULL) return TRUE;
if (ap->action == NULL) return TRUE;
if (ap->action->nap_listed)
return PL__Actions__Patterns__Named__within_action_context(ap->action->nap_listed, an);
for (anl = ap->action; anl; anl = anl->next)
if (((anl->action_listed == an) && (anl->parity == 1)) ||
((anl->action_listed != an) && (anl->parity == -1)))
return TRUE;
return FALSE;
}
action_name_list *PL__Actions__Patterns__list(action_pattern *ap) {
if (ap == NULL) return NULL;
return ap->action;
}
action_name *PL__Actions__Patterns__required_action(action_pattern *ap) {
if ((ap->action) && (ap->action->next == NULL) && (ap->action->parity == 1) && (ap->action->negate_pattern == FALSE))
return ap->action->action_listed;
return NULL;
}
int PL__Actions__Patterns__object_based(action_pattern *ap) {
if ((ap) && (ap->action)) return TRUE;
return FALSE;
}
int PL__Actions__Patterns__is_unspecific(action_pattern *ap) {
action_name *an = PL__Actions__Patterns__required_action(ap);
if (an == NULL) return TRUE;
int N = PL__Actions__get_min_parameters(an);
if ((N > 0) && (ap->noun_spec == NULL)) return TRUE;
if ((N > 1) && (ap->second_spec == NULL)) return TRUE;
N = PL__Actions__get_max_parameters(an);
if ((N > 0) && (PL__Actions__Patterns__ap_clause_is_unspecific(ap->noun_spec))) return TRUE;
if ((N > 1) && (PL__Actions__Patterns__ap_clause_is_unspecific(ap->second_spec))) return TRUE;
if (PL__Actions__Patterns__ap_clause_is_unspecific(ap->actor_spec)) return TRUE;
return FALSE;
}
int PL__Actions__Patterns__ap_clause_is_unspecific(parse_node *spec) {
if (spec == NULL) return FALSE;
if (Specifications__is_description(spec) == FALSE) return FALSE;
return TRUE;
}
int PL__Actions__Patterns__is_overspecific(action_pattern *ap) {
if (ap->when != NULL) return TRUE;
if (ap->room_spec != NULL) return TRUE;
if (ap->presence_spec != NULL) return TRUE;
if (ap->optional_clauses != NULL) return TRUE;
if (ap->nowhere_flag) return TRUE;
if (ap->applies_to_any_actor) return TRUE;
if (TimePeriods__is_valid(&(ap->duration))) return TRUE;
return FALSE;
}
void PL__Actions__Patterns__suppress_action_testing(action_pattern *ap) {
if (TimePeriods__is_valid(&(ap->duration)) == FALSE) ap->test_anl = FALSE;
}
#line 360 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__categorise_as(action_pattern *ap, wording W) {
LOGIF(ACTION_PATTERN_PARSING, "Categorising the action:\n$A...as $w\n", ap, W);
if (Preform__parse_nt_against_word_range(article_NTM, W, NULL, NULL)) {
Problems__Issue__sentence_problem(_p_(PM_NamedAPIsArticle),
"there's only an article here",
"not a name, so I'm not sure what this action is supposed to be.");
return;
}
if (ap->actor_spec) {
Problems__Issue__sentence_problem(_p_(PM_NamedAPWithActor),
"behaviour characterised by named action patterns can only specify the action",
"not the actor: as a result, it cannot include requests to other people to "
"do things.");
return;
}
PL__Actions__Patterns__Named__add(ap, W);
}
#line 391 "inform7/Chapter 35/Action Patterns.w"
parse_node *last_spec_failing_to_validate = NULL;
kind *last_kind_failing_to_validate = NULL;
kind *last_kind_found_failing_to_validate = NULL;
void PL__Actions__Patterns__clear_validation_case(void) {
last_spec_failing_to_validate = NULL;
last_kind_failing_to_validate = NULL;
last_kind_found_failing_to_validate = NULL;
}
int PL__Actions__Patterns__get_validation_case(parse_node **spec, kind **set_K,
kind **set_K2) {
*spec = last_spec_failing_to_validate;
*set_K = last_kind_failing_to_validate;
*set_K2 = last_kind_found_failing_to_validate;
if ((*spec == NULL) || (*set_K == NULL)) return FALSE;
return TRUE;
}
int ap_validation_suspended = FALSE;
void PL__Actions__Patterns__suspend_validation(int state) {
ap_validation_suspended = state;
}
int PL__Actions__Patterns__validate_parameter(parse_node *spec, kind *K) {
parse_node *vts;
kind *kind_found = NULL;
if (spec == NULL) return TRUE;
LOGIF(ACTION_PATTERN_PARSING, "Validating parameter in action pattern: $P ($u)\n",
spec, K);
if (ParseTree__is(spec, UNKNOWN_VNT)) goto DontValidate;
if (Specifications__is_description(spec)) {
pcalc_prop *prop = Descriptions__to_proposition(spec);
if ((prop) && (Calculus__Variables__number_free(prop) != 1)) return FALSE;
}
if (ap_validation_suspended) return TRUE;
if (Specifications__is_description(spec)) Dash__check_condition(spec);
else Dash__check_value(spec, NULL); /* to force a generic return kind to be evaluated */
kind_found = Specifications__to_kind(spec);
if ((Kinds__get_construct(kind_found) == CON_property) && (Kinds__Compare__le(K, K_object)))
return TRUE;
if ((Kinds__Compare__eq(kind_found, K_snippet)) && (Kinds__Compare__eq(K, K_understanding)))
return TRUE;
if ((Kinds__Compare__eq(K, K_understanding)) && (ParseTree__is(spec, CONSTANT_VNT) == FALSE) &&
(Kinds__Compare__eq(kind_found, K_text)))
goto DontValidate;
vts = Specifications__from_kind(K);
if (Kinds__Compare__compatible_with_description(spec, vts) == NEVER_MATCH) {
if ((Kinds__Compare__eq(K, K_understanding)) && (ParseTree__is(spec, CONSTANT_VNT))) {
vts = Specifications__from_kind(K_snippet);
if (Kinds__Compare__compatible_with_description(spec, vts) != NEVER_MATCH) return TRUE;
}
if (Kinds__Compare__eq(kind_found, K_value)) return TRUE; /* pick up later in type-checking */
goto DontValidate;
}
return TRUE;
DontValidate:
LOGIF(ACTION_PATTERN_PARSING,
"Fails to validate for type-checking reasons: wanted $u, found $u\n",
K, kind_found);
last_spec_failing_to_validate = ParseTree__duplicate(spec);
last_kind_failing_to_validate = K;
last_kind_found_failing_to_validate = kind_found;
return FALSE;
}
int PL__Actions__Patterns__validate_when(parse_node *spec) {
LOGIF(ACTION_PATTERN_PARSING, "Validating 'when' clause in action pattern: $P\n", spec);
if (spec == NULL) return TRUE;
if (ParseTree__is(spec, UNKNOWN_VNT)) return FALSE;
if (Dash__check_condition(spec) == NEVER_MATCH) return FALSE;
return TRUE;
}
parse_node *PL__Actions__Patterns__nullify_nonspecific_references(parse_node *spec) {
if (spec == NULL) return spec;
if (ParseTree__is(spec, UNKNOWN_VNT)) return NULL;
return spec;
}
int PL__Actions__Patterns__check_going(parse_node *spec, char *keyword,
kind *ka, kind *kb) {
if (spec == NULL) return TRUE;
if (Specifications__is_description_like(spec)) {
instance *oref = Specifications__object_exactly_described_if_any(spec);
if ((oref == NULL) || (ka == NULL) || (Instances__of_kind(oref, ka)) ||
((kb) && (Instances__of_kind(oref, kb)))) return TRUE;
Problems__quote_source(1, current_sentence);
Problems__quote_object(2, oref);
Problems__quote_text(3, keyword);
Problems__quote_kind(4, ka);
Problems__quote_kind(5, Instances__to_kind(oref));
if (kb) Problems__quote_kind(6, kb);
Problems__Issue__handmade_problem(_p_(PM_GoingWrongKind));
if (kb)
Problems__issue_problem_segment(
"In the sentence %1, %2 seems to be intended as something the "
"player might be going %3, but this has the wrong kind: %5 "
"rather than %4 or %6.");
else
Problems__issue_problem_segment(
"In the sentence %1, %2 seems to be intended as something the player "
"might be going %3, but this has the wrong kind: %5 rather than %4.");
Problems__issue_problem_end();
return TRUE;
}
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(spec));
Problems__quote_text(3, keyword);
Problems__Issue__handmade_problem(_p_(PM_GoingWithoutObject));
Problems__issue_problem_segment(
"In the sentence %1, '%2' seems to be intended as something the player "
"might be going %3, but it doesn't make sense in that context.");
Problems__issue_problem_end();
return FALSE;
}
#line 516 "inform7/Chapter 35/Action Patterns.w"
action_pattern PL__Actions__Patterns__parse_parametric(wording W, kind *K) {
action_pattern ap = PL__Actions__Patterns__new();
ap.parameter_spec = PL__Actions__Patterns__parse_action_parameter(W);
ap.parameter_kind = K;
ap.valid = PL__Actions__Patterns__validate_parameter(ap.parameter_spec, K);
return ap;
}
#line 527 "inform7/Chapter 35/Action Patterns.w"
parse_node *PL__Actions__Patterns__parse_action_parameter(wording W) {
if (Preform__parse_nt_against_word_range(action_parameter_NTM, W, NULL, NULL)) return most_recent_result_p;
return Specifications__new_UNKNOWN(W);
}
parse_node *PL__Actions__Patterns__parse_verified_action_parameter(wording W) {
parse_node *spec = PL__Actions__Patterns__parse_action_parameter(W);
if (ParseTree__is(spec, UNKNOWN_VNT)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_BadOptionalAPClause));
Problems__issue_problem_segment(
"In %1, I tried to read a description of an action - a complicated "
"one involving optional clauses; but '%2' wasn't something I "
"recognised.");
Problems__issue_problem_end();
}
return spec;
}
#line 554 "inform7/Chapter 35/Action Patterns.w"
int suppress_ap_parsing = FALSE;
wording last_successful_wording = EMPTY_WORDING_INIT;
int prevailing_ap_tense = IS_TENSE;
#line 595 "inform7/Chapter 35/Action Patterns.w"
int action_pattern_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = ACTOR_REQUESTED; *XP = RP[2]; action_pattern *ap = *XP; ap->request = TRUE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = ACTOR_NAMED; *XP = RP[2]; ap = *XP; ap->request = FALSE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = ACTOR_EXPLICITLY_UNIVERSAL; *XP = RP[1]; ap = *XP; ap->applies_to_any_actor = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = ACTOR_EXPLICITLY_UNIVERSAL; *XP = RP[1]; ap = *XP; ap->applies_to_any_actor = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = ACTOR_IMPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 602 "inform7/Chapter 35/Action Patterns.w"
#line 609 "inform7/Chapter 35/Action Patterns.w"
int we_are_action_pattern_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = ACTOR_REQUESTED; *XP = RP[2]; action_pattern *ap = *XP; ap->request = TRUE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = ACTOR_REQUESTED; *XP = RP[2]; ap = *XP; ap->request = TRUE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = ACTOR_NAMED; *XP = RP[2]; ap = *XP; ap->request = FALSE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = ACTOR_EXPLICITLY_UNIVERSAL; *XP = RP[1]; ap = *XP; ap->applies_to_any_actor = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = ACTOR_EXPLICITLY_UNIVERSAL; *XP = RP[1]; ap = *XP; ap->applies_to_any_actor = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = ACTOR_IMPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 619 "inform7/Chapter 35/Action Patterns.w"
int action_pattern_negated_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = ACTOR_REQUESTED; *XP = RP[2]; action_pattern *ap = *XP; ap->request = TRUE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = ACTOR_REQUESTED; *XP = RP[2]; ap = *XP; ap->request = TRUE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = ACTOR_NAMED; *XP = RP[2]; ap = *XP; ap->request = FALSE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = ACTOR_EXPLICITLY_UNIVERSAL; *XP = RP[1]; ap = *XP; ap->applies_to_any_actor = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = ACTOR_EXPLICITLY_UNIVERSAL; *XP = RP[1]; ap = *XP; ap->applies_to_any_actor = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = ACTOR_IMPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 630 "inform7/Chapter 35/Action Patterns.w"
int action_pattern_past_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = ACTOR_REQUESTED; *XP = RP[2]; action_pattern *ap = *XP; ap->request = TRUE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = ACTOR_NAMED; *XP = RP[2]; ap = *XP; ap->request = FALSE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = ACTOR_EXPLICITLY_UNIVERSAL; *XP = RP[1]; ap = *XP; ap->applies_to_any_actor = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = ACTOR_EXPLICITLY_UNIVERSAL; *XP = RP[1]; ap = *XP; ap->applies_to_any_actor = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 638 "inform7/Chapter 35/Action Patterns.w"
int action_pattern_past_negated_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = ACTOR_REQUESTED; *XP = RP[2]; action_pattern *ap = *XP; ap->request = TRUE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = ACTOR_NAMED; *XP = RP[2]; ap = *XP; ap->request = FALSE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = ACTOR_EXPLICITLY_UNIVERSAL; *XP = RP[1]; ap = *XP; ap->applies_to_any_actor = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = ACTOR_EXPLICITLY_UNIVERSAL; *XP = RP[1]; ap = *XP; ap->applies_to_any_actor = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = ACTOR_EXPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 646 "inform7/Chapter 35/Action Patterns.w"
#line 660 "inform7/Chapter 35/Action Patterns.w"
int action_pattern_core_actor_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = ACTOR_IMPLICITLY_PLAYER; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = ACTOR_NAMED; *XP = RP[2]; action_pattern *ap = *XP; ap->request = FALSE; ap->actor_spec = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 663 "inform7/Chapter 35/Action Patterns.w"
#line 679 "inform7/Chapter 35/Action Patterns.w"
int actor_description_NTMR(wording W, int *X, void **XP) {
#line 680 "inform7/Chapter 35/Action Patterns.w"
if (permit_trying_omission) {
int bl = 0;
LOOP_THROUGH_WORDING(i, W)
if (i > Wordings__first_wn(W)) {
if (Lexer__word(i) == OPENBRACKET_V) bl++;
if (Lexer__word(i) == CLOSEBRACKET_V) bl--;
if ((bl == 0) && (Preform__parse_nt_against_word_range(probable_participle_NTM, Wordings__one_word(i), NULL, NULL))) {
if (Preform__parse_nt_against_word_range(k_kind_NTM, Wordings__up_to(W, i-1), NULL, NULL)) continue;
parse_node *try_stem = NULL;
instance *I;
int old_state = PL__Actions__Patterns__suppress();
if (Preform__parse_nt_against_word_range(action_parameter_NTM, Wordings__up_to(W, i-1), NULL, NULL)) try_stem = most_recent_result_p;
PL__Actions__Patterns__resume(old_state);
int k = 0;
LOOP_THROUGH_WORDING(j, Wordings__up_to(W, i-1))
if (Vocabulary__test_flags(j, ACTION_PARTICIPLE_MC)) k++;
if (k>0) continue;
I = Rvalues__to_object_instance(try_stem);
if (Instances__full_name_includes(I, Lexer__word(i))) continue;
if ((Lvalues__get_storage_form(try_stem) == LOCAL_VARIABLE_VNT) ||
(Lvalues__get_storage_form(try_stem) == NONLOCAL_VARIABLE_VNT) ||
(ParseTree__is(try_stem, CONSTANT_VNT)) ||
(Specifications__is_description(try_stem))) {
*XP = try_stem;
return i-1;
}
}
}
}
return 0;
}
#line 715 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__suppress(void) {
int old_state = suppress_ap_parsing;
suppress_ap_parsing = TRUE;
return old_state;
}
void PL__Actions__Patterns__resume(int old_state) {
suppress_ap_parsing = old_state;
}
#line 746 "inform7/Chapter 35/Action Patterns.w"
int action_pattern_core_NTMR(wording W, int *X, void **XP) {
#line 747 "inform7/Chapter 35/Action Patterns.w"
if (suppress_ap_parsing) return FALSE;
action_pattern *ap = PL__Actions__Patterns__ap_parse_inner(W, IS_TENSE);
if (ap) { *XP = ap; return TRUE; }
return FALSE;
}
int action_pattern_past_core_NTMR(wording W, int *X, void **XP) {
#line 754 "inform7/Chapter 35/Action Patterns.w"
action_pattern *ap = PL__Actions__Patterns__ap_parse_inner(W, HASBEEN_TENSE);
if (ap) { *XP = ap; return TRUE; }
return FALSE;
}
#line 769 "inform7/Chapter 35/Action Patterns.w"
int action_pronominal_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 771 "inform7/Chapter 35/Action Patterns.w"
#line 775 "inform7/Chapter 35/Action Patterns.w"
action_pattern *PL__Actions__Patterns__ap_parse_inner(wording W, int tense) {
if (Lexer__word(Wordings__first_wn(W)) == OPENBRACE_V) return NULL;
if (Wordings__empty(W)) internal_error("PAP on illegal word range");
unsigned int d = Vocabulary__disjunction_of_flags(W);
if (((tense == IS_TENSE) && ((d & (ACTION_PARTICIPLE_MC+NAMED_AP_MC)) == 0))) {
pap_failure_reason = NOPARTICIPLE_PAPF;
return NULL;
}
LOGIF(ACTION_PATTERN_PARSING, "Parse action pattern (tense %d): $w\n", tense, W);
int duration_set = FALSE;
time_period duration = TimePeriods__parse(W);
if (TimePeriods__is_valid(&duration)) {
W = Wordings__up_to(W, TimePeriods__is_valid(&duration));
duration_set = TRUE;
}
int s = prevailing_ap_tense;
prevailing_ap_tense = tense;
action_pattern *ap = NULL;
pap_failure_reason = MISC_PAPF;
if (Preform__parse_nt_against_word_range(action_pronominal_NTM, W, NULL, NULL)) {
if (Wordings__nonempty(last_successful_wording)) {
LOGIF(ACTION_PATTERN_PARSING, "Doing it refers to $w\n", W);
if (Preform__parse_nt_against_word_range(ap_common_core_NTM, last_successful_wording, NULL, NULL))
ap = most_recent_result_p;
}
} else {
if (Preform__parse_nt_against_word_range(ap_common_core_NTM, W, NULL, NULL)) {
ap = most_recent_result_p;
last_successful_wording = W;
LOGIF(ACTION_PATTERN_PARSING, "Last successful W set to: $w\n",
last_successful_wording);
}
}
prevailing_ap_tense = s;
if ((duration_set) && (ap)) ap->duration = duration;
LOGIF(ACTION_PATTERN_PARSING, "PAP result (pfr %d): $A\n", pap_failure_reason, ap);
return ap;
}
#line 820 "inform7/Chapter 35/Action Patterns.w"
int ap_common_core_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1]; action_pattern *ap = *XP; ap->when = RP[2]; if (pap_failure_reason == MISC_PAPF) pap_failure_reason = WHENOKAY_PAPF;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; pap_failure_reason = WHENOKAY_PAPF; return FALSE; /* used only to diagnose problems */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 0; if (pap_failure_reason != WHENOKAY_PAPF) pap_failure_reason = WHEN_PAPF; return FALSE; /* used only to diagnose problems */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 825 "inform7/Chapter 35/Action Patterns.w"
#line 831 "inform7/Chapter 35/Action Patterns.w"
int condition_in_ap_NTMR(wording W, int *X, void **XP) {
#line 832 "inform7/Chapter 35/Action Patterns.w"
ph_stack_frame *phsf = NULL;
if (Frames__current_stack_frame() == NULL) phsf = Frames__new_nonphrasal();
StackedVariables__append_owner_list(
Frames__get_stvol(),
all_nonempty_stacked_action_vars);
LOGIF(ACTION_PATTERN_PARSING, "A when clause <$w> is suspected.\n", W);
parse_node *wts = NULL;
int s = pap_failure_reason;
int pto = permit_trying_omission;
permit_trying_omission = FALSE;
if (Preform__parse_nt_against_word_range(s_condition_NTM, W, NULL, NULL)) wts = most_recent_result_p;
pap_failure_reason = s;
permit_trying_omission = pto;
if (phsf) Frames__remove_nonphrase_stack_frame();
if ((wts) && (PL__Actions__Patterns__validate_when(wts))) {
LOGIF(ACTION_PATTERN_PARSING, "When clause validated: $P.\n", wts);
*XP = wts;
return TRUE;
}
return FALSE;
}
#line 857 "inform7/Chapter 35/Action Patterns.w"
int ap_common_core_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1]; action_pattern *ap = *XP; ap->presence_spec = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 860 "inform7/Chapter 35/Action Patterns.w"
#line 868 "inform7/Chapter 35/Action Patterns.w"
int ap_common_core_inner_inner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 875 "inform7/Chapter 35/Action Patterns.w"
if (PL__Actions__Patterns__validate_parameter(RP[1], K_object) == FALSE)
return FALSE; /* the "room" isn't even an object */
action_pattern ap = PL__Actions__Patterns__new();
ap.valid = TRUE; ap.text_of_pattern = W;
ap.room_spec = RP[1];
*XP = PL__Actions__Patterns__ap_store(ap);
}
#line 869 "inform7/Chapter 35/Action Patterns.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 871 "inform7/Chapter 35/Action Patterns.w"
#line 892 "inform7/Chapter 35/Action Patterns.w"
int ap_common_core_inner_inner_inner_NTMR(wording W, int *X, void **XP) {
#line 893 "inform7/Chapter 35/Action Patterns.w"
if (Wordings__mismatched_brackets(W)) return FALSE;
if (scanning_anl_only_mode) {
action_name_list *anl = PL__Actions__Lists__parse(W, prevailing_ap_tense);
if (anl == NULL) return FALSE;
action_pattern ap = PL__Actions__Patterns__new(); ap.valid = TRUE;
ap.text_of_pattern = W;
ap.action = anl;
*XP = PL__Actions__Patterns__ap_store(ap);
return TRUE;
} else {
LOGIF(ACTION_PATTERN_PARSING, "Parsing action pattern: $w\n", W);
LOG_INDENT;
action_pattern ap = PL__Actions__Patterns__parse_action_pattern_dash(W);
LOG_OUTDENT;
if (PL__Actions__Patterns__is_valid(&ap)) {
*XP = PL__Actions__Patterns__ap_store(ap);
return TRUE;
}
}
return FALSE;
}
#line 921 "inform7/Chapter 35/Action Patterns.w"
int action_operand_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 925 "inform7/Chapter 35/Action Patterns.w"
int going_action_irregular_operand_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 929 "inform7/Chapter 35/Action Patterns.w"
int understanding_action_irregular_operand_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 933 "inform7/Chapter 35/Action Patterns.w"
#line 938 "inform7/Chapter 35/Action Patterns.w"
int action_parameter_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; return FAIL_NONTERMINAL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE; return FAIL_NONTERMINAL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = TRUE; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 944 "inform7/Chapter 35/Action Patterns.w"
int if_nonconstant_action_context_NTMR(wording W, int *X, void **XP) {
#line 946 "inform7/Chapter 35/Action Patterns.w"
return permit_nonconstant_action_parameters;
}
#line 952 "inform7/Chapter 35/Action Patterns.w"
action_pattern PL__Actions__Patterns__parse_action_pattern_dash(wording W) {
int failure_this_call = pap_failure_reason;
int i, j, k = 0;
action_name_list *anl = NULL;
int tense = prevailing_ap_tense;
action_pattern ap = PL__Actions__Patterns__new(); ap.valid = FALSE;
ap.text_of_pattern = W;
{
#line 1007 "inform7/Chapter 35/Action Patterns.w"
action_name_list *preliminary_anl =
PL__Actions__Lists__parse(W, tense);
action_name *chief_an =
PL__Actions__Lists__get_single_action(preliminary_anl);
if (chief_an == NULL) {
int x;
chief_an = PL__Actions__longest_null(W, tense, &x);
}
if (chief_an) {
stacked_variable *last_stv_specified = NULL;
i = Wordings__first_wn(W) + 1; j = -1;
LOGIF(ACTION_PATTERN_PARSING, "Trying special clauses at <$w>\n", Wordings__new(i, Wordings__last_wn(W)));
while (i < Wordings__last_wn(W)) {
stacked_variable *stv = NULL;
if (Text__unexpectedly_upper_case(i) == FALSE)
stv = PL__Actions__parse_match_clause(chief_an, Wordings__new(i, Wordings__last_wn(W)));
if (stv != NULL) {
LOGIF(ACTION_PATTERN_PARSING,
"Special clauses found on <$w>\n", Wordings__from(W, i));
if (last_stv_specified == NULL) j = i-1;
else PL__Actions__Patterns__ap_add_optional_clause(&ap,
PL__Actions__Patterns__apoc_new(last_stv_specified, PL__Actions__Patterns__parse_verified_action_parameter(Wordings__new(k, i-1))));
k = i+1;
last_stv_specified = stv;
}
i++;
}
if (last_stv_specified != NULL)
PL__Actions__Patterns__ap_add_optional_clause(&ap,
PL__Actions__Patterns__apoc_new(last_stv_specified, PL__Actions__Patterns__parse_verified_action_parameter(Wordings__new(k, Wordings__last_wn(W)))));
if (j >= 0) W = Wordings__up_to(W, j);
}
}
#line 961 "inform7/Chapter 35/Action Patterns.w"
;
{
#line 1045 "inform7/Chapter 35/Action Patterns.w"
anl = PL__Actions__Lists__parse(W, tense);
if (anl == NULL) goto Failed;
LOGIF(ACTION_PATTERN_PARSING, "ANL from PAR(i):\n$L\n", anl);
}
#line 962 "inform7/Chapter 35/Action Patterns.w"
;
{
#line 1067 "inform7/Chapter 35/Action Patterns.w"
int no_positions = 0;
int position_at[MAX_AP_POSITIONS], position_min_parc[MAX_AP_POSITIONS];
{
#line 1102 "inform7/Chapter 35/Action Patterns.w"
action_name_list *entry;
for (entry = anl; entry; entry = entry->next) {
int pos = -1;
{
#line 1114 "inform7/Chapter 35/Action Patterns.w"
int i;
for (i=0; i<no_positions; i++)
if (entry->word_position == position_at[i])
pos = i;
if (pos == -1) {
if (no_positions == MAX_AP_POSITIONS) goto Failed;
position_at[no_positions] = entry->word_position;
position_min_parc[no_positions] = UNTHINKABLE_POSITION;
pos = no_positions++;
}
}
#line 1105 "inform7/Chapter 35/Action Patterns.w"
;
if ((position_min_parc[pos] == UNTHINKABLE_POSITION) ||
(entry->parc < position_min_parc[pos]))
position_min_parc[pos] = entry->parc;
}
}
#line 1069 "inform7/Chapter 35/Action Patterns.w"
;
{
#line 1128 "inform7/Chapter 35/Action Patterns.w"
LOGIF(ACTION_PATTERN_PARSING, "List after action decomposition:\n$L\n", anl);
for (i=0; i<no_positions; i++) {
int min = position_min_parc[i];
LOGIF(ACTION_PATTERN_PARSING, "ANL position %d (word %d): min parc %d\n",
i, position_at[i], min);
}
}
#line 1070 "inform7/Chapter 35/Action Patterns.w"
;
{
#line 1141 "inform7/Chapter 35/Action Patterns.w"
int positions_with_min_parc[3];
for (i=0; i<3; i++) positions_with_min_parc[i] = 0;
for (i=0; i<no_positions; i++) {
int min = position_min_parc[i];
if ((min >= 0) && (min < 3)) positions_with_min_parc[min]++;
}
if ((positions_with_min_parc[1] > 1) ||
(positions_with_min_parc[2] > 1)) {
failure_this_call = MIXEDNOUNS_PAPF; goto Failed;
}
}
#line 1071 "inform7/Chapter 35/Action Patterns.w"
;
action_name_list *entry = anl;
int first_position = anl->word_position;
action_name_list *first_valid = NULL;
action_pattern trial_ap;
for (entry = anl; entry; entry = entry->next) {
LOGIF(ACTION_PATTERN_PARSING, "Entry (%d):\n$L\n", entry->parc, entry);
{
#line 1156 "inform7/Chapter 35/Action Patterns.w"
trial_ap.noun_spec = NULL; trial_ap.second_spec = NULL; trial_ap.room_spec = NULL; trial_ap.nowhere_flag = FALSE;
if (entry->parc >= 1) {
if (Wordings__nonempty(entry->parameter[0])) {
if ((entry->action_listed == going_action) && (Preform__parse_nt_against_word_range(going_action_irregular_operand_NTM, entry->parameter[0], NULL, NULL))) {
if (most_recent_result == FALSE) trial_ap.nowhere_flag = TRUE;
else trial_ap.nowhere_flag = 2;
} else PL__Actions__Patterns__put_action_object_into_ap(&trial_ap, 1, entry->parameter[0]);
}
}
if (entry->parc >= 2) {
if (Wordings__nonempty(entry->parameter[1])) {
if ((entry->action_listed != NULL)
&& (Kinds__Compare__eq(PL__Actions__get_data_type_of_second_noun(entry->action_listed), K_understanding))
&& (Preform__parse_nt_against_word_range(understanding_action_irregular_operand_NTM, entry->parameter[1], NULL, NULL))) {
trial_ap.second_spec = Rvalues__from_grammar_verb(NULL); /* Why no GV here? */
ParseTree__set_text(trial_ap.second_spec, entry->parameter[1]);
} else {
PL__Actions__Patterns__put_action_object_into_ap(&trial_ap, 2, entry->parameter[1]);
}
}
}
if (Wordings__nonempty(entry->in_clause))
PL__Actions__Patterns__put_action_object_into_ap(&trial_ap, 3, entry->in_clause);
}
#line 1079 "inform7/Chapter 35/Action Patterns.w"
;
{
#line 1185 "inform7/Chapter 35/Action Patterns.w"
kind *check_n = K_object;
kind *check_s = K_object;
if (entry->action_listed != NULL) {
check_n = PL__Actions__get_data_type_of_noun(entry->action_listed);
check_s = PL__Actions__get_data_type_of_second_noun(entry->action_listed);
}
trial_ap.valid = TRUE;
if ((trial_ap.noun_any == FALSE) &&
(PL__Actions__Patterns__validate_parameter(trial_ap.noun_spec, check_n) == FALSE))
trial_ap.valid = FALSE;
if ((trial_ap.second_any == FALSE) &&
(PL__Actions__Patterns__validate_parameter(trial_ap.second_spec, check_s) == FALSE))
trial_ap.valid = FALSE;
if ((trial_ap.room_any == FALSE) &&
(PL__Actions__Patterns__validate_parameter(trial_ap.room_spec, K_object) == FALSE))
trial_ap.valid = FALSE;
}
#line 1080 "inform7/Chapter 35/Action Patterns.w"
;
if ((trial_ap.valid) && (first_valid == NULL) && (entry->word_position == first_position)) {
first_valid = entry;
ap.noun_spec = trial_ap.noun_spec; ap.second_spec = trial_ap.second_spec;
ap.room_spec = trial_ap.room_spec; ap.nowhere_flag = trial_ap.nowhere_flag;
ap.valid = TRUE;
}
if (trial_ap.valid == FALSE) entry->delete_this_link = TRUE;
}
if (first_valid == NULL) goto Failed;
{
#line 1205 "inform7/Chapter 35/Action Patterns.w"
kind *K[2];
K[0] = NULL; K[1] = NULL;
action_name_list *entry, *prev = NULL;
for (entry = anl; entry; prev = entry, entry = entry->next) {
if ((entry->delete_this_link == FALSE) && (entry->action_listed)) {
if ((prev == NULL) || (prev->word_position != entry->word_position)) {
if ((entry->next == NULL) || (entry->next->word_position != entry->word_position)) {
if ((K[0] == NULL) && (PL__Actions__get_max_parameters(entry->action_listed) >= 1))
K[0] = PL__Actions__get_data_type_of_noun(entry->action_listed);
if ((K[1] == NULL) && (PL__Actions__get_max_parameters(entry->action_listed) >= 2))
K[1] = PL__Actions__get_data_type_of_second_noun(entry->action_listed);
}
}
}
}
LOGIF(ACTION_PATTERN_PARSING, "Necessary kinds: $u, $u\n", K[0], K[1]);
for (entry = anl; entry; prev = entry, entry = entry->next) {
if ((entry->delete_this_link == FALSE) && (entry->action_listed)) {
int poor_choice = FALSE;
if ((K[0]) && (PL__Actions__get_max_parameters(entry->action_listed) >= 1)) {
kind *L = PL__Actions__get_data_type_of_noun(entry->action_listed);
if (Kinds__Compare__compatible(L, K[0]) == FALSE) poor_choice = TRUE;
}
if ((K[1]) && (PL__Actions__get_max_parameters(entry->action_listed) >= 2)) {
kind *L = PL__Actions__get_data_type_of_second_noun(entry->action_listed);
if (Kinds__Compare__compatible(L, K[1]) == FALSE) poor_choice = TRUE;
}
if (poor_choice) {
if (((prev) && (prev->word_position == entry->word_position) &&
(prev->delete_this_link == FALSE))
||
((entry->next) && (entry->next->word_position == entry->word_position) &&
(entry->next->delete_this_link == FALSE)))
entry->delete_this_link = TRUE;
}
}
}
}
#line 1091 "inform7/Chapter 35/Action Patterns.w"
;
LOGIF(ACTION_PATTERN_PARSING, "List before action winnowing:\n$L\n", anl);
{
#line 1246 "inform7/Chapter 35/Action Patterns.w"
action_name_list *entry, *prev = NULL;
int pos = -1, negation_state = (anl)?(anl->negate_pattern):FALSE;
for (entry = anl; entry; entry = entry->next) {
if ((entry->delete_this_link) || (pos == entry->word_position)) {
if (prev == NULL) anl = entry->next;
else prev->next = entry->next;
} else {
prev = entry;
pos = entry->word_position;
}
}
if (anl) anl->negate_pattern = negation_state;
}
#line 1093 "inform7/Chapter 35/Action Patterns.w"
;
LOGIF(ACTION_PATTERN_PARSING, "List after action winnowing:\n$L\n", anl);
}
#line 963 "inform7/Chapter 35/Action Patterns.w"
;
{
#line 1269 "inform7/Chapter 35/Action Patterns.w"
int immiscible = FALSE, no_oow = 0, no_iw = 0, no_of_pars = 0;
kind *kinds_observed_in_list[2];
kinds_observed_in_list[0] = NULL;
kinds_observed_in_list[1] = NULL;
for (action_name_list *entry = anl; entry; entry = entry->next)
if (entry->nap_listed == NULL) {
if (entry->parc > 0) {
if (no_of_pars > 0) immiscible = TRUE;
no_of_pars = entry->parc;
}
action_name *this = entry->action_listed;
if (this) {
if (PL__Actions__is_out_of_world(this)) no_oow++; else no_iw++;
if (entry->parc >= 1) {
kind *K = PL__Actions__get_data_type_of_noun(this);
kind *A = kinds_observed_in_list[0];
if ((A) && (K) && (Kinds__Compare__eq(A, K) == FALSE))
immiscible = TRUE;
kinds_observed_in_list[0] = K;
}
if (entry->parc >= 2) {
kind *K = PL__Actions__get_data_type_of_second_noun(this);
kind *A = kinds_observed_in_list[1];
if ((A) && (K) && (Kinds__Compare__eq(A, K) == FALSE))
immiscible = TRUE;
kinds_observed_in_list[1] = K;
}
}
}
if ((no_oow > 0) && (no_iw > 0)) immiscible = TRUE;
for (action_name_list *entry = anl; entry; entry = entry->next)
if (entry->action_listed)
if (no_of_pars > PL__Actions__get_max_parameters(entry->action_listed))
immiscible = TRUE;
if (immiscible) {
failure_this_call = IMMISCIBLE_PAPF;
goto Failed;
}
}
#line 964 "inform7/Chapter 35/Action Patterns.w"
;
{
#line 976 "inform7/Chapter 35/Action Patterns.w"
pap_failure_reason = 0;
ap.text_of_pattern = W;
ap.action = anl;
if ((anl != NULL) && (anl->nap_listed == NULL) && (anl->action_listed == NULL)) ap.action = NULL;
ap.valid = TRUE;
ap.actor_spec = PL__Actions__Patterns__nullify_nonspecific_references(ap.actor_spec);
ap.noun_spec = PL__Actions__Patterns__nullify_nonspecific_references(ap.noun_spec);
ap.second_spec = PL__Actions__Patterns__nullify_nonspecific_references(ap.second_spec);
ap.room_spec = PL__Actions__Patterns__nullify_nonspecific_references(ap.room_spec);
int ch = Plugins__Call__check_going(ap.from_spec, ap.to_spec, ap.by_spec, ap.through_spec, ap.pushing_spec);
if (ch == FALSE) ap.valid = FALSE;
if (ap.valid == FALSE) goto Failed;
LOGIF(ACTION_PATTERN_PARSING, "Matched action pattern: $A\n", &ap);
}
#line 965 "inform7/Chapter 35/Action Patterns.w"
;
return ap;
Failed: ;
{
#line 996 "inform7/Chapter 35/Action Patterns.w"
pap_failure_reason = failure_this_call;
ap.valid = FALSE;
ap.optional_clauses = NULL;
ap.from_spec = NULL; ap.to_spec = NULL; ap.by_spec = NULL; ap.through_spec = NULL;
ap.pushing_spec = NULL; ap.nowhere_flag = FALSE;
LOGIF(ACTION_PATTERN_PARSING, "Parse action failed: $w\n", W);
}
#line 969 "inform7/Chapter 35/Action Patterns.w"
;
return ap;
}
#line 1320 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__ap_count_rooms(action_pattern *ap) {
int c = 0;
if (ap->room_spec) c += 2;
if (ap->from_spec) c += 2;
if (ap->to_spec) c += 2;
return c;
}
int PL__Actions__Patterns__ap_count_going(action_pattern *ap) {
int c = 0;
if (ap->pushing_spec) c += 2;
if (ap->by_spec) c += 2;
if (ap->through_spec) c += 2;
return c;
}
int PL__Actions__Patterns__count_aspects(action_pattern *ap) {
int c = 0;
if (ap == NULL) return 0;
if ((ap->pushing_spec) ||
(ap->by_spec) ||
(ap->through_spec))
c++;
if ((ap->room_spec) ||
(ap->from_spec) ||
(ap->to_spec))
c++;
if ((ap->nowhere_flag) ||
(ap->noun_spec) ||
(ap->second_spec) ||
(ap->actor_spec))
c++;
if (ap->presence_spec) c++;
if ((TimePeriods__is_valid(&(ap->duration))) || (ap->when))
c++;
if (ap->parameter_spec) c++;
return c;
}
int PL__Actions__Patterns__compare_specificity(action_pattern *ap1, action_pattern *ap2) {
int rv, suspend_usual_from_and_room = FALSE, rct1, rct2;
if ((ap1 == NULL) && (ap2)) return -1;
if ((ap1) && (ap2 == NULL)) return 1;
if ((ap1 == NULL) && (ap2 == NULL)) return 0;
LOGIF(SPECIFICITIES,
"Comparing specificity of action patterns:\n(1) $A(2) $A\n", ap1, ap2);
if ((ap1->valid == FALSE) && (ap2->valid != FALSE)) return -1;
if ((ap1->valid != FALSE) && (ap2->valid == FALSE)) return 1;
c_s_stage_law = "III.1 - Object To Which Rule Applies";
rv = Specifications__compare_specificity(ap1->parameter_spec, ap2->parameter_spec, NULL);
if (rv != 0) return rv;
c_s_stage_law = "III.2.1 - Action/Where/Going In Exotic Ways";
rct1 = PL__Actions__Patterns__ap_count_going(ap1); rct2 = PL__Actions__Patterns__ap_count_going(ap2);
if (rct1 > rct2) return 1;
if (rct1 < rct2) return -1;
rv = Specifications__compare_specificity(ap1->pushing_spec, ap2->pushing_spec, NULL);
if (rv != 0) return rv;
rv = Specifications__compare_specificity(ap1->by_spec, ap2->by_spec, NULL);
if (rv != 0) return rv;
rv = Specifications__compare_specificity(ap1->through_spec, ap2->through_spec, NULL);
if (rv != 0) return rv;
c_s_stage_law = "III.2.2 - Action/Where/Room Where Action Takes Place";
rct1 = PL__Actions__Patterns__ap_count_rooms(ap1); rct2 = PL__Actions__Patterns__ap_count_rooms(ap2);
if (rct1 > rct2) return 1;
if (rct1 < rct2) return -1;
if ((ap1->from_spec) && (ap1->room_spec == NULL)
&& (ap2->room_spec) && (ap2->from_spec == NULL)) {
rv = Specifications__compare_specificity(ap1->from_spec, ap2->room_spec, NULL);
if (rv != 0) return rv;
suspend_usual_from_and_room = TRUE;
}
if ((ap2->from_spec) && (ap2->room_spec == NULL)
&& (ap1->room_spec) && (ap1->from_spec == NULL)) {
rv = Specifications__compare_specificity(ap1->room_spec, ap2->from_spec, NULL);
if (rv != 0) return rv;
suspend_usual_from_and_room = TRUE;
}
if (suspend_usual_from_and_room == FALSE) {
rv = Specifications__compare_specificity(ap1->from_spec, ap2->from_spec, NULL);
if (rv != 0) return rv;
}
if (suspend_usual_from_and_room == FALSE) {
rv = Specifications__compare_specificity(ap1->room_spec, ap2->room_spec, NULL);
if (rv != 0) return rv;
}
rv = Specifications__compare_specificity(ap1->to_spec, ap2->to_spec, NULL);
if (rv != 0) return rv;
c_s_stage_law = "III.2.3 - Action/Where/In The Presence Of";
rv = Specifications__compare_specificity(ap1->presence_spec, ap2->presence_spec, NULL);
if (rv != 0) return rv;
c_s_stage_law = "III.2.4 - Action/Where/Other Optional Clauses";
rv = PL__Actions__Patterns__compare_specificity_of_apoc_list(ap1, ap2);
if (rv != 0) return rv;
c_s_stage_law = "III.3.1 - Action/What/Second Thing Acted On";
rv = Specifications__compare_specificity(ap1->second_spec, ap2->second_spec, NULL);
if (rv != 0) return rv;
c_s_stage_law = "III.3.2 - Action/What/Thing Acted On";
rv = Specifications__compare_specificity(ap1->noun_spec, ap2->noun_spec, NULL);
if (rv != 0) return rv;
if ((ap1->nowhere_flag) && (ap2->nowhere_flag == FALSE)) return -1;
if ((ap1->nowhere_flag == FALSE) && (ap2->nowhere_flag)) return 1;
c_s_stage_law = "III.3.3 - Action/What/Actor Performing Action";
rv = Specifications__compare_specificity(ap1->actor_spec, ap2->actor_spec, NULL);
if (rv != 0) return rv;
c_s_stage_law = "III.4.1 - Action/How/What Happens";
rv = PL__Actions__Lists__compare_specificity(ap1->action, ap2->action);
if (rv != 0) return rv;
c_s_stage_law = "III.5.1 - Action/When/Duration";
rv = TimePeriods__compare_specificity(&(ap1->duration), &(ap2->duration));
if (rv != 0) return rv;
c_s_stage_law = "III.5.2 - Action/When/Circumstances";
rv = Conditions__compare_specificity_of_CONDITIONs(ap1->when, ap2->when);
if (rv != 0) return rv;
c_s_stage_law = "III.6.1 - Action/Name/Is This Named";
if ((PL__Actions__Patterns__is_named(ap1)) && (PL__Actions__Patterns__is_named(ap2) == FALSE))
return 1;
if ((PL__Actions__Patterns__is_named(ap1) == FALSE) && (PL__Actions__Patterns__is_named(ap2)))
return -1;
return 0;
}
#line 1481 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__put_action_object_into_ap(action_pattern *ap, int pos, wording W) {
parse_node *spec = NULL;
int any_flag = FALSE;
if (Preform__parse_nt_against_word_range(action_operand_NTM, W, NULL, NULL)) {
if (most_recent_result) spec = most_recent_result_p;
else { any_flag = TRUE; spec = Specifications__from_kind(K_thing); }
}
if (spec == NULL) spec = Specifications__new_UNKNOWN(W);
if (Rvalues__is_CONSTANT_of_kind(spec, K_text))
ParseTree__set_kind_of_value(spec, K_understanding);
ParseTree__set_text(spec, W);
LOGIF(ACTION_PATTERN_PARSING, "PAOIA (position %d) $w = $P\n", pos, W, spec);
switch(pos) {
case 1: ap->noun_spec = spec; ap->noun_any = any_flag; break;
case 2: ap->second_spec = spec; ap->second_any = any_flag; break;
case 3: ap->room_spec = spec; ap->room_any = any_flag; break;
}
}
#line 1503 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__compile_try(OUTPUT_STREAM, action_pattern *ap, int store_instead) {
parse_node *spec0 = ap->noun_spec; /* the noun */
parse_node *spec1 = ap->second_spec; /* the second noun */
parse_node *spec2 = ap->actor_spec; /* the actor */
if ((Rvalues__is_CONSTANT_of_kind(spec0, K_understanding)) &&
(Preform__parse_nt_against_word_range(nominative_pronoun_NTM, ParseTree__get_text(spec0), NULL, NULL) == FALSE))
spec0 = Rvalues__from_wording(ParseTree__get_text(spec0));
if ((Rvalues__is_CONSTANT_of_kind(spec1, K_understanding)) &&
(Preform__parse_nt_against_word_range(nominative_pronoun_NTM, ParseTree__get_text(spec1), NULL, NULL) == FALSE))
spec1 = Rvalues__from_wording(ParseTree__get_text(spec1));
action_name_list *anl = ap->action;
action_name *an = PL__Actions__Lists__get_singleton_action(anl);
LOGIF(EXPRESSIONS, "Compiling from action name list:\n$L\n", anl);
int flag_bits = 0;
if (Kinds__Compare__eq(Specifications__to_kind(spec0), K_text)) flag_bits += 16;
if (Kinds__Compare__eq(Specifications__to_kind(spec1), K_text)) flag_bits += 32;
if (flag_bits > 0) Kinds__RunTime__ensure_basic_heap_present();
if (ap->request) flag_bits += 1;
WRITE("TryAction(%d, ", flag_bits);
if (spec2) PL__Actions__Patterns__compile_try_action_parameter(OUT, spec2, K_object);
else WRITE("player");
WRITE(", ##%s, ", PL__Actions__identifier(an));
if (spec0) PL__Actions__Patterns__compile_try_action_parameter(OUT, spec0, PL__Actions__get_data_type_of_noun(an));
else WRITE("0");
WRITE(", ");
if (spec1) PL__Actions__Patterns__compile_try_action_parameter(OUT, spec1, PL__Actions__get_data_type_of_second_noun(an));
else WRITE("0");
if (store_instead) {
WRITE(", STORED_ACTION_TY_Current(");
Frames__compile_allocation(OUT, K_stored_action);
WRITE("))");
} else {
WRITE(");");
}
}
#line 1549 "inform7/Chapter 35/Action Patterns.w"
void PL__Actions__Patterns__compile_try_action_parameter(OUTPUT_STREAM, parse_node *spec, kind *required_kind) {
if (Kinds__Compare__eq(required_kind, K_understanding)) {
kind *K = Specifications__to_kind(spec);
if ((Kinds__Compare__compatible(K, K_understanding)) ||
(Kinds__Compare__compatible(K, K_text))) {
required_kind = NULL;
}
}
if (Dash__check_value(spec, required_kind)) {
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__Compiler__compile(OUT, spec);
END_COMPILATION_MODE;
}
}
#line 1575 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__CAP_insert_clause(int f, OUTPUT_STREAM, char *i6_condition) {
if (f) WRITE(" && ");
WRITE("(%s)", i6_condition);
return TRUE;
}
#line 1601 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__compile_pattern_match_clause(int f,
OUTPUT_STREAM, nonlocal_variable *I6_global_variable,
parse_node *spec, kind *verify_as_kind, int adapt_region) {
parse_node *I6_var_TS;
int force_proposition = FALSE;
if (spec == NULL) return f;
LOGIF(ACTION_PATTERN_COMPILATION, "[MPE on $Z: $P]\n", I6_global_variable, spec);
kind *K = Specifications__to_kind(spec);
if (Kinds__Behaviour__definite(K) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_APClauseIndefinite),
"that action seems to involve a value which is unclear about "
"its kind",
"and that's not allowed. For example, you're not allowed to just "
"say 'Instead of taking a value: ...' because the taking action "
"applies to objects; the vaguest you're allowed to be is 'Instead "
"of taking an object: ...'.");
return TRUE;
}
I6_var_TS = Lvalues__new_actual_NONLOCAL_VARIABLE(I6_global_variable);
if (f) WRITE(" && ");
wording C = Descriptions__get_calling(spec);
if (Wordings__nonempty(C)) {
local_variable *lvar =
LocalVariables__ensure_called_local(C,
Specifications__to_kind(spec));
LocalVariables__add_calling_to_condition(lvar);
WRITE("(%s = %s, (",
LocalVariables__lvalue(lvar),
NonlocalVariables__identifier(I6_global_variable));
}
force_proposition = TRUE;
if (ParseTree__is(spec, UNKNOWN_VNT)) {
if (problem_count == 0) internal_error("MPE found unknown SP");
force_proposition = FALSE;
}
else if (ParseTree__is_lvalue(spec)) {
force_proposition = TRUE;
if (ParseTree__is(spec, TABLE_ENTRY_VNT)) {
if (ParseTree__no_children(spec) != 2) internal_error("MPE with bad no of args");
LocalVariables__add_table_lookup();
WRITE("(ct_1=ExistsTableRowCorr(ct_0=");
Specifications__Compiler__compile(OUT, spec->down->next);
WRITE(",");
Specifications__Compiler__compile(OUT, spec->down);
WRITE(",");
Specifications__Compiler__compile(OUT, I6_var_TS);
WRITE("))");
force_proposition = FALSE;
}
}
else if ((Specifications__is_kind_like(spec)) &&
(Kinds__Compare__le(Specifications__to_kind(spec), K_object) == FALSE)) {
force_proposition = FALSE;
}
else if (ParseTree__is_rvalue(spec)) {
if (Rvalues__is_CONSTANT_of_kind(spec, K_understanding)) {
if ((Preform__parse_nt_against_word_range(understanding_action_irregular_operand_NTM, ParseTree__get_text(spec), NULL, NULL)) &&
(most_recent_result == TRUE))
WRITE("(true)");
else {
WRITE("(");
Specifications__Compiler__compile(OUT, spec);
WRITE("(consult_from, consult_words)~=GPR_FAIL)");
}
force_proposition = FALSE;
}
if ((I6_global_variable != parameter_object_VAR) &&
(Rvalues__is_object(spec))) {
instance *I = Specifications__object_exactly_described_if_any(spec);
if ((I) && (Instances__of_kind(I, K_region))) {
LOGIF(ACTION_PATTERN_PARSING,
"$P on $u : $T\n", spec, verify_as_kind, current_sentence);
if (adapt_region) {
WRITE("(TestRegionalContainment(");
Specifications__Compiler__compile(OUT, I6_var_TS);
WRITE(",");
Specifications__Compiler__compile(OUT, spec);
WRITE("))");
force_proposition = FALSE;
}
}
}
}
else if (Specifications__is_description(spec)) {
if ((I6_global_variable != parameter_object_VAR) &&
((Descriptions__to_instance(spec)) &&
(adapt_region) &&
(Instances__of_kind(Descriptions__to_instance(spec), K_region)))) {
WRITE("(TestRegionalContainment(");
Specifications__Compiler__compile(OUT, I6_var_TS);
WRITE(",");
Specifications__Compiler__compile(OUT, spec);
WRITE("))");
}
force_proposition = FALSE;
}
pcalc_prop *prop = NULL;
if (Specifications__is_description(spec))
prop = Descriptions__to_proposition(spec);
if (ParseTree__is_lvalue(spec))
LOGIF(ACTION_PATTERN_COMPILATION, "Storage has $D\n", prop);
if ((force_proposition) && (prop == NULL)) {
prop = Calculus__Propositions__from_spec(spec);
LOGIF(ACTION_PATTERN_COMPILATION, "[MPE forced proposition: $D]\n", prop);
if (prop == NULL) internal_error("MPE unable to force proposition");
if (verify_as_kind) {
prop = Calculus__Propositions__concatenate(prop,
Calculus__Atoms__KIND_new(
verify_as_kind, Calculus__Terms__new_variable(0)));
Calculus__Deferrals__prop_verify_descriptive(prop,
"an action or activity to apply to things matching a given "
"description", spec);
}
}
if (prop) {
LOGIF(ACTION_PATTERN_COMPILATION, "[MPE faces proposition: $D]\n", prop);
Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_no_problem_reporting());
Calculus__Deferrals__compile_test_of_proposition(OUT, I6_var_TS, prop);
}
if (Wordings__nonempty(C)) WRITE("))");
return TRUE;
}
void PL__Actions__Patterns__as_stored_action(OUTPUT_STREAM, action_pattern *ap) {
text_stream *BC = Kinds__RunTime__begin_block_constant(OUT, K_stored_action);
Kinds__RunTime__compile_block_value_header(BC, K_stored_action, FALSE, 6);
action_name *an = PL__Actions__Lists__get_singleton_action(ap->action);
WRITE_TO(BC, "##%s ", PL__Actions__identifier(an));
int request_bits = ap->request;
if (ap->noun_spec) {
if (Rvalues__is_CONSTANT_of_kind(ap->noun_spec, K_understanding)) {
request_bits = request_bits | 16;
Strings__TextLiterals__compile_literal(BC, ParseTree__get_text(ap->noun_spec));
} else Specifications__Compiler__compile(BC, ap->noun_spec);
} else {
WRITE_TO(BC, "0");
}
WRITE_TO(BC, " ");
if (ap->second_spec) {
if (Rvalues__is_CONSTANT_of_kind(ap->second_spec, K_understanding)) {
request_bits = request_bits | 32;
Strings__TextLiterals__compile_literal(BC, ParseTree__get_text(ap->second_spec));
} else Specifications__Compiler__compile(BC, ap->second_spec);
} else {
WRITE_TO(BC, "0");
}
WRITE_TO(BC, " ");
if (ap->actor_spec)
Specifications__Compiler__compile(BC, ap->actor_spec);
else
WRITE_TO(BC, "selfobj");
WRITE_TO(BC, " ");
WRITE_TO(BC, "%d ", request_bits);
WRITE_TO(BC, "0");
Kinds__RunTime__end_block_constant(K_stored_action);
}
void PL__Actions__Patterns__compile_pattern_match(OUTPUT_STREAM, action_pattern ap, int naming_mode) {
int f = FALSE;
kind *kind_of_noun = K_object;
ap_optional_clause *apoc;
LOGIF(ACTION_PATTERN_COMPILATION, "Compiling action pattern:\n $A", &ap);
if (TimePeriods__is_valid(&(ap.duration))) {
Chronology__compile_past_action_pattern(OUT, ap.duration, ap);
} else {
LocalVariables__begin_condition(OUT);
if (PL__Actions__Lists__negated(ap.action)) {
{
#line 1923 "inform7/Chapter 35/Action Patterns.w"
if (naming_mode == FALSE) {
if (ap.applies_to_any_actor == FALSE) {
int impose = FALSE;
if (ap.actor_spec != NULL) {
impose = TRUE;
nonlocal_variable *var = Lvalues__get_nonlocal_variable_if_any(ap.actor_spec);
if ((var) && (var == player_VAR)) impose = FALSE;
instance *I = Rvalues__to_object_instance(ap.actor_spec);
if ((I) && (I == I_yourself)) impose = FALSE;
}
if (impose) {
if (f) WRITE(" && ");
WRITE(" (actor~=player) && ");
if (ap.request) WRITE("(act_requester)");
else WRITE("(act_requester==nothing)");
f = TRUE;
f = PL__Actions__Patterns__compile_pattern_match_clause(f, OUT, I6_actor_VAR, ap.actor_spec, K_object, FALSE);
} else {
if (f) WRITE(" && ");
WRITE(" (actor==player)");
f = TRUE;
}
} else {
if (f) WRITE(" && ");
if (ap.request) WRITE("(act_requester)");
else WRITE("(act_requester==nothing)");
f = TRUE;
}
}
}
#line 1783 "inform7/Chapter 35/Action Patterns.w"
;
if (f) WRITE(" && ");
WRITE("(~~(");
f = FALSE;
}
if ((ap.action != NULL) && (ap.test_anl)) {
if (f) WRITE(" && ");
PL__Actions__Lists__compile(OUT, ap.action);
f = TRUE;
}
if (PL__Actions__Lists__negated(ap.action) == FALSE)
{
#line 1923 "inform7/Chapter 35/Action Patterns.w"
if (naming_mode == FALSE) {
if (ap.applies_to_any_actor == FALSE) {
int impose = FALSE;
if (ap.actor_spec != NULL) {
impose = TRUE;
nonlocal_variable *var = Lvalues__get_nonlocal_variable_if_any(ap.actor_spec);
if ((var) && (var == player_VAR)) impose = FALSE;
instance *I = Rvalues__to_object_instance(ap.actor_spec);
if ((I) && (I == I_yourself)) impose = FALSE;
}
if (impose) {
if (f) WRITE(" && ");
WRITE(" (actor~=player) && ");
if (ap.request) WRITE("(act_requester)");
else WRITE("(act_requester==nothing)");
f = TRUE;
f = PL__Actions__Patterns__compile_pattern_match_clause(f, OUT, I6_actor_VAR, ap.actor_spec, K_object, FALSE);
} else {
if (f) WRITE(" && ");
WRITE(" (actor==player)");
f = TRUE;
}
} else {
if (f) WRITE(" && ");
if (ap.request) WRITE("(act_requester)");
else WRITE("(act_requester==nothing)");
f = TRUE;
}
}
}
#line 1794 "inform7/Chapter 35/Action Patterns.w"
;
if ((ap.action == NULL) && (ap.noun_spec)) {
if (f) WRITE(" && ");
WRITE(" (noun) && (noun == inp1)");
f = TRUE;
}
if ((ap.action == NULL) && (ap.second_spec)) {
if (f) WRITE(" && ");
WRITE(" (second) && (second == inp2)");
f = TRUE;
}
if ((ap.action) && (ap.action->action_listed)) {
kind_of_noun = PL__Actions__get_data_type_of_noun(ap.action->action_listed);
if (kind_of_noun == NULL) kind_of_noun = K_object;
}
if (Kinds__Compare__le(kind_of_noun, K_object)) {
f = PL__Actions__Patterns__compile_pattern_match_clause(f, OUT, I6_noun_VAR, ap.noun_spec,
kind_of_noun, FALSE);
} else {
f = PL__Actions__Patterns__compile_pattern_match_clause(f, OUT,
NonlocalVariables__temporary("parsed_number", kind_of_noun),
ap.noun_spec, kind_of_noun, FALSE);
}
if ((ap.action) && (ap.action->action_listed)) {
kind_of_noun = PL__Actions__get_data_type_of_second_noun(ap.action->action_listed);
if (kind_of_noun == NULL) kind_of_noun = K_object;
}
if (Kinds__Compare__le(kind_of_noun, K_object)) {
f = PL__Actions__Patterns__compile_pattern_match_clause(f, OUT, I6_second_VAR, ap.second_spec,
kind_of_noun, FALSE);
} else {
f = PL__Actions__Patterns__compile_pattern_match_clause(f, OUT,
NonlocalVariables__temporary("parsed_number", kind_of_noun),
ap.second_spec, kind_of_noun, FALSE);
}
if (ap.room_spec) {
if ((ap.applies_to_any_actor == FALSE) && (naming_mode == FALSE) &&
(ap.actor_spec == NULL))
f = PL__Actions__Patterns__compile_pattern_match_clause(f, OUT, real_location_VAR, ap.room_spec, K_object, TRUE);
else {
if (f) WRITE(" && ");
WRITE(" (actor_location = LocationOf(actor))");
f = TRUE;
f = PL__Actions__Patterns__compile_pattern_match_clause(f,
OUT, actor_location_VAR, ap.room_spec, K_object, TRUE);
}
}
kind *saved_kind = NonlocalVariables__kind(parameter_object_VAR);
NonlocalVariables__set_kind(parameter_object_VAR, ap.parameter_kind);
f = PL__Actions__Patterns__compile_pattern_match_clause(f, OUT,
parameter_object_VAR, ap.parameter_spec, ap.parameter_kind, FALSE);
NonlocalVariables__set_kind(parameter_object_VAR, saved_kind);
apoc = ap.optional_clauses;
while (apoc) {
char lvalue_text[64];
StackedVariables__compile_rvalue_to_text(apoc->stv_to_match, lvalue_text);
kind *K = StackedVariables__get_kind(apoc->stv_to_match);
f = PL__Actions__Patterns__compile_pattern_match_clause(f, OUT,
NonlocalVariables__temporary(lvalue_text, K),
apoc->clause_spec, K, apoc->allow_region_as_room);
apoc = apoc->next;
}
if (ap.nowhere_flag) {
if (ap.nowhere_flag == 1)
f = PL__Actions__Patterns__CAP_insert_clause(f, OUT, "(MStack-->MstVON(20007,1)) == nothing");
else {
parse_node *somewhere = Specifications__from_kind(K_room);
f = PL__Actions__Patterns__compile_pattern_match_clause(f, OUT,
NonlocalVariables__temporary("(MStack-->MstVON(20007,1))",
K_object),
somewhere, K_object, FALSE);
}
} else {
if ((ap.to_spec == NULL) &&
((ap.from_spec != NULL)||(ap.by_spec != NULL)||
(ap.through_spec != NULL)||(ap.pushing_spec != NULL)))
f = PL__Actions__Patterns__CAP_insert_clause(f, OUT, "(MStack-->MstVON(20007,1)) ~= nothing");
}
if (ap.presence_spec != NULL) {
instance *to_be_present =
Specifications__object_exactly_described_if_any(ap.presence_spec);
if (f) WRITE(" && ");
if (to_be_present) {
WRITE("(");
PL__Actions__Patterns__compile_pattern_match_clause(FALSE, OUT,
NonlocalVariables__temporary(
Instances__identifier(to_be_present), K_object),
ap.presence_spec, K_object, FALSE);
WRITE("&& (TestScope(%s, actor)))",
Instances__identifier(to_be_present));
} else {
loop_over_scope *los = PL__Actions__ScopeLoops__new(ap.presence_spec);
wording PC = Descriptions__get_calling(ap.presence_spec);
if (Wordings__nonempty(PC)) {
local_variable *lvar = LocalVariables__ensure_called_local(PC,
Specifications__to_kind(ap.presence_spec));
WRITE("(los_rv=false, LoopOverScope(LOS_%d, actor), %s=los_rv)",
los->allocation_id, LocalVariables__lvalue(lvar));
} else {
WRITE("(los_rv=false, LoopOverScope(LOS_%d, actor), los_rv)",
los->allocation_id);
}
}
f = TRUE;
}
if (PL__Actions__Lists__negated(ap.action)) {
if (f == FALSE) WRITE("FALSE");
WRITE("))");
}
if (ap.when != NULL) {
if (f) WRITE(" && ");
WRITE("(self=actor,true) && ");
Specifications__Compiler__compile(OUT, ap.when);
f = TRUE;
}
if (f == FALSE) WRITE("TRUE");
LocalVariables__end_condition(OUT);
}
}
#line 1956 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__refers_to_past(action_pattern *ap) {
if (TimePeriods__is_valid(&(ap->duration))) return TRUE;
return FALSE;
}
void PL__Actions__Patterns__convert_to_present_tense(action_pattern *ap) {
TimePeriods__make_invalid(&(ap->duration));
}
int PL__Actions__Patterns__pta_acceptable(parse_node *spec) {
instance *I;
if (spec == NULL) return TRUE;
if (Specifications__is_description(spec) == FALSE) return TRUE;
I = Specifications__object_exactly_described_if_any(spec);
if (I) return TRUE;
return FALSE;
}
int PL__Actions__Patterns__makes_callings(action_pattern *ap) {
if (Descriptions__makes_callings(ap->noun_spec)) return TRUE;
if (Descriptions__makes_callings(ap->second_spec)) return TRUE;
if (Descriptions__makes_callings(ap->actor_spec)) return TRUE;
if (Descriptions__makes_callings(ap->room_spec)) return TRUE;
if (Descriptions__makes_callings(ap->parameter_spec)) return TRUE;
if (Descriptions__makes_callings(ap->presence_spec)) return TRUE;
return FALSE;
}
void PL__Actions__Patterns__compile_present_tense(OUTPUT_STREAM, action_pattern *ap) {
PL__Actions__Patterns__compile_pattern_match(OUT, *ap, FALSE);
}
void PL__Actions__Patterns__compile_past_tense(OUTPUT_STREAM, action_pattern *ap) {
int bad_form = FALSE;
WRITE("(");
WRITE("TestActionBitmap(");
if (ap->noun_spec == NULL)
WRITE("nothing");
else
Specifications__Compiler__compile(OUT, ap->noun_spec);
WRITE(",");
if (ap->action == NULL)
WRITE("-1");
else {
if (ap->action->next) bad_form = TRUE;
if (PL__Actions__can_be_compiled_in_past_tense(ap->action->action_listed) == FALSE)
bad_form = TRUE;
WRITE("##%s", PL__Actions__identifier(ap->action->action_listed));
}
if (PL__Actions__Patterns__pta_acceptable(ap->noun_spec) == FALSE) bad_form = TRUE;
if (PL__Actions__Patterns__pta_acceptable(ap->second_spec) == FALSE) bad_form = TRUE;
if (PL__Actions__Patterns__pta_acceptable(ap->actor_spec) == FALSE) bad_form = TRUE;
if (ap->room_spec) bad_form = TRUE;
if (ap->parameter_spec) bad_form = TRUE;
if (ap->presence_spec) bad_form = TRUE;
if (ap->when) bad_form = TRUE;
if (ap->optional_clauses) bad_form = TRUE;
WRITE(")");
WRITE(")");
if (bad_form)
Problems__Issue__sentence_problem(_p_(PM_PTAPTooComplex),
"that is too complex a past tense action",
"at least for this version of Inform to handle: we may improve "
"matters in later releases. The restriction is that the "
"actions used in the past tense may take at most one "
"object, and that this must be a physical thing (not a "
"value, in other words). And no details of where or what "
"else was then happening can be specified.");
}
#line 2031 "inform7/Chapter 35/Action Patterns.w"
int PL__Actions__Patterns__is_an_action_variable(parse_node *spec) {
nonlocal_variable *nlv;
if (spec == NULL) return FALSE;
if (Lvalues__get_storage_form(spec) != NONLOCAL_VARIABLE_VNT) return FALSE;
nlv = ParseTree__get_constant_nonlocal_variable(spec);
if (nlv == I6_noun_VAR) return TRUE;
if (nlv == I6_second_VAR) return TRUE;
if (nlv == I6_actor_VAR) return TRUE;
return FALSE;
}
#line 24 "inform7/Chapter 35/Looping Over Scope.w"
loop_over_scope *PL__Actions__ScopeLoops__new(parse_node *what) {
loop_over_scope *los = CREATE(loop_over_scope);
los->what_to_find = ParseTree__duplicate(what);
if (Specifications__is_description(what)) {
los->what_to_find->down = ParseTree__duplicate(los->what_to_find->down);
Descriptions__clear_calling(los->what_to_find);
}
return los;
}
loop_over_scope *latest_los = NULL;
int PL__Actions__ScopeLoops__compilation_coroutine(OUTPUT_STREAM) {
int N = 0;
while (TRUE) {
loop_over_scope *los;
if (latest_los == NULL)
los = FIRST_OBJECT(loop_over_scope);
else los = NEXT_OBJECT(latest_los, loop_over_scope);
if (los == NULL) break;
latest_los = los;
{
#line 53 "inform7/Chapter 35/Looping Over Scope.w"
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "LOS_%d", los->allocation_id);
OUT = Routines__begin(OUT, i6_routine_identifier);
ph_stack_frame *phsf = Frames__current_stack_frame();
LocalVariables__add_pronoun(phsf, EMPTY_WORDING, K_object);
WRITE("if ");
LocalVariables__begin_condition(OUT);
PL__Actions__Patterns__compile_pattern_match_clause(FALSE, OUT,
NonlocalVariables__temporary("t_0", K_object),
los->what_to_find, K_object, FALSE);
LocalVariables__end_condition(OUT);
WRITE(" los_rv = t_0;\n");
OUT = Routines__end(OUT);
}
#line 44 "inform7/Chapter 35/Looping Over Scope.w"
;
N++;
}
return N;
}
#line 27 "inform7/Chapter 35/Named Action Patterns.w"
named_action_pattern *PL__Actions__Patterns__Named__nap_new(wording W) {
named_action_pattern *nap = CREATE(named_action_pattern);
nap->first = NULL;
nap->text_of_declaration = W;
Semantics__Nouns__ExcerptMeanings__register(NAMED_AP_MC,
nap->text_of_declaration, STORE_POINTER_named_action_pattern(nap));
sprintf(nap->nap_I6_identifier, "NAP_%d", nap->allocation_id);
return nap;
}
named_action_pattern *PL__Actions__Patterns__Named__by_name(wording W) {
parse_node *p = SParser__parse_excerpt(NAMED_AP_MC, W);
if (p) return RETRIEVE_POINTER_named_action_pattern(
Semantics__Nouns__ExcerptMeanings__data(ParseTree__get_meaning(p)));
return NULL;
}
char *PL__Actions__Patterns__Named__identifier(named_action_pattern *nap) {
return nap->nap_I6_identifier;
}
void PL__Actions__Patterns__Named__add(action_pattern *app, wording W) {
app->entered_into_NAP_here = current_sentence;
named_action_pattern *nap;
nap = PL__Actions__Patterns__Named__by_name(W);
if (nap) {
action_pattern *list;
list = nap->first; while (list->next) list = list->next;
list->next = app;
return;
}
nap = PL__Actions__Patterns__Named__nap_new(W);
nap->first = app;
}
int PL__Actions__Patterns__Named__within_action_context(named_action_pattern *nap, action_name *an) {
action_pattern *ap;
for (ap = nap->first; ap; ap = ap->next)
if (PL__Actions__Patterns__within_action_context(ap, an)) return TRUE;
return FALSE;
}
void PL__Actions__Patterns__Named__index(void) {
named_action_pattern *nap;
action_pattern *ap;
int num_naps = NUMBER_CREATED(named_action_pattern);
if (num_naps == 0) {
INDEX("<p>No names for kinds of action have yet been defined.</p>");
}
LOOP_OVER(nap, named_action_pattern) {
INDEX("<p><b>");
Wordings__index_raw(nap->text_of_declaration);
INDEX("</b>");
Index__link(Wordings__first_wn(nap->text_of_declaration));
ap = nap->first;
INDEX("<br>&nbsp;&nbsp;<i>defined as any of the following acts:</i>\n");
while (ap != NULL) {
INDEX("<br>\n");
INDEX("&nbsp;&nbsp;&nbsp;&nbsp;");
Wordings__index_raw(ap->text_of_pattern);
Index__link(Wordings__first_wn(ap->text_of_pattern));
ap = ap->next;
}
INDEX("</p>\n");
}
}
void PL__Actions__Patterns__Named__compile(OUTPUT_STREAM) {
named_action_pattern *nap;
action_pattern *ap;
LOOP_OVER(nap, named_action_pattern) {
OUT = Routines__begin_numbered(OUT, "NAP_%d", nap->allocation_id);
ap = nap->first;
while (ap != NULL) {
current_sentence = ap->entered_into_NAP_here;
WRITE("if (");
PL__Actions__Patterns__compile_pattern_match(OUT, *ap, TRUE);
WRITE(") rtrue;\n");
ap = ap->next;
}
WRITE("rfalse;\n");
OUT = Routines__end(OUT);
}
}
#line 39 "inform7/Chapter 35/Actions Index.w"
void PL__Actions__Index__index_meta_verb(char *t) {
command_index_entry *vie;
vie = CREATE(command_index_entry);
vie->command_headword = t;
vie->nature = OUT_OF_WORLD_COMMAND;
vie->gv_indexed = NULL;
vie->next_alphabetically = NULL;
}
void PL__Actions__Index__test_verb(char *t) {
command_index_entry *vie;
vie = CREATE(command_index_entry);
vie->command_headword = t;
vie->nature = TESTING_COMMAND;
vie->gv_indexed = NULL;
vie->next_alphabetically = NULL;
}
void PL__Actions__Index__verb_definition(char *p, char *trueverb, wording W) {
int i = 1;
if ((p[0] == 0) || (p[1] == 0)) return;
if (trueverb) {
if (strcmp(trueverb, "0") != 0) {
INDEX("%s", trueverb);
if (Wordings__nonempty(W))
PL__Parsing__Verbs__index_command_aliases(
PL__Parsing__Verbs__find_command(W));
for (i=1; p[i+1]; i++) if (p[i] == ' ') break;
for (; p[i+1]; i++) if (p[i] != ' ') break;
if (p[i+1]) INDEX(" ");
}
}
unsigned char *q = (unsigned char *) p;
for (; q[i+1]; i++) {
int c = q[i];
switch(c) {
case '"': INDEX("&quot;"); break;
default: PUT_TO(ifl, c); break;
}
}
}
command_index_entry *PL__Actions__Index__vie_new_from(char *headword, grammar_verb *gv, int nature) {
command_index_entry *vie;
vie = CREATE(command_index_entry);
vie->command_headword = headword;
vie->nature = nature;
vie->gv_indexed = gv;
vie->next_alphabetically = NULL;
return vie;
}
void PL__Actions__Index__commands(void) {
command_index_entry *vie, *vie2, *last_vie2, *list_start = NULL;
grammar_verb *gv;
char head_letter;
LOOP_OVER(gv, grammar_verb)
PL__Parsing__Verbs__make_command_index_entries(gv);
vie = CREATE(command_index_entry);
vie->command_headword = "0";
vie->nature = BARE_DIRECTION_COMMAND;
vie->gv_indexed = NULL;
vie->next_alphabetically = NULL;
LOOP_OVER(vie, command_index_entry) {
if (list_start == NULL) { list_start = vie; continue; }
vie2 = list_start;
last_vie2 = NULL;
while (vie2 && (strcmp(vie->command_headword, vie2->command_headword) > 0)) {
last_vie2 = vie2;
vie2 = vie2->next_alphabetically;
}
if (last_vie2 == NULL) {
vie->next_alphabetically = list_start; list_start = vie;
} else {
last_vie2->next_alphabetically = vie; vie->next_alphabetically = vie2;
}
}
for (vie = list_start, head_letter = 0; vie; vie = vie->next_alphabetically) {
grammar_verb *gv;
if (vie->command_headword[0] != head_letter) {
if (head_letter) INDEX("<br>");
head_letter = vie->command_headword[0];
}
gv = vie->gv_indexed;
switch (vie->nature) {
case NORMAL_COMMAND:
PL__Parsing__Verbs__index_normal(gv, vie->command_headword);
break;
case ALIAS_COMMAND:
PL__Parsing__Verbs__index_alias(gv, vie->command_headword);
break;
case OUT_OF_WORLD_COMMAND:
INDEX("<font color=\"#800000\">");
INDEX("&quot;%s&quot;, <i>a command for controlling play</i></font><br>",
vie->command_headword);
break;
case TESTING_COMMAND:
INDEX("<font color=\"#800000\">");
INDEX("&quot;%s&quot;, <i>a testing command not available "
"in the final game</i></font><br>",
vie->command_headword);
break;
case BARE_DIRECTION_COMMAND:
INDEX("&quot;[direction]&quot; - <i>Going</i><br>");
break;
}
}
}
void PL__Actions__Index__alphabetical(void) {
int nr = NUMBER_CREATED(action_name);
action_name **sorted = Memory__I7_calloc(nr, sizeof(action_name *), INDEX_SORTING_MREASON);
if (sorted) {
{
#line 210 "inform7/Chapter 35/Actions Index.w"
int i = 0;
action_name *an;
LOOP_OVER(an, action_name) sorted[i++] = an;
qsort(sorted, (size_t) nr, sizeof(action_name *), PL__Actions__Index__compare_action_names);
}
#line 156 "inform7/Chapter 35/Actions Index.w"
;
{
#line 165 "inform7/Chapter 35/Actions Index.w"
HTML__begin_html_table(ifl, NULL, FALSE, 0, 0, 0, 0, 0);
HTML__first_html_column(ifl, 0);
INDEX("<b>action</b>");
HTML__next_html_column(ifl, 0);
INDEX("<b>noun</b>");
HTML__next_html_column(ifl, 0);
INDEX("<b>second noun</b>");
HTML__end_html_row(ifl);
int i;
for (i=0; i<nr; i++) {
HTML__first_html_column(ifl, 0);
action_name *an = sorted[i];
if (an->out_of_world) INDEX("<font color=\"#800000\">");
Wordings__index(an->present_name);
if (an->out_of_world) INDEX("</font>");
Index__detail_link("A", an->allocation_id, TRUE);
if (an->requires_light) INDEX(" <i>requires light</i>");
HTML__next_html_column(ifl, 0);
if (an->max_parameters < 1) {
INDEX("&mdash;");
} else {
if (an->noun_access == REQUIRES_ACCESS) INDEX("<i>touchable</i> ");
if (an->noun_access == REQUIRES_POSSESSION) INDEX("<i>carried</i> ");
INDEX("<b>"); Kinds__Index__index_kind(an->noun_kind, FALSE, FALSE);
INDEX("</b>");
}
HTML__next_html_column(ifl, 0);
if (an->max_parameters < 2) {
INDEX("&mdash;");
} else {
if (an->second_access == REQUIRES_ACCESS) INDEX("<i>touchable</i> ");
if (an->second_access == REQUIRES_POSSESSION) INDEX("<i>carried</i> ");
INDEX("<b>"); Kinds__Index__index_kind(an->second_kind, FALSE, FALSE);
INDEX("</b>");
}
HTML__end_html_row(ifl);
}
HTML__end_html_table(ifl);
}
#line 157 "inform7/Chapter 35/Actions Index.w"
;
Memory__I7_free(sorted, INDEX_SORTING_MREASON);
}
}
#line 218 "inform7/Chapter 35/Actions Index.w"
int PL__Actions__Index__compare_action_names(const void *ent1, const void *ent2) {
const action_name *an1 = *((const action_name **) ent1);
const action_name *an2 = *((const action_name **) ent2);
return Wordings__strcmp(an1->present_name, an2->present_name);
}
#line 227 "inform7/Chapter 35/Actions Index.w"
void PL__Actions__Index__page(void) {
int f = FALSE, par_count = 0;
action_name *an;
heading *current_area = NULL;
extension_file *ext = NULL;
LOOP_OVER(an, action_name) {
int new_par = FALSE;
f = PL__Actions__index(an, 1, &ext, &current_area, f, &new_par, FALSE, FALSE);
if (new_par) par_count++;
an->an_index_group = par_count;
}
}
void PL__Actions__Index__detail_pages(void) {
int f = FALSE;
action_name *an;
heading *current_area = NULL;
extension_file *ext = NULL;
LOOP_OVER(an, action_name) {
Index__open_file("A.html", "<Actions", an->allocation_id,
"Detail view");
f = FALSE;
int new_par = FALSE;
action_name *an2;
current_area = NULL;
ext = NULL;
LOOP_OVER(an2, action_name) {
if (an2->an_index_group == an->an_index_group)
f = PL__Actions__index(an2, 1, &ext, &current_area, f, &new_par, (an2 == an)?TRUE:FALSE, TRUE);
}
INDEX("<p><hr><p>");
PL__Actions__index(an, 2, &ext, &current_area, FALSE, &new_par, FALSE, FALSE);
}
}
void PL__Actions__Index__tokens(void) {
INDEX("<p>In addition to the tokens listed below, any description of an object "
"or value can be used: for example, \"[number]\" matches text like 127 or "
" SIX, and \"[open door]\" matches the name of any nearby door which is "
"currently open.</p>");
INDEX("<p>Names of objects are normally understood only when they are within "
"sight, but writing 'any' lifts this restriction. So \"[any person]\" allows "
"every name of a person, wherever they happen to be.</p>");
PL__Parsing__Verbs__index_tokens();
}
#line 62 "inform7/Chapter 36/Traverse for Grammar.w"
int base_problem_count = 0;
void PL__Parsing__traverse(void) {
ParseTree__traverse(PL__Parsing__visit);
}
void PL__Parsing__visit(parse_node *p) {
if (ParseTree__get_type(p) == SENTENCE_NT) {
if ((p->down)
&& (ParseTree__get_type(p->down) == AVERB_NT)
&& (ParseTree__int_annotation(p->down, verb_id_ANNOT) == UNDERSTAND_VB)) {
wording W = ParseTree__get_text(p->down->next);
wording ASW = ParseTree__get_text(p->down->next->next);
base_problem_count = problem_count;
PL__Parsing__understand_sentence(W, ASW);
}
}
}
#line 90 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__compile_understanding(OUTPUT_STREAM, wording W, int table_entry) {
if (Preform__parse_nt_against_word_range(nominative_pronoun_NTM, W, NULL, NULL)) WRITE("0");
else {
cached_understanding *cu;
LOOP_OVER(cu, cached_understanding)
if (Wordings__match(cu->understanding_text, W)) {
WRITE("Consult_Grammar_%d", cu->consult_grammar_no);
return;
}
base_problem_count = problem_count;
PL__Parsing__Tokens__General__prepare_consultation_gv();
if (table_entry) {
LOOP_THROUGH_WORDING(k, W) {
if (Preform__parse_nt_against_word_range(quoted_text_NTM, Wordings__one_word(k), NULL, NULL)) {
PL__Parsing__understand_block(Wordings__one_word(k), NULL, EMPTY_WORDING, TRUE);
}
}
} else {
PL__Parsing__understand_block(W, NULL, EMPTY_WORDING, FALSE);
}
int G = PL__Parsing__Tokens__General__print_consultation_gv_name(OUT);
if (G >= 0) {
cu = CREATE(cached_understanding);
cu->understanding_text = W; cu->consult_grammar_no = G;
}
}
}
#line 137 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = NOTHING_UNDERSTAND_FORM; *XP = NULL;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = PROPERTY_UNDERSTAND_FORM; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = COMMAND_UNDERSTAND_FORM; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 147 "inform7/Chapter 36/Traverse for Grammar.w"
*X = NO_UNDERSTAND_FORM;
Problems__Issue__sentence_problem(_p_(PM_OldVerbUsage),
"this is an outdated form of words",
"and Inform now prefers 'Understand the command ...' "
"rather than 'Understand the verb ...'. (Since this "
"change was made in beta-testing, quite a few old "
"source texts still use the old form: the authors "
"of Inform apologise for any nuisance incurred.)");
}
#line 141 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = GRAMMAR_UNDERSTAND_FORM; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 143 "inform7/Chapter 36/Traverse for Grammar.w"
#line 159 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_regular_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = NULL; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 201 "inform7/Chapter 36/Traverse for Grammar.w"
understanding_item *ui1 = RP[1];
understanding_item *ui2 = RP[2];
if (ui1 == NULL) { *XP = ui2; }
else if (ui2 == NULL) { *XP = ui1; }
else {
ui1->next = ui2;
*XP = ui1;
}
}
#line 161 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 163 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_regular_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 167 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_regular_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 213 "inform7/Chapter 36/Traverse for Grammar.w"
*XP = NULL;
if (!preform_lookahead_mode) {
understanding_item *ui = CREATE(understanding_item);
ui->quoted_text = W;
ui->quoted_property = NULL;
ui->next = NULL;
*XP = ui;
}
}
#line 169 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 170 "inform7/Chapter 36/Traverse for Grammar.w"
#line 175 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_property_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = NULL; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 201 "inform7/Chapter 36/Traverse for Grammar.w"
understanding_item *ui1 = RP[1];
understanding_item *ui2 = RP[2];
if (ui1 == NULL) { *XP = ui2; }
else if (ui2 == NULL) { *XP = ui1; }
else {
ui1->next = ui2;
*XP = ui1;
}
}
#line 177 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 179 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_property_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 183 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_property_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 225 "inform7/Chapter 36/Traverse for Grammar.w"
*XP = NULL;
if (!preform_lookahead_mode) {
understanding_item *ui = CREATE(understanding_item);
ui->quoted_text = EMPTY_WORDING;
ui->quoted_property = RP[1];
ui->next = NULL;
*XP = ui;
}
}
#line 185 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 191 "inform7/Chapter 36/Traverse for Grammar.w"
if (!preform_lookahead_mode)
Problems__Issue__sentence_problem(_p_(PM_UnknownUnderstandProperty),
"I don't understand what property that refers to",
"but it doesn't seem to be a property I know. An example of "
"correct usage is 'understand the transparent property as "
"describing a container.'");
}
#line 186 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 187 "inform7/Chapter 36/Traverse for Grammar.w"
#line 237 "inform7/Chapter 36/Traverse for Grammar.w"
understanding_reference ur_being_parsed;
#line 248 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 2; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 1; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 251 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_sentence_object_uncond_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 267 "inform7/Chapter 36/Traverse for Grammar.w"
understanding_reference *ui1 = RP[1];
understanding_reference *ui2 = RP[2];
if (ui1 == NULL) { *XP = ui2; }
else if (ui2 == NULL) { *XP = ui1; }
else {
ui1->next = ui2;
*XP = ui1;
}
}
#line 254 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 256 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_sentence_object_tail_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 260 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_sentence_entry_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; if (!preform_lookahead_mode)
{
#line 279 "inform7/Chapter 36/Traverse for Grammar.w"
if (R[1] == -1) {
*XP = NULL;
} else {
understanding_reference *ur = CREATE(understanding_reference);
*ur = ur_being_parsed;
*XP = ur;
}
}
#line 262 "inform7/Chapter 36/Traverse for Grammar.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 263 "inform7/Chapter 36/Traverse for Grammar.w"
#line 290 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_as_this_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0;
{
#line 310 "inform7/Chapter 36/Traverse for Grammar.w"
ur_being_parsed.reference_text = W;
ur_being_parsed.mword = -1;
ur_being_parsed.mistaken = FALSE;
ur_being_parsed.pluralised_reference = FALSE;
ur_being_parsed.reversed_reference = FALSE;
ur_being_parsed.an_reference = NULL;
ur_being_parsed.spec_reference = NULL;
ur_being_parsed.next = NULL;
ur_being_parsed.gv_result = GV_IS_OBJECT;
}
#line 291 "inform7/Chapter 36/Traverse for Grammar.w"
; return preform_lookahead_mode; /* match only when looking ahead */;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; ur_being_parsed.gv_result = GV_IS_COMMAND; ur_being_parsed.mistaken = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0; ur_being_parsed.gv_result = GV_IS_COMMAND; ur_being_parsed.mistaken = TRUE; ur_being_parsed.mword = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 323 "inform7/Chapter 36/Traverse for Grammar.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_TextlessMistake),
"when 'understand' results in a mistake it can only be "
"followed by a textual message in brackets",
"so for instance 'understand \"take\" as a mistake "
"(\"In this sort of game, a noun is required there.\").'");
}
#line 294 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = R[1]; ur_being_parsed.pluralised_reference = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = R[1]; ur_being_parsed.pluralised_reference = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = 0; ur_being_parsed.gv_result = GV_IS_TOKEN;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = R[1]; ur_being_parsed.reversed_reference = TRUE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 300 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_ref_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; ur_being_parsed.an_reference = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; ur_being_parsed.spec_reference = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 333 "inform7/Chapter 36/Traverse for Grammar.w"
*X = -1;
LOG("Offending pseudo-meaning is: $w\n", W);
Problems__Issue__sentence_problem(_p_(PM_UnderstandVariable),
"this meaning is a value that varies",
"whereas I need something fixed. "
"(The most common case of this is saying that something should be "
"understood as 'the player', which is actually a variable, because "
"the perspective of play can change. Writing 'yourself' instead will "
"usually do.)");
}
#line 304 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 346 "inform7/Chapter 36/Traverse for Grammar.w"
*X = -1;
LOG("Offending pseudo-meaning is: $w\n", W);
{
#line 353 "inform7/Chapter 36/Traverse for Grammar.w"
Problems__Issue__sentence_problem(_p_(PM_UnderstandVague),
"'understand ... as ...' should be followed "
"by a meaning",
"which might be an action (e.g., "
"'understand \"take [something]\" as taking'), a "
"thing ('understand \"stove\" as the oven') or more "
"generally a value ('understand \"huitante\" as 80'), "
"or a named token for use in further grammar "
"('understand \"near [something]\" as \"[location "
"phrase]\"'). Also, the meaning needs to be precise, "
"so 'understand \"x\" as a number' is not "
"allowed - it does not say which number.");
}
#line 348 "inform7/Chapter 36/Traverse for Grammar.w"
;
}
#line 305 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 306 "inform7/Chapter 36/Traverse for Grammar.w"
#line 373 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_command_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 382 "inform7/Chapter 36/Traverse for Grammar.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_UnderstandCommandWhen),
"'understand the command ... as ...' is not allowed to have a "
"'... when ...' clause",
"for the moment at any rate.");
}
#line 374 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = Wordings__first_wn(W);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 391 "inform7/Chapter 36/Traverse for Grammar.w"
*X = -1;
{
#line 568 "inform7/Chapter 36/Traverse for Grammar.w"
Problems__Issue__sentence_problem(_p_(PM_NotOldCommand),
"'understand the command ... as ...' should end with a command "
"already defined",
"as in 'understand the command \"steal\" as \"take\"'. (This "
"problem is sometimes seen when the wrong sort of Understand... "
"sentence has been used: 'Understand the command \"steal\" as "
"\"take\".' tells me to treat the command STEAL as a "
"synonym for TAKE when reading the player's commands, whereas "
"'Understand \"steal [something]\" as taking.' tells me that "
"here is a specific grammar for what can be said using the "
"STEAL command.)");
}
#line 392 "inform7/Chapter 36/Traverse for Grammar.w"
;
}
#line 377 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 378 "inform7/Chapter 36/Traverse for Grammar.w"
#line 402 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_property_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 2; *XP = RP[1]; level_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 1; *XP = RP[1]; level_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 405 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_property_sentence_object_unconditional_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 1; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 2; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 426 "inform7/Chapter 36/Traverse for Grammar.w"
*X = 0;
Problems__Issue__sentence_problem(_p_(PM_BadUnderstandProperty),
"'understand the ... property as ...' is only allowed if "
"followed by 'describing ...' or 'referring to ...'",
"so for instance 'understand the transparent property as "
"describing a container.'");
}
#line 409 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 410 "inform7/Chapter 36/Traverse for Grammar.w"
int understand_property_reference_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 419 "inform7/Chapter 36/Traverse for Grammar.w"
kind *K = RP[1];
if (Kinds__Compare__lt(K, K_object)) *XP = Kinds__Behaviour__as_subject(K);
else return FALSE;
}
#line 412 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0; *XP = Instances__as_subject(RP[1]);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 436 "inform7/Chapter 36/Traverse for Grammar.w"
*XP = NULL;
Problems__Issue__sentence_problem(_p_(PM_BadUnderstandPropertyAs),
"I don't understand what single thing or kind of thing that refers to",
"but it does need to be an object (or kind of object) and not "
"some other sort of value. For instance, 'understand the transparent "
"property as describing a container.' is okay because 'a container' "
"is a kind of object.");
}
#line 414 "inform7/Chapter 36/Traverse for Grammar.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 415 "inform7/Chapter 36/Traverse for Grammar.w"
#line 447 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__understand_sentence(wording W, wording ASW) {
LOGIF(GRAMMAR, "Parsing understand <$w> as <$w>\n", W, ASW);
if (problem_count > base_problem_count) return;
Preform__parse_nt_against_word_range(understand_sentence_subject_NTM, W, NULL, NULL);
if (problem_count > base_problem_count) return;
understanding_item *ui_list = most_recent_result_p;
int form = most_recent_result;
switch (form) {
case COMMAND_UNDERSTAND_FORM:
{
#line 465 "inform7/Chapter 36/Traverse for Grammar.w"
Preform__parse_nt_against_word_range(understand_command_sentence_object_NTM, ASW, NULL, NULL);
if (problem_count > base_problem_count) return;
wording W = (most_recent_result != 0) ? (Wordings__one_word(most_recent_result)) : EMPTY_WORDING;
for (; ui_list; ui_list = ui_list->next) {
if (problem_count > base_problem_count) break;
PL__Parsing__understand_the_command(ui_list->quoted_text, W);
}
}
#line 455 "inform7/Chapter 36/Traverse for Grammar.w"
; break;
case PROPERTY_UNDERSTAND_FORM:
{
#line 476 "inform7/Chapter 36/Traverse for Grammar.w"
Preform__parse_nt_against_word_range(understand_property_sentence_object_NTM, ASW, NULL, NULL);
if (problem_count > base_problem_count) return;
wording UW = EMPTY_WORDING;
inference_subject *subj = most_recent_result_p;
if (most_recent_result == 2) UW = GET_RW(understand_property_sentence_object_NTM, 1);
for (; ui_list; ui_list = ui_list->next) {
if (problem_count > base_problem_count) break;
PL__Parsing__understand_property_block(ui_list->quoted_property, level_NTMV, subj, UW);
}
}
#line 456 "inform7/Chapter 36/Traverse for Grammar.w"
; break;
case GRAMMAR_UNDERSTAND_FORM: /* and */
case NOTHING_UNDERSTAND_FORM:
{
#line 489 "inform7/Chapter 36/Traverse for Grammar.w"
Preform__parse_nt_against_word_range(understand_sentence_object_NTM, ASW, NULL, NULL);
if (problem_count > base_problem_count) return;
understanding_reference *ur_list_from = most_recent_result_p;
wording UW = EMPTY_WORDING;
if (most_recent_result == 2) UW = GET_RW(understand_sentence_object_NTM, 1);
if (form == NOTHING_UNDERSTAND_FORM) {
understanding_reference *ur_list;
for (ur_list = ur_list_from; ur_list; ur_list = ur_list->next) {
if (problem_count > base_problem_count) break;
PL__Parsing__understand_nothing(ur_list, UW);
}
} else {
for (; ui_list; ui_list = ui_list->next) {
understanding_reference *ur_list;
for (ur_list = ur_list_from; ur_list; ur_list = ur_list->next) {
if (problem_count > base_problem_count) break;
PL__Parsing__understand_block(ui_list->quoted_text, ur_list, UW, FALSE);
}
}
}
}
#line 458 "inform7/Chapter 36/Traverse for Grammar.w"
; break;
}
}
#line 523 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__understand_the_command(wording W, wording ASW) {
W = Wordings__last_word(W);
Text__dequote_word(Wordings__first_wn(W));
char *p = Lexer__word_text(Wordings__first_wn(W));
for (int i=0; p[i]; i++)
if (p[i] == ' ') {
Problems__Issue__sentence_problem(_p_(PM_SpacyCommand),
"'understand the command ... as ...' is only allowed when "
"the old command is a single word",
"so for instance 'understand the command \"capture\" as \"get\"' "
"is okay, but 'understand the command \"capture the flag\" as "
"\"get\"' is not.");
break;
}
grammar_verb *gv = PL__Parsing__Verbs__find_command(W);
if (Wordings__empty(ASW)) {
if (gv) PL__Parsing__Verbs__remove_command(gv, W);
} else {
if (gv) {
if (PL__Parsing__Verbs__is_empty(gv)) {
DESTROY(gv, grammar_verb);
gv = NULL;
} else {
Problems__Issue__sentence_problem(_p_(PM_NotNewCommand),
"'understand the command ... as ...' is only allowed when "
"the new command has no meaning already",
"so for instance 'understand \"drop\" as \"throw\"' is not "
"allowed because \"drop\" already has a meaning.");
return;
}
}
Text__dequote_word(Wordings__first_wn(ASW));
gv = PL__Parsing__Verbs__find_command(ASW);
if (gv == NULL) {
{
#line 568 "inform7/Chapter 36/Traverse for Grammar.w"
Problems__Issue__sentence_problem(_p_(PM_NotOldCommand),
"'understand the command ... as ...' should end with a command "
"already defined",
"as in 'understand the command \"steal\" as \"take\"'. (This "
"problem is sometimes seen when the wrong sort of Understand... "
"sentence has been used: 'Understand the command \"steal\" as "
"\"take\".' tells me to treat the command STEAL as a "
"synonym for TAKE when reading the player's commands, whereas "
"'Understand \"steal [something]\" as taking.' tells me that "
"here is a specific grammar for what can be said using the "
"STEAL command.)");
}
#line 558 "inform7/Chapter 36/Traverse for Grammar.w"
;
} else {
PL__Parsing__Verbs__add_command(gv, W);
}
}
}
#line 583 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__understand_property_block(property *pr, int level, inference_subject *subj, wording WHENW) {
if ((Properties__is_either_or(pr) == FALSE) &&
(Kinds__Behaviour__get_recognition_only_GPR(Properties__Valued__kind(pr)) == NULL) &&
((Kinds__Compare__le(Properties__Valued__kind(pr), K_object)) ||
(Kinds__Behaviour__request_I6_GPR(Properties__Valued__kind(pr)) == FALSE))) {
Problems__Issue__sentence_problem(_p_(PM_BadReferringProperty),
"that property is of a kind which I can't recognise in "
"typed commands",
"so that it cannot be understand as describing or referring to "
"something. I can understand either/or properties, properties "
"with a limited list of named possible values, numbers, times "
"of day, or units; but certain built-into-Inform kinds of value "
"(like snippet or rulebook, for instance) I can't use.");
}
if (PL__Parsing__Visibility__seek(pr, subj, level, WHENW) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_UnknownUnpermittedProperty),
"that property is not allowed for the thing or kind in question",
"just as (ordinarily) 'understand the open property as describing a "
"device' would not be allowed because it makes no sense to call a "
"device 'open'.");
}
return;
}
#line 610 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__understand_nothing(understanding_reference *ur, wording WHENW) {
if ((ur == NULL) || (ur->gv_result != GV_IS_OBJECT) || (ur->an_reference == NULL)) {
Problems__Issue__sentence_problem(_p_(PM_UnderstandNothingNonAction),
"'Understand nothing as ...' must be followed by an action",
"such as 'Understand nothing as taking.'");
} else if (Wordings__nonempty(WHENW)) {
Problems__Issue__sentence_problem(_p_(PM_UnderstandNothingWhen),
"'Understand nothing as ...' must be unconditional",
"so your 'when' or 'while' condition will have to go.");
} else {
action_name *an = ur->an_reference;
LOGIF(GRAMMAR_CONSTRUCTION, "Understand nothing as: $l\n", an);
PL__Actions__remove_gl(an);
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb) PL__Parsing__Verbs__remove_action(gv, an);
}
}
#line 631 "inform7/Chapter 36/Traverse for Grammar.w"
void PL__Parsing__understand_block(wording W, understanding_reference *ur, wording WHENW,
int table_entry) {
int gv_is = GV_IS_COMMAND,
reversed = FALSE, mistake_text_at = 0, mistakenly = FALSE, pluralised = FALSE;
wording file_under = EMPTY_WORDING;
wording XW = EMPTY_WORDING;
kind *K = NULL;
action_name *an = NULL;
grammar_line *gl = NULL;
parse_node *to_pn = NULL;
inference_subject *subj = NULL;
property *gv_prn = NULL;
parse_node *gl_value = NULL;
pcalc_prop *u_prop = NULL;
if (problem_count > base_problem_count) return;
if (Preform__parse_nt_against_word_range(quoted_text_NTM, W, NULL, NULL) == FALSE) {
if (table_entry)
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"a table entry in a 'topic' column must be a single double-quoted "
"text",
"such as \"eternity\" or \"peruvian skies\".");
else if (TEST_COMPILATION_MODE(SPECIFICATIONS_CMODE))
Problems__Issue__sentence_problem(_p_(PM_NontextualUnderstandInAP),
"the topic here should be in the form of a textual description",
"as in 'asking about \"[something]\"'.");
else
Problems__Issue__sentence_problem(_p_(PM_NontextualUnderstand),
"'understand' should be followed by a textual description",
"as in 'understand \"take [something]\" as taking the noun'.");
return;
}
if (Text__well_formed_text_routine(Lexer__word_text(Wordings__first_wn(W))) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_UnderstandMismatch),
"'understand' should be followed by text in which brackets "
"'[' and ']' match",
"so for instance 'understand \"take [something]\" as taking the noun' "
"is fine, but 'understand \"take]\" as taking' is not.");
return;
}
mistake_text_at = 0;
mistakenly = FALSE;
if (ur == NULL) gv_is = GV_IS_CONSULT;
else {
an = ur->an_reference;
pluralised = ur->pluralised_reference;
reversed = ur->reversed_reference;
if (ur->mword >= 0) mistake_text_at = ur->mword;
if (ur->mistaken) mistakenly = TRUE;
gv_is = ur->gv_result;
if (gv_is == GV_IS_OBJECT) {
gv_is = GV_IS_COMMAND;
if (an == NULL) {
instance *target;
parse_node *spec = ur->spec_reference;
target = Specifications__object_exactly_described_if_any(spec);
if (target) {
subj = Instances__as_subject(target);
gv_is = GV_IS_OBJECT;
if (Descriptions__is_qualified(spec)) {
LOG("Offending description: $T", spec);
Problems__Issue__sentence_problem(_p_(PM_UnderstandAsQualified),
"I cannot understand text as meaning an object "
"qualified by relative clauses or properties",
"only a specific thing, a specific value or a kind. "
"(But the same effect can usually be achieved with "
"a 'when' clause. For instance, although 'Understand "
"\"bad luck\" as the broken mirror' is not allowed, "
"'Understand \"bad luck\" as the mirror when the "
"mirror is broken' produces the desired effect.)");
return;
}
} else {
RetryValue:
LOGIF(GRAMMAR_CONSTRUCTION, "Understand as specification: $T", spec);
if ((Specifications__is_kind_like(spec)) &&
(Kinds__Compare__le(Specifications__to_kind(spec), K_object) == FALSE)) goto ImpreciseProblemMessage;
if (ParseTree__is_phrasal(spec)) goto ImpreciseProblemMessage;
if (Rvalues__is_nothing_object_constant(spec)) goto ImpreciseProblemMessage;
if (ParseTree__is_rvalue(spec)) {
K = ParseTree__get_kind_of_value(spec);
if (Kinds__Behaviour__request_I6_GPR(K)) {
gl_value = spec;
gv_is = GV_IS_VALUE;
} else {
if (Kinds__get_construct(K) == CON_activity)
Problems__Issue__sentence_problem(_p_(PM_UnderstandAsActivity),
"this 'understand ... as ...' gives text "
"meaning an activity",
"rather than an action. Since activities "
"happen when Inform decides they need to "
"happen, not in response to typed commands, "
"this doesn't make sense.");
else
Problems__Issue__sentence_problem(_p_(PM_UnderstandAsBadValue),
"'understand ... as ...' gives text "
"meaning a value whose kind is not allowed",
"and should be a value such as 100.");
return;
}
} else if (Specifications__is_description(spec)) {
if ((Descriptions__to_instance(spec) == NULL) &&
(Kinds__Compare__lt(Specifications__to_kind(spec),
K_object) == FALSE)
&& (Descriptions__number_of_adjectives_applied_to(spec) == 1)
&& (Adjectives__Usages__get_parity(Calculus__Propositions__first_adjective_usage(Specifications__to_proposition(spec), NULL)))) {
adjectival_phrase *aph =
Adjectives__Usages__get_aph(Calculus__Propositions__first_adjective_usage(Specifications__to_proposition(spec), NULL));
instance *q = Adjectives__Phrases__has_ENUMERATIVE_meaning(aph);
if (q) {
spec = Rvalues__from_instance(q);
goto RetryValue;
}
property *prn = Adjectives__Phrases__has_EORP_meaning(aph, NULL);
if (prn) {
gv_is = GV_IS_PROPERTY_NAME;
gv_prn = prn;
LOGIF(GRAMMAR_CONSTRUCTION, "Grammar confirmed for property $Y\n", gv_prn);
}
}
if ((Descriptions__is_qualified(spec)) && (gv_prn == NULL)) {
u_prop = Calculus__Propositions__copy(Descriptions__to_proposition(spec));
spec = Specifications__from_kind(Specifications__to_kind(spec));
}
kind *K = Specifications__to_kind(spec);
if ((K) && (Kinds__Compare__lt(K, K_object))) {
subj = Kinds__Behaviour__as_subject(K);
gv_is = GV_IS_OBJECT;
} else if (gv_prn == NULL) goto ImpreciseProblemMessage;
} else {
ImpreciseProblemMessage:
LOG("Offending pseudo-meaning is: $T", spec);
{
#line 353 "inform7/Chapter 36/Traverse for Grammar.w"
Problems__Issue__sentence_problem(_p_(PM_UnderstandVague),
"'understand ... as ...' should be followed "
"by a meaning",
"which might be an action (e.g., "
"'understand \"take [something]\" as taking'), a "
"thing ('understand \"stove\" as the oven') or more "
"generally a value ('understand \"huitante\" as 80'), "
"or a named token for use in further grammar "
"('understand \"near [something]\" as \"[location "
"phrase]\"'). Also, the meaning needs to be precise, "
"so 'understand \"x\" as a number' is not "
"allowed - it does not say which number.");
}
#line 764 "inform7/Chapter 36/Traverse for Grammar.w"
;
return;
}
}
}
}
}
if ((pluralised) && (gv_is != GV_IS_OBJECT)) {
Problems__Issue__sentence_problem(_p_(PM_UnderstandPluralValue),
"'understand' as a plural can only apply to things, rooms or kinds "
"of things or rooms",
"so 'Understand \"paperwork\" as the plural of a document.' is "
"fine (assuming a document is a kind of thing), but 'Understand "
"\"dozens\" as the plural of 12' is not.");
return;
}
int i, skip = FALSE, literal_punct = FALSE; char *p = Lexer__word_text(Wordings__first_wn(W));
for (i=0; p[i]; i++) {
if (p[i] == '[') skip = TRUE;
if (p[i] == ']') skip = FALSE;
if (skip) continue;
if ((p[i] == '.') || (p[i] == ',') ||
(p[i] == '!') || (p[i] == '?') || (p[i] == ':') || (p[i] == ';'))
literal_punct = TRUE;
}
if (literal_punct) {
Problems__Issue__sentence_problem(_p_(PM_LiteralPunctuation),
"'understand' text cannot contain literal punctuation",
"or more specifically cannot contain any of these: . , ! ? : ; "
"since they are already used in various ways by the parser, and "
"would not correctly match here.");
return;
}
XW = Feeds__feed_text_full(Lexer__word_text(Wordings__first_wn(W)), TRUE, GRAMMAR_PUNCTUATION_MARKS);
to_pn = Sentences__NPs__new_raw(W);
PL__Parsing__Tokens__break_into_tokens(to_pn, XW);
if (to_pn->down == NULL) {
Problems__Issue__sentence_problem(_p_(PM_UnderstandEmptyText),
"'understand' should be followed by text which contains at least "
"one word or square-bracketed token",
"so for instance 'understand \"take [something]\" as taking' "
"is fine, but 'understand \"\" as the fog' is not. The same "
"applies to the contents of 'topic' columns in tables, since "
"those are also instructions for understanding.");
return;
}
if (gv_is == GV_IS_COMMAND) {
LOGIF(GRAMMAR_CONSTRUCTION, "Command grammar: $T\n", to_pn);
LOOP_THROUGH_WORDING(i, XW)
if (i < Wordings__last_wn(XW))
if ((compare_word(i, COMMA_V)) && (compare_word(i+1, COMMA_V))) {
Problems__Issue__sentence_problem(_p_(PM_UnderstandCommaCommand),
"'understand' as an action cannot involve a comma",
"since a command leading to an action never does. "
"(Although Inform understands commands like 'PETE, LOOK' "
"only the part after the comma is read as an action command: "
"the part before the comma is read as the name of someone, "
"according to the usual rules for parsing a name.) "
"Because of the way Inform processes text with square "
"brackets, this problem message is also sometimes seen "
"if empty square brackets are used, as in 'Understand "
"\"bless []\" as blessing.'");
return;
}
if (PL__Parsing__Tokens__is_literal(to_pn->down) == FALSE)
file_under = EMPTY_WORDING; /* this will go into the no verb verb */
else file_under = Wordings__first_word(ParseTree__get_text(to_pn->down));
}
LOGIF(GRAMMAR, "GV is %d, an is $l, file under is $w\n", gv_is, an, file_under);
if (gv_is != GV_IS_COMMAND) gl = PL__Parsing__Lines__new(Wordings__first_wn(W), NULL, to_pn, reversed, pluralised);
else gl = PL__Parsing__Lines__new(Wordings__first_wn(W), an, to_pn, reversed, pluralised);
if (mistakenly) PL__Parsing__Lines__set_mistake(gl, mistake_text_at);
if (Wordings__nonempty(WHENW)) {
PL__Parsing__Lines__set_understand_when(gl, WHENW);
if (gv_is == GV_IS_CONSULT) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible), /* at present, I7 syntax prevents this anyway */
"'when' cannot be used with this kind of 'Understand'",
"for the time being at least.");
return;
}
}
if (Wordings__nonempty(WHENW)) {
PL__Parsing__Lines__set_understand_when(gl, WHENW);
if (gv_is == GV_IS_CONSULT) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible), /* at present, I7 syntax prevents this anyway */
"'when' cannot be used with this kind of 'Understand'",
"for the time being at least.");
return;
}
}
if (u_prop) {
PL__Parsing__Lines__set_understand_prop(gl, u_prop);
if (gv_is == GV_IS_CONSULT) {
Problems__Issue__sentence_problem(_p_(BelievedImpossible), /* at present, I7 syntax prevents this anyway */
"'when' cannot be used with this kind of 'Understand'",
"for the time being at least.");
return;
}
}
switch(gv_is) {
case GV_IS_TOKEN:
XW = Feeds__feed_text_full(Lexer__word_text(Wordings__first_wn(ur->reference_text)), TRUE, GRAMMAR_PUNCTUATION_MARKS);
LOGIF(GRAMMAR_CONSTRUCTION, "GV_IS_TOKEN as words: $w\n", XW);
if (PL__Parsing__valid_new_token_name(XW) == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_UnderstandAsCompoundText),
"if 'understand ... as ...' gives the meaning as text "
"then it must describe a single new token",
"so that 'Understand \"group four/five/six\" as "
"\"[department]\"' is legal (defining a new token "
"\"[department]\", or adding to its definition if it "
"already existed) but 'Understand \"take [thing]\" "
"as \"drop [thing]\"' is not allowed, and would not "
"make sense, because \"drop [thing]\" is a combination "
"of two existing tokens - not a single new one.");
}
PL__Parsing__Verbs__add_line(PL__Parsing__Verbs__named_token_new(Wordings__trim_both_ends(Wordings__trim_both_ends(XW))), gl);
break;
case GV_IS_COMMAND:
PL__Parsing__Verbs__add_line(PL__Parsing__Verbs__find_or_create_command(file_under), gl);
break;
case GV_IS_OBJECT:
PL__Parsing__Verbs__add_line(PL__Parsing__Verbs__for_subject(subj), gl);
break;
case GV_IS_VALUE:
PL__Parsing__Lines__set_single_type(gl, gl_value);
PL__Parsing__Verbs__add_line(PL__Parsing__Verbs__for_kind(K), gl);
break;
case GV_IS_PROPERTY_NAME:
PL__Parsing__Verbs__add_line(PL__Parsing__Verbs__for_prn(gv_prn), gl);
break;
case GV_IS_CONSULT:
PL__Parsing__Lines__set_single_type(gl, gl_value);
PL__Parsing__Verbs__add_line(
PL__Parsing__Tokens__General__get_consultation_gv(), gl);
break;
}
}
int PL__Parsing__valid_new_token_name(wording W) {
int cc=0;
LOOP_THROUGH_WORDING(i, W)
if (compare_word(i, COMMA_V)) cc++;
Text__dequote_word(Wordings__first_wn(W));
if (*(Lexer__word_text(Wordings__first_wn(W))) != 0) return FALSE;
Text__dequote_word(Wordings__last_wn(W));
if (*(Lexer__word_text(Wordings__last_wn(W))) != 0) return FALSE;
if (cc != 2) return FALSE;
return TRUE;
}
#line 52 "inform7/Chapter 36/Grammar Properties.w"
parsing_data *PL__Parsing__Visibility__new_data(inference_subject *subj) {
parsing_data *pd = CREATE(parsing_data);
pd->understand_as_this_object = NULL;
return pd;
}
parsing_pp_data *PL__Parsing__Visibility__new_pp_data(property_permission *pp) {
parsing_pp_data *pd = CREATE(parsing_pp_data);
pd->visibility_level_in_parser = 0;
pd->visibility_condition = EMPTY_WORDING;
pd->visibility_sentence = NULL;
return pd;
}
#line 69 "inform7/Chapter 36/Grammar Properties.w"
void PL__Parsing__Visibility__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_VARIABLE_NOTIFY, PL__Parsing__Visibility__parsing_new_variable_notify);
PLUGIN_REGISTER(PLUGIN_NEW_SUBJECT_NOTIFY, PL__Parsing__Visibility__parsing_new_subject_notify);
PLUGIN_REGISTER(PLUGIN_NEW_PERMISSION_NOTIFY, PL__Parsing__Visibility__parsing_new_permission_notify);
PLUGIN_REGISTER(PLUGIN_COMPLETE_MODEL, PL__Parsing__Visibility__parsing_complete_model);
PLUGIN_REGISTER(PLUGIN_ESTIMATE_PROPERTY_USAGE, PL__Parsing__Visibility__parsing_estimate_property_usage);
}
int PL__Parsing__Visibility__parsing_new_subject_notify(inference_subject *subj) {
CREATE_PF_DATA(parsing, subj, PL__Parsing__Visibility__new_data);
return FALSE;
}
int PL__Parsing__Visibility__parsing_new_permission_notify(property_permission *new_pp) {
CREATE_PLUGIN_PP_DATA(parsing, new_pp, PL__Parsing__Visibility__new_pp_data);
return FALSE;
}
#line 94 "inform7/Chapter 36/Grammar Properties.w"
int notable_parsing_variables_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; kind_understood_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 2;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = 3;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = 4;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = 5;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = 6;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = 7;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 103 "inform7/Chapter 36/Grammar Properties.w"
#line 107 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__parsing_new_variable_notify(nonlocal_variable *var) {
if (Preform__parse_nt_against_word_range(notable_parsing_variables_NTM, var->name, NULL, NULL)) {
switch (most_recent_result) {
case 0:
if (kind_understood_NTMV == NonlocalVariables__kind(var))
NonlocalVariables__set_I6_identifier(var,
"parsed_number", "parsed_number");
break;
case 1: I6_noun_VAR = var; break;
case 2: real_location_VAR = var; break;
case 3: actor_location_VAR = var; break;
case 4: I6_second_VAR = var; break;
case 5: I6_actor_VAR = var; break;
case 6: max_score_VAR = var;
NonlocalVariables__make_initalisable(var); break;
case 7: parameter_object_VAR = var; break;
}
}
return FALSE;
}
#line 131 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__parsing_estimate_property_usage(kind *k, int *words_used) {
wording W = Kinds__Behaviour__get_name(k, FALSE);
*words_used += Wordings__length(W);
wording PW = Kinds__Behaviour__get_name(k, TRUE);
*words_used += Wordings__length(PW);
return FALSE;
}
#line 143 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__parsing_complete_model(int stage) {
if (stage == 5) {
instance *I;
P_name = Properties__Valued__new_nameless("name", K_text);
P_parse_name = Properties__Valued__new_nameless("parse_name", K_value);
P_action_bitmap = Properties__Valued__new_nameless("action_bitmap", K_value);
LOOP_OVER_OBJECT_INSTANCES(I) {
inference_subject *subj = Instances__as_subject(I);
{
#line 188 "inform7/Chapter 36/Grammar Properties.w"
if (PL__Naming__object_is_privately_named(I) == FALSE) {
kind *K = Instances__to_kind(I);
int from_kind = FALSE;
text_stream *name_text = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(name_text) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for name text");
wording W = Instances__get_name_in_play(I, FALSE);
if (Wordings__empty(W)) W = Kinds__Behaviour__get_name_in_play(K, FALSE);
wording PW = Instances__get_name_in_play(I, TRUE);
if (Wordings__empty(PW)) {
from_kind = TRUE; PW = Kinds__Behaviour__get_name_in_play(K, TRUE);
}
LOOP_THROUGH_WORDING(j, W) {
vocabulary_entry *ve = Lexer__word(j);
ve = Preform__Nonparsing__replace_word(ve,
possessive_second_person_NTM,
possessive_first_person_NTM);
char *p = Vocabulary__get_exemplar(ve, FALSE);
DictionaryWords__compile(name_text, p, FALSE);
WRITE_TO(name_text, " ");
}
if (from_kind) /* see test case PM_PluralsFromKind */
LOOP_THROUGH_WORDING(j, PW) {
int additional = TRUE;
LOOP_THROUGH_WORDING(k, W)
if (compare_word(j, Lexer__word(k)))
additional = FALSE;
if (additional) DictionaryWords__compile(name_text, Lexer__word_text(j), TRUE);
WRITE_TO(name_text, " ");
}
if (PF_I(parsing, I)->understand_as_this_object)
PL__Parsing__Verbs__take_out_one_word_grammar(name_text,
PF_I(parsing, I)->understand_as_this_object);
inference_subject *infs;
for (infs = Kinds__Behaviour__as_subject(Instances__to_kind(I));
infs; infs = InferenceSubjects__narrowest_broader_subject(infs)) {
if (PF_S(parsing, infs)) {
if (PF_S(parsing, infs)->understand_as_this_object)
PL__Parsing__Verbs__take_out_one_word_grammar(name_text,
PF_S(parsing, infs)->understand_as_this_object);
}
}
Properties__Valued__assert(P_name, Instances__as_subject(I),
Rvalues__from_permanent_STREAM(name_text), CERTAIN_CE);
}
}
#line 152 "inform7/Chapter 36/Grammar Properties.w"
;
{
#line 242 "inform7/Chapter 36/Grammar Properties.w"
text_stream *S = PL__Parsing__Tokens__General__compile_parse_name_property(subj);
if (S)
Properties__Valued__assert(P_parse_name, subj,
Rvalues__from_permanent_STREAM(S), CERTAIN_CE);
}
#line 153 "inform7/Chapter 36/Grammar Properties.w"
;
{
#line 256 "inform7/Chapter 36/Grammar Properties.w"
if (InferenceSubjects__is_within(subj, Kinds__Behaviour__as_subject(K_room)) == FALSE) {
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for name text");
PL__Actions__compile_action_bitmap_property(PROP);
Properties__Valued__assert(P_action_bitmap, subj,
Rvalues__from_permanent_STREAM(PROP), CERTAIN_CE);
}
}
#line 154 "inform7/Chapter 36/Grammar Properties.w"
;
}
kind *K;
LOOP_OVER_BASE_KINDS(K)
if (Kinds__Compare__lt(K, K_object)) {
inference_subject *subj = Kinds__Behaviour__as_subject(K);
{
#line 242 "inform7/Chapter 36/Grammar Properties.w"
text_stream *S = PL__Parsing__Tokens__General__compile_parse_name_property(subj);
if (S)
Properties__Valued__assert(P_parse_name, subj,
Rvalues__from_permanent_STREAM(S), CERTAIN_CE);
}
#line 161 "inform7/Chapter 36/Grammar Properties.w"
;
}
inference_subject *subj = Kinds__Behaviour__as_subject(K_thing);
{
#line 256 "inform7/Chapter 36/Grammar Properties.w"
if (InferenceSubjects__is_within(subj, Kinds__Behaviour__as_subject(K_room)) == FALSE) {
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for name text");
PL__Actions__compile_action_bitmap_property(PROP);
Properties__Valued__assert(P_action_bitmap, subj,
Rvalues__from_permanent_STREAM(PROP), CERTAIN_CE);
}
}
#line 165 "inform7/Chapter 36/Grammar Properties.w"
;
}
return FALSE;
}
#line 276 "inform7/Chapter 36/Grammar Properties.w"
int PL__Parsing__Visibility__seek(property *pr, inference_subject *subj,
int level, wording WHENW) {
int parity, upto = 1;
if (Properties__is_either_or(pr) == FALSE) upto = 0;
for (parity = 0; parity <= upto; parity++) {
property *seek_prn = (parity == 0)?pr:(Properties__EitherOr__get_negation(pr));
if (seek_prn == NULL) continue;
if (World__Permissions__find(subj, seek_prn, TRUE) == NULL) continue;
property_permission *pp = World__Permissions__grant(subj, seek_prn, FALSE);
PLUGIN_PP(parsing, pp)->visibility_level_in_parser = level;
PLUGIN_PP(parsing, pp)->visibility_sentence = current_sentence;
PLUGIN_PP(parsing, pp)->visibility_condition = WHENW;
return TRUE;
}
return FALSE;
}
int PL__Parsing__Visibility__any_property_visible_to_subject(inference_subject *subj, int allow_inheritance) {
property *pr;
LOOP_OVER(pr, property) {
property_permission *pp =
World__Permissions__find(subj, pr, allow_inheritance);
if ((pp) && (PLUGIN_PP(parsing, pp)->visibility_level_in_parser > 0))
return TRUE;
}
return FALSE;
}
int PL__Parsing__Visibility__get_level(property_permission *pp) {
return PLUGIN_PP(parsing, pp)->visibility_level_in_parser;
}
parse_node *PL__Parsing__Visibility__get_condition(property_permission *pp) {
parse_node *spec;
if (Wordings__empty(PLUGIN_PP(parsing, pp)->visibility_condition)) return NULL;
spec = NULL;
if (Preform__parse_nt_against_word_range(s_condition_NTM, PLUGIN_PP(parsing, pp)->visibility_condition, NULL, NULL)) spec = most_recent_result_p;
else spec = Specifications__new_UNKNOWN(PLUGIN_PP(parsing, pp)->visibility_condition);
if (PL__Actions__Patterns__validate_when(spec) == FALSE) {
LOG("$T", spec);
current_sentence = PLUGIN_PP(parsing, pp)->visibility_sentence;
Problems__Issue__sentence_problem(_p_(PM_BadVisibilityWhen),
"the condition after 'when' makes no sense to me",
"although otherwise this worked - it is only the part after 'when' "
"which I can't follow.");
PLUGIN_PP(parsing, pp)->visibility_condition = EMPTY_WORDING;
return NULL;
}
return spec;
}
void PL__Parsing__Visibility__log_parsing_visibility(inference_subject *infs) {
LOG("Permissions for $j:\n", infs);
property_permission *pp = NULL;
LOOP_OVER_PERMISSIONS_FOR_INFS(pp, infs) {
LOG("$Y: visibility %d, condition $w\n",
World__Permissions__get_property(pp),
PLUGIN_PP(parsing, pp)->visibility_level_in_parser,
PLUGIN_PP(parsing, pp)->visibility_condition);
}
if (InferenceSubjects__narrowest_broader_subject(infs))
PL__Parsing__Visibility__log_parsing_visibility(InferenceSubjects__narrowest_broader_subject(infs));
}
#line 89 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb *PL__Parsing__Verbs__gv_new(int gv_is) {
grammar_verb *gv;
gv = CREATE(grammar_verb);
gv->command = EMPTY_WORDING;
gv->first_line = NULL;
gv->gv_type = PL__Parsing__Tokens__Types__new(FALSE);
gv->gv_is = gv_is;
gv->name = EMPTY_WORDING;
gv->no_aliased_commands = 0;
gv->sorted_first_line = NULL;
gv->subj_understood = NULL;
gv->kind_understood = NULL;
gv->prn_understood = NULL;
gv->where_gv_created = current_sentence;
gv->gv_I6_identifier[0] = 0;
gv->slashed = FALSE;
gv->determined = FALSE;
return gv;
}
void PL__Parsing__Verbs__log(grammar_verb *gv) {
LOG("<GV%d:", gv->allocation_id);
switch(gv->gv_is) {
case GV_IS_COMMAND:
if (Wordings__empty(gv->command)) LOG("command=no-verb verb");
else LOG("command=$w", gv->command);
break;
case GV_IS_TOKEN: LOG("token=$w", gv->name); break;
case GV_IS_OBJECT: LOG("object"); break;
case GV_IS_VALUE: LOG("value=$u", gv->kind_understood); break;
case GV_IS_CONSULT: LOG("consult"); break;
case GV_IS_PROPERTY_NAME: LOG("property-name"); break;
default: LOG("<unknown>"); break;
}
LOG(">");
}
#line 150 "inform7/Chapter 36/Grammar Verbs.w"
wording PL__Parsing__Verbs__get_verb_text(grammar_verb *gv) {
return gv->command;
}
int PL__Parsing__Verbs__gv_is_genuinely_verbal(grammar_verb *gv) {
if ((gv->gv_is == GV_IS_COMMAND) && (Wordings__nonempty(gv->command)))
return TRUE;
return FALSE;
}
#line 166 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb *PL__Parsing__Verbs__find_or_create_command(wording W) {
grammar_verb *gv = PL__Parsing__Verbs__find_command(W);
if (gv) return gv;
gv = PL__Parsing__Verbs__gv_new(GV_IS_COMMAND);
gv->command = W;
if (Wordings__empty(W)) no_verb_verb_defined = TRUE;
else LOGIF(GRAMMAR_CONSTRUCTION, "GV%d has verb $w\n", gv->allocation_id, W);
return gv;
}
#line 184 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb *PL__Parsing__Verbs__find_command(wording W) {
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_COMMAND) {
if (Wordings__empty(W)) {
if (Wordings__empty(gv->command)) return gv;
} else {
if (Wordings__match(gv->command, W)) return gv;
for (int i=0; i<gv->no_aliased_commands; i++)
if (Wordings__match(gv->aliased_command[i], W))
return gv;
}
}
return NULL;
}
#line 211 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__add_command(grammar_verb *gv, wording W) {
if (gv == NULL)
internal_error("tried to add alias command to null GV");
if (gv->gv_is != GV_IS_COMMAND)
internal_error("tried to add alias command to non-command GV");
if (gv->no_aliased_commands == MAX_ALIASED_COMMANDS) {
Problems__Issue__sentence_problem(_p_(PM_TooManyAliases),
"this 'understand the command ... as ...' makes too many aliases "
"for the same command",
"exceeding the limit of 32.");
return;
}
gv->aliased_command[gv->no_aliased_commands++] = W;
LOGIF(GRAMMAR, "Adding alias '$w' to G%d '$w'\n", W, gv->allocation_id, gv->command);
}
void PL__Parsing__Verbs__remove_command(grammar_verb *gv, wording W) {
if (gv == NULL)
internal_error("tried to detach alias command from null GV");
if (gv->gv_is != GV_IS_COMMAND)
internal_error("tried to detach alias command from non-command GV");
LOGIF(GRAMMAR, "Detaching verb '$w' from grammar\n", W);
if (gv == NULL) return;
if (Wordings__match(gv->command, W)) {
LOGIF(GRAMMAR, "Detached verb is the head-verb\n");
if (gv->no_aliased_commands == 0) {
gv->first_line = NULL;
LOGIF(GRAMMAR, "Which had no aliases: clearing grammar to NULL\n");
} else {
gv->command = gv->aliased_command[--(gv->no_aliased_commands)];
LOGIF(GRAMMAR, "Which had aliases: making new head-verb '$w'\n",
gv->command);
}
} else {
LOGIF(GRAMMAR, "Detached verb is one of the aliases\n");
for (int i=0; i<gv->no_aliased_commands; i++) {
if (Wordings__match(gv->aliased_command[i], W)) {
for (int j=i; j<gv->no_aliased_commands-1; j++)
gv->aliased_command[j] = gv->aliased_command[j+1];
gv->no_aliased_commands--;
break;
}
}
}
}
void PL__Parsing__Verbs__index_command_aliases(grammar_verb *gv) {
if (gv == NULL) return;
int i, n = gv->no_aliased_commands;
for (i=0; i<n; i++)
INDEX("/%s", Lexer__word_text(Wordings__first_wn(gv->aliased_command[i])));
}
void PL__Parsing__Verbs__remove_action(grammar_verb *gv, action_name *an) {
if (gv->gv_is != GV_IS_COMMAND) return;
gv->first_line = PL__Parsing__Lines__list_remove(gv->first_line, an);
}
#line 272 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__gv_compile_Verb_directive_header(OUTPUT_STREAM, grammar_verb *gv) {
if (gv->gv_is != GV_IS_COMMAND)
internal_error("tried to compile Verb from non-command GV");
if (gv->first_line == NULL)
internal_error("compiling Verb for empty grammar");
if (Wordings__empty(gv->command))
WRITE("Verb 'no.verb'");
else {
WRITE("Verb ");
if (PL__Parsing__Verbs__command_verb_reserved(Lexer__word_text(Wordings__first_wn(gv->command)))) {
current_sentence = gv->where_gv_created;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, gv->command);
Problems__Issue__handmade_problem(_p_(PM_ReservedVerb));
Problems__issue_problem_segment(
"You wrote %1, but %2 is a built-in Inform testing verb, which "
"means it is reserved for Inform's own use and can't be used "
"for ordinary play purposes. %PThe verbs which are reserved in "
"this way are all listed in the alphabetical catalogue on the "
"Actions Index page.");
Problems__issue_problem_end();
}
DictionaryWords__compile(OUT, Lexer__word_text(Wordings__first_wn(gv->command)), FALSE);
for (int i=0; i<gv->no_aliased_commands; i++) {
WRITE(" ");
DictionaryWords__compile(OUT, Lexer__word_text(Wordings__first_wn(gv->aliased_command[i])), FALSE);
}
}
WRITE("\n");
}
#line 306 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__reserve(char *verb_name) {
reserved_command_verb *rcv = CREATE(reserved_command_verb);
PL__Parsing__Verbs__normalise_cv_to(verb_name, rcv->reserved_text);
PL__Actions__Index__test_verb(rcv->reserved_text);
}
int PL__Parsing__Verbs__command_verb_reserved(char *verb_tried) {
reserved_command_verb *rcv;
char normalised_vt[32];
PL__Parsing__Verbs__normalise_cv_to(verb_tried, normalised_vt);
LOOP_OVER(rcv, reserved_command_verb)
if (strcmp(normalised_vt, rcv->reserved_text) == 0)
return TRUE;
return FALSE;
}
void PL__Parsing__Verbs__normalise_cv_to(char *from, char *to) {
int i;
for (i=0; (i<31) && (from[i]); i++) to[i] = Platform__tolower(from[i]);
to[i] = 0;
}
#line 339 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__make_command_index_entries(grammar_verb *gv) {
if ((gv->gv_is == GV_IS_COMMAND) && (gv->first_line)) {
if (Wordings__empty(gv->command))
PL__Actions__Index__vie_new_from("0", gv, NORMAL_COMMAND);
else
PL__Actions__Index__vie_new_from(Lexer__word_text(Wordings__first_wn(gv->command)), gv, NORMAL_COMMAND);
for (int i=0; i<gv->no_aliased_commands; i++)
PL__Actions__Index__vie_new_from(Lexer__word_text(Wordings__first_wn(gv->aliased_command[i])), gv, ALIAS_COMMAND);
}
}
void PL__Parsing__Verbs__index_normal(grammar_verb *gv, char *headword) {
PL__Parsing__Lines__sorted_list_index_normal(gv->sorted_first_line, headword);
}
void PL__Parsing__Verbs__index_alias(grammar_verb *gv, char *headword) {
INDEX("&quot;%s&quot;, <i>same as</i> &quot;%s&quot;",
headword, Lexer__word_text(Wordings__first_wn(gv->command)));
Index__below_link(Lexer__word_text(Wordings__first_wn(gv->command)));
INDEX("<br>");
}
#line 367 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb *PL__Parsing__Verbs__named_token_new(wording W) {
grammar_verb *gv = PL__Parsing__Verbs__named_token_by_name(W);
if (gv == NULL) {
gv = PL__Parsing__Verbs__gv_new(GV_IS_TOKEN);
gv->name = W;
}
return gv;
}
grammar_verb *PL__Parsing__Verbs__named_token_by_name(wording W) {
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb)
if ((gv->gv_is == GV_IS_TOKEN) && (Wordings__match(W, gv->name)))
return gv;
return NULL;
}
#line 387 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__index_tokens(void) {
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "anybody", NULL, NULL, "someone_token", "same as \"[someone]\"");
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "anyone", NULL, NULL, "someone_token", "same as \"[someone]\"");
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "anything", NULL, NULL, "things_token", "same as \"[thing]\"");
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "other things", NULL, NULL, "things_token", NULL);
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "somebody", NULL, NULL, "someone_token", "same as \"[someone]\"");
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "someone", NULL, NULL, "someone_token", NULL);
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "something", NULL, NULL, "things_token", "same as \"[thing]\"");
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "something preferably held", NULL, NULL, "things_token", NULL);
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "text", NULL, NULL, "text_token", NULL);
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "things", NULL, NULL, "things_token", NULL);
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "things inside", NULL, NULL, "things_token", NULL);
PL__Parsing__Verbs__index_tokens_for(EMPTY_WORDING, "things preferably held", NULL, NULL, "things_token", NULL);
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_TOKEN)
PL__Parsing__Verbs__index_tokens_for(gv->name, NULL,
gv->where_gv_created, gv->sorted_first_line, NULL, NULL);
}
void PL__Parsing__Verbs__index_tokens_for(wording W, char *special, parse_node *where,
grammar_line *defns, char *help, char *explanation) {
HTML__open_para(ifl, 1, "tight");
INDEX("\"[");
if (special) INDEX("%s", special); else Wordings__index_raw(W);
INDEX("]\"");
if (where) Index__link(Wordings__first_wn(ParseTree__get_text(where)));
if (help) Index__DocReferences__link(help);
if (explanation) INDEX(" - %s", explanation);
INDEX("</p>");
if (defns) PL__Parsing__Lines__index_list_for_token(defns);
}
#line 424 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__translates(wording W, parse_node *p2) {
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb)
if ((gv->gv_is == GV_IS_TOKEN) && (Wordings__match(W, gv->name))) {
Problems__Issue__sentence_problem(_p_(PM_GrammarTranslatedAlready),
"this grammar token has already been translated",
"so there must be some duplication somewhere.");
return;
}
gv = PL__Parsing__Verbs__named_token_new(W);
strcpy(gv->gv_I6_identifier, Lexer__word_text(Wordings__first_wn(ParseTree__get_text(p2))));
}
void PL__Parsing__Verbs__compile_i6_token(OUTPUT_STREAM, grammar_verb *gv) {
char *n = gv->gv_I6_identifier;
if (n[0]) WRITE("%s", n);
else WRITE("GPR_Line_%d", gv->allocation_id);
}
#line 450 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb *PL__Parsing__Verbs__consultation_new(void) {
grammar_verb *gv;
gv = PL__Parsing__Verbs__gv_new(GV_IS_CONSULT);
return gv;
}
#line 463 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb *PL__Parsing__Verbs__for_subject(inference_subject *subj) {
grammar_verb *gv;
if (PF_S(parsing, subj)->understand_as_this_object != NULL)
return PF_S(parsing, subj)->understand_as_this_object;
gv = PL__Parsing__Verbs__gv_new(GV_IS_OBJECT);
PF_S(parsing, subj)->understand_as_this_object = gv;
gv->subj_understood = subj;
return gv;
}
void PL__Parsing__Verbs__take_out_one_word_grammar(OUTPUT_STREAM, grammar_verb *gv) {
if (gv->gv_is != GV_IS_OBJECT)
internal_error("One-word optimisation applies only to objects");
gv->first_line = PL__Parsing__Lines__list_take_out_one_word_grammar(OUT, gv->first_line);
}
int PL__Parsing__Verbs__allow_mixed_lines(grammar_verb *gv) {
if ((gv->gv_is == GV_IS_OBJECT) || (gv->gv_is == GV_IS_VALUE))
return TRUE;
return FALSE;
}
#line 490 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb *PL__Parsing__Verbs__for_kind(kind *K) {
grammar_verb *gv;
if (Kinds__Behaviour__get_parsing_grammar(K) != NULL)
return Kinds__Behaviour__get_parsing_grammar(K);
gv = PL__Parsing__Verbs__gv_new(GV_IS_VALUE);
Kinds__Behaviour__set_parsing_grammar(K, gv);
gv->kind_understood = K;
return gv;
}
#line 506 "inform7/Chapter 36/Grammar Verbs.w"
grammar_verb *PL__Parsing__Verbs__for_prn(property *prn) {
grammar_verb *gv;
if (Properties__EitherOr__get_parsing_grammar(prn) != NULL)
return Properties__EitherOr__get_parsing_grammar(prn);
gv = PL__Parsing__Verbs__gv_new(GV_IS_PROPERTY_NAME);
Properties__EitherOr__set_parsing_grammar(prn, gv);
gv->prn_understood = prn;
return gv;
}
#line 522 "inform7/Chapter 36/Grammar Verbs.w"
int PL__Parsing__Verbs__is_empty(grammar_verb *gv) {
if ((gv == NULL) || (gv->first_line == NULL)) return TRUE;
return FALSE;
}
void PL__Parsing__Verbs__add_line(grammar_verb *gv, grammar_line *gl) {
LOGIF(GRAMMAR, "Adding grammar line $g to verb $G\n", gl, gv);
if ((gv->gv_is == GV_IS_COMMAND) &&
(PL__Parsing__Lines__list_length(gv->first_line) >= MAX_LINES_PER_COMMAND)) {
Problems__Issue__sentence_problem(_p_(PM_TooManyGrammarLines),
"this command verb now has too many Understand possibilities",
"that is, there are too many 'Understand \"whatever ...\" as ...' "
"which share the same initial word 'whatever'. The best way to "
"get around this is to try to consolidate some of those lines "
"together, perhaps by using slashes to combine alternative "
"wordings, or by defining new grammar tokens [in square brackets].");
return;
}
gv->first_line = PL__Parsing__Lines__list_add(gv->first_line, gl);
}
#line 549 "inform7/Chapter 36/Grammar Verbs.w"
kind *PL__Parsing__Verbs__get_data_type_as_token(grammar_verb *gv) {
return PL__Parsing__Tokens__Types__get_data_type_as_token(&(gv->gv_type));
}
#line 558 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__compile_conditions(OUTPUT_STREAM) {
grammar_verb *gv;
LOOP_OVER(gv, grammar_verb) {
current_sentence = gv->where_gv_created;
PL__Parsing__Lines__line_list_compile_condition_tokens(OUT, gv->first_line);
}
}
#line 571 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__prepare(void) {
PL__Parsing__Verbs__gv_slash_all();
PL__Parsing__Verbs__gv_determine_all();
}
#line 581 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__gv_slash_all(void) {
grammar_verb *gv;
Log__new_stage_of_Informs_run("Slashing grammar (G1)");
LOOP_OVER(gv, grammar_verb) {
if (gv->slashed == FALSE) {
LOGIF(GRAMMAR_CONSTRUCTION, "Slashing $G\n", gv);
PL__Parsing__Lines__line_list_slash(gv->first_line);
gv->slashed = TRUE;
}
}
}
#line 597 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__gv_determine_all(void) {
grammar_verb *gv;
Log__new_stage_of_Informs_run("Determining grammar (G2)");
LOOP_OVER(gv, grammar_verb)
if ((gv->determined == FALSE) && (gv->first_line)) {
current_sentence = gv->where_gv_created;
PL__Parsing__Verbs__determine(gv, 0);
gv->determined = TRUE;
}
}
parse_node *PL__Parsing__Verbs__determine(grammar_verb *gv, int depth) {
parse_node *spec_union = NULL;
current_sentence = gv->where_gv_created;
if (PL__Parsing__Tokens__Types__has_return_type(&(gv->gv_type)))
return PL__Parsing__Tokens__Types__get_single_type(&(gv->gv_type));
if (depth > NUMBER_CREATED(grammar_verb)) {
Problems__Issue__sentence_problem(_p_(PM_GrammarIllFounded),
"grammar tokens are not allowed to be defined in terms of "
"themselves",
"either directly or indirectly.");
return NULL;
}
LOGIF(GRAMMAR_CONSTRUCTION, "Determining $G\n", gv);
spec_union = PL__Parsing__Lines__line_list_determine(gv->first_line, depth,
gv->gv_is, gv, PL__Parsing__Verbs__gv_is_genuinely_verbal(gv));
LOGIF(GRAMMAR_CONSTRUCTION, "Result of verb $G is $P\n", gv, spec_union);
PL__Parsing__Tokens__Types__set_single_type(&(gv->gv_type), spec_union);
return spec_union;
}
#line 655 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__compile_all(OUTPUT_STREAM) {
grammar_verb *gv;
PL__Parsing__Verbs__gv_slash_all();
PL__Parsing__Verbs__gv_determine_all();
Log__new_stage_of_Informs_run("Sorting and compiling non-value grammar (G3, G4)");
TEMPORARY_STREAM;
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_TOKEN)
PL__Parsing__Verbs__compile(OUT, gv); /* makes GPRs for designed tokens */
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_COMMAND)
PL__Parsing__Verbs__compile(TEMP, gv); /* makes |Verb| directives */
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_OBJECT)
PL__Parsing__Verbs__compile(OUT, gv); /* makes routines for use in |parse_name| */
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_CONSULT)
PL__Parsing__Verbs__compile(OUT, gv); /* routines to parse snippets, used as values */
LOOP_OVER(gv, grammar_verb)
if (gv->gv_is == GV_IS_PROPERTY_NAME)
PL__Parsing__Verbs__compile(OUT, gv); /* makes routines for use in |parse_name| */
PL__Parsing__Lines__compile_slash_gprs(OUT);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
#line 701 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__compile(OUTPUT_STREAM, grammar_verb *gv) {
if (gv->first_line == NULL) return;
LOGIF(GRAMMAR, "Compiling grammar verb $G\n", gv);
current_sentence = gv->where_gv_created;
PL__Parsing__Lines__reset_labels();
switch(gv->gv_is) {
case GV_IS_COMMAND:
PL__Parsing__Verbs__gv_compile_Verb_directive_header(OUT, gv);
break;
case GV_IS_TOKEN:
OUT = PL__Parsing__Tokens__General__compile_gpr_head(OUT, gv->allocation_id);
break;
case GV_IS_CONSULT:
OUT = PL__Parsing__Tokens__General__compile_consult_head(OUT, gv->allocation_id);
break;
case GV_IS_OBJECT:
OUT = PL__Parsing__Tokens__General__compile_parse_name_head(OUT, gv->subj_understood, gv);
break;
case GV_IS_VALUE:
break;
case GV_IS_PROPERTY_NAME:
OUT = PL__Parsing__Tokens__General__compile_prn_pr_head(OUT, gv->prn_understood);
break;
}
if (gv->gv_is == GV_IS_OBJECT) PL__Parsing__Verbs__gv_compile_parse_name_lines(OUT, gv);
else PL__Parsing__Verbs__gv_compile_lines(OUT, gv);
switch(gv->gv_is) {
case GV_IS_COMMAND:
WRITE(";\n");
break;
case GV_IS_TOKEN:
OUT = PL__Parsing__Tokens__General__compile_gpr_tail(OUT);
break;
case GV_IS_CONSULT:
OUT = PL__Parsing__Tokens__General__compile_consult_tail(OUT);
break;
case GV_IS_OBJECT:
OUT = PL__Parsing__Tokens__General__compile_parse_name_tail(OUT);
break;
case GV_IS_VALUE:
break;
case GV_IS_PROPERTY_NAME:
OUT = PL__Parsing__Tokens__General__compile_prn_pr_tail(OUT, gv->prn_understood);
break;
}
}
#line 761 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__gv_compile_parse_name_lines(OUTPUT_STREAM, grammar_verb *gv) {
inference_subject *subj = gv->subj_understood;
if (PF_S(parsing, subj)->understand_as_this_object != gv)
internal_error("link between subject and GV broken");
LOGIF(GRAMMAR, "Parse_name content for $j:\n", subj);
PL__Parsing__Verbs__gv_compile_lines(OUT, PF_S(parsing, subj)->understand_as_this_object);
inference_subject *infs;
for (infs = InferenceSubjects__narrowest_broader_subject(subj);
infs; infs = InferenceSubjects__narrowest_broader_subject(infs)) {
if (PF_S(parsing, infs))
if (PF_S(parsing, infs)->understand_as_this_object) {
LOGIF(GRAMMAR, "And parse_name content inherited from $j:\n", infs);
PL__Parsing__Verbs__gv_compile_lines(OUT, PF_S(parsing, infs)->understand_as_this_object);
}
}
}
#line 784 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__gv_compile_lines(OUTPUT_STREAM, grammar_verb *gv) {
PL__Parsing__Lines__list_assert_ownership(gv->first_line, gv); /* Mark for later indexing */
PL__Parsing__Verbs__sort_grammar_verb(gv); /* Phase III for the GLs in the GV happens here */
PL__Parsing__Lines__sorted_line_list_compile(OUT, gv->sorted_first_line,
gv->gv_is, gv, PL__Parsing__Verbs__gv_is_genuinely_verbal(gv)); /* And Phase IV here */
}
#line 799 "inform7/Chapter 36/Grammar Verbs.w"
void PL__Parsing__Verbs__sort_grammar_verb(grammar_verb *gv) {
if (gv->sorted_first_line == NULL)
gv->sorted_first_line = PL__Parsing__Lines__list_sort(gv->first_line);
}
#line 81 "inform7/Chapter 36/Grammar Lines.w"
grammar_line *PL__Parsing__Lines__new(int wn, action_name *ac,
parse_node *token_list, int reversed, int pluralised) {
grammar_line *gl;
gl = CREATE(grammar_line);
gl->original_text = wn;
gl->resulting_action = ac;
gl->belongs_to_gv = NULL;
if (ac != NULL) PL__Actions__add_gl(ac, gl);
gl->mistaken = FALSE;
gl->mistake_response_text = EMPTY_WORDING;
gl->next_with_action = NULL;
gl->next_line = NULL;
gl->tokens = token_list;
gl->where_grammar_specified = current_sentence;
gl->gl_type = PL__Parsing__Tokens__Types__new(TRUE);
gl->lexeme_count = -1; /* no count made as yet */
gl->reversed = reversed;
gl->pluralised = pluralised;
gl->understand_when_text = EMPTY_WORDING;
gl->understand_when_prop = NULL;
gl->suppress_compilation = FALSE;
gl->general_sort_bonus = UNCALCULATED_BONUS;
gl->understanding_sort_bonus = UNCALCULATED_BONUS;
return gl;
}
void PL__Parsing__Lines__log(grammar_line *gl) {
LOG("<GL%d:$w>", gl->allocation_id, ParseTree__get_text(gl->tokens));
}
void PL__Parsing__Lines__set_single_type(grammar_line *gl, parse_node *gl_value) {
PL__Parsing__Tokens__Types__set_single_type(&(gl->gl_type), gl_value);
}
#line 123 "inform7/Chapter 36/Grammar Lines.w"
int PL__Parsing__Lines__list_length(grammar_line *list_head) {
int c = 0;
grammar_line *posn;
for (posn = list_head; posn; posn = posn->next_line) c++;
return c;
}
grammar_line *PL__Parsing__Lines__list_add(grammar_line *list_head, grammar_line *new_gl) {
new_gl->next_line = NULL;
if (list_head == NULL) list_head = new_gl;
else {
grammar_line *posn = list_head;
while (posn->next_line) posn = posn->next_line;
posn->next_line = new_gl;
}
return list_head;
}
grammar_line *PL__Parsing__Lines__list_remove(grammar_line *list_head, action_name *find) {
grammar_line *prev = NULL, *posn = list_head;
while (posn) {
if (posn->resulting_action == find) {
LOGIF(GRAMMAR_CONSTRUCTION, "Removing grammar line: $g\n", posn);
if (prev) prev->next_line = posn->next_line;
else list_head = posn->next_line;
} else {
prev = posn;
}
posn = posn->next_line;
}
return list_head;
}
#line 167 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__line_list_compile_condition_tokens(OUTPUT_STREAM, grammar_line *list_head) {
grammar_line *gl;
for (gl = list_head; gl; gl = gl->next_line) {
PL__Parsing__Lines__gl_compile_condition_token_as_needed(OUT, gl);
PL__Parsing__Lines__gl_compile_mistake_token_as_needed(OUT, gl);
}
}
#line 187 "inform7/Chapter 36/Grammar Lines.w"
int understand_condition_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; parse_node_cond_NTMV = RP[1];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 195 "inform7/Chapter 36/Grammar Lines.w"
Problems__Issue__sentence_problem(_p_(PM_WhenAction),
"the condition after 'when' involves the current action",
"but this can never work, because when Inform is still trying to "
"understand a command, the current action isn't yet decided on.");
}
#line 189 "inform7/Chapter 36/Grammar Lines.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 203 "inform7/Chapter 36/Grammar Lines.w"
Problems__Issue__sentence_problem(_p_(PM_BadWhen),
"the condition after 'when' makes no sense to me",
"although otherwise this worked - it is only the part after 'when' "
"which I can't follow.");
}
#line 190 "inform7/Chapter 36/Grammar Lines.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 191 "inform7/Chapter 36/Grammar Lines.w"
#line 216 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__set_understand_when(grammar_line *gl, wording W) {
gl->understand_when_text = W;
}
void PL__Parsing__Lines__set_understand_prop(grammar_line *gl, pcalc_prop *prop) {
gl->understand_when_prop = prop;
}
int PL__Parsing__Lines__conditional(grammar_line *gl) {
if ((Wordings__nonempty(gl->understand_when_text)) || (gl->understand_when_prop))
return TRUE;
return FALSE;
}
void PL__Parsing__Lines__gl_compile_condition_token_as_needed(OUTPUT_STREAM, grammar_line *gl) {
if (PL__Parsing__Lines__conditional(gl)) {
current_sentence = gl->where_grammar_specified;
char i6_routine_identifier[32];
sprintf(i6_routine_identifier, "Cond_Token_%d", gl->allocation_id);
OUT = Routines__begin(OUT, i6_routine_identifier);
parse_node *spec = NULL;
if (Wordings__nonempty(gl->understand_when_text)) {
current_sentence = gl->where_grammar_specified;
if (Preform__parse_nt_against_word_range(understand_condition_NTM, gl->understand_when_text, NULL, NULL)) {
spec = parse_node_cond_NTMV;
if (PL__Actions__Patterns__validate_when(spec) == FALSE) {
{
#line 203 "inform7/Chapter 36/Grammar Lines.w"
Problems__Issue__sentence_problem(_p_(PM_BadWhen),
"the condition after 'when' makes no sense to me",
"although otherwise this worked - it is only the part after 'when' "
"which I can't follow.");
}
#line 242 "inform7/Chapter 36/Grammar Lines.w"
;
spec = NULL;
}
}
}
pcalc_prop *prop = gl->understand_when_prop;
if ((spec) || (prop)) {
WRITE("if (");
if (spec) {
if (prop) WRITE("(");
Specifications__Compiler__compile(OUT, spec);
if (prop) WRITE(") && (");
}
if (prop) {
Calculus__Deferrals__compile_test_of_proposition(OUT, Rvalues__new_self_object_constant(), prop);
if (spec) WRITE(")");
}
WRITE(") return GPR_PREPOSITION;\n");
WRITE("return GPR_FAIL;\n");
}
OUT = Routines__end(OUT);
}
}
void PL__Parsing__Lines__gl_compile_extra_token_for_condition(OUTPUT_STREAM, grammar_line *gl,
int gv_is, int current_label) {
if (PL__Parsing__Lines__conditional(gl)) {
if (gv_is == GV_IS_COMMAND)
WRITE("Cond_Token_%d ", gl->allocation_id);
else
WRITE("if (Cond_Token_%d() == GPR_FAIL) jump Fail_%d;\n",
gl->allocation_id, current_label);
}
}
#line 301 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__set_mistake(grammar_line *gl, int wn) {
gl->mistaken = TRUE;
gl->mistake_response_text = Wordings__one_word(wn);
}
void PL__Parsing__Lines__gl_compile_mistake_token_as_needed(OUTPUT_STREAM, grammar_line *gl) {
if (gl->mistaken) {
OUT = Routines__begin_numbered(OUT,
"Mistake_Token_%d", gl->allocation_id);
WRITE("if (actor ~= player) return GPR_FAIL;\n");
WRITE("understand_as_mistake_number = %d;\n", 100 + gl->allocation_id);
WRITE("return GPR_PREPOSITION;\n");
OUT = Routines__end(OUT);
}
}
void PL__Parsing__Lines__gl_compile_extra_token_for_mistake(OUTPUT_STREAM, grammar_line *gl,
int gv_is, int current_label) {
if (gl->mistaken) {
if (gv_is == GV_IS_COMMAND)
WRITE("Mistake_Token_%d ", gl->allocation_id);
else
internal_error("GLs may only be mistaken in command grammar");
}
}
int PL__Parsing__Lines__gl_compile_result_of_mistake(OUTPUT_STREAM, grammar_line *gl) {
if (gl->mistaken) { WRITE(" -> MistakeAction\n"); return TRUE; }
return FALSE;
}
void PL__Parsing__Lines__MistakeActionSub_routine(OUTPUT_STREAM) {
OUT = Routines__begin(OUT, "MistakeActionSub");
WRITE("switch(understand_as_mistake_number) {\n"); INDENT;
grammar_line *gl;
LOOP_OVER(gl, grammar_line)
if (gl->mistaken) {
if (Wordings__nonempty(gl->mistake_response_text)) {
current_sentence = gl->where_grammar_specified;
parse_node *spec = NULL;
if (Preform__parse_nt_against_word_range(s_value_NTM, gl->mistake_response_text, NULL, NULL))
spec = most_recent_result_p;
else spec = Specifications__new_UNKNOWN(gl->mistake_response_text);
WRITE("%d: ParserError(", 100+gl->allocation_id);
Specifications__Compiler__compile_constant_to_kind(OUT, spec, K_text);
WRITE(");\n");
}
}
WRITE("default: \"I didn't understand that sentence.\";\n");
OUTDENT; WRITE("}\n");
WRITE("say__p = 1;\n");
OUT = Routines__end(OUT);
}
#line 364 "inform7/Chapter 36/Grammar Lines.w"
int PL__Parsing__Lines__gl_contains_single_unconditional_word(grammar_line *gl) {
parse_node *pn = gl->tokens->down;
if ((pn)
&& (pn->next == NULL)
&& (ParseTree__int_annotation(pn, slash_class_ANNOT) == 0)
&& (ParseTree__int_annotation(pn, grammar_token_literal_ANNOT))
&& (gl->pluralised == FALSE)
&& (PL__Parsing__Lines__conditional(gl) == FALSE))
return Wordings__first_wn(ParseTree__get_text(pn));
return -1;
}
#line 386 "inform7/Chapter 36/Grammar Lines.w"
grammar_line *PL__Parsing__Lines__list_take_out_one_word_grammar(OUTPUT_STREAM,
grammar_line *list_head) {
grammar_line *gl, *glp;
for (gl = list_head, glp = NULL; gl; gl = gl->next_line) {
int wn = PL__Parsing__Lines__gl_contains_single_unconditional_word(gl);
if (wn >= 0) {
if (OUT) {
DictionaryWords__compile(OUT, Lexer__word_text(wn), FALSE);
WRITE(" ");
}
gl->suppress_compilation = TRUE;
} else glp = gl;
}
return list_head;
}
#line 407 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__line_list_slash(grammar_line *gl_head) {
grammar_line *gl;
for (gl = gl_head; gl; gl = gl->next_line) {
PL__Parsing__Lines__slash_grammar_line(gl);
}
}
#line 427 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__slash_grammar_line(grammar_line *gl) {
parse_node *pn;
int alternatives_group = 0;
current_sentence = gl->where_grammar_specified; /* to report problems */
if (gl->tokens == NULL)
internal_error("Null tokens on grammar");
LOGIF(GRAMMAR_CONSTRUCTION, "Preparing grammar line:\n$T", gl->tokens);
for (pn = gl->tokens->down; pn; pn = pn->next)
ParseTree__annotate_int(pn, slash_class_ANNOT, 0);
parse_node *class_start = NULL;
for (pn = gl->tokens->down; pn; pn = pn->next) {
if ((pn->next) &&
(Wordings__length(ParseTree__get_text(pn->next)) == 1) &&
(Lexer__word(Wordings__first_wn(ParseTree__get_text(pn->next))) == FORWARDSLASH_V)) { /* slash follows: */
if (ParseTree__int_annotation(pn, slash_class_ANNOT) == 0) {
class_start = pn; alternatives_group++; /* start new equiv class */
ParseTree__annotate_int(class_start, slash_dash_dash_ANNOT, FALSE);
}
ParseTree__annotate_int(pn, slash_class_ANNOT,
alternatives_group); /* make two sides of slash equiv */
if (pn->next->next)
ParseTree__annotate_int(pn->next->next, slash_class_ANNOT, alternatives_group);
if ((pn->next->next) &&
(Wordings__length(ParseTree__get_text(pn->next->next)) == 1) &&
(Lexer__word(Wordings__first_wn(ParseTree__get_text(pn->next->next))) == DOUBLEDASH_V)) { /* -- follows: */
ParseTree__annotate_int(class_start, slash_dash_dash_ANNOT, TRUE);
pn->next = pn->next->next->next; /* excise slash and dash-dash */
} else {
pn->next = pn->next->next; /* excise the slash from the token list */
}
}
}
LOGIF(GRAMMAR_CONSTRUCTION, "Regrouped as:\n$T", gl->tokens);
for (pn = gl->tokens->down; pn; pn = pn->next)
if ((ParseTree__int_annotation(pn, slash_class_ANNOT) > 0) &&
(ParseTree__int_annotation(pn, grammar_token_literal_ANNOT) == FALSE)) {
Problems__Issue__sentence_problem(_p_(PM_OverAmbitiousSlash),
"the slash '/' can only be used between single literal words",
"so 'underneath/under/beneath' is allowed but "
"'beneath/[florid ways to say under]/under' isn't.");
break;
}
gl->lexeme_count = 0;
for (pn = gl->tokens->down; pn; pn = pn->next) {
int i = ParseTree__int_annotation(pn, slash_class_ANNOT);
if (i > 0)
while ((pn->next) && (ParseTree__int_annotation(pn->next, slash_class_ANNOT) == i))
pn = pn->next;
gl->lexeme_count++;
}
LOGIF(GRAMMAR_CONSTRUCTION, "Slashed as:\n$T", gl->tokens);
}
#line 504 "inform7/Chapter 36/Grammar Lines.w"
parse_node *PL__Parsing__Lines__line_list_determine(grammar_line *list_head,
int depth, int gv_is, grammar_verb *gv, int genuinely_verbal) {
grammar_line *gl;
int first_flag = TRUE;
parse_node *spec_union = NULL;
LOGIF(GRAMMAR_CONSTRUCTION, "Determining GL list for $G\n", gv);
for (gl = list_head; gl; gl = gl->next_line) {
parse_node *spec_of_line =
PL__Parsing__Lines__gl_determine(gl, depth, gv_is, gv, genuinely_verbal);
if (first_flag) { /* initially no expectations: |spec_union| is meaningless */
spec_union = spec_of_line; /* so we set it to the first result */
first_flag = FALSE;
continue;
}
if ((spec_union == NULL) && (spec_of_line == NULL))
continue; /* we expected to find no result, and did: so no problem */
if ((spec_union) && (spec_of_line)) {
if (Kinds__Compare__compatible_with_description(spec_union, spec_of_line) == ALWAYS_MATCH) {
spec_union = spec_of_line; /* here |spec_of_line| was a wider type */
continue;
}
if (Kinds__Compare__compatible_with_description(spec_of_line, spec_union) == ALWAYS_MATCH) {
continue; /* here |spec_union| was already wide enough */
}
}
if (PL__Parsing__Verbs__allow_mixed_lines(gv)) continue;
current_sentence = gl->where_grammar_specified;
Problems__Issue__sentence_problem(_p_(PM_MixedOutcome),
"grammar tokens must have the same outcome whatever the way they are "
"reached",
"so writing a line like 'Understand \"within\" or \"next to "
"[something]\" as \"[my token]\" must be wrong: one way it produces "
"a thing, the other way it doesn't.");
spec_union = NULL;
break; /* to prevent the problem being repeated for the same grammar */
}
LOGIF(GRAMMAR_CONSTRUCTION, "Union: $P\n");
return spec_union;
}
#line 557 "inform7/Chapter 36/Grammar Lines.w"
parse_node *PL__Parsing__Lines__gl_determine(grammar_line *gl, int depth,
int gv_is, grammar_verb *gv, int genuinely_verbal) {
parse_node *spec = NULL;
parse_node *pn, *pn2;
int nulls_count, i, nrv, line_length;
current_sentence = gl->where_grammar_specified;
gl->understanding_sort_bonus = 0;
gl->general_sort_bonus = 0;
nulls_count = 0; /* number of tokens with null results */
pn = gl->tokens->down; /* start from first token */
if ((genuinely_verbal) && (pn)) pn = pn->next; /* unless it's a command verb */
for (pn2=pn, line_length=0; pn2; pn2 = pn2->next) line_length++;
int multiples = 0;
for (i=0; pn; pn = pn->next, i++) {
if (ParseTree__get_type(pn) != TOKEN_NT)
internal_error("Bogus node types on grammar");
int score = 0;
spec = PL__Parsing__Tokens__determine(pn, depth, &score);
LOGIF(GRAMMAR_CONSTRUCTION, "Result of token <$w> is $P\n", ParseTree__get_text(pn), spec);
if (spec) {
if ((Specifications__is_kind_like(spec)) &&
(Kinds__Compare__eq(Specifications__to_kind(spec), K_understanding))) { /* "[text]" token */
int usb_contribution = i - 100;
if (usb_contribution >= 0) usb_contribution = -1;
usb_contribution = 100*usb_contribution + (line_length-1-i);
gl->understanding_sort_bonus += usb_contribution; /* reduces! */
}
gl->general_sort_bonus +=
PL__Parsing__Tokens__Types__add_type(&(gl->gl_type), spec,
PL__Parsing__Tokens__is_multiple(pn), score);
} else nulls_count++;
if (PL__Parsing__Tokens__is_multiple(pn)) multiples++;
}
if (multiples > 1)
Problems__Issue__sentence_problem(_p_(PM_MultipleMultiples),
"there can be at most one token in any line which can match "
"multiple things",
"so you'll have to remove one of the 'things' tokens and "
"make it a 'something' instead.");
nrv = PL__Parsing__Tokens__Types__get_no_resulting_values(&(gl->gl_type));
if (nrv == 0) gl->general_sort_bonus = 100*nulls_count;
if (gv_is == GV_IS_COMMAND) spec = NULL;
else {
if (nrv < 2) spec = PL__Parsing__Tokens__Types__get_single_type(&(gl->gl_type));
else Problems__Issue__sentence_problem(_p_(PM_TwoValuedToken),
"there can be at most one varying part in the definition of a "
"named token",
"so 'Understand \"button [a number]\" as \"[button indication]\"' "
"is allowed but 'Understand \"button [a number] on [something]\" "
"as \"[button indication]\"' is not.");
}
LOGIF(GRAMMAR_CONSTRUCTION,
"Determined $g: lexeme count %d, sorting bonus %d, arguments %d, "
"fixed initials %d, type $P\n",
gl, gl->lexeme_count, gl->general_sort_bonus, nrv,
gl->understanding_sort_bonus, spec);
return spec;
}
#line 633 "inform7/Chapter 36/Grammar Lines.w"
grammar_line *PL__Parsing__Lines__list_sort(grammar_line *list_head) {
grammar_line *gl, *gl2, *gl3, *sorted_head;
if (list_head == NULL) return NULL;
sorted_head = list_head;
list_head->sorted_next_line = NULL;
gl = list_head;
while (gl->next_line) {
gl = gl->next_line;
gl2 = sorted_head;
if (PL__Parsing__Lines__grammar_line_must_precede(gl, gl2)) {
sorted_head = gl;
gl->sorted_next_line = gl2;
continue;
}
while (gl2) {
gl3 = gl2;
gl2 = gl2->sorted_next_line;
if (gl2 == NULL) {
gl3->sorted_next_line = gl;
break;
}
if (PL__Parsing__Lines__grammar_line_must_precede(gl, gl2)) {
gl3->sorted_next_line = gl;
gl->sorted_next_line = gl2;
break;
}
}
}
return sorted_head;
}
#line 826 "inform7/Chapter 36/Grammar Lines.w"
int PL__Parsing__Lines__grammar_line_must_precede(grammar_line *L1, grammar_line *L2) {
int cs, a, b;
if ((L1 == NULL) || (L2 == NULL))
internal_error("tried to sort null GLs");
if ((L1->lexeme_count == -1) || (L2->lexeme_count == -1))
internal_error("tried to sort unslashed GLs");
if ((L1->general_sort_bonus == UNCALCULATED_BONUS) ||
(L2->general_sort_bonus == UNCALCULATED_BONUS))
internal_error("tried to sort uncalculated GLs");
if (L1 == L2) return FALSE;
a = FALSE; if ((L1->resulting_action) || (L1->mistaken)) a = TRUE;
b = FALSE; if ((L2->resulting_action) || (L2->mistaken)) b = TRUE;
if (a != b) {
LOG("L1 = $g\nL2 = $g\n", L1, L2);
internal_error("tried to sort on incomparable GLs");
}
if (L1->understanding_sort_bonus > L2->understanding_sort_bonus) return TRUE;
if (L1->understanding_sort_bonus < L2->understanding_sort_bonus) return FALSE;
if (a) { /* command grammar: shorter beats longer */
if (L1->lexeme_count < L2->lexeme_count) return TRUE;
if (L1->lexeme_count > L2->lexeme_count) return FALSE;
} else { /* all other grammars: longer beats shorter */
if (L1->lexeme_count < L2->lexeme_count) return FALSE;
if (L1->lexeme_count > L2->lexeme_count) return TRUE;
}
if ((L1->mistaken) && (L2->mistaken == FALSE)) return TRUE;
if ((L1->mistaken == FALSE) && (L2->mistaken)) return FALSE;
if (L1->general_sort_bonus > L2->general_sort_bonus) return TRUE;
if (L1->general_sort_bonus < L2->general_sort_bonus) return FALSE;
cs = PL__Parsing__Tokens__Types__must_precede(&(L1->gl_type), &(L2->gl_type));
if (cs != NOT_APPLICABLE) return cs;
if ((PL__Parsing__Lines__conditional(L1)) && (PL__Parsing__Lines__conditional(L2) == FALSE)) return TRUE;
if ((PL__Parsing__Lines__conditional(L1) == FALSE) && (PL__Parsing__Lines__conditional(L2))) return FALSE;
return FALSE;
}
#line 886 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__sorted_line_list_compile(OUTPUT_STREAM, grammar_line *list_head,
int gv_is, grammar_verb *gv, int genuinely_verbal) {
grammar_line *gl;
INDENT;
for (gl = list_head; gl; gl = gl->sorted_next_line)
if (gl->suppress_compilation == FALSE)
PL__Parsing__Lines__compile_grammar_line(OUT, gl, gv_is, gv, genuinely_verbal);
OUTDENT;
}
#line 902 "inform7/Chapter 36/Grammar Lines.w"
int current_grammar_block = 0;
int current_label = 1;
int GV_IS_VALUE_instance_mode = FALSE;
void PL__Parsing__Lines__reset_labels(void) {
current_label = 1;
}
#line 918 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__compile_grammar_line(OUTPUT_STREAM, grammar_line *gl, int gv_is, grammar_verb *gv,
int genuinely_verbal) {
parse_node *pn;
int i;
int token_values;
kind *token_value_kinds[2];
int code_mode, consult_mode;
LOGIF(GRAMMAR, "Compiling grammar line: $g\n", gl);
current_sentence = gl->where_grammar_specified;
if (gv_is == GV_IS_COMMAND) code_mode = FALSE; else code_mode = TRUE;
if (gv_is == GV_IS_CONSULT) consult_mode = TRUE; else consult_mode = FALSE;
switch (gv_is) {
case GV_IS_COMMAND:
case GV_IS_TOKEN:
case GV_IS_CONSULT:
case GV_IS_OBJECT:
case GV_IS_VALUE:
case GV_IS_PROPERTY_NAME:
break;
default: internal_error("tried to compile unknown GV type");
}
current_grammar_block++;
token_values = 0;
for (i=0; i<2; i++) token_value_kinds[i] = NULL;
if (code_mode == FALSE) WRITE("* ");
PL__Parsing__Lines__gl_compile_extra_token_for_condition(OUT, gl, gv_is, current_label);
PL__Parsing__Lines__gl_compile_extra_token_for_mistake(OUT, gl, gv_is, current_label);
pn = gl->tokens->down;
if ((genuinely_verbal) && (pn)) {
if (ParseTree__int_annotation(pn, slash_class_ANNOT) != 0) {
Problems__Issue__sentence_problem(_p_(PM_SlashedCommand),
"at present you're not allowed to use a / between command "
"words at the start of a line",
"so 'put/interpose/insert [something]' is out.");
return;
}
pn = pn->next; /* skip command word: the |Verb| header contains it already */
}
if ((gv_is == GV_IS_VALUE) && (GV_IS_VALUE_instance_mode)) {
WRITE("if (instance == ");
PL__Parsing__Tokens__Types__compile_to_string(OUT, &(gl->gl_type));
WRITE(") {\n"); INDENT;
}
parse_node *pn_from = pn, *pn_to = pn_from;
for (; pn; pn = pn->next) pn_to = pn;
PL__Parsing__Lines__compile_token_line(OUT, code_mode, pn_from, pn_to, gv_is, consult_mode, &token_values, token_value_kinds);
switch (gv_is) {
case GV_IS_COMMAND:
if (PL__Parsing__Lines__gl_compile_result_of_mistake(OUT, gl)) break;
WRITE(" -> %s", PL__Actions__identifier(gl->resulting_action));
if (gl->reversed) {
if (token_values < 2) {
Problems__Issue__sentence_problem(_p_(PM_CantReverseOne),
"you can't use a 'reversed' action when you supply fewer "
"than two values for it to apply to",
"since reversal is the process of exchanging them.");
return;
}
kind *swap = token_value_kinds[0];
token_value_kinds[0] = token_value_kinds[1];
token_value_kinds[1] = swap;
WRITE(" reverse");
}
WRITE("\n");
PL__Actions__check_types_for_grammar(gl->resulting_action, token_values,
token_value_kinds);
break;
case GV_IS_PROPERTY_NAME:
case GV_IS_TOKEN:
WRITE("return rv;\n");
WRITE(".Fail_%d; rv = GPR_PREPOSITION; wn = original_wn;\n",
current_label);
break;
case GV_IS_CONSULT:
WRITE("if ((range_words==0) || (wn-range_from==range_words)) return rv;\n");
WRITE(".Fail_%d; rv = GPR_PREPOSITION; wn = original_wn;\n", current_label);
break;
case GV_IS_OBJECT:
PL__Parsing__Tokens__General__after_gl_failed(OUT, current_label, gl->pluralised);
break;
case GV_IS_VALUE:
WRITE("parsed_number = ");
PL__Parsing__Tokens__Types__compile_to_string(OUT, &(gl->gl_type)); WRITE(";\n");
WRITE("return GPR_NUMBER;\n");
WRITE(".Fail_%d; wn = original_wn;\n", current_label);
break;
}
if ((gv_is == GV_IS_VALUE) && (GV_IS_VALUE_instance_mode)) {
OUTDENT; WRITE("}\n");
}
current_label++;
}
void PL__Parsing__Lines__compile_token_line(OUTPUT_STREAM, int code_mode, parse_node *pn, parse_node *pn_to, int gv_is, int consult_mode,
int *token_values, kind **token_value_kinds) {
int lexeme_equivalence_class = 0;
int alternative_number = 0;
int empty_text_allowed_in_lexeme = FALSE;
for (; pn; pn = pn->next) {
if ((PL__Parsing__Tokens__is_text(pn)) && (pn->next) &&
(PL__Parsing__Tokens__is_literal(pn->next) == FALSE)) {
Problems__Issue__sentence_problem(_p_(PM_TextFollowedBy),
"a '[text]' token must either match the end of some text, or "
"be followed by definitely known wording",
"since otherwise the run-time parser isn't good enough to "
"make sense of things.");
}
if ((ParseTree__get_grammar_token_relation(pn)) && (gv_is != GV_IS_OBJECT)) {
Problems__Issue__sentence_problem(_p_(PM_GrammarObjectlessRelation),
"a grammar token in an 'Understand...' can only be based "
"on a relation if it is to understand the name of a room or thing",
"since otherwise there is nothing for the relation to be with.");
continue;
}
int first_token_in_lexeme = FALSE, last_token_in_lexeme = FALSE;
if (ParseTree__int_annotation(pn, slash_class_ANNOT) != 0) { /* in a multi-token lexeme */
if ((pn->next == NULL) ||
(ParseTree__int_annotation(pn->next, slash_class_ANNOT) !=
ParseTree__int_annotation(pn, slash_class_ANNOT)))
last_token_in_lexeme = TRUE;
if (ParseTree__int_annotation(pn, slash_class_ANNOT) != lexeme_equivalence_class) {
first_token_in_lexeme = TRUE;
empty_text_allowed_in_lexeme =
ParseTree__int_annotation(pn, slash_dash_dash_ANNOT);
}
lexeme_equivalence_class = ParseTree__int_annotation(pn, slash_class_ANNOT);
if (first_token_in_lexeme) alternative_number = 1;
else alternative_number++;
} else { /* in a single-token lexeme */
lexeme_equivalence_class = 0;
first_token_in_lexeme = TRUE;
last_token_in_lexeme = TRUE;
empty_text_allowed_in_lexeme = FALSE;
alternative_number = 1;
}
char failure_label[32];
sprintf(failure_label, "Fail_%d", current_label);
if (lexeme_equivalence_class > 0) {
if (code_mode) {
if (first_token_in_lexeme) WRITE("group_wn = wn;\n");
WRITE(".group_%d_%d_%d; wn = group_wn;\n",
current_grammar_block, lexeme_equivalence_class, alternative_number);
if ((last_token_in_lexeme == FALSE) || (empty_text_allowed_in_lexeme))
sprintf(failure_label, "group_%d_%d_%d",
current_grammar_block,
lexeme_equivalence_class, alternative_number+1);
}
}
if ((empty_text_allowed_in_lexeme) && (code_mode == FALSE)) {
slash_gpr *sgpr = CREATE(slash_gpr);
sgpr->first_choice = pn;
while ((pn->next) &&
(ParseTree__int_annotation(pn->next, slash_class_ANNOT) ==
ParseTree__int_annotation(pn, slash_class_ANNOT))) pn = pn->next;
sgpr->last_choice = pn;
WRITE("SlashGPR_%d", sgpr->allocation_id);
last_token_in_lexeme = TRUE;
} else {
kind *grammar_token_kind =
PL__Parsing__Tokens__compile(OUT, pn, code_mode, failure_label, consult_mode);
if (grammar_token_kind) {
if (token_values) {
if (*token_values == 2) {
internal_error(
"There can be at most two value-producing tokens and this "
"should have been detected earlier.");
return;
}
token_value_kinds[(*token_values)++] = grammar_token_kind;
}
}
}
if (lexeme_equivalence_class > 0) {
if (code_mode) {
if (last_token_in_lexeme) {
if (empty_text_allowed_in_lexeme) {
WRITE("jump group_%d_%d_end;\n",
current_grammar_block, lexeme_equivalence_class);
WRITE(".group_%d_%d_%d;\n",
current_grammar_block,
lexeme_equivalence_class, alternative_number+1);
WRITE("wn = group_wn;\n");
}
WRITE(".group_%d_%d_end;\n",
current_grammar_block, lexeme_equivalence_class);
} else {
WRITE("jump group_%d_%d_end;\n",
current_grammar_block, lexeme_equivalence_class);
}
} else {
if (last_token_in_lexeme == FALSE) WRITE(" /");
}
}
if (code_mode == FALSE) WRITE(" "); /* |Verb| tokens divide by spaces */
if (pn == pn_to) break;
}
}
void PL__Parsing__Lines__compile_slash_gprs(OUTPUT_STREAM) {
slash_gpr *sgpr;
LOOP_OVER(sgpr, slash_gpr) {
OUT = Routines__begin_numbered(OUT, "SlashGPR_%d", sgpr->allocation_id);
LocalVariables__add_internal_local_c("group_wn",
"first word matched against A/B/C/.../-- disjunction");
PL__Parsing__Lines__compile_token_line(OUT, TRUE, sgpr->first_choice, sgpr->last_choice, GV_IS_TOKEN, FALSE, NULL, NULL);
WRITE("return GPR_PREPOSITION;\n");
OUT = Routines__end(OUT);
}
}
#line 1160 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__sorted_list_index_normal(grammar_line *list_head, char *headword) {
grammar_line *gl;
for (gl = list_head; gl; gl = gl->sorted_next_line)
PL__Parsing__Lines__gl_index_normal(gl, headword);
}
void PL__Parsing__Lines__gl_index_normal(grammar_line *gl, char *headword) {
action_name *an = gl->resulting_action;
if (an == NULL) return;
Index__anchor(headword);
if (PL__Actions__is_out_of_world(an))
INDEX("<font color=\"#800000\">");
INDEX("&quot;");
PL__Actions__Index__verb_definition(Lexer__word_text(gl->original_text),
headword, EMPTY_WORDING);
INDEX("&quot;");
Index__link(gl->original_text);
INDEX(" - <i>");
Wordings__index_raw(an->present_name);
Index__detail_link("A", an->allocation_id, TRUE);
if (gl->reversed) INDEX(" (reversed)");
INDEX("</i>");
if (PL__Actions__is_out_of_world(an))
INDEX("</font>");
INDEX("<br>");
}
#line 1201 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__list_assert_ownership(grammar_line *list_head, grammar_verb *gv) {
grammar_line *gl;
for (gl = list_head; gl; gl = gl->next_line)
gl->belongs_to_gv = gv;
}
#line 1210 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__list_with_action_add(grammar_line *list_head, grammar_line *gl) {
if (list_head == NULL) internal_error("tried to add to null action list");
while (list_head->next_with_action)
list_head = list_head->next_with_action;
list_head->next_with_action = gl;
}
#line 1221 "inform7/Chapter 36/Grammar Lines.w"
int PL__Parsing__Lines__index_list_with_action(grammar_line *gl) {
int said_something = FALSE;
while (gl != NULL) {
if (gl->belongs_to_gv) {
wording VW = PL__Parsing__Verbs__get_verb_text(gl->belongs_to_gv);
char *trueverb = NULL;
if (Wordings__nonempty(VW)) trueverb = Lexer__word_text(Wordings__first_wn(VW));
HTML__open_para(ifl, 2, "hanging");
INDEX("&quot;");
PL__Actions__Index__verb_definition(
Lexer__word_text(gl->original_text), trueverb, VW);
INDEX("&quot;");
Index__link(gl->original_text);
if (gl->reversed) INDEX(" <i>reversed</i>");
INDEX("</p>");
said_something = TRUE;
}
gl = gl->next_with_action;
}
return said_something;
}
#line 1246 "inform7/Chapter 36/Grammar Lines.w"
void PL__Parsing__Lines__index_list_for_token(grammar_line *gl) {
int k = 0;
while (gl != NULL) {
if (gl->belongs_to_gv) {
wording VW = PL__Parsing__Verbs__get_verb_text(gl->belongs_to_gv);
char *trueverb = NULL;
if (Wordings__nonempty(VW)) trueverb = Lexer__word_text(Wordings__first_wn(VW));
HTML__open_para(ifl, 2, "hanging");
if (k++ == 0) INDEX("="); else INDEX("or");
INDEX(" &quot;");
PL__Actions__Index__verb_definition(
Lexer__word_text(gl->original_text), trueverb, EMPTY_WORDING);
INDEX("&quot;");
Index__link(gl->original_text);
if (gl->reversed) INDEX(" <i>reversed</i>");
INDEX("</p>");
}
gl = gl->sorted_next_line;
}
}
#line 27 "inform7/Chapter 36/Grammar Types.w"
grammar_type PL__Parsing__Tokens__Types__new(int supports_return_type) {
grammar_type gty;
gty.first_type = NULL;
gty.second_type = NULL;
gty.first_multiplicity = FALSE;
gty.second_multiplicity = FALSE;
if (supports_return_type)
gty.no_resulting_values = 0;
else
gty.no_resulting_values = -1;
return gty;
}
#line 45 "inform7/Chapter 36/Grammar Types.w"
int PL__Parsing__Tokens__Types__add_type(grammar_type *gty, parse_node *spec,
int multiple_flag, int score) {
switch((gty->no_resulting_values)++) {
case 0:
gty->first_type = spec;
gty->first_multiplicity = multiple_flag;
return 10*score;
case 1:
gty->second_type = spec;
gty->second_multiplicity = multiple_flag;
return score;
case 2:
Problems__Issue__sentence_problem(_p_(PM_ThreeValuedLine),
"there can be at most two varying parts to a line of grammar",
"so 'put [something] in [a container]' is allowed but 'put "
"[something] in [something] beside [a door]' is not.");
}
return 0;
}
int PL__Parsing__Tokens__Types__has_return_type(grammar_type *gty) {
if (gty->no_resulting_values == -1) return FALSE;
return TRUE;
}
int PL__Parsing__Tokens__Types__get_no_resulting_values(grammar_type *gty) {
return gty->no_resulting_values;
}
parse_node *PL__Parsing__Tokens__Types__get_single_type(grammar_type *gty) {
switch(gty->no_resulting_values) {
case 0: return NULL;
case 1: return gty->first_type;
default: internal_error("gty improperly typed");
}
return NULL;
}
void PL__Parsing__Tokens__Types__set_single_type(grammar_type *gty, parse_node *spec) {
if (spec == NULL) gty->no_resulting_values = 0;
else {
gty->no_resulting_values = 1;
gty->first_type = spec;
}
}
void PL__Parsing__Tokens__Types__compile_to_string(OUTPUT_STREAM, grammar_type *gty) {
Specifications__Compiler__compile(OUT, gty->first_type);
}
kind *PL__Parsing__Tokens__Types__get_data_type_as_token(grammar_type *gty) {
if (gty->no_resulting_values > 0) {
if ((ParseTree__is(gty->first_type, CONSTANT_VNT)) ||
(Specifications__is_description(gty->first_type)))
return Specifications__to_kind(gty->first_type);
}
return NULL;
}
#line 109 "inform7/Chapter 36/Grammar Types.w"
int PL__Parsing__Tokens__Types__must_precede(grammar_type *gty1, grammar_type *gty2) {
int cs;
if ((gty1->no_resulting_values) < (gty2->no_resulting_values)) return TRUE;
if ((gty1->no_resulting_values) > (gty2->no_resulting_values)) return FALSE;
if (gty1->no_resulting_values == 0) return NOT_APPLICABLE;
cs = Specifications__compare_specificity(gty1->first_type, gty2->first_type, NULL);
if (cs == 1) return TRUE;
if (cs == -1) return FALSE;
if ((gty1->first_multiplicity) && (gty2->first_multiplicity == FALSE))
return FALSE;
if ((gty1->first_multiplicity == FALSE) && (gty2->first_multiplicity))
return TRUE;
if (gty1->no_resulting_values == 1) return NOT_APPLICABLE;
cs = Specifications__compare_specificity(gty1->second_type, gty2->second_type, NULL);
if (cs == 1) return TRUE;
if (cs == -1) return FALSE;
if ((gty1->second_multiplicity) && (gty2->second_multiplicity == FALSE))
return FALSE;
if ((gty1->second_multiplicity == FALSE) && (gty2->second_multiplicity))
return TRUE;
return NOT_APPLICABLE;
}
#line 63 "inform7/Chapter 36/Grammar Tokens.w"
int grammar_token_breaking_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = NOT_APPLICABLE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 67 "inform7/Chapter 36/Grammar Tokens.w"
#line 81 "inform7/Chapter 36/Grammar Tokens.w"
void PL__Parsing__Tokens__break_into_tokens(parse_node *pn, wording W) {
Preform__parse_nt_against_word_range(grammar_token_breaking_NTM, W, NULL, NULL);
switch (most_recent_result) {
case NOT_APPLICABLE: {
wording LW = GET_RW(grammar_token_breaking_NTM, 1);
wording RW = GET_RW(grammar_token_breaking_NTM, 2);
PL__Parsing__Tokens__break_into_tokens(pn, LW);
PL__Parsing__Tokens__break_into_tokens(pn, RW);
break;
}
case TRUE:
Text__dequote_word(Wordings__first_wn(W));
if (*(Lexer__word_text(Wordings__first_wn(W))) == 0) return;
W = Feeds__feed_text_full(Lexer__word_text(Wordings__first_wn(W)), FALSE, GRAMMAR_PUNCTUATION_MARKS);
LOOP_THROUGH_WORDING(i, W) {
parse_node *newpn = Sentences__NPs__new_raw(Wordings__one_word(i));
ParseTree__set_type(newpn, TOKEN_NT);
ParseTree__annotate_int(newpn, grammar_token_literal_ANNOT, TRUE);
ParseTree__graft(newpn, pn);
}
break;
case FALSE: {
parse_node *newpn = Sentences__NPs__new_raw(W);
ParseTree__set_type(newpn, TOKEN_NT);
ParseTree__annotate_int(newpn, grammar_token_literal_ANNOT, FALSE);
ParseTree__graft(newpn, pn);
break;
}
}
}
int PL__Parsing__Tokens__is_literal(parse_node *pn) {
return ParseTree__int_annotation(pn, grammar_token_literal_ANNOT);
}
#line 121 "inform7/Chapter 36/Grammar Tokens.w"
int PL__Parsing__Tokens__is_multiple(parse_node *pn) {
switch (ParseTree__int_annotation(pn, grammar_token_code_ANNOT)) {
case MULTI_TOKEN_GTC:
case MULTIINSIDE_TOKEN_GTC:
case MULTIHELD_TOKEN_GTC:
case MULTIEXCEPT_TOKEN_GTC:
return TRUE;
}
return FALSE;
}
#line 135 "inform7/Chapter 36/Grammar Tokens.w"
int PL__Parsing__Tokens__is_text(parse_node *pn) {
switch (ParseTree__int_annotation(pn, grammar_token_code_ANNOT)) {
case TOPIC_TOKEN_GTC:
return TRUE;
}
return FALSE;
}
#line 148 "inform7/Chapter 36/Grammar Tokens.w"
int PL__Parsing__Tokens__gsb_for_special_token(int gtc) {
switch(gtc) {
case NOUN_TOKEN_GTC: return 0;
case MULTI_TOKEN_GTC: return 0;
case MULTIINSIDE_TOKEN_GTC: return 1;
case MULTIHELD_TOKEN_GTC: return 2;
case HELD_TOKEN_GTC: return 3;
case CREATURE_TOKEN_GTC: return 0;
case TOPIC_TOKEN_GTC: return -1;
case MULTIEXCEPT_TOKEN_GTC: return 2;
default: internal_error("tried to find GSB for invalid GTC");
}
return 0; /* to prevent a gcc error: never reached */
}
#line 166 "inform7/Chapter 36/Grammar Tokens.w"
char *PL__Parsing__Tokens__i6_token_for_special_token(int gtc) {
switch(gtc) {
case NOUN_TOKEN_GTC: return "noun";
case MULTI_TOKEN_GTC: return "multi";
case MULTIINSIDE_TOKEN_GTC: return "multiinside";
case MULTIHELD_TOKEN_GTC: return "multiheld";
case HELD_TOKEN_GTC: return "held";
case CREATURE_TOKEN_GTC: return "creature";
case TOPIC_TOKEN_GTC: return "topic";
case MULTIEXCEPT_TOKEN_GTC: return "multiexcept";
default: internal_error("tried to find I6 token for invalid GTC");
}
return ""; /* to prevent a gcc error: never reached */
}
char *PL__Parsing__Tokens__i6_constant_for_special_token(int gtc) {
switch(gtc) {
case NOUN_TOKEN_GTC: return "NOUN_TOKEN";
case MULTI_TOKEN_GTC: return "MULTI_TOKEN";
case MULTIINSIDE_TOKEN_GTC: return "MULTIINSIDE_TOKEN";
case MULTIHELD_TOKEN_GTC: return "MULTIHELD_TOKEN";
case HELD_TOKEN_GTC: return "HELD_TOKEN";
case CREATURE_TOKEN_GTC: return "CREATURE_TOKEN";
case TOPIC_TOKEN_GTC: return "TOPIC_TOKEN";
case MULTIEXCEPT_TOKEN_GTC: return "MULTIEXCEPT_TOKEN";
default: internal_error("tried to find I6 constant for invalid GTC");
}
return ""; /* to prevent a gcc error: never reached */
}
#line 200 "inform7/Chapter 36/Grammar Tokens.w"
kind *PL__Parsing__Tokens__kind_for_special_token(int gtc) {
if (gtc == TOPIC_TOKEN_GTC) return K_understanding;
return K_object;
}
#line 208 "inform7/Chapter 36/Grammar Tokens.w"
int grammar_token_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = NAMED_TOKEN_GTC; grammar_verb_named_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = ANY_THINGS_GTC; parse_node_s_NTMV = Specifications__from_kind(K_thing);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = ANY_STUFF_GTC; parse_node_s_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = ANY_STUFF_GTC; parse_node_s_NTMV = Specifications__from_kind(K_thing);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = ANY_STUFF_GTC; parse_node_s_NTMV = Specifications__from_kind(K_person);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = ANY_STUFF_GTC; parse_node_s_NTMV = Specifications__from_kind(K_person);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = ANY_STUFF_GTC; parse_node_s_NTMV = Specifications__from_kind(K_room);;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = RELATED_GTC; *XP = BinaryPredicates__get_reversal(RP[1]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = RELATED_GTC; *XP = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9:
{
#line 251 "inform7/Chapter 36/Grammar Tokens.w"
*X = RELATED_GTC; *XP = NULL;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_GrammarBadRelation));
Problems__issue_problem_segment(
"The grammar token '%2' in the sentence %1 "
"invites me to understand names of related things, "
"but the relation is not one that I know.");
Problems__issue_problem_end();
}
#line 218 "inform7/Chapter 36/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11: *X = STUFF_GTC; parse_node_s_NTMV = Specifications__from_kind(RP[2]);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12: *X = STUFF_GTC; parse_node_s_NTMV = RP[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13:
{
#line 341 "inform7/Chapter 36/Grammar Tokens.w"
*X = STUFF_GTC;
ParseTree__log_subtree(current_sentence);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__quote_kind_of(3, RP[1]);
Problems__Issue__handmade_problem(_p_(PM_BizarreToken));
Problems__issue_problem_segment(
"The grammar token '%2' in the sentence %1 looked to me as "
"if it might be %3, but this isn't something allowed in "
"parsing grammar.");
Problems__issue_problem_end();
}
#line 222 "inform7/Chapter 36/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14:
{
#line 356 "inform7/Chapter 36/Grammar Tokens.w"
*X = STUFF_GTC;
ParseTree__log_subtree(current_sentence);
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_UnknownToken));
Problems__issue_problem_segment(
"I was unable to understand what you meant by the grammar token '%2' "
"in the sentence %1.");
Problems__issue_problem_end();
}
#line 223 "inform7/Chapter 36/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 224 "inform7/Chapter 36/Grammar Tokens.w"
int standard_grammar_token_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = NOUN_TOKEN_GTC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = MULTI_TOKEN_GTC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = MULTIINSIDE_TOKEN_GTC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = MULTIHELD_TOKEN_GTC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = HELD_TOKEN_GTC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = MULTIEXCEPT_TOKEN_GTC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6: *X = CREATURE_TOKEN_GTC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 7: *X = CREATURE_TOKEN_GTC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 8: *X = TOPIC_TOKEN_GTC;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 9:
{
#line 264 "inform7/Chapter 36/Grammar Tokens.w"
*X = TOPIC_TOKEN_GTC;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_UseTextNotTopic));
Problems__issue_problem_segment(
"The grammar token '%2' in the sentence %1 would in some "
"ways be the right logical way to suggest 'any words at "
"all here', but Inform in actually uses the special syntax "
"'[text]' for that. %P"
"This is partly for historical reasons, but also because "
"'[text]' is a token which can't be used in every sort of "
"Understand grammar - for example, it can't be used with 'matches' "
"or in descriptions of actions or in table columns; it's really "
"intended only for defining new commands.");
Problems__issue_problem_end();
}
#line 235 "inform7/Chapter 36/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 10:
{
#line 264 "inform7/Chapter 36/Grammar Tokens.w"
*X = TOPIC_TOKEN_GTC;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_UseTextNotTopic));
Problems__issue_problem_segment(
"The grammar token '%2' in the sentence %1 would in some "
"ways be the right logical way to suggest 'any words at "
"all here', but Inform in actually uses the special syntax "
"'[text]' for that. %P"
"This is partly for historical reasons, but also because "
"'[text]' is a token which can't be used in every sort of "
"Understand grammar - for example, it can't be used with 'matches' "
"or in descriptions of actions or in table columns; it's really "
"intended only for defining new commands.");
Problems__issue_problem_end();
}
#line 236 "inform7/Chapter 36/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 11:
{
#line 283 "inform7/Chapter 36/Grammar Tokens.w"
*X = MULTI_TOKEN_GTC;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_UseThingNotObject));
Problems__issue_problem_segment(
"The grammar token '%2' in the sentence %1 would in some "
"ways be the right logical way to suggest 'any object at "
"all here', but Inform uses the special syntax '[thing]' "
"for that. (Or '[things]' if multiple objects are allowed.)");
Problems__issue_problem_end();
}
#line 237 "inform7/Chapter 36/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 12:
{
#line 283 "inform7/Chapter 36/Grammar Tokens.w"
*X = MULTI_TOKEN_GTC;
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, W);
Problems__Issue__handmade_problem(_p_(PM_UseThingNotObject));
Problems__issue_problem_segment(
"The grammar token '%2' in the sentence %1 would in some "
"ways be the right logical way to suggest 'any object at "
"all here', but Inform uses the special syntax '[thing]' "
"for that. (Or '[things]' if multiple objects are allowed.)");
Problems__issue_problem_end();
}
#line 238 "inform7/Chapter 36/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 13:
{
#line 297 "inform7/Chapter 36/Grammar Tokens.w"
*X = HELD_TOKEN_GTC;
PL__Parsing__Tokens__incompatible_change_problem(
"something held", "something", "something preferably held");
}
#line 239 "inform7/Chapter 36/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 14:
{
#line 304 "inform7/Chapter 36/Grammar Tokens.w"
*X = MULTIHELD_TOKEN_GTC;
PL__Parsing__Tokens__incompatible_change_problem(
"things held", "things", "things preferably held");
}
#line 240 "inform7/Chapter 36/Grammar Tokens.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 241 "inform7/Chapter 36/Grammar Tokens.w"
int named_grammar_token_NTMR(wording W, int *X, void **XP) {
#line 243 "inform7/Chapter 36/Grammar Tokens.w"
grammar_verb *gv = PL__Parsing__Verbs__named_token_by_name(W);
if (gv) { *XP = gv; return TRUE; }
return FALSE;
}
#line 312 "inform7/Chapter 36/Grammar Tokens.w"
void PL__Parsing__Tokens__incompatible_change_problem(char *token_tried, char *token_instead,
char *token_better) {
Problems__quote_source(1, current_sentence);
Problems__quote_text(2, token_tried);
Problems__quote_text(3, token_instead);
Problems__quote_text(4, token_better);
Problems__Issue__handmade_problem(_p_(PM_ObsoleteHeldTokens));
Problems__issue_problem_segment(
"In the sentence %1, you used the '[%2]' as a token, which was "
"allowed in the early Public Beta versions of Inform 7, but became "
"out of date in August 2006%|. A change was then made so that if an "
"action needed to apply to something which was carried, this would "
"now be specified when the action is created - not in the Understand "
"line for it. For instance, one might say 'Dismantling is an action "
"which applies to one carried thing', instead of '...which applies "
"to one thing', and then write grammar such as 'Understand \"dismantle "
"[something] as dismantling' instead of '...[something held]...'. "
"So you probably need to change your '[%2]' token to '[%3]', and "
"change the action's definition (unless it is a built-in action "
"such as 'dropping'). An alternative, though, for fine-tuning is to "
"change it to '[%4]', which allows anything to be Understood, but "
"in cases of ambiguity tends to guess that something held is more "
"likely to be what the player means than something not held.");
Problems__issue_problem_end();
}
#line 371 "inform7/Chapter 36/Grammar Tokens.w"
parse_node *PL__Parsing__Tokens__determine(parse_node *pn, int depth, int *score) {
parse_node *spec = NULL;
if (ParseTree__int_annotation(pn, grammar_token_literal_ANNOT)) return NULL;
grammar_verb_named_NTMV = NULL;
Preform__parse_nt_against_word_range(grammar_token_NTM, ParseTree__get_text(pn), NULL, NULL);
switch (most_recent_result) {
case NAMED_TOKEN_GTC:
{
#line 392 "inform7/Chapter 36/Grammar Tokens.w"
parse_node *val = Rvalues__from_grammar_verb(grammar_verb_named_NTMV);
spec = PL__Parsing__Verbs__determine(grammar_verb_named_NTMV, depth+1); /* this is where Phase II recurses */
ParseTree__set_grammar_value(pn, val);
}
#line 378 "inform7/Chapter 36/Grammar Tokens.w"
; break;
case ANY_STUFF_GTC:
{
#line 399 "inform7/Chapter 36/Grammar Tokens.w"
spec = parse_node_s_NTMV;
if (Specifications__is_description(spec)) {
int any_things = FALSE;
if (most_recent_result == ANY_THINGS_GTC) any_things = TRUE;
ParseTree__annotate_int(pn, grammar_token_code_ANNOT,
PL__Parsing__Tokens__Filters__new_id(spec, TRUE, any_things));
ParseTree__set_grammar_value(pn, spec);
}
}
#line 379 "inform7/Chapter 36/Grammar Tokens.w"
; break;
case ANY_THINGS_GTC:
{
#line 399 "inform7/Chapter 36/Grammar Tokens.w"
spec = parse_node_s_NTMV;
if (Specifications__is_description(spec)) {
int any_things = FALSE;
if (most_recent_result == ANY_THINGS_GTC) any_things = TRUE;
ParseTree__annotate_int(pn, grammar_token_code_ANNOT,
PL__Parsing__Tokens__Filters__new_id(spec, TRUE, any_things));
ParseTree__set_grammar_value(pn, spec);
}
}
#line 380 "inform7/Chapter 36/Grammar Tokens.w"
; break;
case RELATED_GTC:
{
#line 411 "inform7/Chapter 36/Grammar Tokens.w"
binary_predicate *bp = most_recent_result_p;
if (bp) ParseTree__set_grammar_token_relation(pn, bp);
}
#line 381 "inform7/Chapter 36/Grammar Tokens.w"
; break;
case STUFF_GTC:
{
#line 417 "inform7/Chapter 36/Grammar Tokens.w"
spec = parse_node_s_NTMV;
ParseTree__set_grammar_value(pn, spec);
if (Specifications__is_description_like(spec)) {
*score = 5;
ParseTree__annotate_int(pn, grammar_token_code_ANNOT,
PL__Parsing__Tokens__Filters__new_id(spec, FALSE, FALSE));
}
}
#line 382 "inform7/Chapter 36/Grammar Tokens.w"
; break;
default:
{
#line 428 "inform7/Chapter 36/Grammar Tokens.w"
int p = most_recent_result;
kind *K = PL__Parsing__Tokens__kind_for_special_token(p);
spec = Specifications__from_kind(K);
ParseTree__set_text(spec, ParseTree__get_text(pn));
*score = PL__Parsing__Tokens__gsb_for_special_token(p);
ParseTree__set_grammar_value(pn, spec);
ParseTree__annotate_int(pn, grammar_token_code_ANNOT, p);
}
#line 383 "inform7/Chapter 36/Grammar Tokens.w"
; break;
}
if (spec)
{
#line 439 "inform7/Chapter 36/Grammar Tokens.w"
if (Specifications__is_description(spec)) {
kind *K = Specifications__to_kind(spec);
if ((Kinds__Compare__le(K, K_object) == FALSE) &&
(Kinds__Compare__eq(K, K_understanding) == FALSE) &&
(Kinds__Behaviour__request_I6_GPR(K) == FALSE)) {
Problems__quote_source(1, current_sentence);
Problems__quote_wording(2, ParseTree__get_text(pn));
Problems__Issue__handmade_problem(_p_(PM_UnparsableKind));
Problems__issue_problem_segment(
"The grammar token '%2' in the sentence %1 "
"invites me to understand values typed by the player during "
"play but for a kind of value which is beyond my ability. "
"Generally speaking, the allowable kinds of value are "
"number, time, text and any new kind of value you may "
"have created - but not, for instance, scene or rule.");
Problems__issue_problem_end();
spec = NULL;
}
}
}
#line 385 "inform7/Chapter 36/Grammar Tokens.w"
;
return spec;
}
#line 471 "inform7/Chapter 36/Grammar Tokens.w"
int ol_loop_counter = 0;
kind *PL__Parsing__Tokens__compile(OUTPUT_STREAM, parse_node *pn, int code_mode,
char *failure_label, int consult_mode) {
int wn = Wordings__first_wn(ParseTree__get_text(pn));
parse_node *spec;
binary_predicate *bp;
grammar_verb *gv;
if (ParseTree__int_annotation(pn, grammar_token_literal_ANNOT)) {
if (code_mode) {
WRITE("if (NextWordStopped() ~= ");
DictionaryWords__compile(OUT, Lexer__word_text(wn), FALSE);
WRITE(") jump %s;\n", failure_label);
} else {
DictionaryWords__compile(OUT, Lexer__word_text(wn), FALSE);
}
return NULL;
}
bp = ParseTree__get_grammar_token_relation(pn);
if (bp) {
WRITE("ArticleDescriptors(); w = wn;\n");
if (bp == R_containment)
WRITE("if (self hasnt container) jump %s;\n", failure_label);
if (bp == R_support)
WRITE("if (self hasnt supporter) jump %s;\n", failure_label);
if ((bp == a_has_b_predicate) || (bp == R_wearing) ||
(bp == R_carrying))
WRITE("if (self hasnt animate) jump %s;\n", failure_label);
if ((bp == R_containment) ||
(bp == R_support) ||
(bp == a_has_b_predicate) ||
(bp == R_wearing) ||
(bp == R_carrying)) {
WRITE("objectloop (rv in self) {\n"); INDENT;
if (bp == R_carrying)
WRITE("if (rv has worn) continue;\n");
if (bp == R_wearing)
WRITE("if (rv hasnt worn) continue;\n");
WRITE("wn = w; wn = w + TryGivenObject(rv, true);\n");
WRITE("if (wn > w) jump ol_mm_%d;\n", ol_loop_counter);
OUTDENT; WRITE("}\n");
WRITE("rv = 0; jump %s;\n", failure_label);
WRITE(".ol_mm_%d; rv = 0;\n", ol_loop_counter++);
} else if (bp == R_incorporation) {
WRITE("for (rv=self.component_child:rv:rv=rv.component_sibling) {\n"); INDENT;
WRITE("wn = w; wn = w + TryGivenObject(rv, true);\n");
WRITE("if (wn > w) jump ol_mm_%d;\n", ol_loop_counter);
OUTDENT; WRITE("}\n");
WRITE("rv = 0; jump %s;\n", failure_label);
WRITE(".ol_mm_%d; rv = 0;\n", ol_loop_counter++);
} else if (bp == R_equality) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, pn);
Problems__Issue__handmade_problem(_p_(PM_RelatedByEquality));
Problems__issue_problem_segment(
"The grammar you give in %1 contains a token %2 which would "
"create a circularity. To follow this, I'd have to compute "
"forever.");
Problems__issue_problem_end();
return K_object;
} else if ((BinaryPredicates__get_reversal(bp) == R_containment) ||
(BinaryPredicates__get_reversal(bp) == R_support) ||
(BinaryPredicates__get_reversal(bp) == a_has_b_predicate) ||
(BinaryPredicates__get_reversal(bp) == R_wearing) ||
(BinaryPredicates__get_reversal(bp) == R_carrying)) {
if (BinaryPredicates__get_reversal(bp) == R_carrying)
WRITE("if (self has worn) jump %s;\n", failure_label);
if (BinaryPredicates__get_reversal(bp) == R_wearing)
WRITE("if (self hasnt worn) jump %s;\n", failure_label);
WRITE("rv = parent(self);\n");
WRITE("wn = w; wn = w + TryGivenObject(rv, true);\n");
WRITE("if (wn == w) jump %s;\n", failure_label);
} else if (BinaryPredicates__get_reversal(bp) == R_incorporation) {
WRITE("rv = self.component_parent;\n");
WRITE("wn = w; wn = w + TryGivenObject(rv, true);\n");
WRITE("if (wn == w) jump %s;\n", failure_label);
} else {
i6_schema *i6s;
int reverse = FALSE;
int continue_loop_on_fail = TRUE;
i6s = BinaryPredicates__get_test_function(bp);
LOGIF(GRAMMAR_CONSTRUCTION, "Read I6s $i from $2\n", i6s, bp);
if ((i6s == NULL) && (BinaryPredicates__get_test_function(BinaryPredicates__get_reversal(bp)))) {
reverse = TRUE;
i6s = BinaryPredicates__get_test_function(BinaryPredicates__get_reversal(bp));
LOGIF(GRAMMAR_CONSTRUCTION, "But read I6s $i from reversal\n", i6s);
}
if (i6s) {
kind *K = BinaryPredicates__term_kind(bp, 1);
if (Kinds__Compare__lt(K, K_object)) {
LOGIF(GRAMMAR_CONSTRUCTION, "Term 1 of BP is $u\n", K);
WRITE("objectloop (rv ofclass %s) {\n",
Kinds__Behaviour__I6_classname(K)); INDENT;
WRITE("if ((");
if (reverse)
Calculus__Schemas__expand_textual(i6s, OUT, "rv", "self");
else
Calculus__Schemas__expand_textual(i6s, OUT, "self", "rv");
continue_loop_on_fail = TRUE;
} else {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, pn);
Problems__Issue__handmade_problem(_p_(PM_GrammarValueRelation));
Problems__issue_problem_segment(
"The grammar you give in %1 contains a token "
"which relates things to values - %2. At present, "
"this is not allowed: only relations between kinds "
"of object can be used in 'Understand' tokens.");
Problems__issue_problem_end();
return K_object;
}
} else {
property *prn = BinaryPredicates__get_i6_storage_property(bp);
reverse = FALSE;
if (BinaryPredicates__is_the_wrong_way_round(bp)) reverse = TRUE;
if (BinaryPredicates__get_form_of_relation(bp) == Relation_VtoO) {
if (reverse) reverse = FALSE; else reverse = TRUE;
}
if (prn) {
if (reverse) {
WRITE("if (self provides %s) {\n", Properties__get_translation(prn));
INDENT;
WRITE("rv = self.%s;\n", Properties__get_translation(prn));
WRITE("if ((rv");
continue_loop_on_fail = FALSE;
} else {
kind *K = BinaryPredicates__term_kind(bp, 1);
if (Kinds__Compare__le(K, K_object) == FALSE) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, pn);
Problems__quote_kind(3, K);
Problems__Issue__handmade_problem(_p_(PM_GrammarValueRelation2));
Problems__issue_problem_segment(
"The grammar you give in %1 contains a token "
"which relates things to values - %2. (It would "
"need to match the name of %3, which isn't a kind "
"of thing.) At present, this is not allowed: only "
"relations between kinds of object can be used in "
"'Understand' tokens.");
Problems__issue_problem_end();
return K_object;
}
WRITE("objectloop (rv ofclass %s) {\n",
Kinds__Behaviour__I6_classname(K)); INDENT;
WRITE("if (((rv provides %s) && (rv.%s == self)",
Properties__get_translation(prn),
Properties__get_translation(prn));
continue_loop_on_fail = TRUE;
}
} else {
LOG("Trouble with: $2\n", bp);
LOG("Whose reversal is: $2\n", BinaryPredicates__get_reversal(bp));
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, pn);
Problems__Issue__handmade_problem(_p_(PM_GrammarTokenCowardice));
Problems__issue_problem_segment(
"The grammar you give in %1 contains a token "
"which uses a relation I'm unable to test - %2.");
Problems__issue_problem_end();
return K_object;
}
}
if (continue_loop_on_fail == FALSE)
WRITE(") == false) jump %s;\n", failure_label);
else
WRITE(") == false) continue;\n");
WRITE("wn = w; wn = w + TryGivenObject(rv, true);\n");
WRITE("if (wn > w) jump ol_mm_%d;\n", ol_loop_counter);
OUTDENT; WRITE("}\n");
WRITE("rv = 0; jump %s;\n", failure_label);
WRITE(".ol_mm_%d; rv = 0;\n", ol_loop_counter++);
}
return NULL;
}
spec = ParseTree__get_grammar_value(pn);
if (spec == NULL) PL__Parsing__Tokens__determine(pn, 10, NULL);
spec = ParseTree__get_grammar_value(pn);
if (spec == NULL) {
ParseTree__log_subtree(pn);
internal_error("NULL result of non-preposition token");
}
if (Specifications__is_kind_like(spec)) {
kind *K = ParseTree__get_kind_of_value(spec);
if ((Kinds__Compare__le(K, K_object) == FALSE) &&
(Kinds__Compare__eq(K, K_understanding) == FALSE)) {
if (Kinds__Behaviour__offers_I6_GPR(K)) {
char *i6_gpr_name = Kinds__Behaviour__get_explicit_I6_GPR(K);
if (code_mode) {
WRITE("w = ParseTokenStopped(GPR_TT, ");
if (i6_gpr_name != NULL) WRITE(i6_gpr_name);
else PL__Parsing__Tokens__Values__gprv_compile(OUT, K);
WRITE(");\n");
WRITE("if (w ~= GPR_NUMBER) jump %s; rv = GPR_NUMBER;\n",
failure_label);
} else {
if (i6_gpr_name != NULL) WRITE(i6_gpr_name);
else PL__Parsing__Tokens__Values__gprv_compile(OUT, K);
}
return K;
}
/* internal_error("Let an invalid type token through"); */
}
}
if (Descriptions__is_complex(spec)) {
Problems__quote_source(1, current_sentence);
Problems__quote_source(2, pn);
Problems__Issue__handmade_problem(_p_(PM_OverComplexToken));
Problems__issue_problem_segment(
"The grammar you give in %1 contains a token "
"which is just too complicated - %2. %PFor instance, a "
"token using subordinate clauses - such as '[a person who "
"can see the player]' will probably not be allowed.");
Problems__issue_problem_end();
return K_object;
} else {
kind *K = NULL;
int gtc = ParseTree__int_annotation(pn, grammar_token_code_ANNOT);
if (gtc < 0) {
char *i6_token = PL__Parsing__Tokens__i6_token_for_special_token(gtc);
char *i6_token_constant = PL__Parsing__Tokens__i6_constant_for_special_token(gtc);
K = PL__Parsing__Tokens__kind_for_special_token(gtc);
if (code_mode) {
if ((consult_mode) && (gtc == TOPIC_TOKEN_GTC)) {
Problems__Issue__sentence_problem(_p_(PM_TextTokenRestricted),
"the '[text]' token is not allowed with 'matches' "
"or in table columns",
"as it is just too complicated to sort out: a "
"'[text]' is supposed to extract a snippet from "
"the player's command, but here we already have "
"a snippet, and don't want to snip it further.");
}
WRITE("w = ParseTokenStopped(ELEMENTARY_TT, %s);\n",
i6_token_constant);
WRITE("if (w == GPR_FAIL) jump %s; rv = w;\n",
failure_label);
} else WRITE("%s", i6_token);
} else {
if (Specifications__is_description(spec)) {
K = Specifications__to_kind(spec);
if (Descriptions__is_qualified(spec)) {
if (code_mode) {
WRITE("w = ParseTokenStopped(");
PL__Parsing__Tokens__Filters__compile_id(OUT, gtc, TRUE);
WRITE(");\n");
WRITE("if (w == GPR_FAIL) jump %s; rv = w;\n",
failure_label);
} else PL__Parsing__Tokens__Filters__compile_id(OUT, gtc, FALSE);
} else {
if (Kinds__Behaviour__offers_I6_GPR(K)) {
char *i6_gpr_name = Kinds__Behaviour__get_explicit_I6_GPR(K);
if (code_mode) {
WRITE("w = ParseTokenStopped(GPR_TT, ");
if (i6_gpr_name != NULL) WRITE(i6_gpr_name);
else PL__Parsing__Tokens__Values__gprv_compile(OUT, K);
WRITE(");\n");
WRITE("if (w ~= GPR_NUMBER) jump %s; rv = GPR_NUMBER;\n",
failure_label);
} else {
if (i6_gpr_name != NULL) WRITE(i6_gpr_name);
else PL__Parsing__Tokens__Values__gprv_compile(OUT, K);
}
} else if (Kinds__Compare__le(K, K_object)) {
if (code_mode) {
WRITE("w = ParseTokenStopped(");
PL__Parsing__Tokens__Filters__compile_id(OUT, gtc, TRUE);
WRITE(");\n");
WRITE("if (w == GPR_FAIL) jump %s; rv = w;\n",
failure_label);
} else PL__Parsing__Tokens__Filters__compile_id(OUT, gtc, FALSE);
K = K_object;
} else internal_error("no token for description");
}
} else {
if (ParseTree__is(spec, CONSTANT_VNT)) {
if (Rvalues__is_CONSTANT_of_kind(spec, K_understanding)) {
gv = Rvalues__to_grammar_verb(spec);
if (code_mode) {
WRITE("w = ParseTokenStopped(GPR_TT, ");
PL__Parsing__Verbs__compile_i6_token(OUT, gv);
WRITE(");\n");
WRITE("if (w == GPR_FAIL) jump %s;\n", failure_label);
WRITE("if (w ~= GPR_PREPOSITION) rv = w;\n");
} else PL__Parsing__Verbs__compile_i6_token(OUT, gv);
K = PL__Parsing__Verbs__get_data_type_as_token(gv);
}
if (Rvalues__is_object(spec)) {
if (code_mode) {
WRITE("w = ParseTokenStopped(");
PL__Parsing__Tokens__Filters__compile_id(OUT, gtc, TRUE);
WRITE(");\n");
WRITE("if (w == GPR_FAIL) jump %s; rv = w;\n",
failure_label);
} else PL__Parsing__Tokens__Filters__compile_id(OUT, gtc, FALSE);
K = K_object;
}
} else K = K_object;
}
}
return K;
}
}
#line 33 "inform7/Chapter 36/Noun Filter Tokens.w"
noun_filter_token *PL__Parsing__Tokens__Filters__nft_new(parse_node *spec, int global_scope, int any_things) {
pcalc_prop *prop = Specifications__to_proposition(spec);
if ((prop) && (Calculus__Variables__number_free(prop) != 1)) {
LOG("So $P and $D\n", spec, prop);
Problems__Issue__sentence_problem(_p_(PM_FilterQuantified),
"the [any ...] doesn't clearly give a description in the '...' part",
"where I was expecting something like '[any vehicle]'.");
spec = Specifications__from_kind(K_object);
}
noun_filter_token *nft = CREATE(noun_filter_token);
nft->the_filter = spec;
nft->global_scope_flag = global_scope;
nft->any_things_flag = any_things;
nft->nft_created_at = current_sentence;
nft->parse_using_gpr = FALSE;
nft->nft_compiled = FALSE;
if (global_scope)
sprintf(nft->nft_routine_name, "Scope_Filter_%d", nft->allocation_id);
else
sprintf(nft->nft_routine_name, "Noun_Filter_%d", nft->allocation_id);
return nft;
}
void PL__Parsing__Tokens__Filters__nft_compile_routine_name(OUTPUT_STREAM, noun_filter_token *nft) {
WRITE("%s", nft->nft_routine_name);
}
void PL__Parsing__Tokens__Filters__nft_compile_routine(OUTPUT_STREAM, noun_filter_token *nft) {
parse_node *noun_var = Lvalues__new_actual_NONLOCAL_VARIABLE(I6_noun_VAR);
kind *R = Specifications__to_kind(nft->the_filter);
kind *K = NonlocalVariables__kind(I6_noun_VAR);
NonlocalVariables__set_kind(I6_noun_VAR, R);
if (Kinds__Compare__le(R, K_object) == FALSE) nft->parse_using_gpr = TRUE;
OUT = Routines__begin(OUT, nft->nft_routine_name);
if (nft->parse_using_gpr) {
LocalVariables__add_internal_local_c("v", "value parsed");
LocalVariables__add_internal_local_c("n", "saved value of noun");
WRITE("v = ");
char *explicit = Kinds__Behaviour__get_explicit_I6_GPR(R);
if (explicit) WRITE("%s", explicit);
else PL__Parsing__Tokens__Values__gprv_compile(OUT, R);
WRITE("();\n");
WRITE("if (v == GPR_NUMBER) {\n"); INDENT;
WRITE("n = noun; noun = parsed_number;\n");
WRITE("if (~~(");
Calculus__Deferrals__compile_test_if_var_matches_description(OUT, noun_var, nft->the_filter);
WRITE(")) v = GPR_FAIL;\n");
WRITE("noun = n;\n");
OUTDENT; WRITE("}\n");
WRITE("return v;\n");
} else if (nft->global_scope_flag) {
LocalVariables__add_internal_local_c("obj", "object loop variable");
LocalVariables__add_internal_local_c("o2", "saved value of noun");
WRITE("switch (scope_stage) {\n"); INDENT;
if (nft->any_things_flag)
WRITE("1: rtrue;\n");
else
WRITE("1: rfalse;\n");
WRITE("2: obj=noun;\n");
WRITE("objectloop(noun ofclass Object && (");
Calculus__Deferrals__compile_test_if_var_matches_description(OUT, noun_var, nft->the_filter);
WRITE(")) {\n"); INDENT;
WRITE("o2 = noun; noun = obj;\n");
WRITE("suppress_scope_loops = true; PlaceInScope(o2, true); suppress_scope_loops = false;\n");
WRITE("noun = o2;\n");
OUTDENT; WRITE("}\n");
WRITE("noun=obj;\n");
WRITE("3: nextbest_etype = NOTINCONTEXT_PE; return -1;\n");
OUTDENT; WRITE("}\n");
} else {
LocalVariables__add_internal_local_c("x", "saved value of noun");
WRITE("x=noun;\n");
WRITE("return ");
if (Specifications__to_proposition(nft->the_filter)) {
Calculus__Propositions__Checker__type_check(Specifications__to_proposition(nft->the_filter), Calculus__Propositions__Checker__tc_no_problem_reporting());
Calculus__Deferrals__compile_test_of_proposition(
OUT, noun_var, Specifications__to_proposition(nft->the_filter));
} else
Calculus__Deferrals__compile_test_if_var_matches_description(
OUT, noun_var, nft->the_filter);
WRITE(";\n");
}
OUT = Routines__end(OUT);
NonlocalVariables__set_kind(I6_noun_VAR, K);
}
#line 126 "inform7/Chapter 36/Noun Filter Tokens.w"
int too_late_for_further_NFTs = FALSE;
int PL__Parsing__Tokens__Filters__new_id(parse_node *spec, int global_scope, int any_things) {
if (too_late_for_further_NFTs)
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"complicated instructions on understanding the player's command "
"are not allowed in the past tense",
"for instance by being applied to several previous turns in a row.");
kind *K = Specifications__to_kind(spec);
if ((Kinds__Compare__le(K, K_object) == FALSE) && (Kinds__Behaviour__request_I6_GPR(K) == FALSE) && (global_scope))
Problems__Issue__sentence_problem(_p_(BelievedImpossible),
"this is a kind of value I can't understand in command grammar",
"so the '[any ...]' part will have to go.");
return PL__Parsing__Tokens__Filters__nft_new(spec, global_scope, any_things)->allocation_id;
}
void PL__Parsing__Tokens__Filters__compile_id(OUTPUT_STREAM, int id, int code_mode) {
noun_filter_token *nft;
LOOP_OVER(nft, noun_filter_token)
if (nft->allocation_id == id) {
if (code_mode) { /* arguments to the I6 routine |ParseTokenStopped| */
if (nft->parse_using_gpr) WRITE("GPR_TT, ");
else if (nft->global_scope_flag) WRITE("SCOPE_TT, ");
else WRITE("ROUTINE_FILTER_TT, ");
} else { /* tokens for use in |Verb| directives */
if (nft->parse_using_gpr == FALSE) {
if (nft->global_scope_flag) WRITE("scope=");
else WRITE("noun=");
}
}
PL__Parsing__Tokens__Filters__nft_compile_routine_name(OUT, nft);
}
}
#line 166 "inform7/Chapter 36/Noun Filter Tokens.w"
void PL__Parsing__Tokens__Filters__compile(OUTPUT_STREAM) {
noun_filter_token *nft;
LOOP_OVER(nft, noun_filter_token)
if (nft->nft_compiled == FALSE) {
current_sentence = nft->nft_created_at;
PL__Parsing__Tokens__Filters__nft_compile_routine(OUT, nft);
nft->nft_compiled = TRUE;
}
/* too_late_for_further_NFTs = TRUE; */
}
#line 19 "inform7/Chapter 36/Tokens Parsing Values.w"
void PL__Parsing__Tokens__Values__number(OUTPUT_STREAM) {
grammar_verb *gv = Kinds__Behaviour__get_parsing_grammar(K_number);
if (gv) PL__Parsing__Verbs__compile(OUT, gv);
}
void PL__Parsing__Tokens__Values__time(OUTPUT_STREAM) {
kind *K = PL__TimesOfDay__kind();
if (K) {
grammar_verb *gv = Kinds__Behaviour__get_parsing_grammar(K);
if (gv) PL__Parsing__Verbs__compile(OUT, gv);
}
}
void PL__Parsing__Tokens__Values__truth_state(OUTPUT_STREAM) {
grammar_verb *gv = Kinds__Behaviour__get_parsing_grammar(K_truth_state);
if (gv) PL__Parsing__Verbs__compile(OUT, gv);
}
void PL__Parsing__Tokens__Values__compile_type_gprs(OUTPUT_STREAM) {
int next_label = 1, longest;
grammar_verb *gv;
kind *K;
LOOP_OVER_BASE_KINDS(K) {
if ((Kinds__Behaviour__is_an_enumeration(K)) ||
(Kinds__Behaviour__is_quasinumerical(K))) {
instance *q; literal_pattern *lp;
if (Kinds__Behaviour__needs_I6_GPR(K) == FALSE) continue;
OUT = Routines__begin_numbered(OUT, "Kind_GPR_%d", Kinds__RunTime__weak_id(K));
LocalVariables__add_internal_local("original_wn");
LocalVariables__add_internal_local("group_wn");
LocalVariables__add_internal_local("v");
LocalVariables__add_internal_local("w");
LocalVariables__add_internal_local("rv");
LITERAL_FORMS_LOOP(lp, K) {
LiteralPatterns__gpr_locals();
break;
}
{
#line 78 "inform7/Chapter 36/Tokens Parsing Values.w"
WRITE("original_wn = wn;\n");
LITERAL_FORMS_LOOP(lp, K) {
LiteralPatterns__gpr(OUT, lp);
WRITE("wn = original_wn;\n");
}
gv = Kinds__Behaviour__get_parsing_grammar(K);
if (gv != NULL) {
PL__Parsing__Verbs__compile(OUT, gv);
WRITE("wn = original_wn;\n");
}
longest = 0;
LOOP_OVER_INSTANCES(q, K) {
wording NW = Instances__get_name_in_play(q, FALSE);
int L = Wordings__length(NW) - 1;
if (L > longest) longest = L;
}
for (; longest >= 0; longest--) {
LOOP_OVER_INSTANCES(q, K) {
wording NW = Instances__get_name_in_play(q, FALSE);
if (Wordings__length(NW) - 1 == longest) {
if (GV_IS_VALUE_instance_mode) {
WRITE("if (instance == %s) {\n", Instances__identifier(q)); INDENT;
}
WRITE("wn = original_wn;");
LOOP_THROUGH_WORDING(k, NW) {
WRITE("if (NextWordStopped() ~= ");
DictionaryWords__compile(OUT, Lexer__word_text(k), FALSE);
WRITE(") jump Failed_%d;\n", next_label);
}
WRITE("parsed_number = %s; return GPR_NUMBER;\n",
Instances__identifier(q));
if (GV_IS_VALUE_instance_mode) {
OUTDENT; WRITE("}\n");
}
WRITE(".Failed_%d;\n", next_label++);
}
}
}
WRITE("return GPR_FAIL;\n");
}
#line 56 "inform7/Chapter 36/Tokens Parsing Values.w"
;
OUT = Routines__end(OUT);
if (Kinds__Behaviour__is_an_enumeration(K)) {
OUT = Routines__begin_numbered(OUT, "Instance_GPR_%d", Kinds__RunTime__weak_id(K));
LocalVariables__add_named_call("instance");
LocalVariables__add_internal_local("original_wn");
LocalVariables__add_internal_local("group_wn");
LocalVariables__add_internal_local("v");
LocalVariables__add_internal_local("w");
LocalVariables__add_internal_local("rv");
GV_IS_VALUE_instance_mode = TRUE;
{
#line 78 "inform7/Chapter 36/Tokens Parsing Values.w"
WRITE("original_wn = wn;\n");
LITERAL_FORMS_LOOP(lp, K) {
LiteralPatterns__gpr(OUT, lp);
WRITE("wn = original_wn;\n");
}
gv = Kinds__Behaviour__get_parsing_grammar(K);
if (gv != NULL) {
PL__Parsing__Verbs__compile(OUT, gv);
WRITE("wn = original_wn;\n");
}
longest = 0;
LOOP_OVER_INSTANCES(q, K) {
wording NW = Instances__get_name_in_play(q, FALSE);
int L = Wordings__length(NW) - 1;
if (L > longest) longest = L;
}
for (; longest >= 0; longest--) {
LOOP_OVER_INSTANCES(q, K) {
wording NW = Instances__get_name_in_play(q, FALSE);
if (Wordings__length(NW) - 1 == longest) {
if (GV_IS_VALUE_instance_mode) {
WRITE("if (instance == %s) {\n", Instances__identifier(q)); INDENT;
}
WRITE("wn = original_wn;");
LOOP_THROUGH_WORDING(k, NW) {
WRITE("if (NextWordStopped() ~= ");
DictionaryWords__compile(OUT, Lexer__word_text(k), FALSE);
WRITE(") jump Failed_%d;\n", next_label);
}
WRITE("parsed_number = %s; return GPR_NUMBER;\n",
Instances__identifier(q));
if (GV_IS_VALUE_instance_mode) {
OUTDENT; WRITE("}\n");
}
WRITE(".Failed_%d;\n", next_label++);
}
}
}
WRITE("return GPR_FAIL;\n");
}
#line 67 "inform7/Chapter 36/Tokens Parsing Values.w"
;
GV_IS_VALUE_instance_mode = FALSE;
OUT = Routines__end(OUT);
}
}
}
}
#line 122 "inform7/Chapter 36/Tokens Parsing Values.w"
void PL__Parsing__Tokens__Values__gprv_compile(OUTPUT_STREAM, kind *K) {
WRITE("Kind_GPR_%d", Kinds__RunTime__weak_id(K));
}
void PL__Parsing__Tokens__Values__igprv_compile(OUTPUT_STREAM, kind *K) {
WRITE("Instance_GPR_%d", Kinds__RunTime__weak_id(K));
}
#line 27 "inform7/Chapter 36/General Parsing Routines.w"
text_stream *PL__Parsing__Tokens__General__compile_gpr_head(OUTPUT_STREAM, int id) {
OUT = Routines__begin_numbered(OUT, "GPR_Line_%d", id);
LocalVariables__add_internal_local_c("original_wn", "first word of text parsed");
LocalVariables__add_internal_local_c("group_wn",
"first word matched against A/B/C/... disjunction");
LocalVariables__add_internal_local_c("w", "for use by individual grammar lines");
LocalVariables__add_internal_local_c("rv", "for use by individual grammar lines");
WRITE("original_wn = wn; rv = GPR_PREPOSITION;\n");
return OUT;
}
text_stream *PL__Parsing__Tokens__General__compile_gpr_tail(OUTPUT_STREAM) {
WRITE("return GPR_FAIL;\n");
OUT = Routines__end(OUT);
return OUT;
}
text_stream *PL__Parsing__Tokens__General__compile_prn_pr_head(OUTPUT_STREAM, property *prn) {
OUT = Routines__begin_numbered(OUT, "PRN_PN_%d", prn->allocation_id);
LocalVariables__add_internal_local_c("original_wn", "first word of text parsed");
LocalVariables__add_internal_local_c("group_wn",
"first word matched against A/B/C/... disjunction");
LocalVariables__add_internal_local_c("w", "for use by individual grammar lines");
LocalVariables__add_internal_local_c("rv", "for use by individual grammar lines");
WRITE("original_wn = wn; rv = GPR_PREPOSITION;\n");
return OUT;
}
text_stream *PL__Parsing__Tokens__General__compile_prn_pr_tail(OUTPUT_STREAM, property *prn) {
WRITE("return GPR_FAIL;\n");
OUT = Routines__end(OUT);
return OUT;
}
#line 71 "inform7/Chapter 36/General Parsing Routines.w"
grammar_verb *consultation_gv = NULL; /* used only in routines below */
grammar_verb *PL__Parsing__Tokens__General__get_consultation_gv(void) {
if (consultation_gv == NULL) consultation_gv = PL__Parsing__Verbs__consultation_new();
return consultation_gv;
}
void PL__Parsing__Tokens__General__prepare_consultation_gv(void) {
consultation_gv = NULL;
}
int PL__Parsing__Tokens__General__print_consultation_gv_name(OUTPUT_STREAM) {
if (consultation_gv) {
WRITE("Consult_Grammar_%d", consultation_gv->allocation_id);
return consultation_gv->allocation_id;
}
return -1;
}
#line 96 "inform7/Chapter 36/General Parsing Routines.w"
text_stream *PL__Parsing__Tokens__General__compile_consult_head(OUTPUT_STREAM, int id) {
OUT = Routines__begin_numbered(OUT, "Consult_Grammar_%d", id);
LocalVariables__add_internal_local_c("range_from", "call parameter: word number of snippet start\n");
LocalVariables__add_internal_local_c("range_words", "call parameter: snippet length\n");
LocalVariables__add_internal_local_c("original_wn", "first word of text parsed\n");
LocalVariables__add_internal_local_c("group_wn", "first word matched against A/B/C/... disjunction\n");
LocalVariables__add_internal_local_c("w", "for use by individual grammar lines\n");
LocalVariables__add_internal_local_c("rv", "for use by individual grammar lines\n");
WRITE("wn = range_from; original_wn = wn; rv = GPR_PREPOSITION;\n");
return OUT;
}
text_stream *PL__Parsing__Tokens__General__compile_consult_tail(OUTPUT_STREAM) {
WRITE("return GPR_FAIL;\n");
OUT = Routines__end(OUT);
return OUT;
}
#line 132 "inform7/Chapter 36/General Parsing Routines.w"
text_stream *PL__Parsing__Tokens__General__compile_parse_name_property(inference_subject *subj) {
grammar_verb *gv = PF_S(parsing, subj)->understand_as_this_object;
text_stream *PROP = STREAM_NEW;
if (SMALL_STREAM_OPEN_IN_MEMORY(PROP) == FALSE)
Problems__Fatal__issue("Out of memory: can't allocate for parse name routine");
if (PL__Parsing__Verbs__is_empty(gv) == FALSE) {
WRITE_TO(PROP, "Parse_Name_GV%d", gv->allocation_id);
return PROP;
} else {
text_stream *XOUT = PL__Parsing__Tokens__General__compile_parse_name_head(PROP, subj, NULL);
if (XOUT) {
PROP = XOUT;
PROP = PL__Parsing__Tokens__General__compile_parse_name_tail(PROP);
WRITE_TO(PROP, ",");
return PROP;
}
}
STREAM_CLOSE(PROP);
return NULL;
}
#line 198 "inform7/Chapter 36/General Parsing Routines.w"
text_stream *PL__Parsing__Tokens__General__compile_parse_name_head(OUTPUT_STREAM,
inference_subject *subj, grammar_verb *gv) {
int test_distinguishability = FALSE,
sometimes_has_visible_properties = FALSE, N = -1;
if (subj == NULL) internal_error("compiling parse_name head for null subj");
if (gv) {
sometimes_has_visible_properties =
PL__Parsing__Visibility__any_property_visible_to_subject(subj, TRUE);
N = gv->allocation_id;
} else {
if (PL__Parsing__Visibility__any_property_visible_to_subject(subj, FALSE)
== FALSE) return NULL;
}
if (InferenceSubjects__domain(subj)) test_distinguishability = TRUE;
OUT = PL__Parsing__Tokens__General__top_of_head(OUT, N, subj, test_distinguishability, sometimes_has_visible_properties);
return OUT;
}
#line 240 "inform7/Chapter 36/General Parsing Routines.w"
text_stream *PL__Parsing__Tokens__General__top_of_head(OUTPUT_STREAM, int id, inference_subject *subj,
int test_distinguishability, int sometimes_has_visible_properties) {
char rname[32];
if (id >= 0) sprintf(rname, "Parse_Name_GV%d", id);
else sprintf(rname, "*");
OUT = Routines__begin(OUT, rname);
LocalVariables__add_internal_local_c("original_wn", "first word of text parsed");
LocalVariables__add_internal_local_c("group_wn", "first word matched against A/B/C/... disjunction");
LocalVariables__add_internal_local_c("try_from_wn", "position to try matching from");
LocalVariables__add_internal_local_c("n", "number of words matched");
LocalVariables__add_internal_local_c("f", "flag: sufficiently good match found to justify success");
LocalVariables__add_internal_local_c("w", "for use by individual grammar lines");
LocalVariables__add_internal_local_c("rv", "for use by individual grammar lines");
LocalVariables__add_internal_local_c("g", "temporary: success flag for parsing visibles");
LocalVariables__add_internal_local_c("ss", "temporary: saves 'self' in distinguishing visibles");
LocalVariables__add_internal_local_c("spn", "temporary: saves 'parsed_number' in parsing visibles");
LocalVariables__add_internal_local_c("pass", "pass counter (1 to 3)");
LocalVariables__add_internal_local_c("pass1_n", "value of n recorded during pass 1");
LocalVariables__add_internal_local_c("pass2_n", "value of n recorded during pass 2");
WRITE("#ifdef DEBUG;\n");
WRITE("if (parser_trace >= 3) print \"Parse_name called^\";\n");
WRITE("#endif;\n");
if ((id >= 0) && (sometimes_has_visible_properties == FALSE))
WRITE("if (parser_action == ##TheSame) return 0;\n");
WRITE("original_wn = wn;\n");
WRITE("for (pass = 1: pass <= 3: pass++) {\n"); INDENT;
WRITE("wn = original_wn;\n");
WRITE("try_from_wn = wn; f = false; n = 0;\n");
WRITE("while (true) {\n"); INDENT;
WRITE("! On pass 1 only, advance wn past name property words\n");
WRITE("! (but do not do this for ##TheSame, when wn is undefined)\n");
WRITE("if ((parser_action ~= ##TheSame) && (pass == 1)) {\n"); INDENT;
WRITE("while (WordInProperty(NextWordStopped(), self, name)) f = true;\n");
WRITE("wn--; try_from_wn = wn;\n");
OUTDENT; WRITE("}\n");
WRITE("if (pass == 1 or 2) {\n"); INDENT;
PL__Parsing__Tokens__General__consider_visible_properties(OUT, subj, test_distinguishability);
OUTDENT; WRITE("}\n");
WRITE("if ((parser_action ~= ##TheSame) && (pass == 1)) {\n"); INDENT;
WRITE("while (WordInProperty(NextWordStopped(), self, name)) f = true;\n");
WRITE("wn--; try_from_wn = wn;\n");
OUTDENT; WRITE("}\n");
return OUT;
}
#line 291 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__after_gl_failed(OUTPUT_STREAM, int label, int pluralised) {
if (pluralised) WRITE("parser_action = ##PluralFound;\n");
WRITE("try_from_wn = wn; f = true; continue;\n");
WRITE(".Fail_%d; wn = try_from_wn;\n", label);
}
#line 304 "inform7/Chapter 36/General Parsing Routines.w"
text_stream *PL__Parsing__Tokens__General__compile_parse_name_tail(OUTPUT_STREAM) {
WRITE("break;\n");
OUTDENT; WRITE("} ! End of endless loop\n");
WRITE("while (WordInProperty(NextWordStopped(), self, name)) n++;\n");
WRITE("if ((f) || (n>0)) n = n + try_from_wn - original_wn;\n");
WRITE("if (pass == 1) pass1_n = n;\n");
WRITE("if (pass == 2) pass2_n = n;\n");
OUTDENT; WRITE("} ! End of pass loop\n");
WRITE("#ifdef DEBUG;\n");
WRITE("if (parser_trace >= 3)\n"); INDENT;
WRITE("print \"Pass 1: \", pass1_n, \" Pass 2: \", pass2_n, \" Pass 3: \", n, \"^\";\n");
OUTDENT;
WRITE("#endif;\n");
WRITE("if (pass1_n > n) n = pass1_n;\n");
WRITE("if (pass2_n > n) n = pass2_n;\n");
WRITE("wn = original_wn + n;\n");
WRITE("if (n == 0) return -1;\n");
WRITE("DetectPluralWord(original_wn, n);\n");
WRITE("return n;\n");
OUT = Routines__end(OUT);
return OUT;
}
#line 335 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__consider_visible_properties(OUTPUT_STREAM, inference_subject *subj,
int test_distinguishability) {
int phase = 2;
if (test_distinguishability) phase = 1;
for (; phase<=2; phase++) {
property *pr;
PL__Parsing__Tokens__General__start_considering_visible_properties(OUT, phase);
LOOP_OVER(pr, property) {
if ((Properties__is_either_or(pr)) && (Properties__EitherOr__stored_in_negation(pr))) continue;
property_permission *pp =
World__Permissions__find(subj, pr, TRUE);
if ((pp) && (PL__Parsing__Visibility__get_level(pp) > 0))
PL__Parsing__Tokens__General__consider_visible_property(OUT, subj, pr, pp, phase);
}
PL__Parsing__Tokens__General__finish_considering_visible_properties(OUT, phase);
}
}
#line 361 "inform7/Chapter 36/General Parsing Routines.w"
int visible_properties_code_written = FALSE; /* persistent state used only here */
void PL__Parsing__Tokens__General__start_considering_visible_properties(OUTPUT_STREAM, int phase) {
visible_properties_code_written = FALSE;
}
void PL__Parsing__Tokens__General__consider_visible_property(OUTPUT_STREAM, inference_subject *subj,
property *pr, property_permission *pp, int phase) {
int conditional_vis = FALSE;
parse_node *spec;
if (visible_properties_code_written == FALSE) {
visible_properties_code_written = TRUE;
if (phase == 1)
PL__Parsing__Tokens__General__begin_distinguishing_visible_properties(OUT);
else
PL__Parsing__Tokens__General__begin_parsing_visible_properties(OUT);
}
spec = PL__Parsing__Visibility__get_condition(pp);
if (spec) {
conditional_vis = TRUE;
TEMPORARY_STREAM;
Specifications__Compiler__compile(TEMP, spec);
if (phase == 1)
PL__Parsing__Tokens__General__test_distinguish_visible_property(OUT, TEMP);
else
PL__Parsing__Tokens__General__test_parse_visible_property(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
if (phase == 1)
PL__Parsing__Tokens__General__distinguish_visible_property(OUT, pr);
else
PL__Parsing__Tokens__General__parse_visible_property(OUT, subj, pr, PL__Parsing__Visibility__get_level(pp));
if (conditional_vis) { OUTDENT; WRITE("}\n"); }
}
void PL__Parsing__Tokens__General__finish_considering_visible_properties(OUTPUT_STREAM, int phase) {
if (visible_properties_code_written) {
if (phase == 1)
PL__Parsing__Tokens__General__finish_distinguishing_visible_properties(OUT);
else
PL__Parsing__Tokens__General__finish_parsing_visible_properties(OUT);
}
}
#line 420 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__begin_distinguishing_visible_properties(OUTPUT_STREAM) {
WRITE("if (parser_action==##TheSame) {\n"); INDENT;
WRITE("#ifdef DEBUG;\n");
WRITE("if (parser_trace >= 4) print \"p1, p2 = \", parser_one, \", \", parser_two, \"^\";\n");
WRITE("#endif;\n");
WRITE("ss = self;\n");
}
void PL__Parsing__Tokens__General__test_distinguish_visible_property(OUTPUT_STREAM, text_stream *COND) {
WRITE("self = parser_one; f = (");
STREAM_COPY(OUT, COND);
WRITE(");\n");
WRITE("self = parser_two; g = (");
STREAM_COPY(OUT, COND);
WRITE(");\n");
WRITE("if (f ~= g) return -2;\n");
WRITE("if (f) {\n"); INDENT;
}
void PL__Parsing__Tokens__General__distinguish_visible_property(OUTPUT_STREAM, property *prn) {
WRITE("! Distinguishing property %s\n", Properties__get_translation(prn));
if (Properties__is_either_or(prn)) {
WRITE("if ((parser_one "); Properties__ObjectImplementation__compile_has_property(OUT, prn);
WRITE(") && (~~(parser_two "); Properties__ObjectImplementation__compile_has_property(OUT, prn);
WRITE("))) return -2;\n");
WRITE("if ((parser_two "); Properties__ObjectImplementation__compile_has_property(OUT, prn);
WRITE(") && (~~(parser_one "); Properties__ObjectImplementation__compile_has_property(OUT, prn);
WRITE("))) return -2;\n");
} else {
kind *K = Properties__Valued__kind(prn);
char *distinguisher = Kinds__Behaviour__get_distinguisher(K);
if (distinguisher) {
WRITE("if (%s(parser_one.%s, parser_two.%s)) return -2;\n",
distinguisher, Properties__get_translation(prn), Properties__get_translation(prn));
} else {
WRITE("if (parser_one.%s ~= parser_two.%s) return -2;\n",
Properties__get_translation(prn), Properties__get_translation(prn));
}
}
}
void PL__Parsing__Tokens__General__finish_distinguishing_visible_properties(OUTPUT_STREAM) {
WRITE("self = ss; return 0;\n");
OUTDENT; WRITE("}\n");
}
#line 473 "inform7/Chapter 36/General Parsing Routines.w"
void PL__Parsing__Tokens__General__begin_parsing_visible_properties(OUTPUT_STREAM) {
WRITE("! Match any number of visible property values\n");
WRITE("try_from_wn = wn; g = true; while (g) {\n"); INDENT;
WRITE("g = false;\n");
}
void PL__Parsing__Tokens__General__test_parse_visible_property(OUTPUT_STREAM, text_stream *COND) {
WRITE("if (");
STREAM_COPY(OUT, COND);
WRITE(") {\n"); INDENT;
}
int unique_pvp_counter = 0;
void PL__Parsing__Tokens__General__parse_visible_property(OUTPUT_STREAM,
inference_subject *subj, property *prn, int visibility_level) {
WRITE("! Parsing property %s\n", Properties__get_translation(prn));
if (Properties__is_either_or(prn)) {
property *prnbar;
PL__Parsing__Tokens__General__parse_visible_either_or(OUT, prn, visibility_level, unique_pvp_counter);
prnbar = Properties__EitherOr__get_negation(prn);
if (prnbar)
PL__Parsing__Tokens__General__parse_visible_either_or(OUT, prnbar, visibility_level, unique_pvp_counter);
WRITE(".pvp_pass_L_%d;\n", unique_pvp_counter++);
} else {
kind *K = Properties__Valued__kind(prn);
char *recog_gpr;
PL__Parsing__Tokens__General__pvp_test_begins(OUT);
WRITE("spn = parsed_number; ss = etype; if ((");
recog_gpr = Kinds__Behaviour__get_recognition_only_GPR(K);
if (recog_gpr) {
WRITE("%s(self.%s) == GPR_PREPOSITION))",
recog_gpr, Properties__get_translation(prn));
} else if (Kinds__Behaviour__offers_I6_GPR(K)) {
char *i6_gpr_name = Kinds__Behaviour__get_explicit_I6_GPR(K);
if (i6_gpr_name)
WRITE("%s() == GPR_NUMBER) && (self.%s == parsed_number)) ",
i6_gpr_name, Properties__get_translation(prn));
else if (Kinds__Behaviour__is_an_enumeration(K)) {
PL__Parsing__Tokens__Values__igprv_compile(OUT, K);
WRITE("(self.%s) == GPR_NUMBER)) ", Properties__get_translation(prn));
} else {
PL__Parsing__Tokens__Values__gprv_compile(OUT, K);
WRITE("() == GPR_NUMBER) && (self.%s == parsed_number)) ",
Properties__get_translation(prn));
}
} else internal_error("Unable to recognise kind of value in parsing");
PL__Parsing__Tokens__General__pvp_test_passes(OUT, visibility_level, -1);
WRITE("parsed_number = spn; etype = ss;\n");
}
}
void PL__Parsing__Tokens__General__parse_visible_either_or(OUTPUT_STREAM, property *prn, int visibility_level,
int pass_l) {
grammar_verb *gv = Properties__EitherOr__get_parsing_grammar(prn);
PL__Parsing__Tokens__General__pvp_test_begins(OUT);
WRITE("if ((self ");
Properties__ObjectImplementation__compile_has_property(OUT, prn);
WRITE(") ");
PL__Parsing__Tokens__General__pvp_test_words(OUT, prn->name);
PL__Parsing__Tokens__General__pvp_test_passes(OUT, visibility_level, pass_l);
if (gv) {
PL__Parsing__Tokens__General__pvp_test_begins(OUT);
WRITE("if ((self ");
Properties__ObjectImplementation__compile_has_property(OUT, prn);
WRITE(") && (PRN_PN_%d() == GPR_PREPOSITION)) ", prn->allocation_id);
PL__Parsing__Tokens__General__pvp_test_passes(OUT, visibility_level, pass_l);
}
}
void PL__Parsing__Tokens__General__pvp_test_begins(OUTPUT_STREAM) {
WRITE("wn = try_from_wn; ");
}
void PL__Parsing__Tokens__General__pvp_test_words(OUTPUT_STREAM, wording W) {
LOOP_THROUGH_WORDING(i, W) {
WRITE(" && ");
WRITE("(NextWordStopped()==");
DictionaryWords__compile(OUT, Lexer__word_text(i), FALSE);
WRITE(")");
}
WRITE(") ");
}
void PL__Parsing__Tokens__General__pvp_test_passes(OUTPUT_STREAM, int visibility_level, int pass_l) {
WRITE("{\n"); INDENT;
WRITE("try_from_wn = wn;\n");
WRITE("g = true;\n");
if (visibility_level == 2) WRITE("f = true;\n");
if (pass_l >= 0) WRITE("jump pvp_pass_L_%d;\n", pass_l);
OUTDENT; WRITE("}\n");
}
void PL__Parsing__Tokens__General__finish_parsing_visible_properties(OUTPUT_STREAM) {
OUTDENT; WRITE("}\n");
WRITE("! try_from_wn is now advanced past any visible property values\n");
WRITE("wn = try_from_wn;\n");
}
#line 79 "inform7/Chapter 36/Test Scripts.w"
int test_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 219 "inform7/Chapter 36/Test Scripts.w"
*X = NO_INTT;
Problems__Issue__sentence_problem(_p_(PM_UnknownInternalTest),
"that's an internal test case which I don't know",
"so I am taking no action.");
}
#line 81 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 203 "inform7/Chapter 36/Test Scripts.w"
*X = FALSE;
Problems__Issue__sentence_problem(_p_(PM_TestQuoted),
"test scenarios must have unquoted names",
"so 'test garden with ...' is allowed but not 'test \"garden\" with...'");
}
#line 82 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = EXTERNAL_INTT;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 211 "inform7/Chapter 36/Test Scripts.w"
*X = FALSE;
Problems__Issue__sentence_problem(_p_(PM_TestMultiWord),
"test scenarios must have single-word names",
"so 'test garden with ...' is allowed but not 'test garden gate with...'");
}
#line 84 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 85 "inform7/Chapter 36/Test Scripts.w"
#line 90 "inform7/Chapter 36/Test Scripts.w"
int internal_test_case_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 105 "inform7/Chapter 36/Test Scripts.w"
#line 109 "inform7/Chapter 36/Test Scripts.w"
test_scenario *ts_being_parsed = NULL;
#line 116 "inform7/Chapter 36/Test Scripts.w"
int test_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE;
{
#line 136 "inform7/Chapter 36/Test Scripts.w"
int i, j, k, x1 = R[1];
Text__dequote_word(x1);
char *p = Lexer__word_text(x1++);
char individual_command[MAX_LENGTH_OF_SCRIPT];
for (i=0, j=0, k=0; p[i]; i++) {
char c = Platform__tolower(p[i]);
if (c == ' ') {
int l;
if (k == 0) continue;
for (l=i+1; p[l]; l++) if (p[l] != ' ') break;
if ((p[l] == '/') || (p[l] == 0)) continue;
}
if (c == '/') {
individual_command[k] = 0;
k = 0;
PL__Parsing__TestScripts__check_test_command(individual_command);
} else individual_command[k++] = c;
ts_being_parsed->text_of_script[j++] = c;
if (j == MAX_LENGTH_OF_SCRIPT) {
Problems__Issue__sentence_problem(_p_(Untestable), /* or at least impracticable: the limit's huge */
"this test script is too long",
"and exceeds the capacity of a single TEST command. TEST "
"is only designed for short batches of commands, whose "
"total text runs to about 250 letters. For really long "
"test run-throughs, it's probably best to use the Skein, "
"but another trick would be to divide your script into "
"several mini-scenarios with their own TEST commands, and "
"then make a 'test all' command which would run through "
"all of them.");
j -= 2;
break;
}
}
if (k > 0) {
individual_command[k] = 0;
PL__Parsing__TestScripts__check_test_command(individual_command);
}
if ((j>0) && (ts_being_parsed->text_of_script[j-1] == '/'))
ts_being_parsed->text_of_script[j++] = ' ';
ts_being_parsed->text_of_script[j] = 0;
}
#line 117 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
{
#line 136 "inform7/Chapter 36/Test Scripts.w"
int i, j, k, x1 = R[1];
Text__dequote_word(x1);
char *p = Lexer__word_text(x1++);
char individual_command[MAX_LENGTH_OF_SCRIPT];
for (i=0, j=0, k=0; p[i]; i++) {
char c = Platform__tolower(p[i]);
if (c == ' ') {
int l;
if (k == 0) continue;
for (l=i+1; p[l]; l++) if (p[l] != ' ') break;
if ((p[l] == '/') || (p[l] == 0)) continue;
}
if (c == '/') {
individual_command[k] = 0;
k = 0;
PL__Parsing__TestScripts__check_test_command(individual_command);
} else individual_command[k++] = c;
ts_being_parsed->text_of_script[j++] = c;
if (j == MAX_LENGTH_OF_SCRIPT) {
Problems__Issue__sentence_problem(_p_(Untestable), /* or at least impracticable: the limit's huge */
"this test script is too long",
"and exceeds the capacity of a single TEST command. TEST "
"is only designed for short batches of commands, whose "
"total text runs to about 250 letters. For really long "
"test run-throughs, it's probably best to use the Skein, "
"but another trick would be to divide your script into "
"several mini-scenarios with their own TEST commands, and "
"then make a 'test all' command which would run through "
"all of them.");
j -= 2;
break;
}
}
if (k > 0) {
individual_command[k] = 0;
PL__Parsing__TestScripts__check_test_command(individual_command);
}
if ((j>0) && (ts_being_parsed->text_of_script[j-1] == '/'))
ts_being_parsed->text_of_script[j++] = ' ';
ts_being_parsed->text_of_script[j] = 0;
}
#line 118 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 195 "inform7/Chapter 36/Test Scripts.w"
Problems__Issue__sentence_problem(_p_(PM_TestBadRequirements),
"I didn't recognise the requirements for this test scenario",
"which should be 'test ... with ... in ...' or '... "
"holding ...'");
}
#line 119 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 120 "inform7/Chapter 36/Test Scripts.w"
int test_case_circumstance_list_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = 0; return preform_lookahead_mode;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = 0;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 125 "inform7/Chapter 36/Test Scripts.w"
int test_case_circumstance_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0:
{
#line 182 "inform7/Chapter 36/Test Scripts.w"
ts_being_parsed->place = RP[1];
}
#line 127 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 187 "inform7/Chapter 36/Test Scripts.w"
if (ts_being_parsed->no_possessions >= MAX_POSSESSIONS_PER_SCENARIO) {
{
#line 195 "inform7/Chapter 36/Test Scripts.w"
Problems__Issue__sentence_problem(_p_(PM_TestBadRequirements),
"I didn't recognise the requirements for this test scenario",
"which should be 'test ... with ... in ...' or '... "
"holding ...'");
}
#line 188 "inform7/Chapter 36/Test Scripts.w"
;
} else
ts_being_parsed->possessions[ts_being_parsed->no_possessions++] = RP[1];
}
#line 128 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 195 "inform7/Chapter 36/Test Scripts.w"
Problems__Issue__sentence_problem(_p_(PM_TestBadRequirements),
"I didn't recognise the requirements for this test scenario",
"which should be 'test ... with ... in ...' or '... "
"holding ...'");
}
#line 129 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3:
{
#line 195 "inform7/Chapter 36/Test Scripts.w"
Problems__Issue__sentence_problem(_p_(PM_TestBadRequirements),
"I didn't recognise the requirements for this test scenario",
"which should be 'test ... with ... in ...' or '... "
"holding ...'");
}
#line 130 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4:
{
#line 227 "inform7/Chapter 36/Test Scripts.w"
Problems__Issue__sentence_problem(_p_(PM_TestDoubleWith),
"the second 'with' should be 'holding'",
"as in 'test frogs with \"get frogs\" holding net' rather than "
"'test frogs with \"get frogs\" with net'.");
}
#line 131 "inform7/Chapter 36/Test Scripts.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 132 "inform7/Chapter 36/Test Scripts.w"
#line 235 "inform7/Chapter 36/Test Scripts.w"
sentence_handler TEST_SH_handler =
{ SENTENCE_NT, TEST_VB, 2, PL__Parsing__TestScripts__new_test_text };
void PL__Parsing__TestScripts__new_test_text(parse_node *PN) {
if (Preform__parse_nt_against_word_range(test_sentence_subject_NTM, ParseTree__get_text(PN->down->next), NULL, NULL)) {
switch (most_recent_result) {
case NO_INTT: return;
case EXTERNAL_INTT:
{
#line 252 "inform7/Chapter 36/Test Scripts.w"
wording XW = GET_RW(test_sentence_subject_NTM, 1);
test_scenario *test;
LOOP_OVER(test, test_scenario) {
if (Wordings__match(XW, test->name)) {
Problems__quote_source(1, test->sentence_test_declared_at);
Problems__quote_source(2, current_sentence);
Problems__Issue__handmade_problem(_p_(PM_TestDuplicate));
Problems__issue_problem_segment(
"Two test scripts have been set up with the same name: "
"%1 and %2.");
Problems__issue_problem_end();
}
}
test = CREATE(test_scenario);
test->name = XW;
test->sentence_test_declared_at = current_sentence;
test->place = NULL;
test->no_possessions = 0;
ts_being_parsed = test;
Preform__parse_nt_against_word_range(test_sentence_object_NTM, ParseTree__get_text(PN->down->next->next), NULL, NULL);
}
#line 242 "inform7/Chapter 36/Test Scripts.w"
; break;
default: PL__Parsing__TestScripts__new_internal(most_recent_result, ParseTree__get_text(PN->down->next->next));
break;
}
}
}
#line 279 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__check_test_command(char *p) {
if (strcmp(p, "undo") == 0) {
Problems__Issue__sentence_problem(_p_(PM_TestContainsUndo),
"this test script contains an UNDO command",
"which the story file has no way to automate the running of. "
"(An UNDO is such a complete reversion to the previous state "
"that it would necessarily lose where it had got to in the "
"script, and might even go round in circles indefinitely.)");
return;
}
if (Platform__strlen(p) > MAX_LENGTH_OF_COMMAND) {
Problems__Issue__sentence_problem(_p_(PM_TestCommandTooLong),
"this test script contains a command which is too long",
"and cannot be fed into Inform for automatic testing. "
"(The format for a test script is a sequence of commands, "
"divided up by slashes '/': maybe you forgot these divisions?)");
return;
}
}
void PL__Parsing__TestScripts__write_text(OUTPUT_STREAM) {
int j;
test_scenario *test;
LOOP_OVER(test, test_scenario) {
WRITE("Array TestText_%d ->\n", test->allocation_id); INDENT;
WRITE("\"");
CompiledText__from_ISO_string(OUT, test->text_of_script,
CT_EXPAND_APOSTROPHES + CT_RECOGNISE_APOSTROPHE_SUBSTITUTION
+ CT_FOR_ARRAY);
WRITE("||||\";\n");
OUTDENT;
WRITE("Array TestReq_%d -->\n", test->allocation_id); INDENT;
if (test->place == NULL) WRITE("0 ");
else WRITE("%s ", Instances__identifier(test->place));
for (j=0; j<test->no_possessions; j++) {
if (test->possessions[j] == NULL) WRITE("0 ");
else WRITE("%s ", Instances__identifier(test->possessions[j]));
}
WRITE("0;\n");
OUTDENT;
}
}
void PL__Parsing__TestScripts__compile_switch(OUTPUT_STREAM) {
test_scenario *test;
LOOP_OVER(test, test_scenario) {
int i, l = 0;
char *p = test->text_of_script;
for (i=0; p[i]; i++, l++)
if ((p[i] == '[') && (p[i+1] == '\'') && (p[i+2] == ']'))
l -= 2;
WRITE("'%s//': TestStart(TestText_%d, TestReq_%d, %d);\n",
Lexer__word_raw_text(Wordings__first_wn(test->name)),
test->allocation_id, test->allocation_id, l);
}
}
void PL__Parsing__TestScripts__compile_printout(OUTPUT_STREAM) {
test_scenario *test;
LOOP_OVER(test, test_scenario)
WRITE("print \"'test %s'^\";\n",
Lexer__word_raw_text(Wordings__first_wn(test->name)));
}
#line 346 "inform7/Chapter 36/Test Scripts.w"
void PL__Parsing__TestScripts__new_internal(int code, wording W) {
internal_test_case *itc = CREATE(internal_test_case);
itc->itc_code = code;
itc->text_supplying_the_case = W;
itc->itc_defined_at = current_sentence;
}
text_stream *itc_save_dl = NULL, *itc_save_OUT = NULL;
void PL__Parsing__TestScripts__InternalTestCases_routine(OUTPUT_STREAM) {
internal_test_case *itc; int n = 0;
OUT = Routines__begin(OUT, "InternalTestCases");
itc_save_OUT = OUT;
LOOP_OVER(itc, internal_test_case) {
n++;
if (itc->itc_code == HEADLINE_INTT) {
n = 0;
WRITE("style bold; print \"^");
Wordings__to_stream_raw(OUT, itc->text_supplying_the_case);
WRITE("^\"; style roman;\n");
continue;
}
WRITE("print \"%d. ", n);
if (itc->itc_code == ARTICLE_INTT) {
Text__dequote_word(Wordings__first_wn(itc->text_supplying_the_case));
WRITE("%s", Lexer__word_text(Wordings__first_wn(itc->text_supplying_the_case)));
} else {
Wordings__to_stream_raw(OUT, itc->text_supplying_the_case);
}
WRITE("^\";\n");
WRITE("print \"");
current_sentence = itc->itc_defined_at;
switch (itc->itc_code) {
case SENTENCE_INTT: {
int SV_not_SN = TRUE;
{
#line 503 "inform7/Chapter 36/Test Scripts.w"
parse_node *p = NULL;
pcalc_prop *prop = NULL;
int tc = FALSE;
if (SV_not_SN) {
if (Preform__parse_nt_against_word_range(s_sentence_NTM, itc->text_supplying_the_case, NULL, NULL)) p = most_recent_result_p;
} else {
if (Preform__parse_nt_against_word_range(s_descriptive_np_NTM, itc->text_supplying_the_case, NULL, NULL)) p = most_recent_result_p;
}
if (p) {
prop = Specifications__to_proposition(p);
tc = Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_no_problem_reporting());
}
{
#line 528 "inform7/Chapter 36/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 516 "inform7/Chapter 36/Test Scripts.w"
;
if (p == NULL) LOG("Failed: not a condition");
else {
LOG("$D\n", prop);
if (tc == FALSE) LOG("Failed: proposition would not type-check\n");
Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_problem_logging());
}
{
#line 533 "inform7/Chapter 36/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 523 "inform7/Chapter 36/Test Scripts.w"
;
}
#line 381 "inform7/Chapter 36/Test Scripts.w"
;
break;
}
case DESCRIPTION_INTT: {
int SV_not_SN = FALSE;
{
#line 503 "inform7/Chapter 36/Test Scripts.w"
parse_node *p = NULL;
pcalc_prop *prop = NULL;
int tc = FALSE;
if (SV_not_SN) {
if (Preform__parse_nt_against_word_range(s_sentence_NTM, itc->text_supplying_the_case, NULL, NULL)) p = most_recent_result_p;
} else {
if (Preform__parse_nt_against_word_range(s_descriptive_np_NTM, itc->text_supplying_the_case, NULL, NULL)) p = most_recent_result_p;
}
if (p) {
prop = Specifications__to_proposition(p);
tc = Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_no_problem_reporting());
}
{
#line 528 "inform7/Chapter 36/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 516 "inform7/Chapter 36/Test Scripts.w"
;
if (p == NULL) LOG("Failed: not a condition");
else {
LOG("$D\n", prop);
if (tc == FALSE) LOG("Failed: proposition would not type-check\n");
Calculus__Propositions__Checker__type_check(prop, Calculus__Propositions__Checker__tc_problem_logging());
}
{
#line 533 "inform7/Chapter 36/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 523 "inform7/Chapter 36/Test Scripts.w"
;
}
#line 386 "inform7/Chapter 36/Test Scripts.w"
;
break;
}
case EVALUATION_INTT: {
parse_node *spec = NULL;
if (Preform__parse_nt_against_word_range(s_value_NTM, itc->text_supplying_the_case, NULL, NULL)) spec = most_recent_result_p;
else spec = Specifications__new_UNKNOWN(itc->text_supplying_the_case);
Dash__check_value(spec, NULL);
kind *K = Specifications__to_kind(spec);
WRITE("Kind of value: ");
{
#line 528 "inform7/Chapter 36/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 396 "inform7/Chapter 36/Test Scripts.w"
;
Kinds__Textual__log(K);
if (Kinds__Behaviour__is_quasinumerical(K))
LOG(" scaled at k=%d", Kinds__Behaviour__scale_factor(K));
{
#line 533 "inform7/Chapter 36/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 400 "inform7/Chapter 36/Test Scripts.w"
;
WRITE("^Prints as: \", (%s) ",
Kinds__Behaviour__get_name_of_printing_rule(K));
TEMPORARY_STREAM;
Specifications__Compiler__compile(TEMP, spec);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
WRITE(", \"^");
break;
}
case DIMENSIONS_INTT:
{
#line 528 "inform7/Chapter 36/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 411 "inform7/Chapter 36/Test Scripts.w"
;
Kinds__Dimensions__log_unit_analysis();
{
#line 533 "inform7/Chapter 36/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 413 "inform7/Chapter 36/Test Scripts.w"
;
break;
case EQUATION_INTT:
Equations__internal_test(itc->text_supplying_the_case);
break;
case ARTICLE_INTT:
Inflections__test_tries(OUT, Lexer__word_text(Wordings__first_wn(itc->text_supplying_the_case)));
break;
case VERB_INTT:
Preform__Nonparsing__test_conjugation(OUT, itc->text_supplying_the_case);
break;
case ADJECTIVE_INTT:
Adjectives__Phrases__test_adjective(OUT, itc->text_supplying_the_case);
break;
case ING_INTT:
Preform__Nonparsing__test_participle(OUT, itc->text_supplying_the_case);
break;
case KIND_INTT:
{
#line 528 "inform7/Chapter 36/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 431 "inform7/Chapter 36/Test Scripts.w"
;
Kinds__Compare__log_poset(
Vocabulary__get_literal_number_value(
Lexer__word(
Wordings__first_wn(
itc->text_supplying_the_case))));
{
#line 533 "inform7/Chapter 36/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 437 "inform7/Chapter 36/Test Scripts.w"
;
break;
case MAP_INTT:
{
#line 528 "inform7/Chapter 36/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 440 "inform7/Chapter 36/Test Scripts.w"
;
PL__SpatialMap__log_spatial_layout();
{
#line 533 "inform7/Chapter 36/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 442 "inform7/Chapter 36/Test Scripts.w"
;
break;
case DASH_INTT:
{
#line 528 "inform7/Chapter 36/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 445 "inform7/Chapter 36/Test Scripts.w"
;
Dash__experiment(itc->text_supplying_the_case, FALSE);
{
#line 533 "inform7/Chapter 36/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 447 "inform7/Chapter 36/Test Scripts.w"
;
break;
case DASHLOG_INTT:
Dash__experiment(itc->text_supplying_the_case, TRUE);
break;
}
WRITE("^\";\n");
}
OUT = Routines__end(OUT);
}
void PL__Parsing__TestScripts__begin_internal_reporting(void) {
{
#line 528 "inform7/Chapter 36/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 459 "inform7/Chapter 36/Test Scripts.w"
;
}
void PL__Parsing__TestScripts__end_internal_reporting(void) {
{
#line 533 "inform7/Chapter 36/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 463 "inform7/Chapter 36/Test Scripts.w"
;
}
void PL__Parsing__TestScripts__showme(OUTPUT_STREAM, parse_node *spec) {
itc_save_OUT = OUT;
if (ParseTree__is(spec, PROPERTY_VALUE_VNT))
spec = Lvalues__underlying_property(spec);
kind *K = Specifications__to_kind(spec);
if (ParseTree__is(spec, CONSTANT_VNT) == FALSE) {
WRITE("~");
Wordings__to_stream_raw_within_i6_literal(OUT, ParseTree__get_text(spec));
WRITE("~ = ");
}
{
#line 528 "inform7/Chapter 36/Test Scripts.w"
itc_save_dl = dl; dl = itc_save_OUT; logging_to_I6_text = TRUE;
}
#line 476 "inform7/Chapter 36/Test Scripts.w"
;
Kinds__Textual__log(K);
{
#line 533 "inform7/Chapter 36/Test Scripts.w"
dl = itc_save_dl; logging_to_I6_text = FALSE;
}
#line 478 "inform7/Chapter 36/Test Scripts.w"
;
if (Kinds__get_construct(K) == CON_list_of) {
WRITE(": \"; LIST_OF_TY_Say(");
TEMPORARY_STREAM;
Specifications__Compiler__compile(TEMP, spec);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
WRITE(", 1); print \"");
} else {
WRITE(": \", (%s) ",
Kinds__Behaviour__get_name_of_printing_rule(K));
TEMPORARY_STREAM;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__Compiler__compile(TEMP, spec);
END_COMPILATION_MODE;
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
WRITE(", \"");
}
}
#line 45 "inform7/Chapter 37/Figures.w"
void PL__Figures__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_INSTANCE_NOTIFY, PL__Figures__figures_new_named_instance_notify);
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL__Figures__figures_new_base_kind_notify);
}
#line 53 "inform7/Chapter 37/Figures.w"
int PL__Figures__figures_new_base_kind_notify(kind *new_base, char *name, wording W) {
if ((name) && (strcmp(name, "FIGURE_NAME_TY") == 0)) {
K_figure_name = new_base; return TRUE;
}
return FALSE;
}
int allow_figure_creations = FALSE;
int PL__Figures__figures_new_named_instance_notify(instance *nc) {
if (K_figure_name == NULL) return FALSE;
kind *K = Instances__to_kind(nc);
if (Kinds__Compare__eq(K, K_figure_name)) {
if (allow_figure_creations == FALSE)
Problems__Issue__sentence_problem(_p_(PM_BackdoorFigureCreation),
"this is not the way to create a new figure name",
"which should be done with a special 'Figure ... is the file ...' "
"sentence.");
Instances__set_connection(nc,
STORE_POINTER_blorb_figure(PL__Figures__new_blorb_figure(nc)));
return TRUE;
}
return FALSE;
}
blorb_figure *PL__Figures__new_blorb_figure(instance *nc) {
blorb_figure *bf = CREATE(blorb_figure);
bf->name = EMPTY_WORDING;
bf->filename_of_image_file = NULL;
bf->figure_number = 0;
bf->alt_description = -1;
return bf;
}
#line 90 "inform7/Chapter 37/Figures.w"
sentence_handler FIGURE_SH_handler =
{ SENTENCE_NT, FIGURE_VB, 1, PL__Figures__handle_figure_definition };
void PL__Figures__handle_figure_definition(parse_node *p) {
if (Plugins__Manage__plugged_in(figures_plugin) == FALSE)
internal_error("Figures plugin inactive");
PL__Figures__register_figure(ParseTree__get_text(p->down->next),
ParseTree__get_text(p->down->next->next));
}
#line 103 "inform7/Chapter 37/Figures.w"
int figure_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; alttext_NTMV = R[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 106 "inform7/Chapter 37/Figures.w"
int figure_source_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = -1;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 115 "inform7/Chapter 37/Figures.w"
Problems__Issue__sentence_problem(_p_(PM_PictureNotTextual),
"a figure can only be declared as a quoted file name",
"which should be the name of a JPEG or PNG image inside the "
"project's .materials folder. For instance, 'Figure 2 is the "
"file \"Crossed Swords.png\".'");
*X = 0;
}
#line 110 "inform7/Chapter 37/Figures.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 111 "inform7/Chapter 37/Figures.w"
#line 127 "inform7/Chapter 37/Figures.w"
int notable_figures_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 129 "inform7/Chapter 37/Figures.w"
#line 133 "inform7/Chapter 37/Figures.w"
void PL__Figures__register_figure(wording F, wording FN) {
alttext_NTMV = -1;
Preform__parse_nt_against_word_range(figure_sentence_object_NTM, FN, NULL, NULL);
int wn = most_recent_result;
if (wn == 0) return;
if (wn > 0) Text__dequote_word(wn);
if (alttext_NTMV > 0) Text__dequote_word(alttext_NTMV);
Assertions__Creator__vet_name_for_noun(F);
if ((Preform__parse_nt_against_word_range(s_value_NTM, F, NULL, NULL)) &&
(Rvalues__is_CONSTANT_of_kind(most_recent_result_p, K_figure_name))) {
Problems__Issue__sentence_problem(_p_(PM_PictureDuplicate),
"this is already the name of a Figure",
"so there must be some duplication somewhere.");
return;
}
allow_figure_creations = TRUE;
pcalc_prop *prop = Calculus__Propositions__Abstract__to_create_something(K_figure_name, F);
Calculus__Propositions__Assert__assert_true(prop, CERTAIN_CE);
allow_figure_creations = FALSE;
blorb_figure *bf = RETRIEVE_POINTER_blorb_figure(
Instances__get_connection(latest_instance));
bf->name = F;
if (wn >= 0) {
bf->figure_number = VirtualMachines__get_next_free_blorb_resource_ID();
bf->filename_of_image_file =
Filenames__in_folder(pathname_of_materials_figures, Lexer__word_text(wn));
bf->alt_description = alttext_NTMV;
} else {
bf->figure_number = 1;
bf->filename_of_image_file = NULL;
bf->alt_description = alttext_NTMV;
F_cover_art = bf;
}
LOGIF(FIGURE_CREATIONS, "Created figure <$w> = filename '%s' = resource ID %d\n",
F, (wn>=0)?Lexer__word_text(wn):"<cover art>", bf->figure_number);
}
char *PL__Figures__description_of_cover_art(void) {
if ((F_cover_art == NULL) || (F_cover_art->alt_description == -1)) return "";
return Lexer__word_text(F_cover_art->alt_description);
}
#line 184 "inform7/Chapter 37/Figures.w"
void PL__Figures__write_picture_manifest(OUTPUT_STREAM, int include_cover,
char *cover_art_format) {
if (Plugins__Manage__plugged_in(figures_plugin) == FALSE) return;
blorb_figure *bf;
WRITE("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
WRITE("<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
"\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n");
WRITE("<plist version=\"1.0\">\n"); INDENT;
WRITE("<dict>\n"); INDENT;
WRITE("<key>Graphics</key>\n");
WRITE("<dict>\n"); INDENT;
if (include_cover) {
WRITE("<key>1</key>\n");
filename *large = NULL;
if (strcmp(cover_art_format, "jpg") == 0)
large = filename_of_large_cover_art_jpeg;
else
large = filename_of_large_cover_art_png;
char cover_fn[MAX_FILENAME_LENGTH];
Filenames__to_string(cover_fn, large);
WRITE("<string>%s</string>\n", cover_fn);
}
LOOP_OVER(bf, blorb_figure)
if (bf->figure_number > 1) {
WRITE("<key>%d</key>\n", bf->figure_number);
char rel[MAX_FILENAME_LENGTH];
Filenames__to_string_relative(rel, bf->filename_of_image_file, pathname_of_area[MATERIALS_FS_AREA]);
WRITE("<string>%s</string>\n", rel);
}
OUTDENT; WRITE("</dict>\n");
PL__Sounds__write_sounds_manifest(OUT);
OUTDENT; WRITE("</dict>\n");
OUTDENT; WRITE("</plist>\n");
}
#line 223 "inform7/Chapter 37/Figures.w"
void PL__Figures__write_blurb_commands(OUTPUT_STREAM) {
if (Plugins__Manage__plugged_in(figures_plugin) == FALSE) return;
blorb_figure *bf;
LOOP_OVER(bf, blorb_figure)
if (bf->figure_number > 1) {
char *desc = "";
if (bf->alt_description >= 0)
desc = Lexer__word_text(bf->alt_description);
if (strlen(desc) > 0)
WRITE("picture %d \"%f\" \"%s\"\n", bf->figure_number, bf->filename_of_image_file, desc);
else
WRITE("picture %d \"%f\"\n", bf->figure_number, bf->filename_of_image_file);
}
}
#line 241 "inform7/Chapter 37/Figures.w"
void PL__Figures__write_copy_commands(void) {
if (Plugins__Manage__plugged_in(figures_plugin) == FALSE) return;
blorb_figure *bf;
LOOP_OVER(bf, blorb_figure)
if (bf->figure_number > 1)
PL__Bibliographic__Release__create_aux_file(bf->filename_of_image_file,
pathname_of_released_figures, "--", SEPARATE_FIGURES_PAYLOAD);
}
#line 253 "inform7/Chapter 37/Figures.w"
void PL__Figures__tableoffigures_array(OUTPUT_STREAM) {
if (Plugins__Manage__plugged_in(figures_plugin) == FALSE) return;
WRITE("Array ResourceIDsOfFigures --> 0 ");
blorb_figure *bf;
LOOP_OVER(bf, blorb_figure) WRITE("%d ", bf->figure_number);
WRITE(" 0;\n");
}
#line 269 "inform7/Chapter 37/Figures.w"
void PL__Figures__index_all(void) {
if (Plugins__Manage__plugged_in(figures_plugin) == FALSE) return;
blorb_figure *bf; FILE *FIGURE_FILE;
char line2[MAX_FILENAME_LENGTH];
int MAX_INDEXED_FIGURES = UseOptions__get_index_figure_thumbnails();
int rv;
if (NUMBER_CREATED(blorb_figure) < 2) { /* cover art always creates 1 */
INDEX("<p>There are no figures, or illustrations, in this project.</p>");
return;
}
INDEX("<p><b>List of Figures</b></p>\n");
HTML__begin_html_table(ifl, "#ffffff", TRUE, 0, 0, 0, 0, 0);
int count_of_displayed_figures = 0;
LOOP_OVER(bf, blorb_figure) {
if (bf->figure_number > 1) {
unsigned int width = 0, height = 0;
rv = 0;
FIGURE_FILE = Platform__iso_fopen(bf->filename_of_image_file, "rb");
if (FIGURE_FILE) {
char *real_format = "JPEG";
rv = ImageFiles__get_JPEG_dimensions(FIGURE_FILE, &width, &height);
fclose(FIGURE_FILE);
if (rv == 0) {
FIGURE_FILE = Platform__iso_fopen(bf->filename_of_image_file, "rb");
if (FIGURE_FILE) {
real_format = "PNG";
rv = ImageFiles__get_PNG_dimensions(FIGURE_FILE, &width, &height);
fclose(FIGURE_FILE);
}
}
if (rv == 0) {
sprintf(line2, "<i>Unknown image format</i><br>\n");
} else {
sprintf(line2, "%s format: %d (width) by %d (height) pixels<br>\n",
real_format, width, height);
}
} else {
sprintf(line2, "<i>Missing from the Figures folder</i><br>\n");
}
HTML__first_html_column(ifl, THUMBNAIL_WIDTH+10);
if (rv == 0)
INDEX("<img border=\"0\" src=\"inform:/doc_images/image_problem.png\">&nbsp;");
else if (count_of_displayed_figures++ < MAX_INDEXED_FIGURES) {
char image_filename[MAX_FILENAME_LENGTH];
Filenames__to_string(image_filename, bf->filename_of_image_file);
INDEX("<img border=\"1\" src=\"file://%s\" width=\"%d\" height=\"%d\">&nbsp;",
image_filename, THUMBNAIL_WIDTH, THUMBNAIL_WIDTH*height/width);
} else
INDEX("<div style=\"width:%dpx; height:%dpx; border:1px solid; background-color:#6495ed;\">"
"&nbsp;</div>",
THUMBNAIL_WIDTH, THUMBNAIL_WIDTH*height/width);
HTML__next_html_column(ifl, 0);
Wordings__index_raw(bf->name);
Index__link(Wordings__first_wn(bf->name));
char rel[MAX_FILENAME_LENGTH];
Filenames__to_string_relative(rel, bf->filename_of_image_file, pathname_of_area[MATERIALS_FS_AREA]);
INDEX("<br>\n%sFilename: \"%s\" - resource number %d", line2, rel, bf->figure_number);
HTML__end_html_row(ifl);
}
}
HTML__end_html_table(ifl);
INDEX("<p>");
if (count_of_displayed_figures > MAX_INDEXED_FIGURES)
INDEX("(Only the first %d thumbnails have been shown here, "
"to avoid Inform taking up too much memory. If you'd like to "
"see more, set 'Use index figure thumbnails of at least %d.', or "
"whatever number you want to wait for.)</p>",
MAX_INDEXED_FIGURES, 10*MAX_INDEXED_FIGURES);
}
#line 41 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__start(void) {
PLUGIN_REGISTER(PLUGIN_NEW_INSTANCE_NOTIFY, PL__Sounds__sounds_new_named_instance_notify);
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL__Sounds__sounds_new_base_kind_notify);
}
#line 49 "inform7/Chapter 37/Sound Effects.w"
int PL__Sounds__sounds_new_base_kind_notify(kind *new_base, char *name, wording W) {
if ((name) && (strcmp(name, "SOUND_NAME_TY") == 0)) {
K_sound_name = new_base; return TRUE;
}
return FALSE;
}
int allow_sound_creations = FALSE;
int PL__Sounds__sounds_new_named_instance_notify(instance *nc) {
if (K_sound_name == NULL) return FALSE;
kind *K = Instances__to_kind(nc);
if (Kinds__Compare__eq(K, K_sound_name)) {
if (allow_sound_creations == FALSE)
Problems__Issue__sentence_problem(_p_(PM_BackdoorSoundCreation),
"this is not the way to create a new sound name",
"which should be done with a special 'Sound ... is the file ...' "
"sentence.");
Instances__set_connection(nc,
STORE_POINTER_blorb_sound(PL__Sounds__new_blorb_sound(nc)));
return TRUE;
}
return FALSE;
}
blorb_sound *PL__Sounds__new_blorb_sound(instance *nc) {
blorb_sound *bs = CREATE(blorb_sound);
return bs;
}
#line 82 "inform7/Chapter 37/Sound Effects.w"
sentence_handler SOUND_SH_handler =
{ SENTENCE_NT, SOUND_VB, 1, PL__Sounds__handle_sound_definition };
void PL__Sounds__handle_sound_definition(parse_node *p) {
if (Plugins__Manage__plugged_in(sounds_plugin) == FALSE)
internal_error("Sounds plugin inactive");
PL__Sounds__register_sound(ParseTree__get_text(p->down->next),
ParseTree__get_text(p->down->next->next));
}
#line 95 "inform7/Chapter 37/Sound Effects.w"
int sound_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; alttext_NTMV = R[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 98 "inform7/Chapter 37/Sound Effects.w"
int sound_source_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 106 "inform7/Chapter 37/Sound Effects.w"
Problems__Issue__sentence_problem(_p_(PM_SoundNotTextual),
"a sound effect can only be declared as a quoted file name",
"which should be the name of an AIFF or OGG file inside the Sounds "
"subfolder of the project's .materials folder. For instance, 'Sound "
"of Swordplay is the file \"Crossed Swords.aiff\".'");
*X = 0;
}
#line 101 "inform7/Chapter 37/Sound Effects.w"
;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 102 "inform7/Chapter 37/Sound Effects.w"
#line 116 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__register_sound(wording F, wording FN) {
alttext_NTMV = -1;
Preform__parse_nt_against_word_range(sound_sentence_object_NTM, FN, NULL, NULL);
int wn = most_recent_result;
if (wn == 0) return;
if (wn > 0) Text__dequote_word(wn);
if (alttext_NTMV > 0) Text__dequote_word(alttext_NTMV);
Assertions__Creator__vet_name_for_noun(F);
if ((Preform__parse_nt_against_word_range(s_value_NTM, F, NULL, NULL)) &&
(Rvalues__is_CONSTANT_of_kind(most_recent_result_p, K_sound_name))) {
Problems__Issue__sentence_problem(_p_(PM_SoundDuplicate),
"this is already the name of a sound effect",
"so there must be some duplication somewhere.");
return;
}
allow_sound_creations = TRUE;
pcalc_prop *prop = Calculus__Propositions__Abstract__to_create_something(
K_sound_name, F);
Calculus__Propositions__Assert__assert_true(prop, CERTAIN_CE);
allow_sound_creations = FALSE;
blorb_sound *bs = RETRIEVE_POINTER_blorb_sound(
Instances__get_connection(latest_instance));
bs->filename_of_sound_file =
Filenames__in_folder(pathname_of_materials_sounds, Lexer__word_text(wn));
bs->name = F;
bs->sound_number = VirtualMachines__get_next_free_blorb_resource_ID();
bs->alt_description = alttext_NTMV;
LOGIF(FIGURE_CREATIONS, "Created sound effect <$w> = filename '%s' = resource ID %d\n",
F, Lexer__word_text(wn), bs->sound_number);
}
#line 160 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__write_sounds_manifest(OUTPUT_STREAM) {
if (Plugins__Manage__plugged_in(sounds_plugin) == FALSE) return;
blorb_sound *bs;
if (NUMBER_CREATED(blorb_sound) == 0) return;
WRITE("<key>Sounds</key>\n");
WRITE("<dict>\n"); INDENT;
LOOP_OVER(bs, blorb_sound) {
WRITE("<key>%d</key>\n", bs->sound_number);
char rel[MAX_FILENAME_LENGTH];
Filenames__to_string_relative(rel, bs->filename_of_sound_file, pathname_of_area[MATERIALS_FS_AREA]);
WRITE("<string>%s</string>\n", rel);
}
OUTDENT; WRITE("</dict>\n");
}
#line 178 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__write_blurb_commands(OUTPUT_STREAM) {
if (Plugins__Manage__plugged_in(sounds_plugin) == FALSE) return;
blorb_sound *bs;
LOOP_OVER(bs, blorb_sound) {
char *desc = "";
if (bs->alt_description >= 0)
desc = Lexer__word_text(bs->alt_description);
if (strlen(desc) > 0)
WRITE("sound %d \"%f\" \"%s\"\n", bs->sound_number, bs->filename_of_sound_file, desc);
else
WRITE("sound %d \"%f\"\n", bs->sound_number, bs->filename_of_sound_file);
}
}
#line 195 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__write_copy_commands(void) {
if (Plugins__Manage__plugged_in(sounds_plugin) == FALSE) return;
blorb_sound *bs;
LOOP_OVER(bs, blorb_sound)
PL__Bibliographic__Release__create_aux_file(
bs->filename_of_sound_file,
pathname_of_released_sounds,
"--",
SEPARATE_SOUNDS_PAYLOAD);
}
#line 209 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__tableofsounds_array(OUTPUT_STREAM) {
if (Plugins__Manage__plugged_in(sounds_plugin) == FALSE) return;
WRITE("Array ResourceIDsOfSounds --> 0 ");
blorb_sound *bs;
LOOP_OVER(bs, blorb_sound) WRITE("%d ", bs->sound_number);
WRITE(" 0;\n");
}
#line 221 "inform7/Chapter 37/Sound Effects.w"
void PL__Sounds__index_all(void) {
if (Plugins__Manage__plugged_in(sounds_plugin) == FALSE) return;
blorb_sound *bs; FILE *SOUND_FILE;
char line2[MAX_FILENAME_LENGTH];
int rv;
if (NUMBER_CREATED(blorb_sound) == 0) {
INDEX("<p>There are no sound effects in this project.</p>");
return;
}
INDEX("<p><b>List of Sounds</b></p>\n");
HTML__begin_html_table(ifl, "#ffffff", TRUE, 0, 0, 0, 0, 0);
LOOP_OVER(bs, blorb_sound) {
unsigned int duration, pBitsPerSecond, pChannels, pSampleRate, fsize,
midi_version = 0, no_tracks = 0;
int preview = TRUE, waveform_style = TRUE;
rv = 0;
SOUND_FILE = Platform__iso_fopen(bs->filename_of_sound_file, "rb");
if (SOUND_FILE) {
char *real_format = "AIFF";
rv = SoundFiles__get_AIFF_duration(SOUND_FILE, &duration, &pBitsPerSecond,
&pChannels, &pSampleRate);
fseek(SOUND_FILE, 0, SEEK_END);
fsize = (unsigned int) (ftell(SOUND_FILE));
fclose(SOUND_FILE);
if (rv == 0) {
SOUND_FILE = Platform__iso_fopen(bs->filename_of_sound_file, "rb");
if (SOUND_FILE) {
real_format = "Ogg Vorbis";
preview = FALSE;
rv = SoundFiles__get_OggVorbis_duration(SOUND_FILE, &duration, &pBitsPerSecond,
&pChannels, &pSampleRate);
fclose(SOUND_FILE);
}
}
if (rv == 0) {
SOUND_FILE = Platform__iso_fopen(bs->filename_of_sound_file, "rb");
if (SOUND_FILE) {
waveform_style = FALSE;
real_format = "MIDI";
preview = TRUE;
rv = SoundFiles__get_MIDI_information(SOUND_FILE,
&midi_version, &no_tracks);
fclose(SOUND_FILE);
}
}
if (rv == 0) {
sprintf(line2, "<i>Unknown sound format</i><br>\n");
} else {
if (waveform_style == FALSE)
sprintf(line2, "Type %d %s file with %d track%s<br>\n"
"<i>Warning: not officially supported in glulx yet</i><br>\n",
midi_version, real_format, no_tracks,
(no_tracks == 1)?"":"s");
else {
int min = (duration/6000), sec = (duration%6000)/100,
centisec = (duration%100);
sprintf(line2, "%d.%01dKB %s file: duration ",
fsize/1024, (fsize%1024)/102, real_format);
if (min > 0)
sprintf(line2+Platform__strlen(line2), "%d minutes ", min);
if ((sec > 0) || (centisec > 0)) {
if (centisec == 0)
sprintf(line2+Platform__strlen(line2), "%d seconds<br>", sec);
else
sprintf(line2+Platform__strlen(line2), "%d.%02d seconds<br>",
sec, centisec);
} else sprintf(line2+Platform__strlen(line2), "exactly<br>");
sprintf(line2+Platform__strlen(line2),
"Sampled as %d.%01dkHz %s (%d.%01d kilobits/sec)<br>",
pSampleRate/1000, (pSampleRate%1000)/100,
(pChannels==1)?"Mono":"Stereo",
pBitsPerSecond/1000, (pSampleRate%1000)/100);
}
}
} else {
sprintf(line2, "<i>Missing from the Sounds folder</i><br>\n");
}
HTML__first_html_column(ifl, THUMBNAIL_WIDTH+10);
if (rv == 0)
INDEX("<img border=\"0\" src=\"inform:/doc_images/image_problem.png\">&nbsp;");
else {
if (preview) {
char sound_filename[MAX_FILENAME_LENGTH];
Filenames__to_string(sound_filename, bs->filename_of_sound_file);
INDEX("<embed src=\"file://%s\" width=\"%d\" height=\"64\" "
"autostart=\"false\" volume=\"50%%\" mastersound></embed>&nbsp;",
sound_filename, THUMBNAIL_WIDTH);
} else
INDEX("<img border=\"0\" src=\"inform:/doc_images/sound_okay.png\">&nbsp;");
}
HTML__next_html_column(ifl, 0);
Wordings__index_raw(bs->name);
Index__link(Wordings__first_wn(bs->name));
char rel[MAX_FILENAME_LENGTH];
Filenames__to_string_relative(rel, bs->filename_of_sound_file, pathname_of_area[MATERIALS_FS_AREA]);
INDEX("<br>\n%sFilename: \"%s\" - resource number %d", line2, rel, bs->sound_number);
HTML__end_html_row(ifl);
}
HTML__end_html_table(ifl);
INDEX("<p>");
}
#line 43 "inform7/Chapter 37/External Files.w"
void PL__Files__start(void) {
PLUGIN_REGISTER(PLUGIN_COMPILE_CONSTANT, PL__Files__files_compile_constant);
PLUGIN_REGISTER(PLUGIN_NEW_BASE_KIND_NOTIFY, PL__Files__files_new_base_kind_notify);
PLUGIN_REGISTER(PLUGIN_NEW_INSTANCE_NOTIFY, PL__Files__files_new_named_instance_notify);
}
#line 52 "inform7/Chapter 37/External Files.w"
int PL__Files__files_new_base_kind_notify(kind *new_base, char *name, wording W) {
if ((name) && (strcmp(name, "EXTERNAL_FILE_TY") == 0)) {
K_external_file = new_base; return TRUE;
}
return FALSE;
}
int allow_exf_creations = FALSE;
int PL__Files__files_new_named_instance_notify(instance *nc) {
if (K_external_file == NULL) return FALSE;
kind *K = Instances__to_kind(nc);
if (Kinds__Compare__eq(K, K_external_file)) {
if (allow_exf_creations == FALSE)
Problems__Issue__sentence_problem(_p_(PM_BackdoorFileCreation),
"this is not the way to create a new external file",
"which should be done with a special 'The File ... is called ...' "
"sentence.");
Instances__set_connection(nc,
STORE_POINTER_external_file(PL__Files__new_external_file(nc)));
return TRUE;
}
return FALSE;
}
#line 79 "inform7/Chapter 37/External Files.w"
external_file *PL__Files__new_external_file(instance *nc) {
external_file *exf = CREATE(external_file);
return exf;
}
#line 91 "inform7/Chapter 37/External Files.w"
int external_file_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[2];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = FALSE; ownership_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = TRUE; ownership_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = FALSE; ownership_NTMV = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 96 "inform7/Chapter 37/External Files.w"
int external_file_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = NOT_APPLICABLE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 100 "inform7/Chapter 37/External Files.w"
int external_file_owner_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = FALSE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = TRUE;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 109 "inform7/Chapter 37/External Files.w"
*X = NOT_APPLICABLE;
Problems__Issue__sentence_problem(_p_(PM_BadFileOwner),
"the owner of this file is wrongly specified",
"since it is not one of the three possibilities - "
"(1) Specify nothing: making the file belong to this "
"project. (2) Specify only that it belongs to someone, "
"without saying whom: 'The File of Wisdom (owned by "
"another project) is called \"wisdom\".' (3) Specify "
"that it belongs to a project with a given double-quoted "
"IFID: 'The File of Wisdom (owned by project "
"\"4122DDA8-A153-46BC-8F57-42220F9D8795\") "
"is called \"wisdom\".'");
}
#line 104 "inform7/Chapter 37/External Files.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 105 "inform7/Chapter 37/External Files.w"
#line 127 "inform7/Chapter 37/External Files.w"
int external_file_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1:
{
#line 134 "inform7/Chapter 37/External Files.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_FilenameNotTextual),
"a file can only be called with a single quoted piece of text",
"as in: 'The File of Wisdom is called \"wisdom\".'");
}
#line 129 "inform7/Chapter 37/External Files.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 130 "inform7/Chapter 37/External Files.w"
#line 142 "inform7/Chapter 37/External Files.w"
sentence_handler FILE_SH_handler =
{ SENTENCE_NT, FILE_VB, 1, PL__Files__handle_file_definition };
void PL__Files__handle_file_definition(parse_node *p) {
if (Plugins__Manage__plugged_in(files_plugin) == FALSE)
internal_error("Files plugin inactive");
PL__Files__register_file(ParseTree__get_text(p->down->next), ParseTree__get_text(p->down->next->next));
}
void PL__Files__register_file(wording F, wording FN) {
int bad_filename = FALSE;
Preform__parse_nt_against_word_range(external_file_sentence_object_NTM, FN, NULL, NULL);
FN = Wordings__from(FN, most_recent_result);
if (Wordings__empty(FN)) return;
char *p = Lexer__word_text(Wordings__first_wn(FN));
if (Platform__strlen(p) < 5) bad_filename = TRUE;
if (isalpha(p[1]) == FALSE) bad_filename = TRUE;
for (int i=0; p[i]; i++) {
if (p[i] == '"') {
if ((i==0) || (p[i+1] == 0)) continue;
}
if (i>24) bad_filename = TRUE;
if ((isalpha(p[i])) || (isdigit(p[i]))) continue;
LOG("Objected to character %c\n", p[i]);
bad_filename = TRUE;
}
if (bad_filename) {
LOG("Filename: %s\n", p);
Problems__Issue__sentence_problem(_p_(PM_FilenameUnsafe),
"filenames must be very conservatively chosen",
"in order to be viable on a wide range of computers. They must "
"consist of 3 to 23 English letters or digits, with the first being "
"a letter. Spaces are not allowed, and nor are periods. (A file "
"extension, such as '.glkdata', may be added on some platforms "
"automatically: this is invisible to Inform.)");
return;
}
int ownership = OWNED_BY_THIS_PROJECT;
char ifid_of_file[48];
ifid_of_file[0] = 0;
if (Preform__parse_nt_against_word_range(external_file_sentence_subject_NTM, F, NULL, NULL) == FALSE) internal_error("bad ef grammar");
F = GET_RW(external_file_name_NTM, 1);
int binary = most_recent_result;
if (ownership_NTMV == TRUE) {
wording OW = GET_RW(external_file_owner_NTM, 1);
int j, invalid = FALSE;
p = Lexer__word_text(Wordings__last_wn(OW));
for (j=1; (j<47) && (p[j]); j++) {
if ((p[j] == '"') && (p[j+1] == 0)) break;
ifid_of_file[j-1] = p[j];
if ((isalpha(p[j])) || (isdigit(p[j]))) continue;
if (p[j] == '-') continue;
invalid = TRUE;
LOG("Objected to character %c\n", p[j]);
}
ifid_of_file[j-1] = 0;
if ((invalid) || (j==47)) {
Problems__Issue__sentence_problem(_p_(PM_BadFileIFID),
"the owner of the file should be specified "
"using a valid double-quoted IFID",
"as in: 'The File of Wisdom (owned by project "
"\"4122DDA8-A153-46BC-8F57-42220F9D8795\") "
"is called \"wisdom\".'");
} else
ownership = OWNED_BY_SPECIFIC_PROJECT;
}
if (ownership_NTMV == FALSE) {
ownership = OWNED_BY_ANOTHER_PROJECT;
}
Assertions__Creator__vet_name_for_noun(F);
if ((Preform__parse_nt_against_word_range(s_value_NTM, F, NULL, NULL)) &&
(Rvalues__is_CONSTANT_of_kind(most_recent_result_p, K_external_file))) {
Problems__Issue__sentence_problem(_p_(PM_FilenameDuplicate),
"this is already the name of a file",
"so there must be some duplication somewhere.");
return;
}
allow_exf_creations = TRUE;
pcalc_prop *prop = Calculus__Propositions__Abstract__to_create_something(
K_external_file, F);
Calculus__Propositions__Assert__assert_true(prop, CERTAIN_CE);
allow_exf_creations = FALSE;
external_file *exf = RETRIEVE_POINTER_external_file(
Instances__get_connection(latest_instance));
exf->name = F;
exf->unextended_filename = Wordings__first_wn(FN);
exf->file_is_binary = binary;
exf->file_ownership = ownership;
strcpy(exf->IFID_of_owner, ifid_of_file);
LOGIF(FIGURE_CREATIONS, "Created external file <$w> = filename '%s'\n",
F, Lexer__word_text(exf->unextended_filename));
Identifiers__compose(exf->exf_I6_identifier, 'X', exf->allocation_id, exf->name);
}
#line 246 "inform7/Chapter 37/External Files.w"
int PL__Files__files_compile_constant(OUTPUT_STREAM, kind *K, parse_node *spec) {
if (Plugins__Manage__plugged_in(files_plugin) == FALSE)
internal_error("files plugin inactive");
wording W = ParseTree__get_text(spec);
if ((Kinds__Compare__eq(K, K_external_file)) && (Preform__parse_nt_against_word_range(s_literal_NTM, W, NULL, NULL))) {
internal_error("LAMIA");
external_file *exf;
LOOP_OVER(exf, external_file) {
if (exf->allocation_id == most_recent_result) {
WRITE("%s", exf->exf_I6_identifier);
return TRUE;
}
}
}
return FALSE;
}
#line 266 "inform7/Chapter 37/External Files.w"
void PL__Files__arrays(OUTPUT_STREAM) {
if (Plugins__Manage__plugged_in(files_plugin) == FALSE) return;
external_file *exf;
WRITE("Constant NO_EXTERNAL_FILES %d;\n", NUMBER_CREATED(external_file));
WRITE("Array TableOfExternalFiles --> 0 ");
LOOP_OVER(exf, external_file) WRITE("%s ", exf->exf_I6_identifier);
WRITE("0;\n");
LOOP_OVER(exf, external_file) {
WRITE("Array %s --> AUXF_MAGIC_VALUE AUXF_STATUS_IS_CLOSED %s 0\n",
exf->exf_I6_identifier,
(exf->file_is_binary)?"true":"false");
INDENT;
WRITE("%s ", Lexer__word_raw_text(exf->unextended_filename));
switch (exf->file_ownership) {
case OWNED_BY_THIS_PROJECT:
WRITE("UUID_ARRAY;\n");
break;
case OWNED_BY_ANOTHER_PROJECT:
WRITE("NULL;\n");
break;
case OWNED_BY_SPECIFIC_PROJECT:
WRITE("IFID_ARRAY_%d;\n", exf->allocation_id);
WRITE("Array IFID_ARRAY_%d string \"//%s//\";\n",
exf->allocation_id, exf->IFID_of_owner);
break;
}
OUTDENT;
}
}
#line 300 "inform7/Chapter 37/External Files.w"
void PL__Files__index_all(void) {
if (Plugins__Manage__plugged_in(files_plugin) == FALSE) return;
external_file *exf;
if (NUMBER_CREATED(external_file) == 0) {
INDEX("<p>This project doesn't read or write external files.</p>");
return;
}
INDEX("<p><b>List of External Files</b></p>\n");
HTML__begin_html_table(ifl, "#ffffff", TRUE, 0, 0, 0, 0, 0);
LOOP_OVER(exf, external_file) {
HTML__first_html_column(ifl, THUMBNAIL_WIDTH+10);
if (exf->file_is_binary)
INDEX("<img border=\"0\" src=\"inform:/doc_images/exf_binary.png\">&nbsp;");
else {
INDEX("<img border=\"0\" src=\"inform:/doc_images/exf_text.png\">&nbsp;");
}
HTML__next_html_column(ifl, 0);
Wordings__index_raw(exf->name);
Index__link(Wordings__first_wn(exf->name));
INDEX("<br>\nFilename: %s %s- owned by ",
(exf->file_is_binary)?"- binary ":"",
Lexer__word_text(exf->unextended_filename));
switch (exf->file_ownership) {
case OWNED_BY_THIS_PROJECT: INDEX("this project"); break;
case OWNED_BY_ANOTHER_PROJECT: INDEX("another project"); break;
case OWNED_BY_SPECIFIC_PROJECT:
INDEX("project with IFID number <b>%s</b>",
exf->IFID_of_owner);
break;
}
HTML__end_html_row(ifl);
}
HTML__end_html_table(ifl);
INDEX("<p>");
}
#line 12 "inform7/Chapter 38/Main Routine.w"
#ifndef SUPPRESS_MAIN
int main(int argc, char *argv[]) {
return Main__core_inform_main(argc, argv);
}
#endif
#line 29 "inform7/Chapter 38/Main Routine.w"
int Main__core_inform_main(int argc, char *argv[]) {
int report_clock_time = FALSE;
clock_t start = clock();
{
#line 54 "inform7/Chapter 38/Main Routine.w"
time_t right_now = time(NULL);
long long int rni = (long long int) right_now;
if (rni < 0) right_now = (time_t) 0;
the_present = localtime(&right_now);
}
#line 33 "inform7/Chapter 38/Main Routine.w"
;
{
#line 62 "inform7/Chapter 38/Main Routine.w"
WRITE_TO(STDOUT, "%s build %s has started.\n", NI_VERSION, NI_BUILD);
STREAM_FLUSH(STDOUT);
Memory__start();
Pathnames__start();
}
#line 34 "inform7/Chapter 38/Main Routine.w"
;
if (argc <= 1) return 0;
{
#line 72 "inform7/Chapter 38/Main Routine.w"
for (int a = 1; a < argc; a++) {
char *option = argv[a];
if ((option[0] == '-') && (option[1] == '-')) option++;
char *val;
if ((val = Main__cli_pair("-format", option)) != 0) story_filename_extension = val;
else if ((val = Main__cli_pair("-log", option)) != 0) Log__set_aspect_from_command_line(val);
else if (strcmp("-census", option) == 0) census_mode = TRUE;
else if (strcmp("-clock", option) == 0) report_clock_time = TRUE;
else if (strcmp("-gdb", option) == 0) crash_on_internal_errors = TRUE;
else if (strcmp("-gdball", option) == 0) crash_on_all_errors = TRUE;
else if (strcmp("-noindex", option) == 0) do_not_generate_index = TRUE;
else if (strcmp("-noprogress", option) == 0) show_progress_indicator = FALSE;
else if (strcmp("-release", option) == 0) this_is_a_release_compile = TRUE;
else if (strcmp("-rng", option) == 0) rng_seed_at_start_of_play = -16339;
else if (strcmp("-scoring", option) == 0) default_scoring_setting = TRUE;
else if (strcmp("-sigils", option) == 0) echo_problem_message_sigils = TRUE;
else if ((strcmp("-case", option) == 0) && (a+1 < argc)) {
HTML__set_source_link_case(argv[a+1]); a++;
}
else if (strcmp("-case B", option) == 0) {
HTML__set_source_link_case("B");
}
else if ((option[0] == '-') && (a+1 < argc) &&
(Locations__command_line_setting(option, argv[a+1]))) a++;
else if (!((option[0] != '-') &&
(Locations__command_line_setting(NULL, option)))) {
fprintf(stderr, "Unknown: %s\n", option);
Problems__Fatal__issue("Unknown parameter at the command line");
}
}
}
#line 38 "inform7/Chapter 38/Main Routine.w"
;
{
#line 109 "inform7/Chapter 38/Main Routine.w"
VirtualMachines__set_identifier(story_filename_extension);
if (Locations__set_defaults(census_mode) == FALSE)
Problems__Fatal__issue("Unable to create folders in local file system");
Log__open();
LOG("Inform called as:");
for (int i=0; i<argc; i++) LOG(" %s", argv[i]);
LOG("\n");
}
#line 39 "inform7/Chapter 38/Main Routine.w"
;
TemplateFiles__interpret(NULL, NULL, "Main.i6t", -1);
clock_t end = clock();
int cpu_time_used = ((int) (end - start)) / (CLOCKS_PER_SEC/100);
{
#line 120 "inform7/Chapter 38/Main Routine.w"
Problems__write_reports(FALSE);
Memory__free_memory();
LOG("Total of %d files written as streams.\n", total_file_writes);
LOG("CPU time: %d centiseconds\n", cpu_time_used);
Log__close();
WRITE_TO(STDOUT, "%s has finished", NI_VERSION);
if (report_clock_time)
WRITE_TO(STDOUT, ": %d centiseconds used", cpu_time_used);
WRITE_TO(STDOUT, ".\n");
}
#line 46 "inform7/Chapter 38/Main Routine.w"
;
if (problem_count > 0) return 1; return 0;
}
#line 136 "inform7/Chapter 38/Main Routine.w"
char *Main__cli_pair(char *wanted, char *got) {
int i;
if (Platform__strlen(wanted)+1 >= Platform__strlen(got)) return NULL;
for (i=0; wanted[i]; i++) if (wanted[i] != got[i]) return NULL;
if (got[i] != '=') return NULL;
return got+i+1;
}
#line 27 "inform7/Chapter 38/Translate to Identifiers.w"
sentence_handler TRANSLATES_SH_handler =
{ SENTENCE_NT, TRANSLATES_VB, 0, IdentifierTranslations__as };
#line 36 "inform7/Chapter 38/Translate to Identifiers.w"
int translates_into_i6_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = PROPERTY_I6TR;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = NAMETAG_I6TR;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2: *X = RULE_I6TR;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 3: *X = VARIABLE_I6TR;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 4: *X = ACTION_I6TR;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 5: *X = GRAMMAR_TOKEN_I6TR;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 6:
{
#line 48 "inform7/Chapter 38/Translate to Identifiers.w"
*X = INVALID_I6TR;
Problems__Issue__sentence_problem(_p_(PM_TranslatedUnknownCategory),
"that isn't one of the things which can be translated to I6",
"and should be '... variable', '... property', '... object', "
"'... kind', '... rule', or '... action'. For instance, 'The yourself "
"object translates into I6 as \"selfobj\".'");
}
#line 43 "inform7/Chapter 38/Translate to Identifiers.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 44 "inform7/Chapter 38/Translate to Identifiers.w"
#line 61 "inform7/Chapter 38/Translate to Identifiers.w"
int translates_into_i6_sentence_object_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[1]; *XP = RP[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1]; *XP = NULL;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 64 "inform7/Chapter 38/Translate to Identifiers.w"
#line 68 "inform7/Chapter 38/Translate to Identifiers.w"
void IdentifierTranslations__as(parse_node *pn) {
parse_node *p1 = pn->down->next;
parse_node *p2 = pn->down->next->next;
parse_node *responses_list = NULL;
int category = INVALID_I6TR;
Preform__parse_nt_against_word_range(translates_into_i6_sentence_subject_NTM, ParseTree__get_text(p1), NULL, NULL);
category = most_recent_result;
if (category == INVALID_I6TR) return;
wording W = GET_RW(translates_into_i6_sentence_subject_NTM, 1);
if (traverse == 1) {
ParseTree__annotate_int(pn, category_of_I6_translation_ANNOT, INVALID_I6TR);
{
#line 112 "inform7/Chapter 38/Translate to Identifiers.w"
int valid = TRUE;
if (Preform__parse_nt_against_word_range(translates_into_i6_sentence_object_NTM, ParseTree__get_text(p2), NULL, NULL) == FALSE) valid = FALSE;
else responses_list = most_recent_result_p;
if (valid)
{
#line 128 "inform7/Chapter 38/Translate to Identifiers.w"
int wn = Wordings__first_wn(ParseTree__get_text(p2));
ParseTree__set_text(p2, Wordings__one_word(wn));
Text__dequote_word(wn);
if (valid) valid = Identifiers__valid(Lexer__word_text(wn));
}
#line 115 "inform7/Chapter 38/Translate to Identifiers.w"
;
if (valid == FALSE) {
Problems__Issue__sentence_problem(_p_(PM_TranslatedToNonIdentifier),
"Inform 7 constructions can only translate into quoted I6 identifiers",
"which must be strings of 1 to 31 characters drawn from 1, 2, ..., 9, "
"a or A, b or B, ..., z or Z, or underscore '_', except that the "
"first character is not allowed to be a digit.");
return;
}
}
#line 80 "inform7/Chapter 38/Translate to Identifiers.w"
;
ParseTree__annotate_int(pn, category_of_I6_translation_ANNOT, category);
if (responses_list) ParseTree__graft(responses_list, p2);
} else category = ParseTree__int_annotation(pn, category_of_I6_translation_ANNOT);
{
#line 92 "inform7/Chapter 38/Translate to Identifiers.w"
switch(category) {
case PROPERTY_I6TR:
Properties__translates(W, p2);
ParseTree__annotate_int(pn, category_of_I6_translation_ANNOT, INVALID_I6TR); break;
case NAMETAG_I6TR: break;
case RULE_I6TR:
if (traverse == 1) Rules__Placement__declare_I6_written_rule(W, p2);
if ((traverse == 2) && (p2->down) && (Preform__parse_nt_against_word_range(rule_name_NTM, W, NULL, NULL)))
IdentifierTranslations__plus_responses(p2->down, most_recent_result_p);
break;
case VARIABLE_I6TR: if (traverse == 2) NonlocalVariables__translates(W, p2); break;
case ACTION_I6TR: if (traverse == 2) PL__Actions__translates(W, p2); break;
case GRAMMAR_TOKEN_I6TR: if (traverse == 2) PL__Parsing__Verbs__translates(W, p2); break;
}
}
#line 85 "inform7/Chapter 38/Translate to Identifiers.w"
;
}
#line 136 "inform7/Chapter 38/Translate to Identifiers.w"
int extra_response_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = R[2];;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 138 "inform7/Chapter 38/Translate to Identifiers.w"
#line 142 "inform7/Chapter 38/Translate to Identifiers.w"
void IdentifierTranslations__plus_responses(parse_node *p, rule *R) {
if (ParseTree__get_type(p) == AND_NT) {
IdentifierTranslations__plus_responses(p->down, R);
IdentifierTranslations__plus_responses(p->down->next, R);
} else {
if (Preform__parse_nt_against_word_range(extra_response_NTM, ParseTree__get_text(p), NULL, NULL)) {
int code = most_recent_result;
response_message *resp = Strings__response_cue(NULL, R,
code, ParseTree__get_text(p), NULL, TRUE);
Rules__now_rule_defines_response(R, code, resp);
} else {
Problems__Issue__sentence_problem(_p_(PM_I6ResponsesAwry),
"additional information about I6 translation of a rule can "
"only take the form of a list of responses",
"each quoted and followed by a bracketed letter.");
}
}
}
#line 160 "inform7/Chapter 38/I6 Template Interpreter.w"
int no_segments_noted = 0;
void TemplateFiles__interpret(OUTPUT_STREAM, unsigned char *sf, char *segment_name, int N_escape) {
FILE *Input_File = NULL;
char default_command[MAX_I6T_COMMAND_LENGTH]; default_command[0] = 0;
char heading_name[MAX_I6T_LINE_LENGTH+1]; heading_name[0] = 0;
int active = TRUE, closed = FALSE, indexing = FALSE, skip_part = FALSE, comment = TRUE;
int no_phases = 0, col = 1, cr, sfp = 0;
if (segment_name) TemplateFiles__I6T_file_intervene(OUT, -1, segment_name, NULL);
if ((segment_name) && (TemplateFiles__I6T_file_intervene(OUT, 0, segment_name, NULL))) goto OmitFile;
if (segment_name) {
{
#line 253 "inform7/Chapter 38/I6 Template Interpreter.w"
Input_File = NULL;
for (int area=0; area<NO_FS_AREAS; area++)
if (Input_File == NULL)
Input_File = Platform__iso_fopen(
Filenames__in_folder(pathname_of_i6t_files[area], segment_name), "r");
if (Input_File == NULL) {
if (strcmp(segment_name, "Main.i6t") == 0)
Problems__Fatal__issue_t("Error: can't open input file", segment_name);
WRITE_TO(STDERR, "inform: Unable to open segment <%s>\n", segment_name);
Problems__Issue__unlocated_problem(_p_(BelievedImpossible), /* or anyway not usefully testable */
"I couldn't open a requested I6T segment: see the console "
"output for details.");
}
}
#line 173 "inform7/Chapter 38/I6 Template Interpreter.w"
;
comment = TRUE;
} else comment = FALSE;
do {
{
#line 275 "inform7/Chapter 38/I6 Template Interpreter.w"
if (Input_File) cr = fgetc(Input_File);
else if (sf) {
cr = sf[sfp]; if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 178 "inform7/Chapter 38/I6 Template Interpreter.w"
;
NewCharacter: if (cr == EOF) break;
char I6T_buffer[MAX_I6T_LINE_LENGTH+1]; /* storage for an I6T command */
char *command = "", *argument = "";
if (abort_I6T_interpreter) { /* in effect, if Inform has thrown an exception */
fclose(Input_File); exit(0);
}
if ((cr == '@') && (col == 1)) {
int inweb_syntax = -1;
{
#line 290 "inform7/Chapter 38/I6 Template Interpreter.w"
int i = 0, committed = FALSE, unacceptable_character = FALSE;
while (i<MAX_I6T_LINE_LENGTH) {
{
#line 275 "inform7/Chapter 38/I6 Template Interpreter.w"
if (Input_File) cr = fgetc(Input_File);
else if (sf) {
cr = sf[sfp]; if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 292 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if ((committed == FALSE) && ((cr == 10) || (cr == 13) || (cr == ' '))) {
I6T_buffer[i] = 0;
if (strcmp(I6T_buffer, "p") == 0) inweb_syntax = INWEB_PARAGRAPH_SYNTAX;
else if (strcmp(I6T_buffer, "c") == 0) inweb_syntax = INWEB_CODE_SYNTAX;
else if (I6T_buffer[0] == '-') inweb_syntax = INWEB_DASH_SYNTAX;
else if (strncmp(I6T_buffer, "Purpose:", 8) == 0) inweb_syntax = INWEB_PURPOSE_SYNTAX;
committed = TRUE;
if (inweb_syntax == -1) {
if (unacceptable_character == FALSE) {
if ((OUT) && (active)) {
PUT_TO(OUT, '@');
int j;
for (j=0; j<i; j++) PUT_TO(OUT, I6T_buffer[j]);
PUT_TO(OUT, cr);
}
break;
} else {
LOG("heading begins: <%s>\n", I6T_buffer);
Problems__quote_text(1, I6T_buffer);
Problems__Issue__unlocated_problem(_p_(PM_BadTemplateAtSign),
"An unknown '@...' marker has been found at column 0 in "
"raw Inform 6 template material: specifically, '@%1'. ('@' "
"has a special meaning in this first column, and this "
"might clash with its use to introduce an assembly-language "
"opcode in Inform 6: if that's a problem, you can avoid it "
"simply by putting one or more spaces or tabs in front of "
"the opcode(s) to keep them clear of the left margin.)");
}
}
}
if (!(((cr >= 'A') && (cr <= 'Z')) || ((cr >= 'a') && (cr <= 'z'))
|| ((cr >= '0') && (cr <= '9'))
|| (cr == '-') || (cr == '>') || (cr == ':') || (cr == '_')))
unacceptable_character = TRUE;
if ((cr == 10) || (cr == 13)) break;
I6T_buffer[i++] = (char) cr;
}
I6T_buffer[i] = 0;
command = I6T_buffer;
}
#line 187 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 338 "inform7/Chapter 38/I6 Template Interpreter.w"
switch (inweb_syntax) {
case INWEB_PARAGRAPH_SYNTAX: {
int i;
if ((heading_name[0] != 0) && (segment_name))
TemplateFiles__I6T_file_intervene(OUT, 1, segment_name, heading_name);
strcpy(heading_name, command+2);
i = Platform__strlen(heading_name)-1;
while ((i>=0) &&
((heading_name[i] == ' ') || (heading_name[i] == '\t') || (heading_name[i] == '.'))) i--;
heading_name[i+1] = 0;
if (heading_name[0] == 0)
TemplateFiles__error("Empty heading name in I6 template file");
comment = TRUE; skip_part = FALSE;
if (segment_name) {
TemplateFiles__I6T_file_intervene(OUT, -1, segment_name, heading_name);
if (TemplateFiles__I6T_file_intervene(OUT, 0, segment_name, heading_name)) skip_part = TRUE;
}
if ((OUT) && (no_segments_noted++ > 0)) {
WRITE("\n! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====\n");
WRITE("! %s: %s%s\n", segment_name, heading_name,
(skip_part)?" (skipping)":"");
WRITE("! ==== ==== ==== ==== ==== ==== ==== ==== ==== ====\n\n");
}
break;
}
case INWEB_CODE_SYNTAX:
if (skip_part == FALSE) comment = FALSE;
break;
case INWEB_DASH_SYNTAX: break;
case INWEB_PURPOSE_SYNTAX: break;
}
}
#line 188 "inform7/Chapter 38/I6 Template Interpreter.w"
;
continue;
}
if (comment == FALSE) {
if (default_command[0] != 0) {
if ((cr == 10) || (cr == 13)) continue; /* skip blank lines here */
{
#line 376 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
strcpy(I6T_buffer, default_command);
command = I6T_buffer;
i = Platform__strlen(command)+1;
argument = command + i;
I6T_buffer[i++] = (char) cr;
while (i<MAX_I6T_LINE_LENGTH) {
{
#line 275 "inform7/Chapter 38/I6 Template Interpreter.w"
if (Input_File) cr = fgetc(Input_File);
else if (sf) {
cr = sf[sfp]; if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 383 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if ((cr == 10) || (cr == 13)) break;
I6T_buffer[i++] = (char) cr;
}
I6T_buffer[i] = 0;
while ((argument[0] == ' ') || (argument[0] == '\t')) argument++;
while ((I6T_buffer[i-1] == ' ') || (I6T_buffer[i-1] == '\t'))
I6T_buffer[--i] = 0;
}
#line 194 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if ((argument[0] == '!') || (argument[0] == 0)) continue; /* skip blanks and comments */
if (strcmp(argument, "{-endlines}") == 0) default_command[0] = 0;
else
{
#line 450 "inform7/Chapter 38/I6 Template Interpreter.w"
{
#line 492 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "open-file") == 0) {
if (OUT) TemplateFiles__error("output file already open");
if (STREAM_OPEN_TO_FILE(inform6_file, filename_of_compiled_i6_code, ISO_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open output file", filename_of_compiled_i6_code);
OUT = inform6_file;
continue;
}
if (strcmp(command, "close-file") == 0) {
if (OUT) STREAM_CLOSE(OUT);
OUT = NULL;
active = TRUE;
continue;
}
}
#line 450 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 511 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "lines") == 0) {
Extensions__IDs__truncated_strcpy(default_command, argument, MAX_I6T_COMMAND_LENGTH);
continue;
}
}
#line 451 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if (active == FALSE) continue;
if (strcmp(command, "segment") == 0) {
if ((existing_story_file) && (strcmp(argument, "Output.i6t") == 0))
TemplateFiles__interpret(OUT, NULL, "Output-Stub.i6t", -1);
else
TemplateFiles__interpret(OUT, NULL, argument, -1);
continue;
}
if (strcmp(command, "plugin") == 0) { Plugins__Manage__command(argument); continue; }
if (strcmp(command, "type") == 0) { Kinds__Interpreter__despatch_kind_command(argument); continue; }
{
#line 523 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "open-index") == 0) { indexing = TRUE; continue; }
if (strcmp(command, "close-index") == 0) { indexing = FALSE; continue; }
if ((indexing) && (do_not_generate_index)) continue;
if (strcmp(command, "index-page") == 0) { Index__new_page(argument); continue; }
if (strcmp(command, "index-element") == 0) {
int i;
char symbol[MAX_FILENAME_LENGTH];
strcpy(symbol, argument);
for (i=0; symbol[i]; i++)
if ((symbol[i] == ' ') || (symbol[i] == '=')) {
symbol[i] = 0; i++;
break;
}
symbol[2] = 0;
char titling[MAX_FILENAME_LENGTH], explanation[MAX_FILENAME_LENGTH];
strcpy(titling, argument+i); explanation[0] = 0;
for (i=0; titling[i]; i++)
if (titling[i] == '=') {
titling[i] = 0;
strcpy(explanation, titling+i+1); break;
}
titling[16] = 0;
Index__new_segment(symbol, titling, explanation); continue;
}
if (strcmp(command, "index") == 0) {
int i;
char leafname[MAX_FILENAME_LENGTH];
strcpy(leafname, argument);
for (i=0; leafname[i]; i++)
if ((leafname[i] == ' ') || (leafname[i] == '=')) {
leafname[i] = 0;
break;
}
strcpy(leafname+i, ".png");
char titling[MAX_FILENAME_LENGTH], explanation[MAX_FILENAME_LENGTH],
image[MAX_FILENAME_LENGTH], caption[MAX_FILENAME_LENGTH];
strcpy(image, leafname);
strcpy(leafname+i, ".html");
strcpy(titling, argument); explanation[0] = 0; caption[0] = 0;
for (i=0; titling[i]; i++)
if (titling[i] == '=') {
titling[i] = 0;
if (explanation[0] == 0) strcpy(explanation, titling+i+1);
else strcpy(caption, titling+i+1);
}
for (i=0; explanation[i]; i++)
if (explanation[i] == '=') {
explanation[i] = 0;
}
Index__set_thumbnail_image(image, caption);
Index__open_file(leafname, titling, -1, explanation);
continue;
}
}
#line 465 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 589 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "log") == 0) {
Log__new_stage_of_Informs_run(argument); continue;
}
if (strcmp(command, "log-phase") == 0) {
char *phase_names[] = {
"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X",
"XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX" };
Log__new_phase_of_Informs_run(phase_names[no_phases], argument);
if (no_phases < 19) no_phases++;
continue;
}
if (strcmp(command, "progress-stage") == 0) {
ProgressBar__update_progress_bar(atoi(argument), 0); continue;
}
}
#line 466 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 610 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "counter") == 0) {
if (OUT == NULL) continue;
WRITE("%d", JumpLabels__read_counter(argument, NOT_APPLICABLE)); continue;
}
}
#line 467 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 623 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "value") == 0) {
if (OUT == NULL) continue;
{
#line 841 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 625 "inform7/Chapter 38/I6 Template Interpreter.w"
;
ALLOW_VALUE(NUMBER_CREATED(action_name));
ALLOW_VALUE(NUMBER_CREATED(binary_predicate));
ALLOW_VALUE(NUMBER_CREATED(blorb_figure));
ALLOW_VALUE(NUMBER_CREATED(blorb_sound));
ALLOW_VALUE(NUMBER_CREATED(property));
ALLOW_VALUE(NUMBER_CREATED(rulebook));
ALLOW_VALUE(NUMBER_CREATED(scene));
ALLOW_VALUE(NUMBER_CREATED(test_scenario));
ALLOW_VALUE(extent_of_runtime_quotations_array);
ALLOW_VALUE(Instances__count(K_door));
ALLOW_VALUE(Instances__count(K_object));
ALLOW_VALUE(Instances__count(K_room));
ALLOW_VALUE(max_frame_size_needed);
ALLOW_VALUE(no_verb_verb_defined);
ALLOW_VALUE(rng_seed_at_start_of_play);
ALLOW_VALUE(default_scoring_setting);
LOG("command: <%s> argument: <%s>\n", command, argument);
TemplateFiles__error("Unknown {-value:...} value in I6 segment");
}
}
#line 468 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 658 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "read-assertions") == 0) {
if (strcmp(argument, "1") == 0) Assertions__Traverse__traverse(1);
if (strcmp(argument, "2") == 0) Assertions__Traverse__traverse(2);
if (problem_count > 0) active = FALSE;
continue;
}
}
#line 469 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 684 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "callv") == 0) {
{
#line 841 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 685 "inform7/Chapter 38/I6 Template Interpreter.w"
;
ALLOW_CALLV(Calculus__Deferrals__allow_no_further_deferrals);
ALLOW_CALLV(Chronology__allow_no_further_past_tenses);
ALLOW_CALLV(Phrases__Manager__add_rules_to_rulebooks);
ALLOW_CALLV(Phrases__Adjectives__traverse);
ALLOW_CALLV(Phrases__Index__index_page_Phrasebook);
ALLOW_CALLV(Phrases__Manager__parse_rule_parameters);
ALLOW_CALLV(Phrases__Manager__parse_rule_placements);
ALLOW_CALLV(Phrases__Manager__register_meanings);
ALLOW_CALLV(Phrases__Timed__check_for_unused);
ALLOW_CALLV(Phrases__Manager__traverse_for_names);
ALLOW_CALLV(Phrases__Manager__traverse);
ALLOW_CALLV(Rules__check_response_usages);
ALLOW_CALLV(Plugins__Manage__start);
ALLOW_CALLV(TemplateFiles__report_unacted_upon_interventions);
ALLOW_CALLV(Equations__index);
ALLOW_CALLV(Equations__traverse_to_create);
ALLOW_CALLV(Equations__traverse_to_stock);
ALLOW_CALLV(NonlocalVariables__index_all);
ALLOW_CALLV(Nametags__name_all);
ALLOW_CALLV(Strings__TextSubstitutions__allow_no_further_text_subs);
ALLOW_CALLV(Tables__check_tables_for_kind_clashes);
ALLOW_CALLV(Tables__complete);
ALLOW_CALLV(Tables__index);
ALLOW_CALLV(Tables__traverse_to_create);
ALLOW_CALLV(Tables__traverse_to_stock);
ALLOW_CALLV(Extensions__Files__check_versions);
ALLOW_CALLV(Extensions__Files__handle_census_mode);
ALLOW_CALLV(Extensions__Files__index);
ALLOW_CALLV(Extensions__Files__update_census);
ALLOW_CALLV(Extensions__Inclusion__traverse);
ALLOW_CALLV(Index__complete);
ALLOW_CALLV(Index__DocReferences__log_statistics);
ALLOW_CALLV(Memory__log_statistics);
ALLOW_CALLV(ParseTree__plant_parse_tree);
ALLOW_CALLV(ParseTree__write_to_file);
ALLOW_CALLV(ParseTree__write_main_source_to_log);
ALLOW_CALLV(ParseTree__verify);
ALLOW_CALLV(Sentences__break_source);
ALLOW_CALLV(Sentences__break_source);
ALLOW_CALLV(Sentences__RuleSubtrees__create_standard_csps);
ALLOW_CALLV(Sentences__declare_source_loaded);
ALLOW_CALLV(Sentences__Headings__index);
ALLOW_CALLV(Sentences__Headings__make_tree);
ALLOW_CALLV(Sentences__Headings__satisfy_dependencies);
ALLOW_CALLV(Sentences__Headings__write_as_xml);
ALLOW_CALLV(Sentences__RuleSubtrees__register_recently_lexed_phrases);
ALLOW_CALLV(Sentences__Rearrangement__tidy_up_ofs_and_froms);
ALLOW_CALLV(Sentences__VPs__traverse);
ALLOW_CALLV(SParser__debug_parser_statistics);
ALLOW_CALLV(PL__Actions__Index__page);
ALLOW_CALLV(PL__Actions__name_all);
ALLOW_CALLV(PL__Bibliographic__index_library_card);
ALLOW_CALLV(PL__Bibliographic__Release__write_ifiction_and_blurb);
ALLOW_CALLV(PL__Figures__index_all);
ALLOW_CALLV(PL__Files__index_all);
ALLOW_CALLV(PL__Parsing__traverse);
ALLOW_CALLV(PL__Parsing__Verbs__prepare);
ALLOW_CALLV(PL__Scenes__Index__index);
ALLOW_CALLV(PL__Sounds__index_all);
ALLOW_CALLV(Properties__ObjectImplementation__allocate_attributes);
ALLOW_CALLV(Properties__Measurement__validate_definitions);
ALLOW_CALLV(BinaryPredicates__make_built_in_further);
ALLOW_CALLV(BinaryPredicates__make_built_in);
ALLOW_CALLV(LiteralPatterns__define_named_phrases);
ALLOW_CALLV(Quantifiers__make_built_in);
ALLOW_CALLV(Verbs__log_all);
ALLOW_CALLV(Verbs__stock);
ALLOW_CALLV(Preform__log_language);
ALLOW_CALLV(Preform__read_definition);
ALLOW_CALLV(SourceFiles__read_primary_source_text);
ALLOW_CALLV(Lexer__start);
ALLOW_CALLV(Plurals__traverse_for_definitions);
ALLOW_CALLV(Kinds__Interpreter__include_templates_for_kinds);
ALLOW_CALLV(Kinds__Interpreter__batch_done);
ALLOW_CALLV(Kinds__Interpreter__start);
ALLOW_CALLV(InferenceSubjects__begin);
ALLOW_CALLV(World__complete_additions);
ALLOW_CALLV(World__complete);
ALLOW_CALLV(Data__Objects__page_Kinds);
ALLOW_CALLV(Data__Objects__page_World);
LOG("command: <%s> argument: <%s>\n", command, argument);
TemplateFiles__error("Unknown {-callv:...} function in I6 segment");
}
}
#line 470 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 778 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "call") == 0) {
if (OUT == NULL) continue;
{
#line 841 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 780 "inform7/Chapter 38/I6 Template Interpreter.w"
;
ALLOW_CALL(Calculus__Propositions__Deferred__compile_remaining_deferred);
ALLOW_CALL(Activities__compile_activity_constants);
ALLOW_CALL(Chronology__chronology_extents_i6_escape);
ALLOW_CALL(Chronology__past_actions_i6_routines);
ALLOW_CALL(Chronology__past_tenses_i6_escape);
ALLOW_CALL(Phrases__Manager__compile_first_block);
ALLOW_CALL(Phrases__Manager__compile_rule_printing_switch);
ALLOW_CALL(Phrases__Manager__compile_rulebooks);
ALLOW_CALL(Phrases__Manager__compile_as_needed);
ALLOW_CALL(Phrases__Constants__compile_closures);
ALLOW_CALL(Rulebooks__rulebook_var_creators_lookup);
ALLOW_CALL(UseOptions__compile_icl_commands);
ALLOW_CALL(UseOptions__compile);
ALLOW_CALL(Plugins__Manage__define_IFDEF_symbols);
ALLOW_CALL(TemplateFiles__compile_build_number);
ALLOW_CALL(Equations__compile);
ALLOW_CALL(Lists__check);
ALLOW_CALL(Lists__compile);
ALLOW_CALL(Strings__compile_responses);
ALLOW_CALL(Strings__TextLiterals__compile);
ALLOW_CALL(Tables__Support__compile_max_score);
ALLOW_CALL(Tables__Support__compile_print_table_names);
ALLOW_CALL(Tables__Support__compile);
ALLOW_CALL(JumpLabels__compile_necessary_storage);
ALLOW_CALL(PL__Actions__compile_action_routines);
ALLOW_CALL(PL__Actions__Patterns__Named__compile);
ALLOW_CALL(PL__Bibliographic__compile_constants);
ALLOW_CALL(PL__Files__arrays);
ALLOW_CALL(PL__Parsing__TestScripts__compile_printout);
ALLOW_CALL(PL__Parsing__TestScripts__compile_switch);
ALLOW_CALL(PL__Parsing__TestScripts__write_text);
ALLOW_CALL(PL__Parsing__Tokens__Filters__compile);
ALLOW_CALL(PL__Parsing__Tokens__Values__compile_type_gprs);
ALLOW_CALL(PL__Parsing__Tokens__Values__number);
ALLOW_CALL(PL__Parsing__Tokens__Values__time);
ALLOW_CALL(PL__Parsing__Tokens__Values__truth_state);
ALLOW_CALL(PL__Parsing__Verbs__compile_all);
ALLOW_CALL(PL__Parsing__Verbs__compile_conditions);
ALLOW_CALL(Properties__alias_translations);
ALLOW_CALL(Properties__ObjectImplementation__compile_attributes);
ALLOW_CALL(Properties__ObjectImplementation__compile_stub_properties);
ALLOW_CALL(Properties__Measurement__compile_MADJ_routines);
ALLOW_CALL(Adjectives__Meanings__agreements);
ALLOW_CALL(Relations__compile_defined_relations);
ALLOW_CALL(Relations__compile_defined_relation_constants);
ALLOW_CALL(Relations__relations_command);
ALLOW_CALL(Kinds__RunTime__compile_data_type_support_routines);
ALLOW_CALL(Kinds__RunTime__compile_heap_allocator);
ALLOW_CALL(Kinds__Constructors__compile_I6_constants);
ALLOW_CALL(Kinds__RunTime__compile_structures);
ALLOW_CALL(Kinds__RunTime__compile_block_constants);
ALLOW_CALL(PL__Showme__compile_SHOWME_details);
ALLOW_CALL(World__Compile__compile);
LOG("command: <%s> argument: <%s>\n", command, argument);
TemplateFiles__error("Unknown {-call:...} function in I6 segment");
}
}
#line 471 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 855 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "array") == 0) {
if (OUT == NULL) continue;
{
#line 841 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 857 "inform7/Chapter 38/I6 Template Interpreter.w"
;
ALLOW_ARRAY(PL__Actions__ActionCoding);
ALLOW_ARRAY(PL__Actions__ActionData);
ALLOW_ARRAY(PL__Actions__ActionHappened);
ALLOW_ARRAY(Activities__Activity_after_rulebooks);
ALLOW_ARRAY(Activities__Activity_atb_rulebooks);
ALLOW_ARRAY(Activities__Activity_before_rulebooks);
ALLOW_ARRAY(Activities__activity_var_creators);
ALLOW_ARRAY(Activities__Activity_for_rulebooks);
ALLOW_ARRAY(Phrases__Manager__TimedEventsTable);
ALLOW_ARRAY(Phrases__Manager__TimedEventTimesTable);
ALLOW_ARRAY(PL__Player__InitialSituation);
ALLOW_ARRAY(Properties__ObjectImplementation__property_metadata);
ALLOW_ARRAY(Rulebooks__rulebook_var_creators);
ALLOW_ARRAY(Phrases__Manager__RulebookNames);
ALLOW_ARRAY(Phrases__Manager__rulebooks_array);
ALLOW_ARRAY(PL__Figures__tableoffigures);
ALLOW_ARRAY(PL__Sounds__tableofsounds);
ALLOW_ARRAY(PL__Bibliographic__IFID__UUID_ARRAY);
LOG("command: <%s> argument: <%s>\n", command, argument);
TemplateFiles__error("Unknown {-array:...} function in I6 segment");
}
}
#line 472 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 888 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "routine") == 0) {
if (OUT == NULL) continue;
{
#line 841 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 890 "inform7/Chapter 38/I6 Template Interpreter.w"
;
ALLOW_ROUTINE(Properties__ObjectImplementation__CreatePropertyOffsets);
ALLOW_ROUTINE(Kinds__RunTime__I7_Kind_Name);
ALLOW_ROUTINE(Rulebooks__Outcomes__RulebookOutcomePrintingRule);
ALLOW_ROUTINE(PL__Scenes__DetectSceneChange);
ALLOW_ROUTINE(PL__Scenes__ShowSceneStatus);
ALLOW_ROUTINE(PL__Scenes__PrintSceneName);
ALLOW_ROUTINE(Extensions__Files__ShowExtensionVersions);
ALLOW_ROUTINE(UseOptions__TestUseOption);
ALLOW_ROUTINE(PL__Parsing__Lines__MistakeActionSub);
ALLOW_ROUTINE(PL__Parsing__TestScripts__InternalTestCases);
ALLOW_ROUTINE(Verbs__ConjugateVerb);
LOG("command: <%s> argument: <%s>\n", command, argument);
TemplateFiles__error("Unknown {-routine:...} function in I6 segment");
}
}
#line 473 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 912 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "testing-command") == 0) {
if (OUT == NULL) continue;
PL__Parsing__Verbs__reserve(argument);
WRITE("Verb meta '%s'\n", argument);
continue;
}
}
#line 474 "inform7/Chapter 38/I6 Template Interpreter.w"
;
LOG("command: <%s> argument: <%s>\n", command, argument);
Problems__quote_text(1, command);
Problems__Issue__unlocated_problem(_p_(PM_BadTemplateInsertion),
"In an explicit Inform 6 code insertion, I recognise a few special "
"notations in the form '{-command}'. This time, though, the unknown notation "
"{-%1} has been used, and this is an error. (It seems very unlikely indeed "
"that this could be legal Inform 6 which I'm misreading, but if so, try "
"adjusting the spacing to make this problem message go away.)");
}
#line 197 "inform7/Chapter 38/I6 Template Interpreter.w"
;
continue;
}
if (cr == '{') {
{
#line 275 "inform7/Chapter 38/I6 Template Interpreter.w"
if (Input_File) cr = fgetc(Input_File);
else if (sf) {
cr = sf[sfp]; if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 201 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if (cr == '-') {
{
#line 397 "inform7/Chapter 38/I6 Template Interpreter.w"
int i=0;
while (i<MAX_I6T_LINE_LENGTH) {
{
#line 275 "inform7/Chapter 38/I6 Template Interpreter.w"
if (Input_File) cr = fgetc(Input_File);
else if (sf) {
cr = sf[sfp]; if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 399 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if ((cr == '}') || (cr == EOF)) break;
I6T_buffer[i++] = (char) cr;
}
I6T_buffer[i] = 0;
command = I6T_buffer;
for (i=0; I6T_buffer[i]; i++)
if (I6T_buffer[i] == ':') {
I6T_buffer[i] = 0;
argument = I6T_buffer+i+1;
break;
}
}
#line 203 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if (command[0] == '!') continue;
{
#line 450 "inform7/Chapter 38/I6 Template Interpreter.w"
{
#line 492 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "open-file") == 0) {
if (OUT) TemplateFiles__error("output file already open");
if (STREAM_OPEN_TO_FILE(inform6_file, filename_of_compiled_i6_code, ISO_ENC) == FALSE)
Problems__Fatal__filename_related("Can't open output file", filename_of_compiled_i6_code);
OUT = inform6_file;
continue;
}
if (strcmp(command, "close-file") == 0) {
if (OUT) STREAM_CLOSE(OUT);
OUT = NULL;
active = TRUE;
continue;
}
}
#line 450 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 511 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "lines") == 0) {
Extensions__IDs__truncated_strcpy(default_command, argument, MAX_I6T_COMMAND_LENGTH);
continue;
}
}
#line 451 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if (active == FALSE) continue;
if (strcmp(command, "segment") == 0) {
if ((existing_story_file) && (strcmp(argument, "Output.i6t") == 0))
TemplateFiles__interpret(OUT, NULL, "Output-Stub.i6t", -1);
else
TemplateFiles__interpret(OUT, NULL, argument, -1);
continue;
}
if (strcmp(command, "plugin") == 0) { Plugins__Manage__command(argument); continue; }
if (strcmp(command, "type") == 0) { Kinds__Interpreter__despatch_kind_command(argument); continue; }
{
#line 523 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "open-index") == 0) { indexing = TRUE; continue; }
if (strcmp(command, "close-index") == 0) { indexing = FALSE; continue; }
if ((indexing) && (do_not_generate_index)) continue;
if (strcmp(command, "index-page") == 0) { Index__new_page(argument); continue; }
if (strcmp(command, "index-element") == 0) {
int i;
char symbol[MAX_FILENAME_LENGTH];
strcpy(symbol, argument);
for (i=0; symbol[i]; i++)
if ((symbol[i] == ' ') || (symbol[i] == '=')) {
symbol[i] = 0; i++;
break;
}
symbol[2] = 0;
char titling[MAX_FILENAME_LENGTH], explanation[MAX_FILENAME_LENGTH];
strcpy(titling, argument+i); explanation[0] = 0;
for (i=0; titling[i]; i++)
if (titling[i] == '=') {
titling[i] = 0;
strcpy(explanation, titling+i+1); break;
}
titling[16] = 0;
Index__new_segment(symbol, titling, explanation); continue;
}
if (strcmp(command, "index") == 0) {
int i;
char leafname[MAX_FILENAME_LENGTH];
strcpy(leafname, argument);
for (i=0; leafname[i]; i++)
if ((leafname[i] == ' ') || (leafname[i] == '=')) {
leafname[i] = 0;
break;
}
strcpy(leafname+i, ".png");
char titling[MAX_FILENAME_LENGTH], explanation[MAX_FILENAME_LENGTH],
image[MAX_FILENAME_LENGTH], caption[MAX_FILENAME_LENGTH];
strcpy(image, leafname);
strcpy(leafname+i, ".html");
strcpy(titling, argument); explanation[0] = 0; caption[0] = 0;
for (i=0; titling[i]; i++)
if (titling[i] == '=') {
titling[i] = 0;
if (explanation[0] == 0) strcpy(explanation, titling+i+1);
else strcpy(caption, titling+i+1);
}
for (i=0; explanation[i]; i++)
if (explanation[i] == '=') {
explanation[i] = 0;
}
Index__set_thumbnail_image(image, caption);
Index__open_file(leafname, titling, -1, explanation);
continue;
}
}
#line 465 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 589 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "log") == 0) {
Log__new_stage_of_Informs_run(argument); continue;
}
if (strcmp(command, "log-phase") == 0) {
char *phase_names[] = {
"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X",
"XI", "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XVIII", "XIX", "XX" };
Log__new_phase_of_Informs_run(phase_names[no_phases], argument);
if (no_phases < 19) no_phases++;
continue;
}
if (strcmp(command, "progress-stage") == 0) {
ProgressBar__update_progress_bar(atoi(argument), 0); continue;
}
}
#line 466 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 610 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "counter") == 0) {
if (OUT == NULL) continue;
WRITE("%d", JumpLabels__read_counter(argument, NOT_APPLICABLE)); continue;
}
}
#line 467 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 623 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "value") == 0) {
if (OUT == NULL) continue;
{
#line 841 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 625 "inform7/Chapter 38/I6 Template Interpreter.w"
;
ALLOW_VALUE(NUMBER_CREATED(action_name));
ALLOW_VALUE(NUMBER_CREATED(binary_predicate));
ALLOW_VALUE(NUMBER_CREATED(blorb_figure));
ALLOW_VALUE(NUMBER_CREATED(blorb_sound));
ALLOW_VALUE(NUMBER_CREATED(property));
ALLOW_VALUE(NUMBER_CREATED(rulebook));
ALLOW_VALUE(NUMBER_CREATED(scene));
ALLOW_VALUE(NUMBER_CREATED(test_scenario));
ALLOW_VALUE(extent_of_runtime_quotations_array);
ALLOW_VALUE(Instances__count(K_door));
ALLOW_VALUE(Instances__count(K_object));
ALLOW_VALUE(Instances__count(K_room));
ALLOW_VALUE(max_frame_size_needed);
ALLOW_VALUE(no_verb_verb_defined);
ALLOW_VALUE(rng_seed_at_start_of_play);
ALLOW_VALUE(default_scoring_setting);
LOG("command: <%s> argument: <%s>\n", command, argument);
TemplateFiles__error("Unknown {-value:...} value in I6 segment");
}
}
#line 468 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 658 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "read-assertions") == 0) {
if (strcmp(argument, "1") == 0) Assertions__Traverse__traverse(1);
if (strcmp(argument, "2") == 0) Assertions__Traverse__traverse(2);
if (problem_count > 0) active = FALSE;
continue;
}
}
#line 469 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 684 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "callv") == 0) {
{
#line 841 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 685 "inform7/Chapter 38/I6 Template Interpreter.w"
;
ALLOW_CALLV(Calculus__Deferrals__allow_no_further_deferrals);
ALLOW_CALLV(Chronology__allow_no_further_past_tenses);
ALLOW_CALLV(Phrases__Manager__add_rules_to_rulebooks);
ALLOW_CALLV(Phrases__Adjectives__traverse);
ALLOW_CALLV(Phrases__Index__index_page_Phrasebook);
ALLOW_CALLV(Phrases__Manager__parse_rule_parameters);
ALLOW_CALLV(Phrases__Manager__parse_rule_placements);
ALLOW_CALLV(Phrases__Manager__register_meanings);
ALLOW_CALLV(Phrases__Timed__check_for_unused);
ALLOW_CALLV(Phrases__Manager__traverse_for_names);
ALLOW_CALLV(Phrases__Manager__traverse);
ALLOW_CALLV(Rules__check_response_usages);
ALLOW_CALLV(Plugins__Manage__start);
ALLOW_CALLV(TemplateFiles__report_unacted_upon_interventions);
ALLOW_CALLV(Equations__index);
ALLOW_CALLV(Equations__traverse_to_create);
ALLOW_CALLV(Equations__traverse_to_stock);
ALLOW_CALLV(NonlocalVariables__index_all);
ALLOW_CALLV(Nametags__name_all);
ALLOW_CALLV(Strings__TextSubstitutions__allow_no_further_text_subs);
ALLOW_CALLV(Tables__check_tables_for_kind_clashes);
ALLOW_CALLV(Tables__complete);
ALLOW_CALLV(Tables__index);
ALLOW_CALLV(Tables__traverse_to_create);
ALLOW_CALLV(Tables__traverse_to_stock);
ALLOW_CALLV(Extensions__Files__check_versions);
ALLOW_CALLV(Extensions__Files__handle_census_mode);
ALLOW_CALLV(Extensions__Files__index);
ALLOW_CALLV(Extensions__Files__update_census);
ALLOW_CALLV(Extensions__Inclusion__traverse);
ALLOW_CALLV(Index__complete);
ALLOW_CALLV(Index__DocReferences__log_statistics);
ALLOW_CALLV(Memory__log_statistics);
ALLOW_CALLV(ParseTree__plant_parse_tree);
ALLOW_CALLV(ParseTree__write_to_file);
ALLOW_CALLV(ParseTree__write_main_source_to_log);
ALLOW_CALLV(ParseTree__verify);
ALLOW_CALLV(Sentences__break_source);
ALLOW_CALLV(Sentences__break_source);
ALLOW_CALLV(Sentences__RuleSubtrees__create_standard_csps);
ALLOW_CALLV(Sentences__declare_source_loaded);
ALLOW_CALLV(Sentences__Headings__index);
ALLOW_CALLV(Sentences__Headings__make_tree);
ALLOW_CALLV(Sentences__Headings__satisfy_dependencies);
ALLOW_CALLV(Sentences__Headings__write_as_xml);
ALLOW_CALLV(Sentences__RuleSubtrees__register_recently_lexed_phrases);
ALLOW_CALLV(Sentences__Rearrangement__tidy_up_ofs_and_froms);
ALLOW_CALLV(Sentences__VPs__traverse);
ALLOW_CALLV(SParser__debug_parser_statistics);
ALLOW_CALLV(PL__Actions__Index__page);
ALLOW_CALLV(PL__Actions__name_all);
ALLOW_CALLV(PL__Bibliographic__index_library_card);
ALLOW_CALLV(PL__Bibliographic__Release__write_ifiction_and_blurb);
ALLOW_CALLV(PL__Figures__index_all);
ALLOW_CALLV(PL__Files__index_all);
ALLOW_CALLV(PL__Parsing__traverse);
ALLOW_CALLV(PL__Parsing__Verbs__prepare);
ALLOW_CALLV(PL__Scenes__Index__index);
ALLOW_CALLV(PL__Sounds__index_all);
ALLOW_CALLV(Properties__ObjectImplementation__allocate_attributes);
ALLOW_CALLV(Properties__Measurement__validate_definitions);
ALLOW_CALLV(BinaryPredicates__make_built_in_further);
ALLOW_CALLV(BinaryPredicates__make_built_in);
ALLOW_CALLV(LiteralPatterns__define_named_phrases);
ALLOW_CALLV(Quantifiers__make_built_in);
ALLOW_CALLV(Verbs__log_all);
ALLOW_CALLV(Verbs__stock);
ALLOW_CALLV(Preform__log_language);
ALLOW_CALLV(Preform__read_definition);
ALLOW_CALLV(SourceFiles__read_primary_source_text);
ALLOW_CALLV(Lexer__start);
ALLOW_CALLV(Plurals__traverse_for_definitions);
ALLOW_CALLV(Kinds__Interpreter__include_templates_for_kinds);
ALLOW_CALLV(Kinds__Interpreter__batch_done);
ALLOW_CALLV(Kinds__Interpreter__start);
ALLOW_CALLV(InferenceSubjects__begin);
ALLOW_CALLV(World__complete_additions);
ALLOW_CALLV(World__complete);
ALLOW_CALLV(Data__Objects__page_Kinds);
ALLOW_CALLV(Data__Objects__page_World);
LOG("command: <%s> argument: <%s>\n", command, argument);
TemplateFiles__error("Unknown {-callv:...} function in I6 segment");
}
}
#line 470 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 778 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "call") == 0) {
if (OUT == NULL) continue;
{
#line 841 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 780 "inform7/Chapter 38/I6 Template Interpreter.w"
;
ALLOW_CALL(Calculus__Propositions__Deferred__compile_remaining_deferred);
ALLOW_CALL(Activities__compile_activity_constants);
ALLOW_CALL(Chronology__chronology_extents_i6_escape);
ALLOW_CALL(Chronology__past_actions_i6_routines);
ALLOW_CALL(Chronology__past_tenses_i6_escape);
ALLOW_CALL(Phrases__Manager__compile_first_block);
ALLOW_CALL(Phrases__Manager__compile_rule_printing_switch);
ALLOW_CALL(Phrases__Manager__compile_rulebooks);
ALLOW_CALL(Phrases__Manager__compile_as_needed);
ALLOW_CALL(Phrases__Constants__compile_closures);
ALLOW_CALL(Rulebooks__rulebook_var_creators_lookup);
ALLOW_CALL(UseOptions__compile_icl_commands);
ALLOW_CALL(UseOptions__compile);
ALLOW_CALL(Plugins__Manage__define_IFDEF_symbols);
ALLOW_CALL(TemplateFiles__compile_build_number);
ALLOW_CALL(Equations__compile);
ALLOW_CALL(Lists__check);
ALLOW_CALL(Lists__compile);
ALLOW_CALL(Strings__compile_responses);
ALLOW_CALL(Strings__TextLiterals__compile);
ALLOW_CALL(Tables__Support__compile_max_score);
ALLOW_CALL(Tables__Support__compile_print_table_names);
ALLOW_CALL(Tables__Support__compile);
ALLOW_CALL(JumpLabels__compile_necessary_storage);
ALLOW_CALL(PL__Actions__compile_action_routines);
ALLOW_CALL(PL__Actions__Patterns__Named__compile);
ALLOW_CALL(PL__Bibliographic__compile_constants);
ALLOW_CALL(PL__Files__arrays);
ALLOW_CALL(PL__Parsing__TestScripts__compile_printout);
ALLOW_CALL(PL__Parsing__TestScripts__compile_switch);
ALLOW_CALL(PL__Parsing__TestScripts__write_text);
ALLOW_CALL(PL__Parsing__Tokens__Filters__compile);
ALLOW_CALL(PL__Parsing__Tokens__Values__compile_type_gprs);
ALLOW_CALL(PL__Parsing__Tokens__Values__number);
ALLOW_CALL(PL__Parsing__Tokens__Values__time);
ALLOW_CALL(PL__Parsing__Tokens__Values__truth_state);
ALLOW_CALL(PL__Parsing__Verbs__compile_all);
ALLOW_CALL(PL__Parsing__Verbs__compile_conditions);
ALLOW_CALL(Properties__alias_translations);
ALLOW_CALL(Properties__ObjectImplementation__compile_attributes);
ALLOW_CALL(Properties__ObjectImplementation__compile_stub_properties);
ALLOW_CALL(Properties__Measurement__compile_MADJ_routines);
ALLOW_CALL(Adjectives__Meanings__agreements);
ALLOW_CALL(Relations__compile_defined_relations);
ALLOW_CALL(Relations__compile_defined_relation_constants);
ALLOW_CALL(Relations__relations_command);
ALLOW_CALL(Kinds__RunTime__compile_data_type_support_routines);
ALLOW_CALL(Kinds__RunTime__compile_heap_allocator);
ALLOW_CALL(Kinds__Constructors__compile_I6_constants);
ALLOW_CALL(Kinds__RunTime__compile_structures);
ALLOW_CALL(Kinds__RunTime__compile_block_constants);
ALLOW_CALL(PL__Showme__compile_SHOWME_details);
ALLOW_CALL(World__Compile__compile);
LOG("command: <%s> argument: <%s>\n", command, argument);
TemplateFiles__error("Unknown {-call:...} function in I6 segment");
}
}
#line 471 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 855 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "array") == 0) {
if (OUT == NULL) continue;
{
#line 841 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 857 "inform7/Chapter 38/I6 Template Interpreter.w"
;
ALLOW_ARRAY(PL__Actions__ActionCoding);
ALLOW_ARRAY(PL__Actions__ActionData);
ALLOW_ARRAY(PL__Actions__ActionHappened);
ALLOW_ARRAY(Activities__Activity_after_rulebooks);
ALLOW_ARRAY(Activities__Activity_atb_rulebooks);
ALLOW_ARRAY(Activities__Activity_before_rulebooks);
ALLOW_ARRAY(Activities__activity_var_creators);
ALLOW_ARRAY(Activities__Activity_for_rulebooks);
ALLOW_ARRAY(Phrases__Manager__TimedEventsTable);
ALLOW_ARRAY(Phrases__Manager__TimedEventTimesTable);
ALLOW_ARRAY(PL__Player__InitialSituation);
ALLOW_ARRAY(Properties__ObjectImplementation__property_metadata);
ALLOW_ARRAY(Rulebooks__rulebook_var_creators);
ALLOW_ARRAY(Phrases__Manager__RulebookNames);
ALLOW_ARRAY(Phrases__Manager__rulebooks_array);
ALLOW_ARRAY(PL__Figures__tableoffigures);
ALLOW_ARRAY(PL__Sounds__tableofsounds);
ALLOW_ARRAY(PL__Bibliographic__IFID__UUID_ARRAY);
LOG("command: <%s> argument: <%s>\n", command, argument);
TemplateFiles__error("Unknown {-array:...} function in I6 segment");
}
}
#line 472 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 888 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "routine") == 0) {
if (OUT == NULL) continue;
{
#line 841 "inform7/Chapter 38/I6 Template Interpreter.w"
int i;
for (i=0; argument[i]; i++)
if ((argument[i] == ':') && (argument[i+1] == ':')) {
argument[i] = '_';
argument[i+1] = '_';
}
}
#line 890 "inform7/Chapter 38/I6 Template Interpreter.w"
;
ALLOW_ROUTINE(Properties__ObjectImplementation__CreatePropertyOffsets);
ALLOW_ROUTINE(Kinds__RunTime__I7_Kind_Name);
ALLOW_ROUTINE(Rulebooks__Outcomes__RulebookOutcomePrintingRule);
ALLOW_ROUTINE(PL__Scenes__DetectSceneChange);
ALLOW_ROUTINE(PL__Scenes__ShowSceneStatus);
ALLOW_ROUTINE(PL__Scenes__PrintSceneName);
ALLOW_ROUTINE(Extensions__Files__ShowExtensionVersions);
ALLOW_ROUTINE(UseOptions__TestUseOption);
ALLOW_ROUTINE(PL__Parsing__Lines__MistakeActionSub);
ALLOW_ROUTINE(PL__Parsing__TestScripts__InternalTestCases);
ALLOW_ROUTINE(Verbs__ConjugateVerb);
LOG("command: <%s> argument: <%s>\n", command, argument);
TemplateFiles__error("Unknown {-routine:...} function in I6 segment");
}
}
#line 473 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 912 "inform7/Chapter 38/I6 Template Interpreter.w"
if (strcmp(command, "testing-command") == 0) {
if (OUT == NULL) continue;
PL__Parsing__Verbs__reserve(argument);
WRITE("Verb meta '%s'\n", argument);
continue;
}
}
#line 474 "inform7/Chapter 38/I6 Template Interpreter.w"
;
LOG("command: <%s> argument: <%s>\n", command, argument);
Problems__quote_text(1, command);
Problems__Issue__unlocated_problem(_p_(PM_BadTemplateInsertion),
"In an explicit Inform 6 code insertion, I recognise a few special "
"notations in the form '{-command}'. This time, though, the unknown notation "
"{-%1} has been used, and this is an error. (It seems very unlikely indeed "
"that this could be legal Inform 6 which I'm misreading, but if so, try "
"adjusting the spacing to make this problem message go away.)");
}
#line 205 "inform7/Chapter 38/I6 Template Interpreter.w"
;
continue;
} else if ((cr == 'N') && (N_escape >= 0)) {
{
#line 275 "inform7/Chapter 38/I6 Template Interpreter.w"
if (Input_File) cr = fgetc(Input_File);
else if (sf) {
cr = sf[sfp]; if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 208 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if (cr == '}') {
WRITE("%d", N_escape);
continue;
}
if ((OUT) && (active)) WRITE("{N");
goto NewCharacter;
} else { /* otherwise the open brace was a literal */
if ((OUT) && (active)) PUT_TO(OUT, '{');
goto NewCharacter;
}
}
if (cr == '(') {
{
#line 275 "inform7/Chapter 38/I6 Template Interpreter.w"
if (Input_File) cr = fgetc(Input_File);
else if (sf) {
cr = sf[sfp]; if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 221 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if (cr == '+') {
{
#line 416 "inform7/Chapter 38/I6 Template Interpreter.w"
int i=0;
while (i<MAX_I6T_LINE_LENGTH) {
{
#line 275 "inform7/Chapter 38/I6 Template Interpreter.w"
if (Input_File) cr = fgetc(Input_File);
else if (sf) {
cr = sf[sfp]; if (cr == 0) cr = EOF; else sfp++;
} else cr = EOF;
col++; if ((cr == 10) || (cr == 13)) col = 0;
}
#line 418 "inform7/Chapter 38/I6 Template Interpreter.w"
;
if (cr == EOF) { I6T_buffer[i] = 0; break; }
if ((cr == ')') && (i>0) && (I6T_buffer[i-1] == '+')) { I6T_buffer[i-1] = 0; break; }
I6T_buffer[i++] = (char) cr;
}
}
#line 223 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 427 "inform7/Chapter 38/I6 Template Interpreter.w"
TEMPORARY_STREAM;
TemplateFiles__compile_I7_from_I6(TEMP, I6T_buffer);
STREAM_COPY(OUT, TEMP);
CLOSE_TEMPORARY_STREAM;
}
#line 224 "inform7/Chapter 38/I6 Template Interpreter.w"
;
continue;
} else { /* otherwise the open bracket was a literal */
if ((OUT) && (active)) PUT_TO(OUT, '(');
goto NewCharacter;
}
}
if ((OUT) && (active)) PUT_TO(OUT, cr);
}
} while (cr != EOF);
if (Input_File) { if (dl) STREAM_FLUSH(dl); fclose(Input_File); }
if ((heading_name[0] != 0) && (segment_name))
TemplateFiles__I6T_file_intervene(OUT, 1, segment_name, heading_name);
OmitFile:
if (segment_name) TemplateFiles__I6T_file_intervene(OUT, 1, segment_name, NULL);
}
#line 927 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__error(char *message) {
Problems__quote_text(1, message);
Problems__Issue__handmade_problem(_p_(PM_TemplateError));
Problems__issue_problem_segment(
"I ran into a mistake in a template file command: %1. The I6 "
"template files (or .i6t files) are a very low-level part of Inform, "
"and errors like this will only occur if the standard installation "
"has been amended or damaged. One possibility is that you're using "
"an extension which does some 'template hacking', as it's called, "
"but made a mistake doing so.");
Problems__issue_problem_end();
}
#line 948 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__compile_I7_from_I6(OUTPUT_STREAM, char *p) {
wording LW = Feeds__feed_text(p);
if (Preform__parse_nt_against_word_range(property_name_NTM, LW, NULL, NULL)) {
WRITE("%s", Properties__get_translation(most_recent_result_p));
return;
}
if (Preform__parse_nt_against_word_range(k_kind_NTM, LW, NULL, NULL)) {
kind *K = most_recent_result_p;
if (Kinds__Compare__lt(K, K_object)) {
WRITE("%s", Kinds__Behaviour__I6_classname(K));
return;
}
}
instance *I = Instances__parse_object(LW);
if (I) {
WRITE("%s", Instances__identifier(I));
return;
}
adjectival_phrase *aph = Adjectives__Phrases__parse(LW);
if (aph) {
if (Adjectives__Meanings__write_adjective_test_routine(OUT, aph)) return;
Problems__Issue__unlocated_problem(_p_(BelievedImpossible),
"You tried to use '(+' and '+)' to expand to the Inform 6 routine "
"address of an adjective, but it was an adjective with no meaning.");
return;
}
int initial_problem_count = problem_count;
parse_node *spec = NULL;
if (Preform__parse_nt_against_word_range(s_value_NTM, LW, NULL, NULL)) spec = most_recent_result_p;
else spec = Specifications__new_UNKNOWN(LW);
if (initial_problem_count < problem_count) return;
Dash__check_value(spec, NULL);
if (initial_problem_count < problem_count) return;
BEGIN_COMPILATION_MODE;
COMPILATION_MODE_EXIT(DEREFERENCE_POINTERS_CMODE);
Specifications__Compiler__compile(OUT, spec);
END_COMPILATION_MODE;
}
#line 997 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__new_intervention(int stage, char *segment, char *part, unsigned char *i6, char *seg) {
I6T_intervention *i6ti = NULL;
if (stage == 0) {
LOOP_OVER(i6ti, I6T_intervention)
if ((i6ti->intervention_stage == 0) &&
(strcmp(i6ti->segment_name, segment) == 0)) {
if (((part == NULL) || (i6ti->part_name == NULL)) && (part != i6ti->part_name))
continue;
if ((part) && (strcmp(i6ti->part_name, part) != 0)) continue;
break;
}
}
if (i6ti == NULL) i6ti = CREATE(I6T_intervention);
i6ti->intervention_stage = stage;
i6ti->segment_name = segment;
i6ti->part_name = part;
i6ti->I6T_matter = i6;
i6ti->alternative_segment = seg;
i6ti->segment_found = FALSE;
i6ti->part_found = FALSE;
i6ti->where_intervention_requested = current_sentence;
LOGIF(TEMPLATE_READING, "New stage %d Segment %s Part %s\n", stage, segment, (part)?part:"<none>");
}
#line 1025 "inform7/Chapter 38/I6 Template Interpreter.w"
int TemplateFiles__I6T_file_intervene(OUTPUT_STREAM, int stage, char *segment, char *part) {
I6T_intervention *i6ti;
int rv = FALSE;
if (strcmp(segment, "Main.i6t") == 0) return rv;
LOGIF(TEMPLATE_READING, "Stage %d Segment %s Part %s\n", stage, segment, (part)?part:"<none>");
LOOP_OVER(i6ti, I6T_intervention)
if ((i6ti->intervention_stage == stage) &&
(strcmp(i6ti->segment_name, segment) == 0)) {
i6ti->segment_found = TRUE;
if (((part == NULL) || (i6ti->part_name == NULL)) && (part != i6ti->part_name))
continue;
if ((part) && (strcmp(i6ti->part_name, part) != 0)) continue;
i6ti->part_found = TRUE;
current_sentence = i6ti->where_intervention_requested;
LOGIF(TEMPLATE_READING, "Intervention at stage %d Segment %s Part %s\n", stage, segment, (part)?part:"<none>");
if (i6ti->I6T_matter) TemplateFiles__interpret(OUT, i6ti->I6T_matter, NULL, -1);
if (i6ti->alternative_segment) TemplateFiles__interpret(OUT, NULL, i6ti->alternative_segment, -1);
if (stage == 0) rv = TRUE;
}
return rv;
}
#line 1052 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__report_unacted_upon_interventions(void) {
I6T_intervention *i6ti;
LOOP_OVER(i6ti, I6T_intervention) {
if ((i6ti->segment_found == FALSE) && (strcmp(i6ti->segment_name, "Main.i6t") != 0)) {
current_sentence = i6ti->where_intervention_requested;
if (existing_story_file == FALSE)
Problems__Issue__sentence_problem(_p_(PM_NoSuchTemplate),
"no template file of that name was ever read in",
"so this attempt to intervene had no effect. "
"The template files have names like 'Output.i6t', 'Parser.i6t' "
"and so on. (Looking at the typeset form of the template, "
"available at the Inform website, may help.)");
} else if ((i6ti->part_found == FALSE) && (i6ti->part_name) &&
(strcmp(i6ti->segment_name, "Main.i6t") != 0)) {
current_sentence = i6ti->where_intervention_requested;
Problems__Issue__sentence_problem(_p_(PM_NoSuchPart),
"that template file didn't have a part with that name",
"so this attempt to intervene had no effect. "
"Each template file is divided internally into a number of "
"named parts, and you have to quote their names precisely. "
"(Looking at the typeset form of the template, available at "
"the Inform website, may help.)");
}
}
}
#line 1084 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__compile_build_number(OUTPUT_STREAM) {
WRITE("Constant NI_BUILD_COUNT \"%s\";\n", NI_BUILD);
}
#line 1094 "inform7/Chapter 38/I6 Template Interpreter.w"
void TemplateFiles__register_sentence_handlers(void) {
{
#line 1103 "inform7/Chapter 38/I6 Template Interpreter.w"
REGISTER_SENTENCE_HANDLER(TRACE_SH);
REGISTER_SENTENCE_HANDLER(BEGINHERE_SH);
REGISTER_SENTENCE_HANDLER(ENDHERE_SH);
REGISTER_SENTENCE_HANDLER(BIBLIOGRAPHIC_SH);
REGISTER_SENTENCE_HANDLER(INFORM6CODE_SH);
REGISTER_SENTENCE_HANDLER(COMMAND_SH);
REGISTER_SENTENCE_HANDLER(ROUTINE_SH);
REGISTER_SENTENCE_HANDLER(TABLE_SH);
REGISTER_SENTENCE_HANDLER(EQUATION_SH);
REGISTER_SENTENCE_HANDLER(HEADING_SH);
REGISTER_SENTENCE_HANDLER(SENTENCE_SH);
}
#line 1095 "inform7/Chapter 38/I6 Template Interpreter.w"
;
{
#line 1119 "inform7/Chapter 38/I6 Template Interpreter.w"
REGISTER_SENTENCE_HANDLER(ASSERT_SH);
REGISTER_SENTENCE_HANDLER(HAS_SH);
REGISTER_SENTENCE_HANDLER(CANBE_SH);
REGISTER_SENTENCE_HANDLER(TRANSLATES_SH);
REGISTER_SENTENCE_HANDLER(TRANSLATESU_SH);
REGISTER_SENTENCE_HANDLER(TRANSLATESL_SH);
REGISTER_SENTENCE_HANDLER(NEW_ACTIVITY_SH);
REGISTER_SENTENCE_HANDLER(NEW_ACTION_SH);
REGISTER_SENTENCE_HANDLER(NEW_RELATION_SH);
REGISTER_SENTENCE_HANDLER(DOC_SH);
REGISTER_SENTENCE_HANDLER(TEST_SH);
REGISTER_SENTENCE_HANDLER(USEMEANS_SH);
REGISTER_SENTENCE_HANDLER(SPECIFIES_SH);
REGISTER_SENTENCE_HANDLER(DEFINED_BY_SH);
REGISTER_SENTENCE_HANDLER(BEGINS_WHEN_SH);
REGISTER_SENTENCE_HANDLER(ENDS_WHEN_SH);
REGISTER_SENTENCE_HANDLER(USE_SH);
REGISTER_SENTENCE_HANDLER(RELEASE_SH);
REGISTER_SENTENCE_HANDLER(EPISODE_SH);
REGISTER_SENTENCE_HANDLER(PLURAL_SH);
REGISTER_SENTENCE_HANDLER(FIGURE_SH);
REGISTER_SENTENCE_HANDLER(SOUND_SH);
REGISTER_SENTENCE_HANDLER(FILE_SH);
REGISTER_SENTENCE_HANDLER(NEW_ADJ_SH);
}
#line 1096 "inform7/Chapter 38/I6 Template Interpreter.w"
;
}
#line 62 "inform7/Chapter 38/Plugins.w"
int plugin_name_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
*X = R[0];
return TRUE;
}
#line 81 "inform7/Chapter 38/Plugins.w"
#line 87 "inform7/Chapter 38/Plugins.w"
int language_element_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = TRUE; if (registered_plugins[R[1]]->now_plugged_in == FALSE) return FALSE;;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 89 "inform7/Chapter 38/Plugins.w"
#line 93 "inform7/Chapter 38/Plugins.w"
word_assemblage Plugins__Manage__wording(int N) {
return Preform__Nonparsing__wording(plugin_name_NTM, N);
}
#line 136 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__start(void) {
Plugins__Call__initialise_calls();
CREATE_PLUGIN(core_plugin, Plugins__Manage__start_core, FALSE, CORE_PLUGIN_NAME, CORE_PLUGIN_NAME);
core_plugin->now_plugged_in = TRUE;
core_plugin->has_template_file = "Core";
CREATE_PLUGIN(naming_plugin, PL__Naming__start, FALSE,
NAMING_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(counting_plugin, PL__Counting__start, TRUE,
INSTANCE_COUNTING_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(parsing_plugin, PL__Parsing__Visibility__start, FALSE,
COMMAND_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(actions_plugin, PL__Actions__start, FALSE,
ACTIONS_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
actions_plugin->has_template_file = "Actions";
CREATE_PLUGIN(spatial_plugin, PL__Spatial__start, TRUE,
SPATIAL_MODEL_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(map_plugin, PL__Map__start, FALSE,
MAPPING_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(player_plugin, PL__Player__start, FALSE,
PLAYER_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(regions_plugin, PL__Regions__start, TRUE,
REGIONS_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(backdrops_plugin, PL__Backdrops__start, FALSE,
BACKDROPS_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(showme_plugin, PL__Showme__start, FALSE,
SHOWME_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
CREATE_PLUGIN(times_plugin, PL__TimesOfDay__start, FALSE,
TIMES_OF_DAY_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
times_plugin->has_template_file = "Times";
CREATE_PLUGIN(scenes_plugin, PL__Scenes__start, FALSE,
SCENES_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
scenes_plugin->has_template_file = "Scenes";
CREATE_PLUGIN(figures_plugin, PL__Figures__start, FALSE,
FIGURES_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
figures_plugin->has_template_file = "Figures";
CREATE_PLUGIN(sounds_plugin, PL__Sounds__start, FALSE,
SOUNDS_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
sounds_plugin->has_template_file = "Sounds";
CREATE_PLUGIN(files_plugin, PL__Files__start, FALSE,
GLULX_EXTERNAL_FILES_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
files_plugin->has_template_file = "Files";
files_plugin->IFDEF_symbol = "PLUGIN_FILES";
CREATE_PLUGIN(bibliographic_plugin, PL__Bibliographic__start, FALSE,
BIBLIOGRAPHIC_DATA_PLUGIN_NAME, INTERACTIVE_FICTION_PLUGIN_NAME);
}
void Plugins__Manage__start_core(void) {
}
#line 213 "inform7/Chapter 38/Plugins.w"
int use_language_element_sentence_subject_NTMC(int *X, void **XP, int *R, void **RP, wording W) {
switch(R[0]) {
case 0: *X = PLUGIN_REMOVAL_OFFSET + R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 1: *X = R[1];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
case 2:
{
#line 221 "inform7/Chapter 38/Plugins.w"
*X = -1;
Problems__Issue__sentence_problem(_p_(PM_NoSuchLanguageElement),
"this seems to ask to include or exclude a language feature which "
"I don't recognise the name of",
"possibly because you've borrowed it from a different version of "
"Inform, or forgotten what these are called? You can see the current "
"configuration at the bottom of the Contents index.");
}
#line 216 "inform7/Chapter 38/Plugins.w"
;
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
break;
#pragma clang diagnostic pop
default: *X = R[0]; break;
}
return TRUE;
}
#line 217 "inform7/Chapter 38/Plugins.w"
#line 234 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__plug_in(wording W) {
if (Preform__parse_nt_against_word_range(use_language_element_sentence_subject_NTM, W, NULL, NULL)) {
int plugin_number = most_recent_result;
int new_state = TRUE;
if (plugin_number >= PLUGIN_REMOVAL_OFFSET) {
new_state = FALSE;
plugin_number -= PLUGIN_REMOVAL_OFFSET;
}
plugin *P;
LOOP_OVER(P, plugin) {
int definiteness = UNKNOWN_CE;
if (P->plugin_number == plugin_number) definiteness = CERTAIN_CE;
if (P->set_number == plugin_number) definiteness = LIKELY_CE;
if (definiteness != UNKNOWN_CE) {
if ((definiteness == LIKELY_CE) && (P->has_been_set_explicitly)) continue;
if (P == core_plugin) {
if (new_state == FALSE)
{
#line 264 "inform7/Chapter 38/Plugins.w"
Problems__Issue__sentence_problem(_p_(PM_DontRemoveTheCore),
"the core of the Inform language cannot be removed",
"because then what should we do? What should we ever do?");
return;
}
#line 250 "inform7/Chapter 38/Plugins.w"
;
plugin *Q;
LOOP_OVER(Q, plugin) Q->now_plugged_in = FALSE;
}
P->now_plugged_in = new_state;
P->has_been_set_explicitly = TRUE;
}
}
}
}
#line 272 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__show_configuration(OUTPUT_STREAM) {
WRITE("<p>");
Index__anchor("CONFIG");
WRITE("Inform language definition:");
Plugins__Manage__show(OUT, "Included", TRUE);
Plugins__Manage__show(OUT, "Excluded", FALSE);
WRITE("<p>\n");
}
void Plugins__Manage__show(OUTPUT_STREAM, char *label, int state) {
plugin *P;
int c = 0;
WRITE("<p>%s: ", label);
LOOP_OVER(P, plugin) if (P->now_plugged_in == state) {
if (c > 0) WRITE(", ");
WordAssemblages__copy_to_stream(OUT, &(P->plugin_name));
c++;
}
if (c == 0) WRITE("<i>none</i>");
}
#line 296 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__define_IFDEF_symbols(OUTPUT_STREAM) {
plugin *P;
LOOP_OVER(P, plugin)
if ((P->now_plugged_in) && (P->IFDEF_symbol))
WRITE("Constant %s;\n", P->IFDEF_symbol);
}
#line 306 "inform7/Chapter 38/Plugins.w"
void Plugins__Manage__command(char *command) {
if (strcmp(command, "load") == 0) {
plugin *P;
LOOP_OVER(P, plugin)
if (P->now_plugged_in) {
void (*start)() = (void (*)()) P->starter_routine;
(*start)();
if (P->has_template_file) {
char segment_name[64];
sprintf(segment_name, "Load-%s.i6t", P->has_template_file);
TemplateFiles__interpret(NULL, NULL, segment_name, -1);
}
}
return;
}
internal_error("No such plugin command");
}
int Plugins__Manage__plugged_in(plugin *P) {
return P->now_plugged_in;
}
#line 88 "inform7/Chapter 38/Plugin Calls.w"
void Plugins__Call__initialise_calls(void) {
int i;
for (i=0; i<MAX_PLUGS; i++) plugins_stack[i] = NULL;
}
#line 96 "inform7/Chapter 38/Plugin Calls.w"
int Plugins__Call__name_to_early_infs(wording W, inference_subject **infs) {
PLUGINS_CALL(PLUGIN_NAME_TO_EARLY_INFS, W, infs);
}
int Plugins__Call__new_variable_notify(nonlocal_variable *q) {
PLUGINS_CALL(PLUGIN_NEW_VARIABLE_NOTIFY, q);
}
int Plugins__Call__new_base_kind_notify(kind *K, char *d, wording W) {
PLUGINS_CALL(PLUGIN_NEW_BASE_KIND_NOTIFY, K, d, W);
}
int Plugins__Call__compile_constant(OUTPUT_STREAM, kind *K, parse_node *spec) {
PLUGINS_CALL(PLUGIN_COMPILE_CONSTANT, OUT, K, spec);
}
int Plugins__Call__new_subject_notify(inference_subject *subj) {
PLUGINS_CALL(PLUGIN_NEW_SUBJECT_NOTIFY, subj);
}
int Plugins__Call__new_named_instance_notify(instance *nc) {
PLUGINS_CALL(PLUGIN_NEW_INSTANCE_NOTIFY, nc);
}
int Plugins__Call__new_permission_notify(property_permission *pp) {
PLUGINS_CALL(PLUGIN_NEW_PERMISSION_NOTIFY, pp);
}
int Plugins__Call__irregular_genitive(inference_subject *owner, char *genitive, int *propriety) {
PLUGINS_CALL(PLUGIN_IRREGULAR_GENITIVE, owner, genitive, propriety);
}
int Plugins__Call__set_kind_notify(instance *I, kind *k) {
PLUGINS_CALL(PLUGIN_SET_KIND_NOTIFY, I, k);
}
int Plugins__Call__set_subkind_notify(kind *sub, kind *super) {
PLUGINS_CALL(PLUGIN_SET_SUBKIND_NOTIFY, sub, super);
}
int Plugins__Call__complete_model(int stage) {
World__Inferences__diversion_off();
PLUGINS_CALL(PLUGIN_COMPLETE_MODEL, stage);
}
int Plugins__Call__parse_composite_NQs(wording *W, wording *DW,
quantifier **quantifier_used, kind **some_kind) {
PLUGINS_CALL(PLUGIN_PARSE_COMPOSITE_NQS, W, DW, quantifier_used, some_kind);
}
int Plugins__Call__refine_implicit_noun(parse_node *p) {
PLUGINS_CALL(PLUGIN_REFINE_IMPLICIT_NOUN, p);
}
int Plugins__Call__act_on_special_NPs(parse_node *p) {
PLUGINS_CALL(PLUGIN_ACT_ON_SPECIAL_NPS, p);
}
int Plugins__Call__new_property_notify(property *prn) {
PLUGINS_CALL(PLUGIN_NEW_PROPERTY_NOTIFY, prn);
}
int Plugins__Call__property_value_notify(property *prn, parse_node *val) {
PLUGINS_CALL(PLUGIN_PROPERTY_VALUE_NOTIFY, prn, val);
}
int Plugins__Call__more_specific(instance *I1, instance *I2) {
PLUGINS_CALL(PLUGIN_MORE_SPECIFIC, I1, I2);
}
int Plugins__Call__inferences_contradict(inference *A, inference *B, int similarity) {
PLUGINS_CALL(PLUGIN_INFERENCES_CONTRADICT, A, B, similarity);
}
int Plugins__Call__explain_contradiction(inference *A, inference *B, int similarity,
inference_subject *subj) {
PLUGINS_CALL(PLUGIN_EXPLAIN_CONTRADICTION, A, B, similarity, subj);
}
int Plugins__Call__intervene_in_assertion(parse_node *px, parse_node *py) {
PLUGINS_CALL(PLUGIN_INTERVENE_IN_ASSERTION, px, py);
}
int Plugins__Call__log_inference_type(int it) {
PLUGINS_CALL(PLUGIN_LOG_INFERENCE_TYPE, it);
}
int Plugins__Call__compile_object_header(OUTPUT_STREAM, instance *I) {
PLUGINS_CALL(PLUGIN_COMPILE_OBJECT_HEADER, OUT, I);
}
int Plugins__Call__estimate_property_usage(kind *k, int *words_used) {
PLUGINS_CALL(PLUGIN_ESTIMATE_PROPERTY_USAGE, k, words_used);
}
int Plugins__Call__check_going(parse_node *from, parse_node *to,
parse_node *by, parse_node *through, parse_node *pushing) {
PLUGINS_CALL(PLUGIN_CHECK_GOING, from, to, by, through, pushing);
}
int Plugins__Call__compile_model_tables(OUTPUT_STREAM) {
PLUGINS_CALL(PLUGIN_COMPILE_MODEL_TABLES, OUT);
}
int Plugins__Call__default_appearance(inference_subject *infs, parse_node *txt) {
PLUGINS_CALL(PLUGIN_DEFAULT_APPEARANCE, infs, txt);
}
int Plugins__Call__offered_property(kind *K, parse_node *owner, parse_node *what) {
PLUGINS_CALL(PLUGIN_OFFERED_PROPERTY, K, owner, what);
}
int Plugins__Call__offered_specification(parse_node *owner, wording W) {
PLUGINS_CALL(PLUGIN_OFFERED_SPECIFICATION, owner, W);
}
int Plugins__Call__typecheck_equality(kind *K1, kind *K2) {
PLUGINS_CALL(PLUGIN_TYPECHECK_EQUALITY, K1, K2);
}
int Plugins__Call__forbid_setting(kind *K) {
PLUGINS_CALL(PLUGIN_FORBID_SETTING, K);
}
int Plugins__Call__variable_set_warning(nonlocal_variable *q, parse_node *val) {
PLUGINS_CALL(PLUGIN_VARIABLE_SET_WARNING, q, val);
}
int Plugins__Call__detect_bodysnatching(inference_subject *body, int *snatcher,
inference_subject **counterpart) {
PLUGINS_CALL(PLUGIN_DETECT_BODYSNATCHING, body, snatcher, counterpart);
}
int Plugins__Call__add_to_World_index(instance *O) {
PLUGINS_CALL(PLUGIN_ADD_TO_WORLD_INDEX, O);
}
int Plugins__Call__annotate_in_World_index(instance *O) {
PLUGINS_CALL(PLUGIN_ANNOTATE_IN_WORLD_INDEX, O);
}
void register_tangled_nonterminals(void) {
#line 413 "inform7/Chapter 2/Debugging Log.w"
REGISTER_NONTERMINAL("<include-in-debugging-sentence-subject>", include_in_debugging_sentence_subject_NTM);
#line 417 "inform7/Chapter 2/Debugging Log.w"
REGISTER_NONTERMINAL("<debugging-log-request>", debugging_log_request_NTM);
#line 69 "inform7/Chapter 4/HTML Documentation.w"
REGISTER_NONTERMINAL("<extension-documentation-heading>", extension_documentation_heading_NTM);
#line 99 "inform7/Chapter 4/HTML Documentation.w"
REGISTER_NONTERMINAL("<extension-example-header>", extension_example_header_NTM);
#line 103 "inform7/Chapter 4/HTML Documentation.w"
REGISTER_NONTERMINAL("<row-of-asterisks>", row_of_asterisks_NTM);
#line 307 "inform7/Chapter 4/HTML Documentation.w"
REGISTER_NONTERMINAL("<extension-documentation-paste-marker>", extension_documentation_paste_marker_NTM);
#line 130 "inform7/Chapter 5/Documentation References.w"
REGISTER_NONTERMINAL("<documentation-symbol-tail>", documentation_symbol_tail_NTM);
#line 134 "inform7/Chapter 5/Documentation References.w"
REGISTER_NONTERMINAL("<documentation-symbol>", documentation_symbol_NTM);
#line 618 "inform7/Chapter 7/Tries and Inflections.w"
REGISTER_NONTERMINAL("<small-trie-test>", small_trie_test_NTM);
#line 266 "inform7/Chapter 7/Natural Languages.w"
INTERNAL_NONTERMINAL("<natural-language>", natural_language_NTM, 1, 1000000000);
natural_language_NTM->voracious = 0;
#line 460 "inform7/Chapter 7/Preform.w"
INTERNAL_NONTERMINAL("<preform-nonterminal>", preform_nonterminal_NTM, 1, 1);
preform_nonterminal_NTM->voracious = 0;
#line 74 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<singular-noun-to-its-indefinite-article>", singular_noun_to_its_indefinite_article_NTM);
#line 82 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-indef-a>", en_trie_indef_a_NTM);
#line 93 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-indef-b>", en_trie_indef_b_NTM);
#line 161 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-indef-c>", en_trie_indef_c_NTM);
#line 248 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<singular-noun-to-its-plural>", singular_noun_to_its_plural_NTM);
#line 262 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-uninflected>", en_trie_plural_uninflected_NTM);
#line 317 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-pronouns>", en_trie_plural_pronouns_NTM);
#line 345 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-irregular>", en_trie_plural_irregular_NTM);
#line 365 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-irregular-inflections>", en_trie_plural_irregular_inflections_NTM);
#line 382 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-assimilated-classical-inflections>", en_trie_plural_assimilated_classical_inflections_NTM);
#line 413 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-irregular-o-suffixes>", en_trie_plural_irregular_o_suffixes_NTM);
#line 451 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-regular-inflections>", en_trie_plural_regular_inflections_NTM);
#line 535 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-plural-append-s>", en_trie_plural_append_s_NTM);
#line 655 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<verb-conjugation-instructions>", verb_conjugation_instructions_NTM);
#line 724 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-have-conjugation>", to_have_conjugation_NTM);
#line 814 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-have-tabulation>", to_have_tabulation_NTM);
#line 825 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-have-present>", to_have_present_NTM);
#line 862 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-do-conjugation>", to_do_conjugation_NTM);
#line 867 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-do-tabulation>", to_do_tabulation_NTM);
#line 878 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-do-present>", to_do_present_NTM);
#line 901 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<regular-verb-conjugation>", regular_verb_conjugation_NTM);
#line 919 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<regular-verb-tabulation>", regular_verb_tabulation_NTM);
#line 937 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<regular-verb-present>", regular_verb_present_NTM);
#line 943 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-conjugation>", to_be_conjugation_NTM);
#line 948 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-tabulation>", to_be_tabulation_NTM);
#line 958 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-present>", to_be_present_NTM);
#line 961 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-past>", to_be_past_NTM);
#line 983 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-able-to-conjugation>", to_be_able_to_conjugation_NTM);
#line 988 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-able-to-tabulation>", to_be_able_to_tabulation_NTM);
#line 1024 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-able-to-auxiliary>", to_be_able_to_auxiliary_NTM);
#line 1029 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<to-be-able-to-auxiliary-tabulation>", to_be_able_to_auxiliary_tabulation_NTM);
#line 1039 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<modal-conjugation>", modal_conjugation_NTM);
#line 1044 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<modal-tabulation>", modal_tabulation_NTM);
#line 1083 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-be-conjugation>", contracted_to_be_conjugation_NTM);
#line 1089 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-be-tabulation>", contracted_to_be_tabulation_NTM);
#line 1101 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-be-present>", contracted_to_be_present_NTM);
#line 1104 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-be-past>", contracted_to_be_past_NTM);
#line 1107 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-be-past-negated>", contracted_to_be_past_negated_NTM);
#line 1123 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-have-conjugation>", contracted_to_have_conjugation_NTM);
#line 1129 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-have-tabulation>", contracted_to_have_tabulation_NTM);
#line 1141 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<contracted-to-have-present>", contracted_to_have_present_NTM);
#line 1157 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<arent-conjugation>", arent_conjugation_NTM);
#line 1163 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<arent-tabulation>", arent_tabulation_NTM);
#line 1170 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<arent-present>", arent_present_NTM);
#line 1173 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<arent-past>", arent_past_NTM);
#line 1176 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<arent-perfect>", arent_perfect_NTM);
#line 1188 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<informal-negated-modal-conjugation>", informal_negated_modal_conjugation_NTM);
#line 1197 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<informal-negated-modal-tabulation>", informal_negated_modal_tabulation_NTM);
#line 1204 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<informal-negated-modal-present>", informal_negated_modal_present_NTM);
#line 1210 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<cant-modal-conjugation>", cant_modal_conjugation_NTM);
#line 1216 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<cant-modal-tabulation>", cant_modal_tabulation_NTM);
#line 1232 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-modal-contracted-present>", en_trie_modal_contracted_present_NTM);
#line 1244 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-modal-contracted-past>", en_trie_modal_contracted_past_NTM);
#line 1256 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-modal-contracted-future>", en_trie_modal_contracted_future_NTM);
#line 1316 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-present-participle>", en_trie_present_participle_NTM);
#line 1330 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-present-participle>", en_trie_irregular_present_participle_NTM);
#line 1520 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-compound-present-participle>", en_trie_irregular_compound_present_participle_NTM);
#line 1539 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-a-present-participle>", en_trie_regular_a_present_participle_NTM);
#line 1589 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-b-present-participle>", en_trie_regular_b_present_participle_NTM);
#line 1594 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-c-present-participle>", en_trie_regular_c_present_participle_NTM);
#line 1606 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-past-participle>", en_trie_past_participle_NTM);
#line 1610 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-past-participle>", en_trie_irregular_past_participle_NTM);
#line 1770 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-present-verb-form>", en_trie_present_verb_form_NTM);
#line 1774 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-third-person-present>", en_trie_irregular_third_person_present_NTM);
#line 1786 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-past>", en_trie_past_NTM);
#line 1793 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-past>", en_trie_irregular_past_NTM);
#line 2337 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-irregular-compound-past>", en_trie_irregular_compound_past_NTM);
#line 2353 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-a-past>", en_trie_regular_a_past_NTM);
#line 2400 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-b-past>", en_trie_regular_b_past_NTM);
#line 2405 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-regular-c-past>", en_trie_regular_c_past_NTM);
#line 2432 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<pasturise-participle>", pasturise_participle_NTM);
#line 2437 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-pasturise-exceptions>", en_trie_pasturise_exceptions_NTM);
#line 2902 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-pasturise-regular-y>", en_trie_pasturise_regular_y_NTM);
#line 2908 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<en-trie-pasturise-regular>", en_trie_pasturise_regular_NTM);
#line 2916 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<adjective-to-plural>", adjective_to_plural_NTM);
#line 2919 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<adjective-to-masculine-singular>", adjective_to_masculine_singular_NTM);
#line 2922 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<adjective-to-feminine-singular>", adjective_to_feminine_singular_NTM);
#line 2925 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<adjective-to-masculine-plural>", adjective_to_masculine_plural_NTM);
#line 2928 "inform7/Chapter 7/English Inflections.w"
REGISTER_NONTERMINAL("<adjective-to-feminine-plural>", adjective_to_feminine_plural_NTM);
#line 13 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<pronoun>", pronoun_NTM);
#line 17 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<nominative-pronoun>", nominative_pronoun_NTM);
#line 21 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<accusative-pronoun>", accusative_pronoun_NTM);
#line 33 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<possessive-first-person>", possessive_first_person_NTM);
#line 37 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<possessive-second-person>", possessive_second_person_NTM);
#line 41 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<possessive-third-person>", possessive_third_person_NTM);
#line 52 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<relative-clause-marker>", relative_clause_marker_NTM);
#line 58 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<article>", article_NTM);
#line 73 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<definite-article>", definite_article_NTM);
#line 76 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<indefinite-article>", indefinite_article_NTM);
#line 83 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<optional-definite-article>", optional_definite_article_NTM);
#line 87 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<optional-article>", optional_article_NTM);
#line 91 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<compulsory-article>", compulsory_article_NTM);
#line 118 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<non-participles>", non_participles_NTM);
#line 121 "inform7/Chapter 8/Articles and Pronouns.w"
INTERNAL_NONTERMINAL("<probable-participle>", probable_participle_NTM, 1, 1);
probable_participle_NTM->voracious = 0;
#line 132 "inform7/Chapter 8/Articles and Pronouns.w"
REGISTER_NONTERMINAL("<negated-clause>", negated_clause_NTM);
#line 305 "inform7/Chapter 8/Determiners and Quantifiers.w"
REGISTER_NONTERMINAL("<determiner-names>", determiner_names_NTM);
#line 373 "inform7/Chapter 8/Determiners and Quantifiers.w"
REGISTER_NONTERMINAL("<determination-of>", determination_of_NTM);
#line 391 "inform7/Chapter 8/Determiners and Quantifiers.w"
REGISTER_NONTERMINAL("<excluded-from-determiners>", excluded_from_determiners_NTM);
#line 162 "inform7/Chapter 8/Time Periods.w"
REGISTER_NONTERMINAL("<historical-reference-possible>", historical_reference_possible_NTM);
#line 168 "inform7/Chapter 8/Time Periods.w"
REGISTER_NONTERMINAL("<historical-reference>", historical_reference_NTM);
#line 172 "inform7/Chapter 8/Time Periods.w"
REGISTER_NONTERMINAL("<repetition-specification>", repetition_specification_NTM);
#line 182 "inform7/Chapter 8/Time Periods.w"
REGISTER_NONTERMINAL("<repetitions>", repetitions_NTM);
#line 186 "inform7/Chapter 8/Time Periods.w"
REGISTER_NONTERMINAL("<iteration-repetitions>", iteration_repetitions_NTM);
#line 193 "inform7/Chapter 8/Time Periods.w"
REGISTER_NONTERMINAL("<turn-repetitions>", turn_repetitions_NTM);
#line 197 "inform7/Chapter 8/Time Periods.w"
REGISTER_NONTERMINAL("<rep-number>", rep_number_NTM);
#line 63 "inform7/Chapter 9/Adjectives.w"
INTERNAL_NONTERMINAL("<adjective-name>", adjective_name_NTM, 1, 1000000000);
adjective_name_NTM->voracious = 0;
#line 1032 "inform7/Chapter 9/Adjective Meanings.w"
INTERNAL_NONTERMINAL("<adaptive-adjective>", adaptive_adjective_NTM, 1, 1000000000);
adaptive_adjective_NTM->voracious = 0;
#line 1494 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<specifies-sentence-subject>", specifies_sentence_subject_NTM);
#line 1500 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-group-list>", literal_pattern_group_list_NTM);
#line 1504 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-group-tail>", literal_pattern_group_tail_NTM);
#line 1508 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-group>", literal_pattern_group_NTM);
#line 1564 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<specifies-sentence-object>", specifies_sentence_object_NTM);
#line 1568 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<kind-specified>", kind_specified_NTM);
#line 1572 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-specification-tail>", literal_pattern_specification_tail_NTM);
#line 1579 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<scaling-instruction>", scaling_instruction_NTM);
#line 1605 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part-list>", literal_pattern_part_list_NTM);
#line 1611 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part>", literal_pattern_part_NTM);
#line 1615 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part-option-list>", literal_pattern_part_option_list_NTM);
#line 1619 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part-option-tail>", literal_pattern_part_option_tail_NTM);
#line 1623 "inform7/Chapter 10/Literal Patterns.w"
REGISTER_NONTERMINAL("<literal-pattern-part-option>", literal_pattern_part_option_NTM);
#line 1949 "inform7/Chapter 10/Literal Patterns.w"
INTERNAL_NONTERMINAL("<literal-pattern-group-name>", literal_pattern_group_name_NTM, 1, 1000000000);
literal_pattern_group_name_NTM->voracious = 0;
#line 71 "inform7/Chapter 10/Times of Day.w"
REGISTER_NONTERMINAL("<s-literal-time>", s_literal_time_NTM);
#line 76 "inform7/Chapter 10/Times of Day.w"
REGISTER_NONTERMINAL("<elapsed-time>", elapsed_time_NTM);
#line 81 "inform7/Chapter 10/Times of Day.w"
REGISTER_NONTERMINAL("<clock-time>", clock_time_NTM);
#line 85 "inform7/Chapter 10/Times of Day.w"
REGISTER_NONTERMINAL("<am-pm>", am_pm_NTM);
#line 111 "inform7/Chapter 10/Times of Day.w"
INTERNAL_NONTERMINAL("<digital-clock-time>", digital_clock_time_NTM, 1, 1);
digital_clock_time_NTM->voracious = 0;
#line 139 "inform7/Chapter 10/Times of Day.w"
INTERNAL_NONTERMINAL("<continental-clock-time>", continental_clock_time_NTM, 1, 1);
continental_clock_time_NTM->voracious = 0;
#line 167 "inform7/Chapter 10/Times of Day.w"
REGISTER_NONTERMINAL("<event-rule-preamble>", event_rule_preamble_NTM);
#line 44 "inform7/Chapter 10/Unicode Translations.w"
REGISTER_NONTERMINAL("<translates-into-unicode-sentence-subject>", translates_into_unicode_sentence_subject_NTM);
#line 54 "inform7/Chapter 10/Unicode Translations.w"
REGISTER_NONTERMINAL("<translates-into-unicode-sentence-object>", translates_into_unicode_sentence_object_NTM);
#line 77 "inform7/Chapter 10/Unicode Translations.w"
REGISTER_NONTERMINAL("<s-unicode-character>", s_unicode_character_NTM);
#line 81 "inform7/Chapter 10/Unicode Translations.w"
INTERNAL_NONTERMINAL("<unicode-character-name>", unicode_character_name_NTM, 1, 1000000000);
unicode_character_name_NTM->voracious = 0;
#line 335 "inform7/Chapter 10/Nametags.w"
REGISTER_NONTERMINAL("<translates-into-nl-sentence-subject>", translates_into_nl_sentence_subject_NTM);
#line 343 "inform7/Chapter 10/Instances.w"
INTERNAL_NONTERMINAL("<instance-of-object>", instance_of_object_NTM, 1, 1000000000);
instance_of_object_NTM->voracious = 0;
#line 349 "inform7/Chapter 10/Instances.w"
INTERNAL_NONTERMINAL("<instance-of-non-object>", instance_of_non_object_NTM, 1, 1000000000);
instance_of_non_object_NTM->voracious = 0;
#line 356 "inform7/Chapter 10/Instances.w"
INTERNAL_NONTERMINAL("<instance>", instance_NTM, 1, 1000000000);
instance_NTM->voracious = 0;
#line 64 "inform7/Chapter 10/Nonlocal Variables.w"
REGISTER_NONTERMINAL("<notable-variables>", notable_variables_NTM);
#line 658 "inform7/Chapter 10/Nonlocal Variables.w"
REGISTER_NONTERMINAL("<value-understood-variable-name>", value_understood_variable_name_NTM);
#line 697 "inform7/Chapter 11/Binary Predicates.w"
INTERNAL_NONTERMINAL("<relation-name>", relation_name_NTM, 1, 1000000000);
relation_name_NTM->voracious = 0;
#line 66 "inform7/Chapter 11/Relations.w"
REGISTER_NONTERMINAL("<relation-names>", relation_names_NTM);
#line 109 "inform7/Chapter 11/Relations.w"
REGISTER_NONTERMINAL("<relates-sentence-subject>", relates_sentence_subject_NTM);
#line 259 "inform7/Chapter 11/Relations.w"
REGISTER_NONTERMINAL("<relates-sentence-left-object>", relates_sentence_left_object_NTM);
#line 263 "inform7/Chapter 11/Relations.w"
REGISTER_NONTERMINAL("<relates-sentence-right-object>", relates_sentence_right_object_NTM);
#line 268 "inform7/Chapter 11/Relations.w"
REGISTER_NONTERMINAL("<relation-term-right-named>", relation_term_right_named_NTM);
#line 272 "inform7/Chapter 11/Relations.w"
REGISTER_NONTERMINAL("<relation-term-right>", relation_term_right_NTM);
#line 278 "inform7/Chapter 11/Relations.w"
REGISTER_NONTERMINAL("<relation-term-basic>", relation_term_basic_NTM);
#line 742 "inform7/Chapter 11/Relations.w"
REGISTER_NONTERMINAL("<relation-storage-construction>", relation_storage_construction_NTM);
#line 170 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<general-verb>", general_verb_NTM, 1, 1000000000);
general_verb_NTM->voracious = 1;
#line 187 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<general-verb-present-positive>", general_verb_present_positive_NTM, 1, 1000000000);
general_verb_present_positive_NTM->voracious = 1;
#line 208 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<foreign-verb-present-positive>", foreign_verb_present_positive_NTM, 1, 1000000000);
foreign_verb_present_positive_NTM->voracious = 1;
#line 231 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<copular-verb>", copular_verb_NTM, 1, 1000000000);
copular_verb_NTM->voracious = 1;
#line 251 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<copular-verb-present-positive>", copular_verb_present_positive_NTM, 1, 1000000000);
copular_verb_present_positive_NTM->voracious = 1;
#line 275 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<negated-noncopular-verb-present>", negated_noncopular_verb_present_NTM, 1, 1000000000);
negated_noncopular_verb_present_NTM->voracious = 1;
#line 297 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<universal-verb>", universal_verb_NTM, 1, 1000000000);
universal_verb_NTM->voracious = 1;
#line 316 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<possession-verb-present-positive>", possession_verb_present_positive_NTM, 1, 1000000000);
possession_verb_present_positive_NTM->voracious = 1;
#line 338 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<negated-verb>", negated_verb_NTM, 1, 1000000000);
negated_verb_NTM->voracious = 1;
#line 357 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<past-tense-verb>", past_tense_verb_NTM, 1, 1000000000);
past_tense_verb_NTM->voracious = 1;
#line 458 "inform7/Chapter 11/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<inequality-conjugations>", inequality_conjugations_NTM);
#line 588 "inform7/Chapter 11/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<verb-implies-sentence-subject>", verb_implies_sentence_subject_NTM);
#line 592 "inform7/Chapter 11/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<infinitive-usage>", infinitive_usage_NTM);
#line 596 "inform7/Chapter 11/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<infinitive-usage-exceptional>", infinitive_usage_exceptional_NTM);
#line 605 "inform7/Chapter 11/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<conjugation>", conjugation_NTM);
#line 618 "inform7/Chapter 11/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<participle-like>", participle_like_NTM);
#line 634 "inform7/Chapter 11/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<verb-implies-sentence-object>", verb_implies_sentence_object_NTM);
#line 772 "inform7/Chapter 11/Conjugation of Verbs.w"
REGISTER_NONTERMINAL("<list-comma-division>", list_comma_division_NTM);
#line 1201 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<adaptive-verb>", adaptive_verb_NTM, 1, 1000000000);
adaptive_verb_NTM->voracious = 0;
#line 1218 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<adaptive-verb-infinitive>", adaptive_verb_infinitive_NTM, 1, 1000000000);
adaptive_verb_infinitive_NTM->voracious = 0;
#line 1230 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<auxiliary-verb-only>", auxiliary_verb_only_NTM, 1, 1000000000);
auxiliary_verb_only_NTM->voracious = 0;
#line 1234 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<instance-of-verb>", instance_of_verb_NTM, 1, 1000000000);
instance_of_verb_NTM->voracious = 0;
#line 1251 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<not-instance-of-verb-at-run-time>", not_instance_of_verb_at_run_time_NTM, 1, 1000000000);
not_instance_of_verb_at_run_time_NTM->voracious = 0;
#line 1255 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<modal-verb>", modal_verb_NTM, 1, 1000000000);
modal_verb_NTM->voracious = 0;
#line 1274 "inform7/Chapter 11/Conjugation of Verbs.w"
INTERNAL_NONTERMINAL("<verb-infinitive>", verb_infinitive_NTM, 1, 1000000000);
verb_infinitive_NTM->voracious = 0;
#line 125 "inform7/Chapter 11/Prepositions.w"
INTERNAL_NONTERMINAL("<preposition>", preposition_NTM, 1, 1000000000);
preposition_NTM->voracious = 1;
#line 146 "inform7/Chapter 11/Prepositions.w"
INTERNAL_NONTERMINAL("<preposition-implying-player>", preposition_implying_player_NTM, 1, 1000000000);
preposition_implying_player_NTM->voracious = 1;
#line 202 "inform7/Chapter 11/Prepositions.w"
REGISTER_NONTERMINAL("<comparative-property-construction>", comparative_property_construction_NTM);
#line 208 "inform7/Chapter 11/Prepositions.w"
REGISTER_NONTERMINAL("<same-property-as-construction>", same_property_as_construction_NTM);
#line 216 "inform7/Chapter 11/Prepositions.w"
REGISTER_NONTERMINAL("<same-property-as-in-lexicon>", same_property_as_in_lexicon_NTM);
#line 90 "inform7/Chapter 12/Lexical Services.w"
INTERNAL_NONTERMINAL("<if-start-of-paragraph>", if_start_of_paragraph_NTM, 0, 0);
if_start_of_paragraph_NTM->voracious = 0;
#line 107 "inform7/Chapter 12/Lexical Services.w"
INTERNAL_NONTERMINAL("<if-start-of-source-text>", if_start_of_source_text_NTM, 0, 0);
if_start_of_source_text_NTM->voracious = 0;
#line 117 "inform7/Chapter 12/Lexical Services.w"
INTERNAL_NONTERMINAL("<if-not-deliberately-capitalised>", if_not_deliberately_capitalised_NTM, 0, 0);
if_not_deliberately_capitalised_NTM->voracious = 0;
#line 342 "inform7/Chapter 12/Wordings.w"
REGISTER_NONTERMINAL("<balanced-text>", balanced_text_NTM);
#line 429 "inform7/Chapter 13/Sentences.w"
REGISTER_NONTERMINAL("<dividing-sentence>", dividing_sentence_NTM);
#line 433 "inform7/Chapter 13/Sentences.w"
REGISTER_NONTERMINAL("<heading>", heading_NTM);
#line 440 "inform7/Chapter 13/Sentences.w"
REGISTER_NONTERMINAL("<extension-end-marker-sentence>", extension_end_marker_sentence_NTM);
#line 589 "inform7/Chapter 13/Sentences.w"
REGISTER_NONTERMINAL("<structural-sentence>", structural_sentence_NTM);
#line 606 "inform7/Chapter 13/Sentences.w"
REGISTER_NONTERMINAL("<language-modifying-sentence>", language_modifying_sentence_NTM);
#line 617 "inform7/Chapter 13/Sentences.w"
REGISTER_NONTERMINAL("<use-option-sentence-shape>", use_option_sentence_shape_NTM);
#line 677 "inform7/Chapter 13/Sentences.w"
REGISTER_NONTERMINAL("<comma-divisible-sentence>", comma_divisible_sentence_NTM);
#line 695 "inform7/Chapter 13/Sentences.w"
REGISTER_NONTERMINAL("<list-or-division>", list_or_division_NTM);
#line 294 "inform7/Chapter 13/Headings.w"
REGISTER_NONTERMINAL("<heading-qualifier>", heading_qualifier_NTM);
#line 300 "inform7/Chapter 13/Headings.w"
REGISTER_NONTERMINAL("<bracketed-heading-qualifier>", bracketed_heading_qualifier_NTM);
#line 307 "inform7/Chapter 13/Headings.w"
REGISTER_NONTERMINAL("<platform-qualifier>", platform_qualifier_NTM);
#line 311 "inform7/Chapter 13/Headings.w"
REGISTER_NONTERMINAL("<platform-identifier>", platform_identifier_NTM);
#line 317 "inform7/Chapter 13/Headings.w"
REGISTER_NONTERMINAL("<extension-qualifier>", extension_qualifier_NTM);
#line 324 "inform7/Chapter 13/Headings.w"
REGISTER_NONTERMINAL("<extension-identifier>", extension_identifier_NTM);
#line 294 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<nonstructural-sentence>", nonstructural_sentence_NTM);
#line 492 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase>", nounphrase_NTM);
#line 495 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-definite>", nounphrase_definite_NTM);
#line 499 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-figure>", nounphrase_figure_NTM);
#line 502 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-sound>", nounphrase_sound_NTM);
#line 505 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-external-file>", nounphrase_external_file_NTM);
#line 508 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-actionable>", nounphrase_actionable_NTM);
#line 511 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<variable-creation-tail>", variable_creation_tail_NTM);
#line 518 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<translation-target>", translation_target_NTM);
#line 545 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<existential-sentence>", existential_sentence_NTM);
#line 569 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<existential-sentence-inner>", existential_sentence_inner_NTM);
#line 577 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<existential-sentence-inner-tail1>", existential_sentence_inner_tail1_NTM);
#line 581 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<existential-sentence-inner-tail2>", existential_sentence_inner_tail2_NTM);
#line 585 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<existential-sentence-inner-tail3>", existential_sentence_inner_tail3_NTM);
#line 639 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<certainty>", certainty_NTM);
#line 697 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence>", regular_sentence_NTM);
#line 707 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail1-without-rc>", regular_sentence_tail1_without_rc_NTM);
#line 713 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail2-without-rc>", regular_sentence_tail2_without_rc_NTM);
#line 719 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail3-without-rc>", regular_sentence_tail3_without_rc_NTM);
#line 725 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail4-without-rc>", regular_sentence_tail4_without_rc_NTM);
#line 731 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail1>", regular_sentence_tail1_NTM);
#line 735 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail2>", regular_sentence_tail2_NTM);
#line 739 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail3>", regular_sentence_tail3_NTM);
#line 743 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail4>", regular_sentence_tail4_NTM);
#line 777 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail1-inner>", regular_sentence_tail1_inner_NTM);
#line 783 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail2-inner>", regular_sentence_tail2_inner_NTM);
#line 789 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail3-inner>", regular_sentence_tail3_inner_NTM);
#line 795 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<regular-sentence-tail4-inner>", regular_sentence_tail4_inner_NTM);
#line 842 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<bad-nonstructural-sentence-diagnosis>", bad_nonstructural_sentence_diagnosis_NTM);
#line 845 "inform7/Chapter 13/Verb Phrases.w"
REGISTER_NONTERMINAL("<bad-nonstructural-sentence-diagnosis-tail>", bad_nonstructural_sentence_diagnosis_tail_NTM);
#line 74 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-articled>", nounphrase_articled_NTM);
#line 98 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-balanced>", np_balanced_NTM);
#line 102 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-articled-balanced>", np_articled_balanced_NTM);
#line 135 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-articled-list>", nounphrase_articled_list_NTM);
#line 140 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-articled-tail>", np_articled_tail_NTM);
#line 164 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-rule-list>", nounphrase_rule_list_NTM);
#line 169 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-rule-tail>", np_rule_tail_NTM);
#line 173 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-rule>", nounphrase_rule_NTM);
#line 183 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-alternative-list>", nounphrase_alternative_list_NTM);
#line 188 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-alternative-tail>", np_alternative_tail_NTM);
#line 207 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-as-object>", nounphrase_as_object_NTM);
#line 211 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<nounphrase-as-subject>", nounphrase_as_subject_NTM);
#line 216 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-inner>", np_inner_NTM);
#line 224 "inform7/Chapter 13/Noun Phrases.w"
INTERNAL_NONTERMINAL("<if-copular>", if_copular_NTM, 0, 0);
if_copular_NTM->voracious = 0;
#line 263 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-relative-phrase-limited>", np_relative_phrase_limited_NTM);
#line 269 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-relative-phrase-unlimited>", np_relative_phrase_unlimited_NTM);
#line 283 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-relative-phrase-exception>", np_relative_phrase_exception_NTM);
#line 302 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-relative-phrase-implicit>", np_relative_phrase_implicit_NTM);
#line 308 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-relative-phrase-explicit>", np_relative_phrase_explicit_NTM);
#line 387 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-inner-without-rp>", np_inner_without_rp_NTM);
#line 413 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-with-or-having-tail>", np_with_or_having_tail_NTM);
#line 419 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-new-property-list>", np_new_property_list_NTM);
#line 424 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-new-property>", np_new_property_NTM);
#line 427 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-new-property-tail>", np_new_property_tail_NTM);
#line 431 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-tail>", np_tail_NTM);
#line 443 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-kind-phrase>", np_kind_phrase_NTM);
#line 447 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-kind-phrase-unarticled>", np_kind_phrase_unarticled_NTM);
#line 460 "inform7/Chapter 13/Noun Phrases.w"
REGISTER_NONTERMINAL("<np-from-or-of-tail>", np_from_or_of_tail_NTM);
#line 225 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<prohibited-property-owners>", prohibited_property_owners_NTM);
#line 235 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<action-name-formal>", action_name_formal_NTM);
#line 238 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<activity-name-formal>", activity_name_formal_NTM);
#line 241 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<relation-name-formal>", relation_name_formal_NTM);
#line 244 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<rule-name-formal>", rule_name_formal_NTM);
#line 247 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<rulebook-name-formal>", rulebook_name_formal_NTM);
#line 260 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<has-properties-called-sentence-object>", has_properties_called_sentence_object_NTM);
#line 264 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<has-property-name-tail>", has_property_name_tail_NTM);
#line 268 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<has-property-name>", has_property_name_NTM);
#line 272 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<bad-property-name-diagnosis>", bad_property_name_diagnosis_NTM);
#line 328 "inform7/Chapter 13/Of and From.w"
REGISTER_NONTERMINAL("<sentence-needing-second-look>", sentence_needing_second_look_NTM);
#line 1291 "inform7/Chapter 13/Rule Subtrees.w"
REGISTER_NONTERMINAL("<verify-expanded-text-substitution>", verify_expanded_text_substitution_NTM);
#line 1474 "inform7/Chapter 13/Rule Subtrees.w"
REGISTER_NONTERMINAL("<control-structure-phrase>", control_structure_phrase_NTM);
#line 1486 "inform7/Chapter 13/Rule Subtrees.w"
REGISTER_NONTERMINAL("<end-control-structure-phrase>", end_control_structure_phrase_NTM);
#line 1491 "inform7/Chapter 13/Rule Subtrees.w"
REGISTER_NONTERMINAL("<other-significant-phrase>", other_significant_phrase_NTM);
#line 1498 "inform7/Chapter 13/Rule Subtrees.w"
REGISTER_NONTERMINAL("<phrase-with-comma-notation>", phrase_with_comma_notation_NTM);
#line 1504 "inform7/Chapter 13/Rule Subtrees.w"
REGISTER_NONTERMINAL("<instead-keyword>", instead_keyword_NTM);
#line 1511 "inform7/Chapter 13/Rule Subtrees.w"
REGISTER_NONTERMINAL("<phrase-beginning-block>", phrase_beginning_block_NTM);
#line 72 "inform7/Chapter 14/Including Extensions.w"
REGISTER_NONTERMINAL("<extension-title-and-version>", extension_title_and_version_NTM);
#line 78 "inform7/Chapter 14/Including Extensions.w"
REGISTER_NONTERMINAL("<extension-unversioned>", extension_unversioned_NTM);
#line 82 "inform7/Chapter 14/Including Extensions.w"
REGISTER_NONTERMINAL("<extension-unversioned-inner>", extension_unversioned_inner_NTM);
#line 99 "inform7/Chapter 14/Including Extensions.w"
INTERNAL_NONTERMINAL("<extension-version>", extension_version_NTM, 1, 1);
extension_version_NTM->voracious = 0;
#line 230 "inform7/Chapter 14/Including Extensions.w"
REGISTER_NONTERMINAL("<extension-body>", extension_body_NTM);
#line 346 "inform7/Chapter 14/Including Extensions.w"
REGISTER_NONTERMINAL("<begins-here-sentence-subject>", begins_here_sentence_subject_NTM);
#line 306 "inform7/Chapter 15/Traverse for Assertions.w"
REGISTER_NONTERMINAL("<no-verb-diagnosis>", no_verb_diagnosis_NTM);
#line 373 "inform7/Chapter 15/Refine Parse Tree.w"
REGISTER_NONTERMINAL("<newfound-property-of>", newfound_property_of_NTM);
#line 481 "inform7/Chapter 15/Refine Parse Tree.w"
REGISTER_NONTERMINAL("<assertion-np-as-value>", assertion_np_as_value_NTM);
#line 400 "inform7/Chapter 15/The Creator.w"
REGISTER_NONTERMINAL("<grammatical-gender-marker>", grammatical_gender_marker_NTM);
#line 403 "inform7/Chapter 15/The Creator.w"
REGISTER_NONTERMINAL("<grammatical-gender-abbreviation>", grammatical_gender_abbreviation_NTM);
#line 444 "inform7/Chapter 15/The Creator.w"
REGISTER_NONTERMINAL("<creation-problem-diagnosis>", creation_problem_diagnosis_NTM);
#line 1060 "inform7/Chapter 15/The Creator.w"
REGISTER_NONTERMINAL("<text-ending-with-a-calling>", text_ending_with_a_calling_NTM);
#line 1064 "inform7/Chapter 15/The Creator.w"
REGISTER_NONTERMINAL("<text-including-a-calling>", text_including_a_calling_NTM);
#line 1077 "inform7/Chapter 15/The Creator.w"
REGISTER_NONTERMINAL("<unsuitable-name>", unsuitable_name_NTM);
#line 1082 "inform7/Chapter 15/The Creator.w"
REGISTER_NONTERMINAL("<unsuitable-name-for-locals>", unsuitable_name_for_locals_NTM);
#line 1087 "inform7/Chapter 15/The Creator.w"
REGISTER_NONTERMINAL("<unfortunate-name>", unfortunate_name_NTM);
#line 1719 "inform7/Chapter 15/Make Assertions.w"
REGISTER_NONTERMINAL("<something-loose-diagnosis>", something_loose_diagnosis_NTM);
#line 31 "inform7/Chapter 15/Property Declarations.w"
REGISTER_NONTERMINAL("<forbidden-property-owners>", forbidden_property_owners_NTM);
#line 126 "inform7/Chapter 15/Property Declarations.w"
REGISTER_NONTERMINAL("<can-be-sentence-object>", can_be_sentence_object_NTM);
#line 132 "inform7/Chapter 15/Property Declarations.w"
REGISTER_NONTERMINAL("<condition-name>", condition_name_NTM);
#line 136 "inform7/Chapter 15/Property Declarations.w"
REGISTER_NONTERMINAL("<condition-name-inner>", condition_name_inner_NTM);
#line 141 "inform7/Chapter 15/Property Declarations.w"
REGISTER_NONTERMINAL("<condition-name-innermost>", condition_name_innermost_NTM);
#line 24 "inform7/Chapter 16/Architecture of the S-Parser.w"
INTERNAL_NONTERMINAL("<s-plain-text>", s_plain_text_NTM, 1, 1000000000);
s_plain_text_NTM->voracious = 0;
#line 40 "inform7/Chapter 16/Architecture of the S-Parser.w"
INTERNAL_NONTERMINAL("<s-plain-text-with-equals>", s_plain_text_with_equals_NTM, 1, 1000000000);
s_plain_text_with_equals_NTM->voracious = 0;
#line 64 "inform7/Chapter 16/Architecture of the S-Parser.w"
INTERNAL_NONTERMINAL("<s-value>", s_value_NTM, 1, 1000000000);
s_value_NTM->voracious = 0;
#line 76 "inform7/Chapter 16/Architecture of the S-Parser.w"
INTERNAL_NONTERMINAL("<s-condition>", s_condition_NTM, 1, 1000000000);
s_condition_NTM->voracious = 0;
#line 88 "inform7/Chapter 16/Architecture of the S-Parser.w"
INTERNAL_NONTERMINAL("<s-non-action-condition>", s_non_action_condition_NTM, 1, 1000000000);
s_non_action_condition_NTM->voracious = 0;
#line 103 "inform7/Chapter 16/Architecture of the S-Parser.w"
INTERNAL_NONTERMINAL("<s-type-expression>", s_type_expression_NTM, 1, 1000000000);
s_type_expression_NTM->voracious = 0;
#line 119 "inform7/Chapter 16/Architecture of the S-Parser.w"
INTERNAL_NONTERMINAL("<s-descriptive-type-expression>", s_descriptive_type_expression_NTM, 1, 1000000000);
s_descriptive_type_expression_NTM->voracious = 0;
#line 132 "inform7/Chapter 16/Architecture of the S-Parser.w"
REGISTER_NONTERMINAL("<s-type-expression-or-value>", s_type_expression_or_value_NTM);
#line 140 "inform7/Chapter 16/Architecture of the S-Parser.w"
INTERNAL_NONTERMINAL("<s-explicit-action>", s_explicit_action_NTM, 1, 1000000000);
s_explicit_action_NTM->voracious = 0;
#line 157 "inform7/Chapter 16/Architecture of the S-Parser.w"
INTERNAL_NONTERMINAL("<s-constant-action>", s_constant_action_NTM, 1, 1000000000);
s_constant_action_NTM->voracious = 0;
#line 20 "inform7/Chapter 16/Parse Literals.w"
REGISTER_NONTERMINAL("<s-literal>", s_literal_NTM);
#line 32 "inform7/Chapter 16/Parse Literals.w"
INTERNAL_NONTERMINAL("<s-literal-unit-notation>", s_literal_unit_notation_NTM, 1, 1000000000);
s_literal_unit_notation_NTM->voracious = 0;
#line 49 "inform7/Chapter 16/Parse Literals.w"
REGISTER_NONTERMINAL("<cardinal-number-in-words>", cardinal_number_in_words_NTM);
#line 67 "inform7/Chapter 16/Parse Literals.w"
REGISTER_NONTERMINAL("<ordinal-number-in-words>", ordinal_number_in_words_NTM);
#line 94 "inform7/Chapter 16/Parse Literals.w"
INTERNAL_NONTERMINAL("<cardinal-number>", cardinal_number_NTM, 1, 1);
cardinal_number_NTM->voracious = 0;
#line 103 "inform7/Chapter 16/Parse Literals.w"
INTERNAL_NONTERMINAL("<ordinal-number>", ordinal_number_NTM, 1, 1);
ordinal_number_NTM->voracious = 0;
#line 115 "inform7/Chapter 16/Parse Literals.w"
INTERNAL_NONTERMINAL("<cardinal-number-unlimited>", cardinal_number_unlimited_NTM, 1, 1);
cardinal_number_unlimited_NTM->voracious = 0;
#line 148 "inform7/Chapter 16/Parse Literals.w"
INTERNAL_NONTERMINAL("<quoted-text>", quoted_text_NTM, 1, 1);
quoted_text_NTM->voracious = 0;
#line 155 "inform7/Chapter 16/Parse Literals.w"
INTERNAL_NONTERMINAL("<quoted-text-with-subs>", quoted_text_with_subs_NTM, 1, 1);
quoted_text_with_subs_NTM->voracious = 0;
#line 162 "inform7/Chapter 16/Parse Literals.w"
INTERNAL_NONTERMINAL("<quoted-text-without-subs>", quoted_text_without_subs_NTM, 1, 1);
quoted_text_without_subs_NTM->voracious = 0;
#line 173 "inform7/Chapter 16/Parse Literals.w"
INTERNAL_NONTERMINAL("<empty-text>", empty_text_NTM, 1, 1);
empty_text_NTM->voracious = 0;
#line 184 "inform7/Chapter 16/Parse Literals.w"
INTERNAL_NONTERMINAL("<response-letter>", response_letter_NTM, 1, 1);
response_letter_NTM->voracious = 0;
#line 200 "inform7/Chapter 16/Parse Literals.w"
REGISTER_NONTERMINAL("<s-literal-truth-state>", s_literal_truth_state_NTM);
#line 214 "inform7/Chapter 16/Parse Literals.w"
REGISTER_NONTERMINAL("<s-literal-real-number>", s_literal_real_number_NTM);
#line 221 "inform7/Chapter 16/Parse Literals.w"
INTERNAL_NONTERMINAL("<literal-real-in-digits>", literal_real_in_digits_NTM, 1, 1000000000);
literal_real_in_digits_NTM->voracious = 0;
#line 18 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-constant-value>", s_constant_value_NTM);
#line 54 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-miscellaneous-proper-noun>", s_miscellaneous_proper_noun_NTM, 1, 1000000000);
s_miscellaneous_proper_noun_NTM->voracious = 0;
#line 81 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-named-constant>", s_named_constant_NTM, 1, 1000000000);
s_named_constant_NTM->voracious = 0;
#line 97 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-rulebook-outcome-name>", s_rulebook_outcome_name_NTM, 1, 1000000000);
s_rulebook_outcome_name_NTM->voracious = 0;
#line 106 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-use-option-name>", s_use_option_name_NTM, 1, 1000000000);
s_use_option_name_NTM->voracious = 0;
#line 114 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-rule-name>", s_rule_name_NTM, 1, 1000000000);
s_rule_name_NTM->voracious = 0;
#line 129 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-table-column-name>", s_table_column_name_NTM, 1, 1000000000);
s_table_column_name_NTM->voracious = 0;
#line 142 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<property-name-as-noun-phrase>", property_name_as_noun_phrase_NTM);
#line 146 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-property-name>", s_property_name_NTM, 1, 1000000000);
s_property_name_NTM->voracious = 0;
#line 180 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-adjective-list-as-desc>", s_adjective_list_as_desc_NTM);
#line 240 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-adjective-list>", s_adjective_list_NTM);
#line 245 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-adjective-list-unarticled>", s_adjective_list_unarticled_NTM);
#line 255 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-adjective>", s_adjective_NTM, 1, 1000000000);
s_adjective_NTM->voracious = 1;
#line 378 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-qualifiable-noun>", s_qualifiable_noun_NTM);
#line 382 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-qualifiable-common-noun>", s_qualifiable_common_noun_NTM);
#line 385 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-qualifiable-proper-noun>", s_qualifiable_proper_noun_NTM);
#line 392 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-instance-name>", s_instance_name_NTM, 1, 1000000000);
s_instance_name_NTM->voracious = 0;
#line 413 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-applicable-adjective-list>", s_applicable_adjective_list_NTM);
#line 469 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description>", s_description_NTM);
#line 473 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-uncomposite>", s_description_uncomposite_NTM);
#line 476 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-uncomposite-inner>", s_description_uncomposite_inner_NTM);
#line 480 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-uncalled>", s_description_uncalled_NTM);
#line 490 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-unspecified>", s_description_unspecified_NTM);
#line 494 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-common-description-unspecified>", s_common_description_unspecified_NTM);
#line 498 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-proper-description-unspecified>", s_proper_description_unspecified_NTM);
#line 502 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<if-trying-omission-permitted>", if_trying_omission_permitted_NTM, 0, 0);
if_trying_omission_permitted_NTM->voracious = 0;
#line 507 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<if-multiplicitous>", if_multiplicitous_NTM, 0, 0);
if_multiplicitous_NTM->voracious = 0;
#line 516 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-nounless>", s_description_nounless_NTM);
#line 520 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-nounless-uncomposite>", s_description_nounless_uncomposite_NTM);
#line 524 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-nounless-uncalled>", s_description_nounless_uncalled_NTM);
#line 534 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-description-nounless-unspecified>", s_description_nounless_unspecified_NTM);
#line 617 "inform7/Chapter 16/Constants and Descriptions.w"
REGISTER_NONTERMINAL("<s-calling-name>", s_calling_name_NTM);
#line 634 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-specifier>", s_specifier_NTM, 1, 1000000000);
s_specifier_NTM->voracious = 1;
#line 654 "inform7/Chapter 16/Constants and Descriptions.w"
INTERNAL_NONTERMINAL("<s-specifying-noun>", s_specifying_noun_NTM, 1, 1000000000);
s_specifying_noun_NTM->voracious = 1;
#line 58 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-type-expression-uncached>", s_type_expression_uncached_NTM);
#line 62 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-type-expression-unarticled>", s_type_expression_unarticled_NTM);
#line 85 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-descriptive-type-expression-uncached>", s_descriptive_type_expression_uncached_NTM);
#line 89 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-descriptive-type-expression-unarticled>", s_descriptive_type_expression_unarticled_NTM);
#line 106 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-variable-scope>", s_variable_scope_NTM);
#line 111 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-variable-contents>", s_variable_contents_NTM);
#line 162 "inform7/Chapter 16/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<if-let-equation-mode>", if_let_equation_mode_NTM, 0, 0);
if_let_equation_mode_NTM->voracious = 0;
#line 172 "inform7/Chapter 16/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<if-pronoun-present>", if_pronoun_present_NTM, 0, 0);
if_pronoun_present_NTM->voracious = 0;
#line 182 "inform7/Chapter 16/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<if-table-column-expected>", if_table_column_expected_NTM, 0, 0);
if_table_column_expected_NTM->voracious = 0;
#line 188 "inform7/Chapter 16/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<if-property-name-expected>", if_property_name_expected_NTM, 0, 0);
if_property_name_expected_NTM->voracious = 0;
#line 245 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-value-uncached>", s_value_uncached_NTM);
#line 278 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-equation-usage>", s_equation_usage_NTM);
#line 367 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-variable>", s_variable_NTM);
#line 373 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-nonglobal-variable>", s_nonglobal_variable_NTM);
#line 378 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-variable-as-value>", s_variable_as_value_NTM);
#line 384 "inform7/Chapter 16/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<s-local-variable>", s_local_variable_NTM, 1, 1000000000);
s_local_variable_NTM->voracious = 0;
#line 396 "inform7/Chapter 16/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<s-stacked-variable>", s_stacked_variable_NTM, 1, 1000000000);
s_stacked_variable_NTM->voracious = 0;
#line 412 "inform7/Chapter 16/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<s-global-variable>", s_global_variable_NTM, 1, 1000000000);
s_global_variable_NTM->voracious = 0;
#line 423 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<property-of-shape>", property_of_shape_NTM);
#line 435 "inform7/Chapter 16/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<s-value-phrase-non-of>", s_value_phrase_non_of_NTM, 1, 1000000000);
s_value_phrase_non_of_NTM->voracious = 0;
#line 453 "inform7/Chapter 16/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<s-value-phrase>", s_value_phrase_NTM, 1, 1000000000);
s_value_phrase_NTM->voracious = 0;
#line 480 "inform7/Chapter 16/Type Expressions and Values.w"
REGISTER_NONTERMINAL("<s-table-reference>", s_table_reference_NTM);
#line 559 "inform7/Chapter 16/Type Expressions and Values.w"
INTERNAL_NONTERMINAL("<s-action-pattern-as-value>", s_action_pattern_as_value_NTM, 1, 1000000000);
s_action_pattern_as_value_NTM->voracious = 0;
#line 37 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-sentence>", s_sentence_NTM);
#line 52 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-existential-np>", s_existential_np_NTM);
#line 55 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-existential-verb-tail>", s_existential_verb_tail_NTM);
#line 105 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-general-verb-tail>", s_general_verb_tail_NTM);
#line 136 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-universal-relation-term>", s_universal_relation_term_NTM);
#line 158 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-np-with-relative-clause>", s_np_with_relative_clause_NTM);
#line 162 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-implied-relative-verb-tail>", s_implied_relative_verb_tail_NTM);
#line 166 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-relative-verb-tail>", s_relative_verb_tail_NTM);
#line 233 "inform7/Chapter 16/Verbal and Relative Clauses.w"
INTERNAL_NONTERMINAL("<s-purely-physical-description>", s_purely_physical_description_NTM, 1, 1000000000);
s_purely_physical_description_NTM->voracious = 0;
#line 243 "inform7/Chapter 16/Verbal and Relative Clauses.w"
INTERNAL_NONTERMINAL("<if-forced-physical>", if_forced_physical_NTM, 0, 0);
if_forced_physical_NTM->voracious = 0;
#line 254 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-noun-phrase>", s_noun_phrase_NTM);
#line 259 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-noun-phrase-nounless>", s_noun_phrase_nounless_NTM);
#line 268 "inform7/Chapter 16/Verbal and Relative Clauses.w"
REGISTER_NONTERMINAL("<s-descriptive-np>", s_descriptive_np_NTM);
#line 23 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-condition-uncached>", s_condition_uncached_NTM);
#line 32 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-condition-pure>", s_condition_pure_NTM);
#line 54 "inform7/Chapter 16/Conditions and Phrases.w"
INTERNAL_NONTERMINAL("<s-condition-with-chronology>", s_condition_with_chronology_NTM, 1, 1000000000);
s_condition_with_chronology_NTM->voracious = 0;
#line 104 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-condition-atomic>", s_condition_atomic_NTM);
#line 124 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-nonexistential-phrase-to-decide>", s_nonexistential_phrase_to_decide_NTM);
#line 129 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-existential-phrase-to-decide>", s_existential_phrase_to_decide_NTM);
#line 134 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<existential-verb-phrase>", existential_verb_phrase_NTM);
#line 137 "inform7/Chapter 16/Conditions and Phrases.w"
INTERNAL_NONTERMINAL("<s-phrase-to-decide>", s_phrase_to_decide_NTM, 1, 1000000000);
s_phrase_to_decide_NTM->voracious = 0;
#line 153 "inform7/Chapter 16/Conditions and Phrases.w"
INTERNAL_NONTERMINAL("<s-phrase-option-in-use>", s_phrase_option_in_use_NTM, 1, 1000000000);
s_phrase_option_in_use_NTM->voracious = 0;
#line 172 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-action-pattern-as-condition>", s_action_pattern_as_condition_NTM);
#line 175 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-action-pattern-as-negated-condition>", s_action_pattern_as_negated_condition_NTM);
#line 181 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-past-action-pattern-as-condition>", s_past_action_pattern_as_condition_NTM);
#line 184 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-past-action-pattern-as-negated-condition>", s_past_action_pattern_as_negated_condition_NTM);
#line 215 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-command>", s_command_NTM);
#line 219 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-say-command>", s_say_command_NTM);
#line 226 "inform7/Chapter 16/Conditions and Phrases.w"
INTERNAL_NONTERMINAL("<s-to-phrase>", s_to_phrase_NTM, 1, 1000000000);
s_to_phrase_NTM->voracious = 0;
#line 239 "inform7/Chapter 16/Conditions and Phrases.w"
REGISTER_NONTERMINAL("<s-say-phrase>", s_say_phrase_NTM);
#line 248 "inform7/Chapter 16/Conditions and Phrases.w"
INTERNAL_NONTERMINAL("<s-text-substitution>", s_text_substitution_NTM, 1, 1000000000);
s_text_substitution_NTM->voracious = 0;
#line 631 "inform7/Chapter 19/Kinds.w"
REGISTER_NONTERMINAL("<notable-linguistic-kinds>", notable_linguistic_kinds_NTM);
#line 41 "inform7/Chapter 19/Describing Kinds.w"
INTERNAL_NONTERMINAL("<if-parsing-phrase-tokens>", if_parsing_phrase_tokens_NTM, 0, 0);
if_parsing_phrase_tokens_NTM->voracious = 0;
#line 51 "inform7/Chapter 19/Describing Kinds.w"
INTERNAL_NONTERMINAL("<s-phrase-token-type>", s_phrase_token_type_NTM, 1, 1000000000);
s_phrase_token_type_NTM->voracious = 0;
#line 65 "inform7/Chapter 19/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-kind-for-template>", k_kind_for_template_NTM, 1, 1000000000);
k_kind_for_template_NTM->voracious = 0;
#line 78 "inform7/Chapter 19/Describing Kinds.w"
INTERNAL_NONTERMINAL("<s-kind-as-name-token>", s_kind_as_name_token_NTM, 1, 1000000000);
s_kind_as_name_token_NTM->voracious = 0;
#line 97 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind-as-name-token>", k_kind_as_name_token_NTM);
#line 104 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind-abbreviating>", k_kind_abbreviating_NTM);
#line 112 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind>", k_kind_NTM);
#line 123 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind-articled>", k_kind_articled_NTM);
#line 131 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-variable-definition>", k_variable_definition_NTM);
#line 142 "inform7/Chapter 19/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-base-kind>", k_base_kind_NTM, 1, 1000000000);
k_base_kind_NTM->voracious = 0;
#line 176 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-irregular-kind-construction>", k_irregular_kind_construction_NTM);
#line 195 "inform7/Chapter 19/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-kind-construction>", k_kind_construction_NTM, 1, 1000000000);
k_kind_construction_NTM->voracious = 0;
#line 260 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-single-material>", k_single_material_NTM);
#line 265 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-optional-material>", k_optional_material_NTM);
#line 272 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-tupled-material>", k_tupled_material_NTM);
#line 277 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-tuple-list>", k_tuple_list_NTM);
#line 361 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind-of-kind>", k_kind_of_kind_NTM);
#line 407 "inform7/Chapter 19/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-kind-variable>", k_kind_variable_NTM, 1, 1);
k_kind_variable_NTM->voracious = 0;
#line 421 "inform7/Chapter 19/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-formal-kind-variable>", k_formal_kind_variable_NTM, 1, 1);
k_formal_kind_variable_NTM->voracious = 0;
#line 432 "inform7/Chapter 19/Describing Kinds.w"
INTERNAL_NONTERMINAL("<k-formal-kind-variable-singular>", k_formal_kind_variable_singular_NTM, 1, 1);
k_formal_kind_variable_singular_NTM->voracious = 0;
#line 444 "inform7/Chapter 19/Describing Kinds.w"
REGISTER_NONTERMINAL("<k-kind-variable-texts>", k_kind_variable_texts_NTM);
#line 2078 "inform7/Chapter 20/Dash.w"
REGISTER_NONTERMINAL("<structural-phrase-problem-diagnosis>", structural_phrase_problem_diagnosis_NTM);
#line 2426 "inform7/Chapter 20/Dash.w"
REGISTER_NONTERMINAL("<failed-text-substitution-diagnosis>", failed_text_substitution_diagnosis_NTM);
#line 2476 "inform7/Chapter 20/Dash.w"
REGISTER_NONTERMINAL("<condition-problem-diagnosis>", condition_problem_diagnosis_NTM);
#line 2480 "inform7/Chapter 20/Dash.w"
REGISTER_NONTERMINAL("<condition-problem-part-tail>", condition_problem_part_tail_NTM);
#line 2484 "inform7/Chapter 20/Dash.w"
REGISTER_NONTERMINAL("<condition-problem-part>", condition_problem_part_NTM);
#line 2647 "inform7/Chapter 20/Dash.w"
REGISTER_NONTERMINAL("<unknown-text-shape>", unknown_text_shape_NTM);
#line 2652 "inform7/Chapter 20/Dash.w"
REGISTER_NONTERMINAL("<unknown-text-substitution-problem-diagnosis>", unknown_text_substitution_problem_diagnosis_NTM);
#line 2787 "inform7/Chapter 20/Dash.w"
REGISTER_NONTERMINAL("<unknown-value-problem-diagnosis>", unknown_value_problem_diagnosis_NTM);
#line 2794 "inform7/Chapter 20/Dash.w"
REGISTER_NONTERMINAL("<unknown-use-option-diagnosis>", unknown_use_option_diagnosis_NTM);
#line 2798 "inform7/Chapter 20/Dash.w"
REGISTER_NONTERMINAL("<unknown-activity-diagnosis>", unknown_activity_diagnosis_NTM);
#line 228 "inform7/Chapter 21/Properties.w"
REGISTER_NONTERMINAL("<notable-properties>", notable_properties_NTM);
#line 269 "inform7/Chapter 21/Properties.w"
REGISTER_NONTERMINAL("<property-name-construction>", property_name_construction_NTM);
#line 299 "inform7/Chapter 21/Properties.w"
INTERNAL_NONTERMINAL("<property-name>", property_name_NTM, 1, 1000000000);
property_name_NTM->voracious = 0;
#line 313 "inform7/Chapter 21/Properties.w"
INTERNAL_NONTERMINAL("<either-or-property-name>", either_or_property_name_NTM, 1, 1000000000);
either_or_property_name_NTM->voracious = 0;
#line 325 "inform7/Chapter 21/Properties.w"
INTERNAL_NONTERMINAL("<value-property-name>", value_property_name_NTM, 1, 1000000000);
value_property_name_NTM->voracious = 0;
#line 341 "inform7/Chapter 21/Properties.w"
INTERNAL_NONTERMINAL("<property-name-v>", property_name_v_NTM, 1, 1000000000);
property_name_v_NTM->voracious = 1;
#line 357 "inform7/Chapter 21/Properties.w"
REGISTER_NONTERMINAL("<name-looking-like-property-test>", name_looking_like_property_test_NTM);
#line 364 "inform7/Chapter 21/Properties.w"
INTERNAL_NONTERMINAL("<ambiguous-property-name>", ambiguous_property_name_NTM, 1, 1000000000);
ambiguous_property_name_NTM->voracious = 1;
#line 229 "inform7/Chapter 21/Measurement Adjectives.w"
REGISTER_NONTERMINAL("<measurement-adjective-definition>", measurement_adjective_definition_NTM);
#line 234 "inform7/Chapter 21/Measurement Adjectives.w"
REGISTER_NONTERMINAL("<measurement-range>", measurement_range_NTM);
#line 74 "inform7/Chapter 21/Setting Property Relation.w"
REGISTER_NONTERMINAL("<relation-property-name>", relation_property_name_NTM);
#line 60 "inform7/Chapter 24/List Constants.w"
REGISTER_NONTERMINAL("<s-literal-list>", s_literal_list_NTM);
#line 64 "inform7/Chapter 24/List Constants.w"
REGISTER_NONTERMINAL("<literal-list-contents>", literal_list_contents_NTM);
#line 68 "inform7/Chapter 24/List Constants.w"
REGISTER_NONTERMINAL("<literal-list-entry>", literal_list_entry_NTM);
#line 219 "inform7/Chapter 25/Table Columns.w"
REGISTER_NONTERMINAL("<table-column-heading>", table_column_heading_NTM);
#line 226 "inform7/Chapter 25/Table Columns.w"
REGISTER_NONTERMINAL("<table-column-heading-unbracketed>", table_column_heading_unbracketed_NTM);
#line 268 "inform7/Chapter 25/Table Columns.w"
REGISTER_NONTERMINAL("<table-column-name-construction>", table_column_name_construction_NTM);
#line 253 "inform7/Chapter 25/Tables.w"
REGISTER_NONTERMINAL("<table-header>", table_header_NTM);
#line 259 "inform7/Chapter 25/Tables.w"
REGISTER_NONTERMINAL("<table-new-name>", table_new_name_NTM);
#line 281 "inform7/Chapter 25/Tables.w"
REGISTER_NONTERMINAL("<table-names-construction>", table_names_construction_NTM);
#line 291 "inform7/Chapter 25/Tables.w"
REGISTER_NONTERMINAL("<table-footer>", table_footer_NTM);
#line 858 "inform7/Chapter 25/Tables.w"
REGISTER_NONTERMINAL("<table-cell>", table_cell_NTM);
#line 867 "inform7/Chapter 25/Tables.w"
REGISTER_NONTERMINAL("<table-cell-blank>", table_cell_blank_NTM);
#line 870 "inform7/Chapter 25/Tables.w"
REGISTER_NONTERMINAL("<table-cell-value>", table_cell_value_NTM);
#line 878 "inform7/Chapter 25/Tables.w"
REGISTER_NONTERMINAL("<list-of-double-quotes>", list_of_double_quotes_NTM);
#line 312 "inform7/Chapter 25/Runtime Support for Tables.w"
REGISTER_NONTERMINAL("<rankings-table-name>", rankings_table_name_NTM);
#line 30 "inform7/Chapter 25/Tables of Definitions.w"
REGISTER_NONTERMINAL("<defined-by-sentence-subject>", defined_by_sentence_subject_NTM);
#line 52 "inform7/Chapter 25/Tables of Definitions.w"
REGISTER_NONTERMINAL("<defined-by-sentence-object>", defined_by_sentence_object_NTM);
#line 387 "inform7/Chapter 25/Tables of Definitions.w"
REGISTER_NONTERMINAL("<unfortunate-table-column-property>", unfortunate_table_column_property_NTM);
#line 145 "inform7/Chapter 26/Equations.w"
REGISTER_NONTERMINAL("<equation-name>", equation_name_NTM);
#line 198 "inform7/Chapter 26/Equations.w"
REGISTER_NONTERMINAL("<text-ending-in-comma>", text_ending_in_comma_NTM);
#line 242 "inform7/Chapter 26/Equations.w"
REGISTER_NONTERMINAL("<equation-names-construction>", equation_names_construction_NTM);
#line 325 "inform7/Chapter 26/Equations.w"
REGISTER_NONTERMINAL("<equation-where>", equation_where_NTM);
#line 388 "inform7/Chapter 26/Equations.w"
REGISTER_NONTERMINAL("<equation-where-list>", equation_where_list_NTM);
#line 393 "inform7/Chapter 26/Equations.w"
REGISTER_NONTERMINAL("<equation-where-tail>", equation_where_tail_NTM);
#line 397 "inform7/Chapter 26/Equations.w"
REGISTER_NONTERMINAL("<equation-where-setting-entry>", equation_where_setting_entry_NTM);
#line 400 "inform7/Chapter 26/Equations.w"
REGISTER_NONTERMINAL("<equation-where-setting>", equation_where_setting_NTM);
#line 409 "inform7/Chapter 26/Equations.w"
REGISTER_NONTERMINAL("<equation-symbol>", equation_symbol_NTM);
#line 639 "inform7/Chapter 26/Equations.w"
INTERNAL_NONTERMINAL("<valid-equation-symbol>", valid_equation_symbol_NTM, 1, 1000000000);
valid_equation_symbol_NTM->voracious = 0;
#line 160 "inform7/Chapter 27/Rulebooks.w"
REGISTER_NONTERMINAL("<new-rulebook-name>", new_rulebook_name_NTM);
#line 209 "inform7/Chapter 27/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-name-construction>", rulebook_name_construction_NTM);
#line 396 "inform7/Chapter 27/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-variable-name>", rulebook_variable_name_NTM);
#line 583 "inform7/Chapter 27/Rulebooks.w"
INTERNAL_NONTERMINAL("<rulebook-stem>", rulebook_stem_NTM, 1, 1000000000);
rulebook_stem_NTM->voracious = 1;
#line 611 "inform7/Chapter 27/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-stem-inner>", rulebook_stem_inner_NTM);
#line 616 "inform7/Chapter 27/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-stem-inner-unarticled>", rulebook_stem_inner_unarticled_NTM);
#line 625 "inform7/Chapter 27/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-stem-name>", rulebook_stem_name_NTM);
#line 848 "inform7/Chapter 27/Rulebooks.w"
REGISTER_NONTERMINAL("<rulebook-property>", rulebook_property_NTM);
#line 110 "inform7/Chapter 27/Focus and Outcome.w"
REGISTER_NONTERMINAL("<rulebook-default-outcome>", rulebook_default_outcome_NTM);
#line 114 "inform7/Chapter 27/Focus and Outcome.w"
REGISTER_NONTERMINAL("<rule-outcome>", rule_outcome_NTM);
#line 153 "inform7/Chapter 27/Focus and Outcome.w"
REGISTER_NONTERMINAL("<rulebook-outcome-list>", rulebook_outcome_list_NTM);
#line 158 "inform7/Chapter 27/Focus and Outcome.w"
REGISTER_NONTERMINAL("<rulebook-outcome-tail>", rulebook_outcome_tail_NTM);
#line 162 "inform7/Chapter 27/Focus and Outcome.w"
REGISTER_NONTERMINAL("<rulebook-outcome-setting-entry>", rulebook_outcome_setting_entry_NTM);
#line 165 "inform7/Chapter 27/Focus and Outcome.w"
REGISTER_NONTERMINAL("<form-of-named-rule-outcome>", form_of_named_rule_outcome_NTM);
#line 230 "inform7/Chapter 27/Focus and Outcome.w"
INTERNAL_NONTERMINAL("<named-rulebook-outcome>", named_rulebook_outcome_NTM, 1, 1000000000);
named_rulebook_outcome_NTM->voracious = 0;
#line 28 "inform7/Chapter 27/Rule Placement Sentences.w"
INTERNAL_NONTERMINAL("<rulebook-name>", rulebook_name_NTM, 1, 1000000000);
rulebook_name_NTM->voracious = 0;
#line 38 "inform7/Chapter 27/Rule Placement Sentences.w"
INTERNAL_NONTERMINAL("<rule-name>", rule_name_NTM, 1, 1000000000);
rule_name_NTM->voracious = 0;
#line 61 "inform7/Chapter 27/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<substitutes-for-sentence-subject>", substitutes_for_sentence_subject_NTM);
#line 65 "inform7/Chapter 27/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<substitutes-for-sentence-object>", substitutes_for_sentence_object_NTM);
#line 106 "inform7/Chapter 27/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<does-nothing-sentence-subject>", does_nothing_sentence_subject_NTM);
#line 141 "inform7/Chapter 27/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<listed-in-sentence-subject>", listed_in_sentence_subject_NTM);
#line 148 "inform7/Chapter 27/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<listed-in-sentence-object>", listed_in_sentence_object_NTM);
#line 167 "inform7/Chapter 27/Rule Placement Sentences.w"
REGISTER_NONTERMINAL("<destination-rulebook>", destination_rulebook_NTM);
#line 116 "inform7/Chapter 27/Activities.w"
REGISTER_NONTERMINAL("<activity-sentence-subject>", activity_sentence_subject_NTM);
#line 121 "inform7/Chapter 27/Activities.w"
REGISTER_NONTERMINAL("<activity-noted>", activity_noted_NTM);
#line 126 "inform7/Chapter 27/Activities.w"
REGISTER_NONTERMINAL("<activity-new-name>", activity_new_name_NTM);
#line 135 "inform7/Chapter 27/Activities.w"
REGISTER_NONTERMINAL("<activity-name-construction>", activity_name_construction_NTM);
#line 248 "inform7/Chapter 27/Activities.w"
REGISTER_NONTERMINAL("<activity-variable-name>", activity_variable_name_NTM);
#line 434 "inform7/Chapter 27/Activities.w"
REGISTER_NONTERMINAL("<run-time-context>", run_time_context_NTM);
#line 438 "inform7/Chapter 27/Activities.w"
REGISTER_NONTERMINAL("<activity-list-unnegated>", activity_list_unnegated_NTM);
#line 443 "inform7/Chapter 27/Activities.w"
REGISTER_NONTERMINAL("<activity-tail>", activity_tail_NTM);
#line 447 "inform7/Chapter 27/Activities.w"
REGISTER_NONTERMINAL("<activity-list-entry>", activity_list_entry_NTM);
#line 463 "inform7/Chapter 27/Activities.w"
REGISTER_NONTERMINAL("<activity-operand>", activity_operand_NTM);
#line 534 "inform7/Chapter 27/Activities.w"
INTERNAL_NONTERMINAL("<activity-name>", activity_name_NTM, 1, 1000000000);
activity_name_NTM->voracious = 0;
#line 555 "inform7/Chapter 27/Activities.w"
INTERNAL_NONTERMINAL("<if-parsing-al-conditions>", if_parsing_al_conditions_NTM, 0, 0);
if_parsing_al_conditions_NTM->voracious = 0;
#line 285 "inform7/Chapter 28/Phrases.w"
REGISTER_NONTERMINAL("<inline-phrase-definition>", inline_phrase_definition_NTM);
#line 136 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<rule-preamble>", rule_preamble_NTM);
#line 200 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<now-phrase-preamble>", now_phrase_preamble_NTM);
#line 210 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<rule-preamble-fine>", rule_preamble_fine_NTM);
#line 214 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<rule-preamble-finer>", rule_preamble_finer_NTM);
#line 219 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<rulebook-stem-embellished>", rulebook_stem_embellished_NTM);
#line 226 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<rulebook-bud>", rulebook_bud_NTM);
#line 457 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<unrecognised-rule-stem-diagnosis>", unrecognised_rule_stem_diagnosis_NTM);
#line 537 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<when-while-clause>", when_while_clause_NTM);
#line 934 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<parametric-problem-diagnosis>", parametric_problem_diagnosis_NTM);
#line 961 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<action-problem-diagnosis>", action_problem_diagnosis_NTM);
#line 1000 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<action-when-diagnosis>", action_when_diagnosis_NTM);
#line 1010 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<anl-diagnosis>", anl_diagnosis_NTM);
#line 1014 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<anl-inner-diagnosis>", anl_inner_diagnosis_NTM);
#line 1018 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<anl-tail-diagnosis>", anl_tail_diagnosis_NTM);
#line 1022 "inform7/Chapter 28/Phrase Usage.w"
REGISTER_NONTERMINAL("<anl-entry-diagnosis>", anl_entry_diagnosis_NTM);
#line 457 "inform7/Chapter 28/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<phrase-preamble>", phrase_preamble_NTM);
#line 462 "inform7/Chapter 28/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<to-preamble>", to_preamble_NTM);
#line 481 "inform7/Chapter 28/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<phrase-vetting>", phrase_vetting_NTM);
#line 509 "inform7/Chapter 28/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<say-preamble>", say_preamble_NTM);
#line 534 "inform7/Chapter 28/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<to-return-data>", to_return_data_NTM);
#line 543 "inform7/Chapter 28/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<return-kind>", return_kind_NTM);
#line 660 "inform7/Chapter 28/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<phrase-definition-word-or-token>", phrase_definition_word_or_token_NTM);
#line 673 "inform7/Chapter 28/Describing Phrase Type Data.w"
REGISTER_NONTERMINAL("<phrase-token-declaration>", phrase_token_declaration_NTM);
#line 134 "inform7/Chapter 28/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-declaration-list>", phrase_option_declaration_list_NTM);
#line 139 "inform7/Chapter 28/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-declaration-tail>", phrase_option_declaration_tail_NTM);
#line 145 "inform7/Chapter 28/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-declaration-setting-entry>", phrase_option_declaration_setting_entry_NTM);
#line 249 "inform7/Chapter 28/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-list>", phrase_option_list_NTM);
#line 254 "inform7/Chapter 28/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-tail>", phrase_option_tail_NTM);
#line 258 "inform7/Chapter 28/Phrase Options.w"
REGISTER_NONTERMINAL("<phrase-option-setting-entry>", phrase_option_setting_entry_NTM);
#line 289 "inform7/Chapter 28/Phrase Options.w"
INTERNAL_NONTERMINAL("<phrase-option>", phrase_option_NTM, 1, 1000000000);
phrase_option_NTM->voracious = 0;
#line 130 "inform7/Chapter 28/Phrasebook Index.w"
REGISTER_NONTERMINAL("<heading-with-parenthesis>", heading_with_parenthesis_NTM);
#line 135 "inform7/Chapter 28/Phrasebook Index.w"
REGISTER_NONTERMINAL("<heading-name-hyphenated>", heading_name_hyphenated_NTM);
#line 52 "inform7/Chapter 29/Adjectival Definitions.w"
REGISTER_NONTERMINAL("<definition-header>", definition_header_NTM);
#line 85 "inform7/Chapter 29/Adjectival Definitions.w"
REGISTER_NONTERMINAL("<adjective-definition>", adjective_definition_NTM);
#line 90 "inform7/Chapter 29/Adjectival Definitions.w"
REGISTER_NONTERMINAL("<adjective-domain>", adjective_domain_NTM);
#line 95 "inform7/Chapter 29/Adjectival Definitions.w"
REGISTER_NONTERMINAL("<adjective-wording>", adjective_wording_NTM);
#line 11 "inform7/Chapter 29/Adjectives by Raw Phrase.w"
REGISTER_NONTERMINAL("<inform6-routine-adjective-definition>", inform6_routine_adjective_definition_NTM);
#line 10 "inform7/Chapter 29/Adjectives by Raw Condition.w"
REGISTER_NONTERMINAL("<inform6-condition-adjective-definition>", inform6_condition_adjective_definition_NTM);
#line 638 "inform7/Chapter 30/Local Variables.w"
REGISTER_NONTERMINAL("<new-called-name>", new_called_name_NTM);
#line 642 "inform7/Chapter 30/Local Variables.w"
REGISTER_NONTERMINAL("<new-called-name-unarticled>", new_called_name_unarticled_NTM);
#line 648 "inform7/Chapter 30/Local Variables.w"
INTERNAL_NONTERMINAL("<existing-local-name>", existing_local_name_NTM, 1, 1000000000);
existing_local_name_NTM->voracious = 0;
#line 16 "inform7/Chapter 31/Parse Invocations.w"
REGISTER_NONTERMINAL("<end-phrase-construction>", end_phrase_construction_NTM);
#line 366 "inform7/Chapter 31/Compile Invocations Inline.w"
REGISTER_NONTERMINAL("<inline-substitution>", inline_substitution_NTM);
#line 375 "inform7/Chapter 31/Compile Invocations Inline.w"
INTERNAL_NONTERMINAL("<name-local-to-inline-stack-frame>", name_local_to_inline_stack_frame_NTM, 1, 1000000000);
name_local_to_inline_stack_frame_NTM->voracious = 0;
#line 222 "inform7/Chapter 32/Virtual Machines.w"
REGISTER_NONTERMINAL("<vm-description-list>", vm_description_list_NTM);
#line 227 "inform7/Chapter 32/Virtual Machines.w"
REGISTER_NONTERMINAL("<vm-description-tail>", vm_description_tail_NTM);
#line 231 "inform7/Chapter 32/Virtual Machines.w"
REGISTER_NONTERMINAL("<vm-description-entry>", vm_description_entry_NTM);
#line 238 "inform7/Chapter 32/Virtual Machines.w"
REGISTER_NONTERMINAL("<version-identification>", version_identification_NTM);
#line 307 "inform7/Chapter 32/Virtual Machines.w"
INTERNAL_NONTERMINAL("<virtual-machine>", virtual_machine_NTM, 1, 1000000000);
virtual_machine_NTM->voracious = 0;
#line 53 "inform7/Chapter 32/Inform 6 Inclusions.w"
REGISTER_NONTERMINAL("<inform6-inclusion-location>", inform6_inclusion_location_NTM);
#line 61 "inform7/Chapter 32/Inform 6 Inclusions.w"
REGISTER_NONTERMINAL("<inclusion-side>", inclusion_side_NTM);
#line 96 "inform7/Chapter 32/Use Options.w"
REGISTER_NONTERMINAL("<use-translates-as-sentence-object>", use_translates_as_sentence_object_NTM);
#line 129 "inform7/Chapter 32/Use Options.w"
REGISTER_NONTERMINAL("<use-sentence-object>", use_sentence_object_NTM);
#line 140 "inform7/Chapter 32/Use Options.w"
REGISTER_NONTERMINAL("<notable-use-option-name>", notable_use_option_name_NTM);
#line 265 "inform7/Chapter 32/Use Options.w"
REGISTER_NONTERMINAL("<immediate-use>", immediate_use_NTM);
#line 270 "inform7/Chapter 32/Use Options.w"
REGISTER_NONTERMINAL("<immediate-use-tail>", immediate_use_tail_NTM);
#line 274 "inform7/Chapter 32/Use Options.w"
REGISTER_NONTERMINAL("<immediate-use-entry>", immediate_use_entry_NTM);
#line 52 "inform7/Chapter 33/Bibliographic Data.w"
REGISTER_NONTERMINAL("<notable-bibliographic-variables>", notable_bibliographic_variables_NTM);
#line 92 "inform7/Chapter 33/Bibliographic Data.w"
REGISTER_NONTERMINAL("<titling-line>", titling_line_NTM);
#line 96 "inform7/Chapter 33/Bibliographic Data.w"
REGISTER_NONTERMINAL("<plain-titling-line>", plain_titling_line_NTM);
#line 212 "inform7/Chapter 33/Bibliographic Data.w"
REGISTER_NONTERMINAL("<episode-sentence-object>", episode_sentence_object_NTM);
#line 65 "inform7/Chapter 33/Release Instructions.w"
REGISTER_NONTERMINAL("<release-sentence-object>", release_sentence_object_NTM);
#line 104 "inform7/Chapter 33/Release Instructions.w"
REGISTER_NONTERMINAL("<privacy-indicator>", privacy_indicator_NTM);
#line 108 "inform7/Chapter 33/Release Instructions.w"
REGISTER_NONTERMINAL("<exposed-innards>", exposed_innards_NTM);
#line 49 "inform7/Chapter 34/The Naming Thicket.w"
REGISTER_NONTERMINAL("<notable-naming-properties>", notable_naming_properties_NTM);
#line 237 "inform7/Chapter 34/Spatial Model.w"
REGISTER_NONTERMINAL("<notable-spatial-kinds>", notable_spatial_kinds_NTM);
#line 348 "inform7/Chapter 34/Spatial Model.w"
REGISTER_NONTERMINAL("<notable-spatial-properties>", notable_spatial_properties_NTM);
#line 422 "inform7/Chapter 34/Spatial Model.w"
REGISTER_NONTERMINAL("<spatial-specifying-nouns>", spatial_specifying_nouns_NTM);
#line 466 "inform7/Chapter 34/Spatial Model.w"
REGISTER_NONTERMINAL("<notable-spatial-noun-phrases>", notable_spatial_noun_phrases_NTM);
#line 52 "inform7/Chapter 34/The Player.w"
REGISTER_NONTERMINAL("<notable-player-instances>", notable_player_instances_NTM);
#line 92 "inform7/Chapter 34/The Player.w"
REGISTER_NONTERMINAL("<notable-player-variables>", notable_player_variables_NTM);
#line 245 "inform7/Chapter 34/The Player.w"
REGISTER_NONTERMINAL("<implicit-player-relationship>", implicit_player_relationship_NTM);
#line 42 "inform7/Chapter 34/Backdrops.w"
REGISTER_NONTERMINAL("<notable-backdrops-kinds>", notable_backdrops_kinds_NTM);
#line 70 "inform7/Chapter 34/Backdrops.w"
REGISTER_NONTERMINAL("<notable-backdrops-properties>", notable_backdrops_properties_NTM);
#line 178 "inform7/Chapter 34/Backdrops.w"
REGISTER_NONTERMINAL("<notable-backdrops-noun-phrases>", notable_backdrops_noun_phrases_NTM);
#line 71 "inform7/Chapter 34/Regions.w"
REGISTER_NONTERMINAL("<notable-regions-kinds>", notable_regions_kinds_NTM);
#line 140 "inform7/Chapter 34/Regions.w"
REGISTER_NONTERMINAL("<notable-regions-properties>", notable_regions_properties_NTM);
#line 167 "inform7/Chapter 34/The Map.w"
REGISTER_NONTERMINAL("<notable-map-kinds>", notable_map_kinds_NTM);
#line 280 "inform7/Chapter 34/The Map.w"
REGISTER_NONTERMINAL("<notable-map-directions>", notable_map_directions_NTM);
#line 455 "inform7/Chapter 34/The Map.w"
REGISTER_NONTERMINAL("<notable-map-properties>", notable_map_properties_NTM);
#line 536 "inform7/Chapter 34/The Map.w"
REGISTER_NONTERMINAL("<notable-map-noun-phrases>", notable_map_noun_phrases_NTM);
#line 91 "inform7/Chapter 34/Map Connection Relations.w"
REGISTER_NONTERMINAL("<mapping-relation-construction>", mapping_relation_construction_NTM);
#line 94 "inform7/Chapter 34/Map Connection Relations.w"
REGISTER_NONTERMINAL("<mapping-preposition-construction>", mapping_preposition_construction_NTM);
#line 103 "inform7/Chapter 34/Map Connection Relations.w"
REGISTER_NONTERMINAL("<notable-directions>", notable_directions_NTM);
#line 997 "inform7/Chapter 34/HTML Map.w"
REGISTER_NONTERMINAL("<map-name-abbreviation-omission-words>", map_name_abbreviation_omission_words_NTM);
#line 304 "inform7/Chapter 34/EPS Map.w"
REGISTER_NONTERMINAL("<direction-name>", direction_name_NTM);
#line 316 "inform7/Chapter 34/EPS Map.w"
REGISTER_NONTERMINAL("<index-map-sentence-subject>", index_map_sentence_subject_NTM);
#line 328 "inform7/Chapter 34/EPS Map.w"
REGISTER_NONTERMINAL("<map-positioning>", map_positioning_NTM);
#line 388 "inform7/Chapter 34/EPS Map.w"
REGISTER_NONTERMINAL("<map-setting>", map_setting_NTM);
#line 393 "inform7/Chapter 34/EPS Map.w"
REGISTER_NONTERMINAL("<map-setting-scope>", map_setting_scope_NTM);
#line 397 "inform7/Chapter 34/EPS Map.w"
REGISTER_NONTERMINAL("<map-setting-scope-unarticled>", map_setting_scope_unarticled_NTM);
#line 411 "inform7/Chapter 34/EPS Map.w"
INTERNAL_NONTERMINAL("<map-parameter>", map_parameter_NTM, 1, 1000000000);
map_parameter_NTM->voracious = 0;
#line 440 "inform7/Chapter 34/EPS Map.w"
REGISTER_NONTERMINAL("<map-setting-value>", map_setting_value_NTM);
#line 447 "inform7/Chapter 34/EPS Map.w"
REGISTER_NONTERMINAL("<map-setting-boolean>", map_setting_boolean_NTM);
#line 457 "inform7/Chapter 34/EPS Map.w"
INTERNAL_NONTERMINAL("<map-offset>", map_offset_NTM, 1, 1);
map_offset_NTM->voracious = 0;
#line 467 "inform7/Chapter 34/EPS Map.w"
REGISTER_NONTERMINAL("<map-rubric>", map_rubric_NTM);
#line 118 "inform7/Chapter 34/Scenes.w"
REGISTER_NONTERMINAL("<notable-scene-properties>", notable_scene_properties_NTM);
#line 176 "inform7/Chapter 34/Scenes.w"
REGISTER_NONTERMINAL("<notable-scenes>", notable_scenes_NTM);
#line 335 "inform7/Chapter 34/Scenes.w"
REGISTER_NONTERMINAL("<scene-ends-sentence-subject>", scene_ends_sentence_subject_NTM);
#line 352 "inform7/Chapter 34/Scenes.w"
REGISTER_NONTERMINAL("<scene-ends-sentence-adverb>", scene_ends_sentence_adverb_NTM);
#line 360 "inform7/Chapter 34/Scenes.w"
REGISTER_NONTERMINAL("<scene-ends-sentence-object>", scene_ends_sentence_object_NTM);
#line 404 "inform7/Chapter 34/Scenes.w"
REGISTER_NONTERMINAL("<scene-name>", scene_name_NTM);
#line 408 "inform7/Chapter 34/Scenes.w"
REGISTER_NONTERMINAL("<scene-name-unarticled>", scene_name_unarticled_NTM);
#line 424 "inform7/Chapter 34/Scenes.w"
INTERNAL_NONTERMINAL("<scene-end-name>", scene_end_name_NTM, 1, 1000000000);
scene_end_name_NTM->voracious = 0;
#line 430 "inform7/Chapter 34/Scenes.w"
INTERNAL_NONTERMINAL("<scene-end-name-creating>", scene_end_name_creating_NTM, 1, 1000000000);
scene_end_name_creating_NTM->voracious = 0;
#line 850 "inform7/Chapter 34/Scenes.w"
REGISTER_NONTERMINAL("<s-scene-description>", s_scene_description_NTM);
#line 213 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<notable-actions>", notable_actions_NTM);
#line 220 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-name-construction>", action_name_construction_NTM);
#line 326 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-pronoun>", action_pronoun_NTM);
#line 355 "inform7/Chapter 35/Actions.w"
INTERNAL_NONTERMINAL("<action-name>", action_name_NTM, 1, 1000000000);
action_name_NTM->voracious = 0;
#line 382 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-optional-trailing-prepositions>", action_optional_trailing_prepositions_NTM);
#line 491 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-variable>", action_variable_NTM);
#line 499 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-variable-name>", action_variable_name_NTM);
#line 697 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-sentence-subject>", action_sentence_subject_NTM);
#line 725 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-clause>", action_clause_NTM);
#line 732 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-applications>", action_applications_NTM);
#line 744 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<act-req>", act_req_NTM);
#line 748 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-access>", action_access_NTM);
#line 756 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-sentence-object>", action_sentence_object_NTM);
#line 760 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-clauses>", action_clauses_NTM);
#line 765 "inform7/Chapter 35/Actions.w"
REGISTER_NONTERMINAL("<action-clause-terminated>", action_clause_terminated_NTM);
#line 111 "inform7/Chapter 35/Action Name Lists.w"
REGISTER_NONTERMINAL("<action-list>", action_list_NTM);
#line 119 "inform7/Chapter 35/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-excluded>", anl_excluded_NTM);
#line 123 "inform7/Chapter 35/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-minimal-common-operand>", anl_minimal_common_operand_NTM);
#line 148 "inform7/Chapter 35/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-to-tail>", anl_to_tail_NTM);
#line 152 "inform7/Chapter 35/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-operand>", anl_operand_NTM);
#line 155 "inform7/Chapter 35/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-in-tail>", anl_in_tail_NTM);
#line 183 "inform7/Chapter 35/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl>", anl_NTM);
#line 187 "inform7/Chapter 35/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-tail>", anl_tail_NTM);
#line 202 "inform7/Chapter 35/Action Name Lists.w"
REGISTER_NONTERMINAL("<anl-entry>", anl_entry_NTM);
#line 207 "inform7/Chapter 35/Action Name Lists.w"
INTERNAL_NONTERMINAL("<named-action-pattern>", named_action_pattern_NTM, 1, 1000000000);
named_action_pattern_NTM->voracious = 0;
#line 215 "inform7/Chapter 35/Action Name Lists.w"
INTERNAL_NONTERMINAL("<anl-entry-with-action>", anl_entry_with_action_NTM, 1, 1000000000);
anl_entry_with_action_NTM->voracious = 0;
#line 595 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pattern>", action_pattern_NTM);
#line 609 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<we-are-action-pattern>", we_are_action_pattern_NTM);
#line 620 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pattern-negated>", action_pattern_negated_NTM);
#line 631 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pattern-past>", action_pattern_past_NTM);
#line 639 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pattern-past-negated>", action_pattern_past_negated_NTM);
#line 660 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pattern-core-actor>", action_pattern_core_actor_NTM);
#line 679 "inform7/Chapter 35/Action Patterns.w"
INTERNAL_NONTERMINAL("<actor-description>", actor_description_NTM, 1, 1000000000);
actor_description_NTM->voracious = 1;
#line 746 "inform7/Chapter 35/Action Patterns.w"
INTERNAL_NONTERMINAL("<action-pattern-core>", action_pattern_core_NTM, 1, 1000000000);
action_pattern_core_NTM->voracious = 0;
#line 753 "inform7/Chapter 35/Action Patterns.w"
INTERNAL_NONTERMINAL("<action-pattern-past-core>", action_pattern_past_core_NTM, 1, 1000000000);
action_pattern_past_core_NTM->voracious = 0;
#line 769 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<action-pronominal>", action_pronominal_NTM);
#line 820 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<ap-common-core>", ap_common_core_NTM);
#line 831 "inform7/Chapter 35/Action Patterns.w"
INTERNAL_NONTERMINAL("<condition-in-ap>", condition_in_ap_NTM, 1, 1000000000);
condition_in_ap_NTM->voracious = 0;
#line 857 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<ap-common-core-inner>", ap_common_core_inner_NTM);
#line 868 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<ap-common-core-inner-inner>", ap_common_core_inner_inner_NTM);
#line 892 "inform7/Chapter 35/Action Patterns.w"
INTERNAL_NONTERMINAL("<ap-common-core-inner-inner-inner>", ap_common_core_inner_inner_inner_NTM, 1, 1000000000);
ap_common_core_inner_inner_inner_NTM->voracious = 0;
#line 921 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<action-operand>", action_operand_NTM);
#line 926 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<going-action-irregular-operand>", going_action_irregular_operand_NTM);
#line 930 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<understanding-action-irregular-operand>", understanding_action_irregular_operand_NTM);
#line 938 "inform7/Chapter 35/Action Patterns.w"
REGISTER_NONTERMINAL("<action-parameter>", action_parameter_NTM);
#line 945 "inform7/Chapter 35/Action Patterns.w"
INTERNAL_NONTERMINAL("<if-nonconstant-action-context>", if_nonconstant_action_context_NTM, 0, 0);
if_nonconstant_action_context_NTM->voracious = 0;
#line 137 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-sentence-subject>", understand_sentence_subject_NTM);
#line 159 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-regular-list>", understand_regular_list_NTM);
#line 164 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-regular-tail>", understand_regular_tail_NTM);
#line 168 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-regular-entry>", understand_regular_entry_NTM);
#line 175 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-list>", understand_property_list_NTM);
#line 180 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-tail>", understand_property_tail_NTM);
#line 184 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-entry>", understand_property_entry_NTM);
#line 248 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-sentence-object>", understand_sentence_object_NTM);
#line 252 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-sentence-object-uncond>", understand_sentence_object_uncond_NTM);
#line 257 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-sentence-object-tail>", understand_sentence_object_tail_NTM);
#line 261 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-sentence-entry>", understand_sentence_entry_NTM);
#line 290 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-as-this>", understand_as_this_NTM);
#line 301 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-ref>", understand_ref_NTM);
#line 373 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-command-sentence-object>", understand_command_sentence_object_NTM);
#line 402 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-sentence-object>", understand_property_sentence_object_NTM);
#line 406 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-sentence-object-unconditional>", understand_property_sentence_object_unconditional_NTM);
#line 411 "inform7/Chapter 36/Traverse for Grammar.w"
REGISTER_NONTERMINAL("<understand-property-reference>", understand_property_reference_NTM);
#line 94 "inform7/Chapter 36/Grammar Properties.w"
REGISTER_NONTERMINAL("<notable-parsing-variables>", notable_parsing_variables_NTM);
#line 187 "inform7/Chapter 36/Grammar Lines.w"
REGISTER_NONTERMINAL("<understand-condition>", understand_condition_NTM);
#line 63 "inform7/Chapter 36/Grammar Tokens.w"
REGISTER_NONTERMINAL("<grammar-token-breaking>", grammar_token_breaking_NTM);
#line 208 "inform7/Chapter 36/Grammar Tokens.w"
REGISTER_NONTERMINAL("<grammar-token>", grammar_token_NTM);
#line 225 "inform7/Chapter 36/Grammar Tokens.w"
REGISTER_NONTERMINAL("<standard-grammar-token>", standard_grammar_token_NTM);
#line 242 "inform7/Chapter 36/Grammar Tokens.w"
INTERNAL_NONTERMINAL("<named-grammar-token>", named_grammar_token_NTM, 1, 1000000000);
named_grammar_token_NTM->voracious = 0;
#line 79 "inform7/Chapter 36/Test Scripts.w"
REGISTER_NONTERMINAL("<test-sentence-subject>", test_sentence_subject_NTM);
#line 90 "inform7/Chapter 36/Test Scripts.w"
REGISTER_NONTERMINAL("<internal-test-case-name>", internal_test_case_name_NTM);
#line 116 "inform7/Chapter 36/Test Scripts.w"
REGISTER_NONTERMINAL("<test-sentence-object>", test_sentence_object_NTM);
#line 121 "inform7/Chapter 36/Test Scripts.w"
REGISTER_NONTERMINAL("<test-case-circumstance-list>", test_case_circumstance_list_NTM);
#line 126 "inform7/Chapter 36/Test Scripts.w"
REGISTER_NONTERMINAL("<test-case-circumstance>", test_case_circumstance_NTM);
#line 103 "inform7/Chapter 37/Figures.w"
REGISTER_NONTERMINAL("<figure-sentence-object>", figure_sentence_object_NTM);
#line 107 "inform7/Chapter 37/Figures.w"
REGISTER_NONTERMINAL("<figure-source>", figure_source_NTM);
#line 127 "inform7/Chapter 37/Figures.w"
REGISTER_NONTERMINAL("<notable-figures>", notable_figures_NTM);
#line 95 "inform7/Chapter 37/Sound Effects.w"
REGISTER_NONTERMINAL("<sound-sentence-object>", sound_sentence_object_NTM);
#line 99 "inform7/Chapter 37/Sound Effects.w"
REGISTER_NONTERMINAL("<sound-source>", sound_source_NTM);
#line 91 "inform7/Chapter 37/External Files.w"
REGISTER_NONTERMINAL("<external-file-sentence-subject>", external_file_sentence_subject_NTM);
#line 97 "inform7/Chapter 37/External Files.w"
REGISTER_NONTERMINAL("<external-file-name>", external_file_name_NTM);
#line 101 "inform7/Chapter 37/External Files.w"
REGISTER_NONTERMINAL("<external-file-owner>", external_file_owner_NTM);
#line 127 "inform7/Chapter 37/External Files.w"
REGISTER_NONTERMINAL("<external-file-sentence-object>", external_file_sentence_object_NTM);
#line 36 "inform7/Chapter 38/Translate to Identifiers.w"
REGISTER_NONTERMINAL("<translates-into-i6-sentence-subject>", translates_into_i6_sentence_subject_NTM);
#line 61 "inform7/Chapter 38/Translate to Identifiers.w"
REGISTER_NONTERMINAL("<translates-into-i6-sentence-object>", translates_into_i6_sentence_object_NTM);
#line 136 "inform7/Chapter 38/Translate to Identifiers.w"
REGISTER_NONTERMINAL("<extra-response>", extra_response_NTM);
#line 62 "inform7/Chapter 38/Plugins.w"
REGISTER_NONTERMINAL("<plugin-name>", plugin_name_NTM);
#line 87 "inform7/Chapter 38/Plugins.w"
REGISTER_NONTERMINAL("<language-element>", language_element_NTM);
#line 213 "inform7/Chapter 38/Plugins.w"
REGISTER_NONTERMINAL("<use-language-element-sentence-subject>", use_language_element_sentence_subject_NTM);
}